## Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

### Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today. # Python: Number Game Refinement

im debugging what i have right now and so when i type in a number, it tells me "local variable 'count' referenced before assignment. But I initialized my count variable at the very top so i dont understand why it is telling me this. The error occurs in my guessed() method which is the first function below.

```import random

# variables
n1 = 1
n2 = 10
count = 0
guess_count = 10
again = False
guess = ""
secret_numer = ""

# functions
def guessed():
count += 1
guess_count -= 1

def isValid(input):
try:
int(input)
return True
except ValueError:
return False

def winMessage():
print("You guessed the number! It took you {} tries and you had {} guess left".format(count, guess_count))

def loseMessage():
print("You have used all your guesses. Game over")

def incorrectGuessMessage():
if guess > secret_number:
print("{} was incorrect. Your guess was too high. You have {} guesses left".format(guess, guess_count))
else:
print("{} was incorrect. Your guess was too low. You have {} guesses left".format(guess, guess_count))

def promptPlayAgain():
response = input("Would you like to play again? Type 'Y' or 'N'")
if response.upper() == "Y":
main()

# main
def main():
print("Welcome. You have {} guesses to guess the number. Guess a number between {} and {}: ".format(guess_count, n1, n2))
secret_num = random.randint(n1, n2)
while True:

if guess_count != 0:

guess = int(input("> "))
if isValid(guess):
if guess == secret_num:
winMessage()
break
else:
guessed()
incorrectGuessMessage()
else:
print("That is not a proper number")
continue

else:
loseMessage()
break
promptPlayAgain()

main()
``` Ok I did this and it worked. However, I read on stackoverflow that we should NOT use global variables but i honestly dont know how to do this without the use of global variables. i did not yet watch kenneth's solution yet. i was wondering if I can have some feedback on this code.

```import random

count = 0
guess_count = 10

# functions
def guessed():
global count
global guess_count
count += 1
guess_count-=1

def isValid(input):
try:
int(input)
return True
except ValueError:
return False

def winMessage():
print("You guessed the number! It took you {} tries and you had {} guess left".format(count, guess_count))

def loseMessage():
print("You have used all your guesses. Game over")

def incorrectGuessMessage(guess, secret_num):
if guess > secret_num:
print("{} was incorrect. Your guess was too high. You have {} guesses left".format(guess, guess_count))
else:
print("{} was incorrect. Your guess was too low. You have {} guesses left".format(guess, guess_count))

def promptPlayAgain():
response = input("""Would you like to play again? Type 'Y' or 'N':
> """)
if response.upper() == "Y":
main()

# main
def main():
global count
global guess_count
count = 0
guess_count = 10
n1 = 0
n2 = 10
print("Welcome. You have {} guesses to guess the number. Guess a number between {} and {}: ".format(guess_count, n1, n2))
secret_num = random.randint(n1, n2)
while True:

if guess_count != 0:

guess = input("> ")
if isValid(guess):
guess = int(guess)
guessed()
if guess == secret_num:
winMessage()
break
else:
incorrectGuessMessage(guess, secret_num)
continue
else:
print("That is not a proper number")
continue

else:
loseMessage()
break
promptPlayAgain()

main()
``` MOD

To avoid using `global` pass the variables as arguments:

```# functions
def guessed(count, guess_count):
count += 1
guess_count-=1
```

EDIT: Above trivial example does not modify the variables in the global scope because the `int` arguments are immutable. Pass arguments as list or dict:

```>>> counts = {'count': 0, 'global_guesses': 0}
>>> def test_modifies_global(counts):
...     counts['count'] += 1
...     counts['global_guesses'] += 2
...     print("counts", counts)
...
``` That's actually what I did at first but it wasn't updating the "count" and "guess_count" variables located inside my main() method

I tried again and still doesnt work

Am I supposed to return the count and guess_count variables from the guessed() method? and then update the variables from my main method? My fault. The example I used was too trivial.

``` If you pass immutable arguments like integers, strings or tuples to a function, the passing acts like call-by-value. The object reference is passed to the function parameters. They can't be changed within the function, because they can't be changed at all, i.e. they are immutable. It's different, if we pass mutable arguments [like lists, dicts, classes]. They are also passed by object reference, but they can be changed in place in the function. If we pass a list to a function, we have to consider two cases: Elements of a list can be changed in place, i.e. the list will be changed even in the caller's scope. If a new list is assigned to the name, the old list will not be affected, i.e. the list in the caller's scope will remain untouched. ``` Reference

If `count` were a list:

```>>> count = 
>>> def test_modifies_global(count):
...     count += 1
...     print("count:", count)
...
>>> count

>>> test_modifies_global(count)
count: 
>>> test_modifies_global(count)
count: 
>>> test_modifies_global(count)
count: 
>>> test_modifies_global(count)
count: 
```

Or a dict:

```>>> counts = {'count': 0, 'global_guesses': 0}
>>> def test_modifies_global(counts):
...     counts['count'] += 1
...     counts['global_guesses'] += 2
...     print("counts", counts)
...
>>> counts
{'count': 0, 'global_guesses': 0}
>>> test_modifies_global(counts)
counts {'count': 1, 'global_guesses': 2}
>>> test_modifies_global(counts)
counts {'count': 2, 'global_guesses': 4}
>>> test_modifies_global(counts)
counts {'count': 3, 'global_guesses': 6}
>>> counts
{'count': 3, 'global_guesses': 6}
``` thanks alot for that. I didn't understand the dict part as we haven't learned that yet but I do understand what you wrote with the list. Lists are mutable and so if we pass in a parameter that takes in a list and we modify that parameter, the list will be changed even from outside that function. if we pass in string or ints, then a local variable of that parameter will be created. makes sense

