Level up my program
August 25, 2024 9:12 AM   Subscribe

So thanks to you kind folks, I got my guess the number python program working. Now I want to have the user choose a level, where the range of numbers gets bigger in different levels.

I have choosing the level working. However, when I try to assign a value to mystery_number using that level, it breaks.

Here's the code:
import random

print ("This is a game to guess a random number." )
print ("There are three different levels you can play at. ")
print ("Level 1 has numbers 1-10, Level 2 has numbers 1-50 and Level 3 has numbers 1-100")

level = input ("What level would you like to play, 1, 2, or 3? Press Enter: ");
print (level)

# This initalizes the variable?

mystery_number = 5
           
if level == 1:
   mystery_number = random.randint(0,10);
   print ("You chose Level, level")
if level == 2:
    mystery_number = random.ranint(0,50);
    print ("You chose Level, level")
if level == 3:
    mystery_number = random.randit(0-100);
    print ("You chose Level, level")

print (mystery_number)  #This is for debugging
If I set the mystery number to 5 (I was using this for debugging), well, the mystery number is 5. If I comment that code out, then mystery_number isn't defined and the program exits with the following...
What level would you like to play, 1, 2, or 3? Press Enter: 1
name 'mystery_number' is not defined
Stack trace:
 >  File "C:\Users\ksmar\source\repos\Guess the Number\Guess_the_Number_Leveled.py", line 57, in  (Current frame)
 >    print (mystery_number)  #This is for debugging
 >           ^^^^^^^^^^^^^^
 >NameError: name 'mystery_number' is not defined
Loaded '__main__'
Loaded 'runpy
So clearly there's something wrong in that block of code I just can't see.
posted by kathrynm to Computers & Internet (9 answers total)
 
Best answer: Python is NOT my forte, but...

From your output it's never getting to / interpreting the 'print (input)' line for some reason, so the error in the code is probably near there.

Your 'level' is being input as a string, but later your if statements look like you are comparing an integer value. Could it be that you need to run int(level) to make that an integer (or, alternatively, compare using quotes e.g. if level == "1": )? This is often a problem in other languages where variables aren't datatype agnostic like perl.
posted by SquidLips at 9:31 AM on August 25


Best answer: The code level = input("prompt") results in level containing a string (type str), which you cannot compare to an integer. If you need to, you can convince yourself that this is true by printing its' type:
print("the type of level is", type(level))
which will print
the type of level is <class 'str'>
You can either compare your string to another string by quoting what you are comparing to, for example:
if level == '1':
  print("foo")
or you can try to cast your string to an int with something like
level = int(input("What level would you like to play, 1, 2, or 3? Press Enter: "))

The int(foo) block takes the value of foo and tries to interpret it as an integer. If you type something that can't be cast to an integer you'll get an error though -- I'll leave try/catch and error handling as an exercise for you to dig into later!

As a note, your print statements to print the level are not going to do what you want. You typed
print ("You chose Level, level")
which prints the literal string You chose level, level. I think what you wanted to do to is print what level the user chose, which needs the closing quote in a different place:
print ("You chose Level", level)
This prints the string You chose Level and then appends the value of the variable level!
posted by Alterscape at 9:32 AM on August 25


Best answer: The input() function returns a string, not an int. So level will never be equal to 1, 2, or 3, and mystery_number will never be set.

The main fix is to parse the level string into an int:
level = int(input(...))
But a good way to avoid this problem in similar situations is to get in the habit of checking all possible values exhaustively instead of only the expected values
if level == 1:
    ...
elif level == 2:
    ...
elif level == 3:
    ...
else:
    print(f"Unrecognized level {level}. Please choose 1, 2, or 3.")

posted by Phssthpok at 9:34 AM on August 25 [1 favorite]


Best answer: Apart from the issues mentioned, I think you're actual error is just typos:

random.ranint(0,50);

Should be

random.randint(0,50);

and

random.randit(0-100);

should be

random.randint(0,100);


