# Guessing game - Too high. Too low

I will post 2 scripts that are doing (supposedly) the same thing. First one is the script i created, second one is the solution from the course.

What would you consider wrong (if anything) with the script that i made? Should i think scripts more like the second one, with functions and so?

My script

import random

print(art.logo)
print("Welcome to the number guessing game! ")
print("I'm thinking of a number between 1 and 100.")

difficulty = input("Choose a difficulty. Type 'easy' or 'hard': ")

ATTEASY = 10
ATTHARD = 5
playAgain = True

while playAgain :
numberIs = random.randint(0,100)
atteasy = ATTEASY
atthard = ATTHARD

while atteasy and atthard != 0 :
if difficulty == "easy" :
print(f"You have {atteasy} attempts remaining to guess the number. ")
guess = input("Make a guess: ")
if int(guess) == numberIs :
print(f"You are right! The number was indeed {numberIs}")
break
else :
if int(guess) > numberIs :
print("To high.")
else :
print("To low.")
atteasy = atteasy - 1
if atteasy != 0 :
print("Guess again.")
else :
print(f"You have {atthard} attempts remaining to guess the number. ")
guess = input("Make a guess: ")
if int(guess) == numberIs :
print(f"You are right! The number was indeed {numberIs}")
break
else :
if int(guess) > numberIs :
print("To high.")
else :
print("To low.")
atthard = atthard - 1
if atthard != 0 :
print("Guess again.")

if atteasy or atthard == 0 :
print(f"You lost. The numbers was {numberIs}")
break


Script from the course

For comparison, not for review:

from random import randint

EASY_LEVEL_TURNS = 10
HARD_LEVEL_TURNS = 5

#Function to check user's guess against actual answer.
"""checks answer against guess. Returns the number of turns remaining."""
print("Too high.")
return turns - 1
print("Too low.")
return turns - 1
else:

#Make function to set difficulty.
def set_difficulty():
level = input("Choose a difficulty. Type 'easy' or 'hard': ")
if level == "easy":
return EASY_LEVEL_TURNS
else:
return HARD_LEVEL_TURNS

def game():
#Choosing a random number between 1 and 100.
print("Welcome to the Number Guessing Game!")
print("I'm thinking of a number between 1 and 100.")

turns = set_difficulty()
#Repeat the guessing functionality if they get it wrong.
guess = 0
print(f"You have {turns} attempts remaining to guess the number.")

#Let the user guess a number.
guess = int(input("Make a guess: "))

#Track the number of turns and reduce by 1 if they get it wrong.
if turns == 0:
print("You've run out of guesses, you lose.")
return
print("Guess again.")

game()


First of all, it won't run since art is undefined. I'm going to assume that this is some kind of ASCII art you didn't include in the question.

Avoid putting all of your code right into the global namespace; use functions instead.

playAgain should be named play_again.

Your logic dividing up atteasy and atthard has a lot of repeated code. Why not just make one attempt variable that's conditionally assigned before your loop?

Grammar: to high and to low should be too high and too low.

Your int(guess) assumes that the user entered an integer which may not be the case; this would benefit from validation.

You should indent at four spaces and not two.

## What should be done instead

• indent at four spaces instead of two
• add functions, and add type hints to the signature of those functions
• write subroutines such as a check_answer that compares the answer and guess, and returns a boolean indicating whether the guess was successful
• All #comments that you add should have a space between the hash and the text.
• Add """docstrings""" to the first line inside your functions. No other comments before the functions are necessary.
• Consider writing a subroutine to set the number of guesses based on a difficulty lookup dictionary
• Your entry point should be wrapped in a __main__ guard

## Suggested

Based roughly on the "course" script.

from random import randint

DIFFICULTIES = {
'easy': 10,
'hard': 5,
}

"""checks answer against guess. Returns true if the guess was correct."""

return True

direction = "high"
else:
direction = "low"

print(f"Too {direction}.")
return False

def set_difficulty() -> int:
names = ', '.join(DIFFICULTIES.keys())
while True:
level = input(f"Choose a difficulty. Type one of: {names}: ")
difficulty = DIFFICULTIES.get(level)
if difficulty is not None:
return difficulty

def game() -> None:
print("Welcome to the Number Guessing Game!")
print("I'm thinking of a number between 1 and 100.")

turns = set_difficulty()

for turn in range(turns, 0, -1):
print(f"You have {turn} attempts remaining to guess the number.")

while True:
try:
guess = int(input("Make a guess: "))
break
except ValueError:
print("Invalid number.")

return

print("You've run out of guesses, you lose.")

if __name__ == '__main__':
game()

• This review has useful content and I upvoted it. But it lacks a definitive statement that the scripts' problems are not equivalently serious. So I guess I'll make that statement here: put your code in functions, folks.
– FMc
Commented Feb 27, 2022 at 4:34
• Woa. This is amazing. Exactly what i was looking for. Thank you very much !
– perj
Commented Feb 27, 2022 at 5:24
• @FMc Thank you for your answer. But can you explain why? Why shoul i put my code into functions?
– perj
Commented Feb 27, 2022 at 5:27
• The site rules forbid reviewing third-party code. Could you either rephrase the critique of the course's code as advice for the poster, or delete that part of your answer? Commented Feb 27, 2022 at 5:29
• @200_success Sure; I've modified my language Commented Feb 27, 2022 at 14:12

I think here are two examples where you either do not fully understand Python syntax or should maybe make it more explicit what you mean:

while atteasy and atthard != 0 :


and

if atteasy or atthard == 0 :


Python parses the latter as:

if (atteasy) or (atthard == 0):


and not as

if (atteasy == 0) or (atthard == 0):


In Python non-zero integers are truthy and zero is falsey, so if atteasy and if atteasy != 0 are the same, as long as the variable is an integer. See these examples:

a, b = 1, 4
if a and b == 4:
print("This will print")

c, d = 0, 4
if c or d == 0:
print("This will not print")


Either you wanted it to be this way, then you should probably make it explicit:

if atteasy != 0 or atthard == 0:


Or you did not mean it and you should fix it with one of these (in this case) equivalent ways:

if atteasy == 0 or atthard == 0:
if not atteasy or not atthard:
if not (atteasy and atthard):
if 0 in (atteasy, atthard):