import random
def guessNumber(guess):
if guess == randomNumber:
return 'Good job!'
elif guess > randomNumber:
return'That is to high!'
elif guess < randomNumber:
return 'That is to low!'
guesses = 0
randomNumber = random.randint(1, 20)
# print(randomNumber)
print('Im thinking of a number between 1 and 20.')
answer = ''
while answer != 'Good job!':
print('Take a guess')
answer = guessNumber(int(input()))
print(answer)
guesses = guesses + 1
if answer == 'Good job!':
break
print(f'{answer}, You guessed my number in {guesses} guesses!')
I have been trying to learn programming for on and off a year. Currently I am on a hot streak of 2 weeks!
This is my solution. I did this without cheating or first looking at the answer code. I am very happy with myself that I did this one on my own.
-
\$\begingroup\$ Micro-review: spelling is incorrect in user messages - should be "That is too high/low". \$\endgroup\$Toby Speight– Toby Speight2023年06月09日 05:59:06 +00:00Commented Jun 9, 2023 at 5:59
-
\$\begingroup\$ Check that user input is numeric before converting it to int. \$\endgroup\$nico– nico2023年06月09日 07:13:15 +00:00Commented Jun 9, 2023 at 7:13
3 Answers 3
If the user input can't be converted to int
, we'll get an exception (and ugly backtrace) here:
answer = guessNumber(int(input()))
I'd be inclined to create a function for reading integer input, something like this:
def input_int(prompt):
while True:
try:
s = input(prompt)
return int(s)
except ValueError:
print(f"Sorry, {s} isn't a valid integer")
It's usually a good idea to put your overall functionality in a function called main
, and only call that if this is the top level.
if __name__ == '__main__':
main()
This becomes more important when you start writing Python modules, but even at this stage, it helps give the right scope to our variables.
I don't like using the global variables. guesses
is easily removed, since it's only used in the main()
loop. But randomNumber
is also used by guessNumber()
, so we'll need to pass it in as a parameter:
def guessNumber(guess, actual):
⋮
Comparing the user-displayed string seems like a reasonable idea now, but there's actually a problem lurking there. When we add translation to support more languages, that simple test will no longer work.
I think the best fix for that is a complete restructure, so that main()
sees your hidden number and the user's guess (so it chooses the message to display, and breaks out when guess == actual
).
-
\$\begingroup\$ Thank you very much, i will try to redo the exercises with the information you gave me! \$\endgroup\$Jarne Vercruysse– Jarne Vercruysse2023年06月09日 11:04:36 +00:00Commented Jun 9, 2023 at 11:04
-
\$\begingroup\$ I've never understood the
if __name__ == '__main__': main()
motivation. Why not just put the effective script from main() under the if statement instead of adding an extra step? \$\endgroup\$Andrew Holmgren– Andrew Holmgren2023年06月09日 13:55:49 +00:00Commented Jun 9, 2023 at 13:55 -
3\$\begingroup\$ @AndrewHolmgren That way gives you the option of executing the code by importing the file (e.g. from another script or the REPL) and calling main(). (Also makes it easier to parametrise inputs to the script as arguments to main()). \$\endgroup\$Seb– Seb2023年06月09日 14:03:32 +00:00Commented Jun 9, 2023 at 14:03
-
2\$\begingroup\$ @AndrewHolmgren: Putting code inside a function is also better for performance in the CPython interpreter, since variables can be local variables, instead of having to do name lookup up in the global scope. why the local function is faster in python and how to prove? / Performance with global variables vs local \$\endgroup\$Peter Cordes– Peter Cordes2023年06月12日 04:31:18 +00:00Commented Jun 12, 2023 at 4:31
to high
should be too high
.
guessNumber
should be guess_number
by PEP8.
Im
should be I'm
.
guesses = guesses + 1
can be guesses += 1
.
A good program separates its input/output from its business logic, among other reasons so that you can unit test the logic, and so that you can swap out the interface with a different one. There are many ways to do this; I demonstrate one below. This uses some mid-level concepts that will probably pull you out of beginner material, but I consider that healthy.
from random import randint
from typing import Iterator, Iterable
GUESS_LOWER = 1
GUESS_UPPER = 20
def get_guess() -> int:
"""
Keep asking the user for a guess until we get one that is numeric and within the guess bounds.
"""
while True:
try:
guess = int(input('Take a guess: '))
except ValueError:
print('Invalid number')
continue
if not (GUESS_LOWER <= guess <= GUESS_UPPER):
print('Number out of range')
else:
return guess
def calculate_game(guesses: Iterable[int], answer: int) -> Iterator[int]:
"""
Business logic for guessing.
:param guesses: An infinite iterator of user guess integers.
:param answer: The integer the user is trying to guess
:return: An iterator of -1, 0 or 1, meaning too-low, correct or too-high.
"""
for guess in guesses:
diff = guess - answer
if diff == 0:
yield 0
break
yield diff // abs(diff)
def print_game(answer: int) -> int:
"""Run the game with console input/output."""
# This makes an iterator that infinitely yields the return value of get_guess().
guesses = iter(get_guess, None)
responses = {
-1: 'That is too low!',
0: 'Good job!',
1: 'That is too high!',
}
# enumerate() gives us pairs: the number of guesses (starting at 1),
# and the diff from calculate_game().
for guess_count, diff in enumerate(calculate_game(guesses, answer), start=1):
print(responses[diff])
return guess_count
def main() -> None:
print(f"I'm thinking of a number between {GUESS_LOWER} and {GUESS_UPPER}.")
answer = randint(GUESS_LOWER, GUESS_UPPER)
guess_count = print_game(answer)
print(f'You guessed my number in {guess_count} guesses!')
if __name__ == '__main__':
main()
-
2\$\begingroup\$ "I consider that healthy" - agreed; that's a good program to learn from. \$\endgroup\$Toby Speight– Toby Speight2023年06月09日 14:36:09 +00:00Commented Jun 9, 2023 at 14:36
while answer != 'Good job!': print('Take a guess') answer = guessNumber(int(input())) print(answer) guesses = guesses + 1 if answer == 'Good job!': break
The break
statement is not needed, since the while
loop will stop once the the answer is 'Good job!'{
while answer != 'Good job!':
print('Take a guess')
answer = guessNumber(int(input()))
print(answer)
guesses = guesses + 1
Explore related questions
See similar questions with these tags.