11
\$\begingroup\$

I made a number guessing game in Python 3 using jupyter notebook. I would appreciate it a lot if I could get some feedback on my code.

from random import randint
randnumb = randint(1,100)
guesses = 0
maxGuesses = 5
while guesses < maxGuesses:
 personInput = int(input('What is your guess? '))
 guesses = guesses + 1
 if personInput == randnumb:
 print()
 print('You won! It took you', guesses, 'guess(es)!')
 break
 if personInput > randnumb and guesses != maxGuesses:
 print('Guess lower', '(', maxGuesses - guesses,'guess(es) left)')
 print()
 if personInput < randnumb and guesses != maxGuesses:
 print('Guess higher', '(', maxGuesses - guesses,'guess(es) left)')
 print()
 if guesses == maxGuesses and personInput != randnumb:
 print()
 print('You lost! You ran out of your guesses!')
 print('The answer was', randnumb, '!')
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked May 1, 2018 at 20:54
\$\endgroup\$
0

3 Answers 3

11
\$\begingroup\$

Pretty clean looking code, but let's look at a few ways it could be better or more pythonic:

  • Use elif statements:

    if personInput == randnumb:
     # ...
    elif personInput > randnumb: # You already know they're != at this point
     # ...
    elif ...
    
  • Use snake case for your variable names. E.g., use person_input instead of personInput (which is camel case), and rand_num instead of randnumb. In that second case, it's also more common to shorten "number" to "num" instead of "numb".

  • Use format strings instead of print's argument concatenation, e.g.:

    print("Guess lower ({} guesses left)".format(max_guesses - guesses))
    
  • Check for and handle errors:

    try:
     person_input = int(input("What is your guess? "))
    except ValueError:
     print("Not sure what you meant by that, please input an integer")
     continue
    
  • I prefer to be more safe than sorry when handling my own incrementor, such as guesses, just in case I do something funky that lets it skip over max_guesses:

    # Since you "break" on correct answer, we don't need to check that again
    if guesses >= max_guesses:
     # ...
    

EDIT:

One more thing. In Python, to write a script (rather than a module), you should check if __name__ == '__main__': as follows:

from random import randint
def main():
 randnumb = randint(1,100)
 guesses = 0
 maxGuesses = 5
 while guesses < maxGuesses:
 # ...
if __name__ == '__main__':
 main()

This allows for safe code re-use, and makes sure that the code doesn't get run if this file gets imported from another file. It's not technically necessary for a one-file script like you're writing here, but it's a good practice to get into anyway.

answered May 1, 2018 at 21:09
\$\endgroup\$
7
  • \$\begingroup\$ FYI: you don't need the explicit <!-- language --> declarations. \$\endgroup\$ Commented May 1, 2018 at 21:27
  • 1
    \$\begingroup\$ @Coal_ Heh, got my markdown code-reviewed :P I've just had issues on SO getting code to format properly between bullets; just double-indenting like that is the solution? \$\endgroup\$ Commented May 1, 2018 at 21:28
  • \$\begingroup\$ Yep, that's all. \$\endgroup\$ Commented May 1, 2018 at 21:34
  • \$\begingroup\$ I applied almost every tip to my code, especially the format strings is a really nice way of cleaning things up but I still had a few questions. In what context does it matter if I use elif instead of if after already using an if conditional? How can I make sure the player can only input a number between 1 and 100? What do you exactly mean with "you should check if name == 'main':", I don't really get what I should achieve with this piece of code and what it does. \$\endgroup\$ Commented May 2, 2018 at 19:03
  • \$\begingroup\$ @Ian elif is equivalent to else: if, and should be used when only one of a series of conditions should be entered, exclusive to the others. In your case, the guess is either above, below, or equal to the correct answer, it can never be more than one of those. elif captures this logic cleanly and simplifies your conditions in the process. \$\endgroup\$ Commented May 2, 2018 at 19:06
4
\$\begingroup\$

Just a few notes:

  • You should display the range from which the number has been chosen, and specify if the endpoint is included or not (i.e. can the number be 100?).
  • 5 guesses aren't enough to find the number reliably, even with a perfect strategy (a binary search). Do you want your game to include a part of chance? If not, max_guesses should be 7 (math.ceil(math.log(100, 2)))
answered May 2, 2018 at 8:22
\$\endgroup\$
0
4
\$\begingroup\$

Well done.

  • You could make it better by 'encapsulating' it into a function, so that you can use it or use a modified version of it in your other projects.

  • Instead of checking 'maxGuesses' several times, you can make use of logical flags.

  • personally I prefer using "for loops" if you know number of iterations.

  • maybe you can improve it by asking the user if he wants to play again or not.

    from random import randint
    def GuessNumber(maxGuesses=5):
     randnumb = randint(1,100)
     # a logical flag to check whether user guessed the number or not - at the end of all guesses
     user_won = False
     for i in range(maxGuesses):
     personInput = int(input('What is your guess? '))
     if personInput == randnumb:
     print()
     print('You won! It took you {} guess(es).'.format(i+1))
     user_won = True 
     break
     elif personInput > randnumb:
     print('Guess lower, {} guess(es) left.'.format(maxGuesses-i-1))
     print()
     else:
     print('Guess higher, {} guess(es) left.'.format(maxGuesses-i-1))
     print()
     # if user did not guess the number in all guesses
     if not user_won:
     print()
     print('You lost! You ran out of your guesses!')
     print('The answer was', randnumb, '!')
    

=====

update: a way to play it several times:

Here is what we want to do:

  • we want to make a function, that works with "any" game.

  • that function asks the user if he want to play again or not:

______ if he wants to play again, then we run the game again.

______ if he does not want to play again, then end the program.

  • we can "break" the problem to smaller problems,

    by making another function that asks the user if he wants to play again or not:

______ if he want, then that function returns True

______ if he does not want, then it returns False

  • I encourage you to stop reading and try to do it yourself, and below is a code to do it.

=====

def playAgain():
 """returns True if user wants to play again, False otherwise."""
 while True:
 # ask user if he/she wants to play again
 play_again = input('Play again? <y/n>:')
 # if first character of user's answer is 'y', then return True.
 # strip: is used to remove empty spaces that could be in start or end of user's input
 # lower: is used to take the first character and make it in lowercase, for example
 # if user types 'Yes' or 'yes' both will be accepted, and return True
 if play_again.strip().lower()[0] == 'y':
 return True
 # if user types 'no' - either in lowercase or uppercase - return False
 elif play_again.strip().lower()[0] == 'n':
 return False
 # if user writes another word that does not start with 'y' nor 'n', ask him again - that's why its a loop
 else:
 print('Wrong input! Please enter "yes" or "no"!')
def playSeveralTimes(game_func):
 """takes game's function - without () - runs it as many times as user wants."""
 while True:
 # run the game
 game_func()
 # if user does not want to play again - break out of loop
 if not playAgain(): break
# run the game
playSeveralTimes(GuessNumber)
answered May 1, 2018 at 22:00
\$\endgroup\$
2
  • \$\begingroup\$ Thanks a lot for the tips, I haven't been that busy with functions and for loops but I will definitely practice it more. I just had one question, how can I let the user play the game again? I tried some googling and playing around in the code but I can't seem to figure it out. \$\endgroup\$ Commented May 2, 2018 at 19:09
  • \$\begingroup\$ @Ian You're welcome, added a way to the comment, I encourage you not to read the code directly, try to do it first yourself. \$\endgroup\$ Commented May 3, 2018 at 12:00

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.