Hello i'm new to Python and i'm having a little trouble. I'm reading Hello Python
and i'm typing a code down it told me to type, but when i run the code, it gives me an error.
Error: caves[next_cave].append(i) List index out of range
This is the code i'm typing out.
Code:
from random import choice
cave_numbers = range(0,20)
caves = []
for i in cave_numbers:
caves.append([])
unvisited_caves = range(0,20)
visited_caves = [0]
unvisited_caves.remove(0)
while unvisited_caves != []:
i = choice(visited_caves)
if len(caves[i]) >= 3:
continue
next_cave = choice(unvisited_caves)
caves[i].append(next_cave)
caves[next_cave].append(i)
visited_caves.append(next_cave)
unvisited_caves.remove(next_cave)
for number in cave_numbers:
print number, ":", caves[number]
print'-----------'
for i in cave_numbers:
while len(caves[i]) < 3:
passage_to = choice(cave_numbers)
cave[i].append(passage_to)
for number in cave_numbers:
print number, ":", caves[number]
print '----------'
Thank you for answering my question
-Cyr
choice(unvisited_caves) in going to return a number from unvisited_caves = range(0,20), so that would be a random number from 0..19.
caves[next_cave].append(i) will error 90% of the time (18/20 times) because all you have done is caves = [] and caves.append([]), so caves has at most one element in the first iteration of your program.
Maybe you have an indentation problem, but overall, using random numbers of a different range to index a list seems like a bad design.
I think your problem is just with indentation. I believe that your intent was to use the for loop to give your list of caves 20 empty arrays before you begin your simulation. As you had it, your loop would add one array and then start the simulation right away. Your caves list is not ready for this, and so it errors.
The following should work better:
from random import choice
cave_numbers = range(0,20)
caves = []
for i in cave_numbers:
caves.append([])
unvisited_caves = range(0,20)
visited_caves = [0]
unvisited_caves.remove(0)
while unvisited_caves != []:
i = choice(visited_caves)
if len(caves[i]) >= 3:
continue
next_cave = choice(unvisited_caves)
caves[i].append(next_cave)
caves[next_cave].append(i)
visited_caves.append(next_cave)
unvisited_caves.remove(next_cave)
for number in cave_numbers:
print number, ":", caves[number]
print'-----------'
for i in cave_numbers:
while len(caves[i]) < 3:
passage_to = choice(cave_numbers)
caves[i].append(passage_to)
for number in cave_numbers:
print number, ":", caves[number]
print '----------'
I only made two edits:
First, I unindented so that the while loop comes after the for loop finishes
You also had a typo where you said cave[i] instead of caves[i]
Also note, there are some opportunities to simplify your code here. At first this may seem merely aesthetic, but it can actually help avoid errors like this. For example:
for i in cave_numbers:
caves.append([])
can become caves = [ [] for each in cave_numbers] which would have left less room for errors.
That error means that at some point, the value in next_cave exceeds the length of the caves list.
You'd get that same error by doing this:
caves = [[0,1,2], [4,5,6]]
caves[2].append([7,8,9])
Related
Let's say I wanted to add all items in a list. One of the issues is, this list can go on forever. Here's an example:
a = 0
lst = [int(0)]
ItemsInList = int(input("How many items do you want in this list? "))
while a != ItemsInList:
a + 1
Item = int(input("What should item", a, "be? "))
lst.append(Item)
Now I want to add all those together. I cannot do print(lst[0] + lst[1] + lst[2] + lst[3] etc etc.. because if I were to do that and the list were to have more items then 3 I wouldn't have added the whole list. If I were to just do that again and again and again until it reached lst[500] I would get an error because that item probably wont exist most of the time. I'm thinking of making a while command inside the print() but I can't figure out if that is possible or not. Any ideas of simplifying that code or just helping me with the actual issue would be much appreciated. This is to make a mean average calculator by the way.
To add all the items in a list, just use the sum method, like this:
lst = [1,2,3]
print(sum(lst))
Output:
6
But instead of appending all the inputs to a list, you can have a running total, like this:
total = 0
for a in range(ItemsInList):
Item = int(input("What should item", a, "be? "))
total += Item
This would work faster than the code that you're using currently.
Apart from that, there are many flaws in your code, like:
a+1. You did not assign the resulting value to a, so the loop would be infinite. It should instead be a += 1 or a = a+1
Using a while loop when you know how many times you want to execute the loop.
lst = [int(0)]. This isn't wrong, but this isn't the right way either to initialize a list. You can do it like this: lst = []
Make sure that you don't repeat these mistakes! Hope that this helps!
I'm new to a programming language and wanted to start with Python as its the recommendation of most people (as far as i see).
So, im practising on some functions to improve my understanding on loops, and basic statements etc. Though i'm not very good at it yet, i do believe that i'll improve sooner or later.
Here is an example where i'm stuck at:
def L():
List = []
TauS = []
a = 12
for i in range(1,a+1):
if a % i == 0:
List.append(i)
if a % len(List) == 0:
TauS.append(a)
print(List)
print(TauS)
L()
This is the function i want to have and the output is:
[1, 2, 3, 4, 6, 12]
[12]
As i expected.However, the problem is that i want "a" to be a variable instead of a constant.Something like:
def L():
List = []
TauS = []
for a in range(2,20):
for i in range(1,a+1):
if a % i == 0:
List.append(i)
if a % len(List) == 0:
TauS.append(a)
print(List)
print(TauS)
L()
Fails because it seems like for loop is working before the 2nd if statement (if a % len(list)) == 0: TauS.append(a)).I have also tried a "while" loop instead of a "for" loop as:
a = 2
while a <= 20:
for i in range(1,a+1):...(The rest is the same)
It would be a better idea if your help focus on the basic ideas instead of just giving the right function.
Thanks a lot from now!
Regards.
Python uses indention levels to tell whether code is in within a function, loop or condition, the general thing being that if there is a : then all the code indented underneath it is within that statement.
The problem with your code is that the second if statement is on the same indention level as the for loop rather than being on the indention level below the for loop. This means that rather than running in the for loop it runs after it.
So to fix your code all you need to do is select the if statement and press crtl + ] which is pythons keyboard shortcut for indent code section.
edit:
I think what you're asking for is to get all the factors of numbers from 2 to 19 and then print numbers where the number of factors is a factor of that number.
def L():
List = []
TauS = []
for a in range(2,20):
l=[] #this is the list for each individual number
#if i is a factor of a add it to l
for i in range(1,a+1):
if a % i == 0:
l.append(i)
#if length of l is a factor of a add a to TauS
if a % len(l) == 0:
TauS.append(a)
List.append(l)
print(List)
print(TauS)
L()
It fails because of variable scope.
Python uses indention to represent code block. So, here for loop and 2nd if condition has same indention which means they belong to same code block and can access variables defined in the same or the outer code block. "List" & "Taus" in this case.
However, Variable "a" is localize to outer for loop and can be access in the same or inner for loop and cant be access from outside. Similarly variable "i" is specific to inner for loop and cant be access outside of the loops block, not even from outer for loop.
Hope it helps...
I need to write a script that generates random numbers between 1-257000 and stops when a certain number occurs telling me how many numbers it generated so far.
i manged to get this far but can't seem to get it to stop or count
x=1
while x < 257000:
import itertools
import random
def random_gen(low, high):
while True:
yield random.randrange(1, 257000)
gen = random_gen(1, 100)
items = list(itertools.islice(gen, 10))
print items
x = x+1
Thank you so much for your help
Huh. A few flaws (or at least unclear spots) in your code.
You run your loop max 257000 times. Even though the probability is low, there is a chance that you don't hit the number you seek in the loop.
Move your import statements out of your loop, no need to have python check loaded modules each round.
You use a generator for choices of a list (randrange) where you can simply use a randint() call.
You define a closed function within your loop which creates a new function at a new memory address each round.
You slice your results into lists of 10 elements each; is this for printing, or do you actually need your random integers grouped into such lists?
A very simple and straightforward implementation of your described problem could be:
import random
num = 0 # Our counter
certain_number = 123456 # The number we seek
while True: # Run until we break
# Increment for each new step
num += 1
# Generate a single number from the given range
random_number = random.randint(1, 257000)
if random_number == certain_number:
# Break if we hit it
break
print('Hit after {} tries.'.format(num))
>>> Hit after 382001 tries.
First, put your import statements and your function definitons outside your while-loop. That's being super redundant.
>>> def random_gen(low,high):
... while True:
... yield random.randrange(low,high)
...
>>> lucky = 7
>>> rg = random_gen()
>>> rg = random_gen(1,1000)
>>> next(itertools.dropwhile(lambda t: t[1] != lucky, enumerate(rg, 1)))
(811, 7)
>>>
Here's another run, just for fun:
>>> rg = random_gen(1,257000)
>>> n,L = next(itertools.dropwhile(lambda t: t[1] != lucky, enumerate(rg, 1)))
>>> n
22602
>>> L
7
>>>
I am using the simple program below to see how long an iterative process takes to terminate. However, in line 15, I cannot figure out why I am getting index out range error.
An example of what I am trying to count is the number of steps it takes for the following example iteration: User inputs 4 and then 1234. Then we have: [1,2,3,4] --> [1,1,1,1] --> [0,0,0,0] and then termination. 2 steps is required to get to [0,0,0,0]. I have proven that for the values of n that I am inserting, the system goes to [0,0,0,0] eventually.
import math
index = input("Enter length: ")
n = int(index)
game = input("Enter Coordinates of length n as a number: ")
s = list(game)
Game = []
for k in s:
Game.append(int(k))
l = len(game)
while sum(Game) > 0:
Iteration = []
k = 0
j = 0
while j < l-1:
Iteration.append(math.fabs(Game[j]-Game[j+1])) # line 15
j = j+1
k = k+1
Game = Iteration
print(k)
Game = Iteration is probably why. When j = 1, Game will be a list with only one item because of that. Then, Game[1]-Game[2] will be out of bounds.
Your code is written in a very un-Pythonic style that suggests you're translating directly from C code. (Also, you should basically never use input(); it's insecure because it evaluates arbitrarily user-entered Python code! Use raw_input() instead.)
If you rewrite it in a more Pythonic style, it becomes clear what the problem is:
import math
# you don't do anything with this value, but okay
s = index = int(raw_input("Enter length: "))
# game/Game naming will lead to confusion in longer code
game = raw_input("Enter Coordinates of length n as a list of comma-separated numbers: ")
Game = [int(k) for k in game.split(',')]
l = len(Game)
while sum(Game) > 0:
Game = [math.fabs(Game[j]-Game[j+1]) for j in range(l-1)] # problem here
# no idea what k is for, but it's not used in the loop anywhere
The problem is that in every iteration through your inner while loop, or the line marked # problem here in my version, your Game list gets shorter by one element! So on the second time through the outer while loop, it reads an element past the end of Game.
I have no idea what this code is trying to do, so I can't really suggest a fix, but if you truly intend to shorten the list on every pass, then you of course need to account for its shorter length by putting l=len(Game) inside the while loop.
I was told to do this as homework. So far I did the following:
a = raw_input("Please enter a number:")
b = a.split()
for c in range(len(b)):
b[c] = int(b[c])
n=[]
big=b[0]
while b != []:
for i in range(len(b)):
if big < b[i]:
big!=b[i]
n=n+[big]
b.remove(big)
print n
Here's an example:
459113
And the output is suppose to be:
954331
The challenge is not to use sorting algorithms, which is hard for me to do since I don't know how to get around it.
The basis of that program is from:
a = raw_input("Please enter a number:")
b = a.split()
for c in range(len(b)):
b[c] = int(b[c])
n=[]
small=b[0] while b != []:
small=b[0]
for i in range(len(b)):
if small > b[i]:
small=b[i]
n=n+[small]
b.remove(small)
print n
You could try something like this:
a = raw_input("Please enter a number:")
b = map(int, a)
n=[]
while b:
smallest = min(b)
n.append(smallest)
b.remove(smallest)
print
print ''.join(map(str, n))
See it working online: ideone
It's the same algorithm as your existing code, but I've fixed a number of errors. Note that this is not an efficient algorithm. It runs in O(n2) time. Using the builtin sorted function you could achieve O(n log(n)) time, and with a counting sort you could even reach O(n) time.
Note that this sorts in ascending order, not descending order. Since this is homework I'll leave it as an exercise for you to figure out what one thing you need to change to fix this.
Here are some other notes about the changes I made to your program:
Don't call split on your input. That splits on whitespace, which is probably not what you want since your example input doesn't contain any whitespace.
I used map instead of a for loop to convert all elements in a sequence.
I used min to find the smallest value instead of iterating over the sequence.
Maybe not the best way to sort a list but here is another example :)
Im even able to do it without sorting them.
from Queue import Queue
import threading
import time
def sleeper(x, queue):
time.sleep(x)
queue.put(x)
a = [3,2,1,4,3,2,5]
longest = max(a)
threads = {}
queue = Queue()
for num in a:
threads[num] = threading.Thread(target=sleeper, args=(num, queue))
threads[num].start()
threads.get(longest).join()
while not queue.empty():
print queue.get()
For Python you can try the following code :
def Descending_Order(num):
return int("".join(sorted(str(num), reverse=True)))