6
\$\begingroup\$

I am trying to create a simple Python project. It's a minigame about guessing a number.

It's a game where the computer will pick a random number from 1 to 10.

  • The player needs to guess it correctly.
  • Every wrong attempt will give you a clue.
  • 3 clues and the player will lose.

I've built the code and it works just fine. Here's the code :

total = 0
guessme = 0

def GuessNum(guess):
    global total
    global guessme
    
    prime = [2, 3, 5, 7]

    if total == 0:
        randnum = random.randint(1,10)
        guessme = randnum

    total += 1

    if guess == guessme:
        print("You are correct!")
        guessme = 0
        total = 0
    else:
        if total == 1:
            if guessme % 2 == 0:
                print("The number is even")
            else:
                print("The number is odd")
            
        elif total == 2:
            if guessme > 5:
                print("The number is greater than 5")
            else:
                print("The number is smaller than 5")
        
        elif total == 3:
            if guessme in prime:
                print("The number is prime")
            else:
                print("The number is not a prime")
            
        else:
            guessme = 0
            total = 0
            print("You failed to guess the number.")

Are there ways to make this code much more efficient or shorter? I am still new at programming so I would love to learn new things.

\$\endgroup\$
2
  • \$\begingroup\$ How are you taking input from the user? Also since you are using a function try to use return instead of global variables. \$\endgroup\$ Commented Dec 1, 2020 at 18:09
  • 2
    \$\begingroup\$ Printing The number is smaller than 5 when the number is 5 is, hm, tricky. \$\endgroup\$ Commented Dec 1, 2020 at 20:51

2 Answers 2

3
\$\begingroup\$

The code is fairly okay and readable. Since you highlighted performance, my review would not touch on some areas that are lacking.

Prefer random.random() to generate pseudorandom numbers

import timeit

test1 = '''
import random
random.randint(1,10)
'''

test2= '''
import random
int(10 * random.random())
'''

tt1 = timeit.repeat(stmt=test1, repeat=5, number=1)
print('randint time taken: ', min(tt1))

tt2 = timeit.repeat(stmt=test2, repeat=5, number=1)
print('random.random() time taken: ', min(tt2))

On running the above program, the following results were gotten. NOTE: The results might vary on your computer, but there is still some difference.

randint time taken = 2.1700000005546375e-06

random.random() time taken = 6.056000074750045e-06

Though the difference is insignificant, it might mean a lot when the range increases.

\$\endgroup\$
3
\$\begingroup\$

Observations:

  • PEP 8 suggests using snake case for function names. A name like GuessNum is appropriate for a class, but a function should be something like guess_num.
  • This is a less appropriate name than check_guess, which is a better reflection of what the function actually does.
  • As there are no repeats, prime is probably better as a set rather than a list. prime = {2, 3, 5, 7}
  • randnum is assigned, and then that is immediately assigned to guessme. Skip the middleman and just write guessme = random.randint(1,10)
  • The following has unnecessary nesting.
    if guess == guessme:
        print("You are correct!")
        guessme = 0
        total = 0
    else:
        if total == 1:
            if guessme % 2 == 0:
                print("The number is even")
            else:
                print("The number is odd")
            
        elif total == 2:
            if guessme > 5:
                print("The number is greater than 5")
            else:
                print("The number is smaller than 5")
        
        elif total == 3:
            if guessme in prime:
                print("The number is prime")
            else:
                print("The number is not a prime")
            
        else:
            guessme = 0
            total = 0
            print("You failed to guess the number.")

Can just be:

    if guess == guessme:
        print("You are correct!")
        guessme = 0
        total = 0

    elif total == 1:
        if guessme % 2 == 0:
            print("The number is even")
        else:
            print("The number is odd")
            
    elif total == 2:
        if guessme > 5:
            print("The number is greater than 5")
        else:
            print("The number is smaller than 5")
        
    elif total == 3:
        if guessme in prime:
            print("The number is prime")
        else:
            print("The number is not a prime")
            
    else:
        guessme = 0
        total = 0
        print("You failed to guess the number.")
  • guessme is not a great variable name. I would use something like correct_number that more accurately reflects what it is.
  • total isn't a great name either. Maybe number_of_attempts?
  • Persistent state suggests a class/object rather than global variables.

With some of these suggestions in mind, you might write something like the following.

primes = {2, 3, 5, 7}

class GameOverException(Exception):
    pass

class GuessingGame(object):

    def __init__(self, upper_limit=10):
        self.correct_number = random.randint(1, upper_limit)
        self.number_of_attempts = 0

    def make_guess(self, guess):
        if self.number_of_attempts > 3:
            raise GameOverException()

        elif guess == self.correct_number:
            print("You are correct!")

        else:
            self.number_of_attempts += 1

            if self.number_of_attempts == 1:
                if self.correct_number % 2 == 0:
                    print("The number is even")
                else:
                    print("The number is odd")

            elif self.number_of_attempts == 2:
                if self.correct_number > 5:
                    print("The number is greater than 5")
                else:
                    print("The number is smaller than 5")

            elif self.number_of_attempts == 3:
                if self.correct_number in prime:
                    print("The number is prime")
                else:
                    print("The number is not a prime")
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.