Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Basics (2015) Number Game App Number Game Introduction

Sergej Dolezil
Sergej Dolezil
958 Points

Using a function for user input?

Hi,

I tried using a function for the user input and then using the latter function in main() (the function running other functions of the script), but I only get outputs that the guess is too low even for 10...

If I remove the function and just use the input code within main() the script runs fine, so I am just wondering is this due to a logical error I made (likely) or Python just does not run like that?

A - code with the input function B - code without the input function

A:

import random

secret_num = random.randint(1,10)

def usr_input(guess): guess = int(input("Guess a number between 1 and 10: \n"))

def high(): print("Sorry, your guess is too high, try again.")

def low(): print("Sorry, your guess is too low, try again.")

def gotit(secret_num): print("You got it! My number was {}".format(secret_num))

def main(): guess = 0 while secret_num != guess: usr_input(guess)

if guess > secret_num:
  high()

elif guess < secret_num:
  low()

gotit(secret_num)

main()

B:

import random

secret_num = random.randint(1,10)

def high(): print("Sorry, your guess is too high, try again.")

def low(): print("Sorry, your guess is too low, try again.")

def gotit(secret_num): print("You got it! My number was {}".format(secret_num))

def main(): guess = 0 while secret_num != guess: guess = int(input("Guess a number between 1 and 10: \n"))

if guess > secret_num:
  high()

elif guess < secret_num:
  low()

gotit(secret_num)

main()

1 Answer

andren
andren
28,558 Points

It's a bit of both, there is a logic error in your code, but it is likely caused by the fact that you misunderstand a certain part about how Python works.

The reason why your code does not work is because of a concept called variable scope, basically when you create a variable that variable will either have a local or a global scope, the scope determines where the variable can be accessed from. If the variable is declared within a function it will have a local scope and so can only be accessed within that function. If it is declared outside a function it will have a global scope, which means it can be accessed from any function in your application. But global variables are discouraged for the most part, so unless you really need to share some data between a large amount of functions you should stick to local scope variables.

What this means is that when you set the guess variable in the usr_input function you are not actually changing the contents of the guess variable in the main function since the guess variable declared in the main function can only be accessed from the main function. You are instead creating a new variable within the usr_input function called guess. And even though the variables end up having the same name they are considered two completely separate things by Python, setting the guess variable within usr_input will therefore not change the guess variable within the main function.

So the reason why you always get told that the number is too low is that the guess variable in the main function never actually gets set to a new value, meaning that it remains at 0 every time you make a guess.

The way you can work around this problem is to return the input from the usr_input function using the return keyword, and then assign the returned value to the guess variable in the main function, this is how data is usually sent between functions.

Here is an example of how that would look:

import random

secret_num = random.randint(1,10)

def usr_input():
  return int(input("Guess a number between 1 and 10: \n"))

def high():
  print("Sorry, your guess is too high, try again.")

def low():
  print("Sorry, your guess is too low, try again.")

def gotit(secret_num):
  print("You got it! My number was {}".format(secret_num))

def main():
  guess = 0
  while secret_num != guess:
    guess = usr_input()
    if guess > secret_num:
      high()
    elif guess < secret_num:
      low()
  gotit(secret_num)
main()

You might also notice that I remove guess as a parameter for the usr_input function, this is because the function does not actually need that parameter, all it does is take input from the user and return it, knowing what the previous guess was is not something that helps the function in any way.

If you have any further questions about this topic, or if you found some part of my explanation unclear and want something clarified then feel free to ask me follow up questions, I'll be happy to answer any question I can.

Edit: clarified my explanation on local and global scope variables a bit.

Sergej Dolezil
Sergej Dolezil
958 Points

Andren,

thanks a lot for the detailed and insightful answer!

Understand clearly now where the mistake was, and you explained the concepts of local and global scopes of variables very well, thanks a lot!