i encountered some problems now. This is a snippet from my guessed method. I tried to follow your example but I get this error: Index Error: List index out of range

This doesn't make sense to me because we are just increasing the length of the list by 1 or decreasing it by 1. Why would an Index Error possibly occur?

```n1 = 
n2 = 

guessed(count, guess_count, n1, n2)

def guessed(count, guess_count, n1, n2):
count[n1] += 1
guess_count[n2] -=1
```

And also im trying to call len() on the list so i can get the actual number instead of something like . I called the len() function on a list of 10 however instead of the number 10, i get the number 1. Any idea why this is the case?

This is another snippet

```    count = 
guess_count = 
n1 = 0
n2 = 10
print("Welcome. You have {} guesses to guess the number. Guess a number between {} and {}: ".format(len(guess_count), n1, n2))
```

What gets printed is "You have 1 guesses to......" It should say 10 instead of 1

Here is my full code as of now:

```import random

# functions
def guessed(count, guess_count, n1, n2):
count[n1] += 1
guess_count[n2] -=1

def isValid(input):
try:
int(input)
return True
except ValueError:
return False

def winMessage(count, guess_count):
print("You guessed the number! It took you {} tries and you had {} guess left".format(count, guess_count))

def loseMessage():
print("You have used all your guesses. Game over")

def incorrectGuessMessage(guess, secret_num, guess_count):
if guess > secret_num:
print("{} was incorrect. Your guess was too high. You have {} guesses left".format(guess, guess_count))
else:
print("{} was incorrect. Your guess was too low. You have {} guesses left".format(guess, guess_count))

def promptPlayAgain():
response = input("""Would you like to play again? Type 'Y' or 'N':
> """)
if response.upper() == "Y":
main()

# main
def main():
count = 
guess_count = 
n1 = 0
n2 = 10
print("Welcome. You have {} guesses to guess the number. Guess a number between {} and {}: ".format(len(guess_count), n1, n2))
secret_num = random.randint(n1, n2)
while True:

if guess_count != 0:

guess = input("> ")
if isValid(guess):
guess = int(guess)
guessed(count, guess_count, n1, n2)
if guess == secret_num:
winMessage(len(count), len(guess_count))
break
else:
incorrectGuessMessage(guess, secret_num, len(guess_count))
continue
else:
print("That is not a proper number")
continue

else:
loseMessage()
break
promptPlayAgain()

main()
``` The key is not to confuse the index of a value and the list with the actual value.

```count =   # list with one item at index 0 with value count
guess_count =  # list with one item at index 0 with value guess_count

def guessed(count, guess_count):
# count and guess_count passed as lists
# modify the first item in list count. This is the actual count value
count += 1
# modify the first item in list guess_count. This is the actual guess_count value
guess_count -=1
```

My example of modifying the lists `count` and `guess_count` were intended to be examples of technique and not necessarily directly applicable to your code situation. In my example, I was using a 1-item list for `count` and `guess_count` to illustrate how the results of passing a list and modifying the items of that list within a function can be seen outside of the function.

Overall, I'm not sure how you are using `count` vs `guess_count`. Are `n1` and `n2` used as the initial values for the low and high limits? Oh I completely misinterpreted what you were saying. I thought that count =  and guess_count =  meant that we were creating a list with 0 items and 10 items respectively and therefore the lengths of each are 0 and 10 respectively. I got confused with java where you can specify the initial length of an array. After I realized my mistake, everything made sense instantly.

The program is working perfectly now. thanks for the help ```def playAgainCheck():
print("Do you want to play again? Y/N ")
while True:
playAgain = input(">  ")
if playAgain == "Y":
return True
elif playAgain == "N":
return False
else:
print("Please enter Y or N only")

def checkNumber():
print("Is the number bigger or smaller? B/S ")
while True:
checkGuess = input("> ")
if checkGuess == "S":
return "S"
elif checkGuess == "B":
return "B"
else:
print("Please enter either S or B ")

def guessRandomNumber(count,number1,number2,removeList):
valuesList = []
values = range(number1,number2+1)
#print(values)
for i in values:
if i not in valuesList:
valuesList.append(i)
for i in removeList:
#print(removeList)
if i in valuesList:
#print(valuesList)
valuesList.remove(i)
random.shuffle(valuesList)
return valuesList

import random

# check for int input
# too high
# too low
# play again

count = 0
keepPlaying = True
smallBig = "B"
guess = 0
while keepPlaying:
if count == 0:
guessList = []
removeList = []
number1 = 1
number2 = 10
guess = random.randint(1,10)
removeList.append(guess)
else:
guessList = guessRandomNumber(count,number1,number2,removeList)
#for item in guessList:
#print(item)
guess = guessList.pop()
removeList.append(guess)
#print(removeList)
count += 1
answer = input("Computer says {}, Is this right? Y/N  ".format(guess))
print("Computer won!")
count = 0
keepPlaying = playAgainCheck()
elif count == 5:
count = 0
print("Computer lost!")
keepPlaying = playAgainCheck()
else:
smallBig = checkNumber()
if smallBig == "S":
number2 = guess
else:
number1 = guess
```