Reputation: 46
I guess my problem isn't so much with methods as it is with slicing a list (such as list[2:5]). When the code is actually being run, it is not cutting the list at the right place. The program is attempting to guess a number that was given to it by a user. It is doing this using the random module ,which i know may not be the best way, but I was experimenting.
The Code:
import random
number = input('Pick a number from 1-100 for the computer to guess, \nand find out how many tries it takes the computer: ')
print number
possibilities = range(101)
del possibilities[0]
tries = 1
guess = random.choice(possibilities)
print "\n", guess
while guess != number:
if guess > number:
possibilities = possibilities[:(guess-1)]
else:
possibilities = possibilities[(guess-1):]
print possibilities
guess = random.choice(possibilities)
print guess
tries += 1
Example of the errors:
Output of the program, from the print statements above. I would also like to mention that it does not always malfunction, about 50-60% of the time it works fine. Also, it is not just the numbers that I put in, for example, 45 may work fine, or it may fail as it did below, it seems like a pretty random occurrence.
With initial input 45:
45
30 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
88 Initial Error (the program should have cut off the list past 88) [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
54 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82] 40 Fatal Error (Where it cut off the list, removing the number it was 'looking' for) [69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82] 72 [69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82]
With initial input 6:
6
48
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]
9
[1, 2, 3, 4, 5, 6, 7, 8]
5 **Initial Error** (the program should have eliminated 5 from the list below this line)
[5, 6, 7, 8]
5 **Fatal Error** (the program deleted the rest of the list)
[]
Traceback (most recent call last):
File "C:\Users\Joseph\Documents\Programming fun\computer guessing a number game.py", line 32, in <module>
guess = random.choice(possibilities)
File "C:\Python27\lib\random.py", line 274, in choice
return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
IndexError: list index out of range
I would like to know why Python is doing this, and if it is avoidable or not. I don't think there is a problem with my code, it looks to me like Python is just not working the way it is supposed to, but I am extremely new to programming so I am not sure if I am missing something.
Thank you for any help that may be provided.
Upvotes: 0
Views: 688
Reputation: 36011
Slices are defined by the index not the value of the element. If you have a slice x[a:b]
of a list that gives a list with the a
th item followed by the a+1
th item up to but not including the b
th item. If b
is less than or equal to a
the result will be empty. If b
is greater than or equal to the number of items in the list every item after the a
th will be included. If you omit the first number, 0 is assumed and if you omit the second number, the number of items in the list is assumed. Here's an example that doesn't use numbers in the list to avoid confusion:
x = ['a','b','c','d','e','f','g']
print x[3:] # prints ['d','e','f','g']
print x[:2] # prints ['a','b']
print x[1:4] # prints ['b','c','d']
If you use a negative number in a slice then the length of the list will be added to the number to determine the final index.
To get your code to work correctly and still use slices to refine the list of possibilities, there is an index
method for lists that will give the index (of course) of the item passed as an argument. So for your program you could change the lines to read
if guess > number:
possibilities = possibilities[:possibilities.index(guess)]
else:
possibilities = possibilities[possibilities.index(guess):]
A better way to write a guess-the-number type program is to instead use just two variables hi
and lo
that keep track of the biggest and lowest numbers, respectively, that the answer could be. If the answer is greater than the guess then set lo
to be the guess plus one and if the answer is less than the guess set hi
to be the guess minus one.
Upvotes: 0
Reputation: 14261
You are confusing the values in possibilities
with their indices. mylist[:i]
means "all values in mylist up to the ith element", not "up to the element with the value i".
Initially, confusing indices and values doesn't cause a problem because your list values are (almost, since you skip 0) equal to their indices. But when you start cutting pieces of the list away, you get the situation that the list is shorter than some of the values in it. For example, when everything below 80 has been removed and you guess 90, possibilities[90:]
tries to access the 90th element onwards from a list of length 20. Of course, that doesn't work.
Try this instead:
i = possibilities.index(guess)
possibilities = possibilities[:(i-1)]
Upvotes: 1
Reputation: 9926
When "5" is selected, this code will remove from the fifth position onwards. You array has only four elements, so that means all of it.
Upvotes: 0
Reputation: 375594
When you do guess = random.choice(possibilities)
, you are getting a value from the list, but then you use it as an index when you do this: possibilities = possibilities[:(guess-1)]
. After a few times around the loop, your list has values that are outside the range of indexes:
[80, 81, 82, 83, 84, 85, 86, 87]
When you select a value from here (like 85), then do possibilities = possibilities[85:]
, you get back an empty list.
You need to stick to indexes.
Upvotes: 2