Also, given the description, I think you want to start the randint range at 1, not 0?
posted by Zalzidrax at 10:09 AM on August 25 [1 favorite]


Just a sidenote, as a fellow amateur, learning to use the debugger was endlessly helpful to me. If you can make effective use of breakpoints, and keep an eye on how variables change as you step through your code, you'll be ahead of the game next time. Good luck!
posted by AbelMelveny at 10:39 AM on August 25 [2 favorites]


Response by poster: Once again, thank you all. It is now working.

I don't have a problem I need to solve right now, so I'm off to find a new project. If anyone has any suggestions, I'd love to hear them.
posted by kathrynm at 2:29 PM on August 25


If your library has a copy of The Big Book of Small Python Projects, take a look in it to see if there's something that catches your fancy.

Personally, I enjoyed working through the weekly exercises from Python Morsels back when I was trying to keep from getting rusty (and snagged a very discounted subscription). You can try three exercises for free, if you want to give it a try.
posted by needled at 5:58 PM on August 25


Best answer: Just a sidenote, as a fellow amateur, learning to use the debugger was endlessly helpful to me.

Another good approach when you're getting to understand why something isn't working is to walk through your expectations and assumptions at each point.

For example, with this line

level = input ("What level would you like to play, 1, 2, or 3? Press Enter: ");

your assumption (I assume... ;-) was that the variable "level" would now hold a number. When you wrote your if statements, you also expected the level variable to be an integer so it could pass tests like 'does this equal 3?' And you expected the integer to be either 1, 2, or 3, and not say 0 or -5 or 20.

But those assumptions can go wrong in all kinds of ways. One way is what happened in this case, where the input function actually returns a string and not an integer, so the level variable held a string and not an integer. And your if statements were expecting an integer, so none of them matched and the code inside them never got executed.

Think of other ways those assumptions could fail: the user enters something that's not a number. The user enters a number like 10000 or 4.23. The user just hits enter without inputting anything. Etc. Some of those will cause errors that python complains about. Others (like the level variable holding an integer that's not 1, 2, or 3) will be fine from python's perspective but your code will just silently not work the way you expect, because for example right now you're expecting one of the three if statements to match and a number like 27 won't match any of them.


To write code that works it helps to think from both directions:

(a) what things might happen that I'm not imagining, like a wise-ass user entering 3*8 or the input function not returning what I expect it to return?

(b) what assumptions need to be met for this line or function to actually work? What am I doing to make sure those assumptions are met?

For example, in a line like

if level == 1:

you ask yourself what kind of values level could hold that would make the test fail. Not just 2 or 3, but possibly 1.0 (I don't know if this would fail in python or not - do you?), or -1 or "1", or "one", or "", or a null value, or ....

And then you think "how can I make sure that level holds only the kind of values that would work in this if statement?"

Similarly, how might a line like

level = int(input(...))

fail? (Hint: what kind of input does the int() function require? What kind of errors does it throw if it's given input it doesn't know how to turn into an integer?)


I'd suggest doing a short project that lets you learn about error handling and has lots of room for assumptions to go wrong. (Projects that rely on user input or input from reading files have a high chance of that happening, since often that input isn't in the form you expect.)
posted by trig at 1:15 AM on August 26 [2 favorites]


Best answer: Another good thing that's worth learning about is "test driven development" or just unit testing in general.

If you write little tests for each individual bit of your program, it's much easier to figure out what exactly has gone wrong when the overall thing stuffs up in some confusing way.

This forces you to write the code (and think of it) as separate individual bits at different levels of abstraction, which helps avoid having it all mush together into confusing spaghetti that's hard for you to understand.

You can also use "assert" just wherever in your code, to make sure that something you believe to be true, is really true. This isn't a great idea in fancy production code (where you need user-friendly error handling), but for learning purposes it can be really useful.
posted by quacks like a duck at 6:43 AM on August 26 [2 favorites]


« Older Changing careers when you don't know what your...   |   Fence gate: must be to code and must solve marital... Newer »

You are not logged in, either login or create an account to post comments