3
\$\begingroup\$

Is there any room for improvement?

import random

def play_again():
    while True:
        replay = input('Play again? Yes or No?\n')
        if replay.lower() == 'yes':
            return True
        elif replay.lower() == 'no':
            return False
        print('Invalid input.')

def main():
    print('Welcome to the number guess game!', end='\n\n')

    random_number = random.choice(range(1, 51)) #Genarate a number between 1 and 50 inclusive

    print("I'm thinking of a number which is between 1 and 50 (inclusive). Can you guess it?")

    guesses, guess = 0, 0

    while guess != random_number:
        try:
            guess = int(input("Enter a number: "))
        except:
            print('Invalid input.')
            continue
        if guess > random_number:
            print('Too high. Guess lower.')
        elif guess < random_number:
            print('Too low. Guess higher.')
        guesses+=1
    print('Congratz. You guessed my number {0} in {1} guesses'.format(random_number, guesses))

    if play_again():
        main()
    else:
        print('Bye!')

main()
\$\endgroup\$
3
\$\begingroup\$

main()

You should use if __name__ == "__main__":, like this:

if __name__ == "__main__": 
    main()

This will prevent your code from automatically running if you ever import this module into another module.

Methods

I like how you split play_again() into a separate method. However, you should use more methods, including a unique method to play the game, and perhaps a method to input a guess from the user.

Recursion

Recursion here is not good. If the user plays the game enough times, you could have a stack overflow exception:

if play_again():
    main()
else:
    print('Bye!')

If you split the game up into multiple methods that you can call, each method could finish and get removed from the stack before it returns control to the caller, so you never have a stack overflow.

An example of this would be to have something like this:

def play_again():
    # code here

def game():
    # play game here

def main():
    print('Welcome to the number guess game!', end='\n\n')

    play_game = True
    while play_game:
        game()
        play_game = play_again()

if __name__ == "__main__":
    main()
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I'm wondering what is the solution with the recursion problem. Is removing that part from main and adding while play_again(): main() print('Bye!') (the print is unindented) at the end of the program good? \$\endgroup\$ – Spikatrix Jun 10 '15 at 6:47
  • \$\begingroup\$ @CoolGuy I posted a snippet demonstrating what I mean. \$\endgroup\$ – user34073 Jun 10 '15 at 15:45
2
\$\begingroup\$

In play_again, it's not very friendly that users must type "yes" or "no". A more common practice is to be forgiving, for example allow a simple "y" or "n", or even assume that a simple enter means Yes. Like this:

def play_again():
    return input('Play again? Yes or No?\n').lower() != 'no'

That is, play again until user types "no". Much more ergonomic, easier to play.


In the main while loop, initially the condition is true, and when the if and elif both don't match, it implies guess != random_number but this fact is not used. I would rework the loop like this:

while True:
    try:
        guess = int(input("Enter a number: "))
    except:
        print('Invalid input.')
        continue

    guessCount += 1

    if guess > random_number:
        print('Too high. Guess lower.')
    elif guess < random_number:
        print('Too low. Guess higher.')
    else:
        break

It's better to avoid similar variable names, I'm talking about guesses, guess. I'd rename guesses to guessCount.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.