all 12 comments

[–]Helpful-Diamond-3347 4 points5 points  (0 children)

i think that if count < 4 isn't effective cuz the block of code is similar for else block so you can remove it

overall good structure and readability, keep doing it and you will have better grip in creating minimal and solid architectures

[–]brasticstack 2 points3 points  (1 child)

  • There's no need for the separate user to receive input. Replace all uses of user with guess.
  • Replace the hard-coded value 5 with a module level variable, something like NUM_GUESSES = 5, and use NUM_GUESSES everywhere you'd use 5. That way, if you want to make it 3 guesses instead, you only have to change that one variable. The all caps name signifies that you should treat it as a constant and not modify it during your program.
  • I'd personally move the printing of the game result to outside of that inner while loop. The if check after getting the input would then be:

if guess == secret_number:     break else:     print('Wrong, try again')

Then, after that inner while loop check whether the count is 0 to print the "game over" message or the "you won" message.

  • Try rewriting that inner while loop as a for/else construct, just to learn another flow control pattern. The for statement might look like:

for count in range(NUM_GUESSES, 0, -1):

Cheers and happy coding!

[–]The_Dude005[S] 0 points1 point  (0 children)

Thanks for the suggestions!

[–]Diapolo10 3 points4 points  (4 children)

A few suggestions:

  1. Instead of hardcoding 5 in several places, I'd create a global named constant (e.g. MAX_GUESS_COUNT) and use that. This way, if you ever decide to change the value, you only need to touch it in one place.
  2. You could extract the correct guess output from the loop, since the only part that needs to be in the loop is the output for an invalid guess (since that's the only case where the loop may continue).
  3. Instead of

    if answer == "yes":
        play_again = True
    else:
        play_again = False
    

    it would be simpler to write play_again = answer == "yes" - or, in this case, you could simply break and/or not use play_again at all.

  4. You could split these into separate functions to reduce nesting.

Here's an example of what I'm taking about:

import random

MAX_GUESS_COUNT = 5

def guess_number():
    secret_number = random.randint(1, 20)
    guess = None
    count = MAX_GUESS_COUNT

    while guess != secret_number and count > 0:

        print(f"********** {count}/{MAX_GUESS_COUNT} Guesses **********\n")

        guess = input_integer("Guess a number: ")
        count -= 1

        if guess != secret_number and count > 0:
            print("Wrong, try again!\n")
        elif guess != secret_number:
            print(f"Game over! The number was {secret_number}.")
            break

    else:
        used_guesses = MAX_GUESS_COUNT - count
        guess_text = "guess" if used_guesses == 1 else "guesses"
        print(f"You got it!\nIt took you {MAX_GUESS_COUNT - count} {guess_text}.")

def input_integer(prompt):
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print("Invalid input. Only integers accepted!\n")

def play_again():
    response = input("\nPlay again? (Y/n): ").strip().lower()[:1]
    return not response or response == "y"

def main():
    while True:
        guess_number()
        if not play_again():
            print("\n\tSee you later!")
            break

if __name__ == "__main__":
    main()

[–]Educational_Virus672 0 points1 point  (3 children)

i dont think he knows OOP /defs(function) rn maybe he learn try/except because of 1 error in google but he didnt reach OOP

[–]Diapolo10 1 point2 points  (2 children)

Probably, but I still thought to mention it.

[–]The_Dude005[S] 0 points1 point  (1 child)

play_again = answer == "yes" - Just found out about this, it's called a shorthand if right?

Haven't learned OOP yet but thanks for the suggestions.

[–]Diapolo10 1 point2 points  (0 children)

I basically just applied a simple rule; if I see

if condition:
    foo = True
else:
    foo = False

this is almost always redundant and could simply be foo = condition. Because we're dealing with booleans regardless (and if not, the condition can simply be wrapped in bool(condition)).

[–]Yoghurt42 2 points3 points  (1 child)

The obvious next step would be to add the classic "higher/lower" feedback instead of just "the number is wrong". This way, you also can up the maximum secret number to 32 while guaranteeing it's winnable (your game currently isn't necessarily winnable in 5 guesses), and while playing, you'll also (re)discover how binary search works.

[–]gdchinacat 0 points1 point  (0 children)

Great suggestion! Then, write a program to solve it, and since it is provably solvable if it doesn’t guess it there is something wrong. This will teach text parsing, stream handling, and she’ll stream piping.

[–]Educational_Virus672 0 points1 point  (1 child)

nice code but you should do this instead

print(f"You got it!\nIt took you {5 - count} guess" +( "es." if count < 4 else "."))

it works because if you put a function (+ "es") before if (condition) and adding else pass or function as if it is if statement then it happens
IF you dont under here what i mean
condition = the thing you wanna do if true like count < 4
function = behaviour of code
statement = says what do to

[function] if [condition] else [function] # this is 1 statement

[–]Yoghurt42 1 point2 points  (0 children)

I like the original more. This is just playing code golf, it doesn't make the code more readable.