Problem with number guessing game

Asked

Viewed 212 times

1

This number guessing game script doesn’t work, in part if z = "s" Python says the syntax is invalid. Someone could tell me why it doesn’t work, and what would be the right one?

import random
def rerun():
    if z = "s"
        numero_aleatorio= random.randint(1,10)
        x = numero_aleatorio
        y = input("Advinhe o numero ")
        y = int(y)
        if y > x:
            y = int(input("Numero muito alto! "))
            while y > x:
                y = int(input("Numero muito alto! "))
                if y == x:
                    print("Voce advinhou!")
                    z = input("Você quer continuar jogando?(s/n) ")
                elif y < x:
                y = int(input("Numero muito baixo! "))
            while y < x:
                y = int(input("Numero muito baixo! "))
                if y == x:
                    print("Voce advinhou!")
                    z = input("Você quer continuar jogando?(s/n) ")
                     if z == "s":
                         rerun()
                     if z == "n":
                         quit()
numero_aleatorio= random.randint(1,10)
x = numero_aleatorio
y = input("Advinhe o numero ")
y = int(y)
if y > x:
    y = int(input("Numero muito alto! "))
    while y > x:
            y = int(input("Numero muito alto! "))
            if y == x:
                print("Voce advinhou!")
                z = input("Você quer continuar jogando?(s/n) ")
                    rerun()
elif y < x:
    y = int(input("Numero muito baixo! "))
    while y < x:
            y = int(input("Numero muito baixo! "))
            if y == x:
                print("Voce advinhou!")
                z = input("Você quer continuar jogando?(s/n) ")
                    rerun()

I also tried with the code like this:

import random
def rerun():
    if z == "s":
        numero_aleatorio= random.randint(1,10)
        x = numero_aleatorio
        y = input("Advinhe o numero ")
        y = int(y)
        if y > x:
            y = int(input("Numero muito alto! "))
            while y > x:
                y = int(input("Numero muito alto! "))
                if y == x:
                    print("Voce advinhou!")
                    z = input("Você quer continuar jogando?(s/n) ")
                elif y < x:
                    y = int(input("Numero muito baixo! "))
            while y < x:
                y = int(input("Numero muito baixo! "))
                if y == x:
                    print("Voce advinhou!")
                    z = input("Você quer continuar jogando?(s/n) ")
                    if z == "s":
                         rerun()
                    if z == "n":
                         quit()
numero_aleatorio= random.randint(1,10)
x = numero_aleatorio
y = input("Advinhe o numero ")
y = int(y)
if y > x:
    y = int(input("Numero muito alto! "))
    while y > x:
            y = int(input("Numero muito alto! "))
            if y == x:
                print("Voce advinhou!")
                z = input("Você quer continuar jogando?(s/n) ")
                rerun()
elif y < x:
    y = int(input("Numero muito baixo! "))
    while y < x:
            y = int(input("Numero muito baixo! "))
            if y == x:
                print("Voce advinhou!")
                z = input("Você quer continuar jogando?(s/n) ")
                rerun()

But now gives the error below, after user select whether to continue playing or not:

Traceback (most recent call last):
  File "C:/Users/chlav/Documents/Python scripts/advinhar.py", line 45, in <module>
    rerun()
  File "C:/Users/chlav/Documents/Python scripts/advinhar.py", line 3, in rerun
    if z == "s":
UnboundLocalError: local variable 'z' referenced before assignment
  • Lacked a : at the end of the line that is giving error, and as is a comparison, need to ==...

  • Yet you still make the same mistake...

  • Carlos Henrique the correct would be if z == 's': in the third line of your script.

  • Python = is assignment, for equality test use ==.

  • I fixed it and some paragraphs that were giving error and now it was like this

  • Another error appeared?

  • Yes, I’ve edited the post

  • avoids the use of global variables... draws the comparison from within the function and plays it for the global scope... you are using the same global variable z within the function and making a comparison hoping that it is the global z. but since you have another z within the scope of the function it tries to take the local z and a syntax error

  • But then how do I restart the game?

  • A repeat loop would have to be used.

  • Google Scope of Variables in Python and you’ll understand your code error

Show 6 more comments

3 answers

2

It is not necessary to repeat all the code twice just to start over. Instead use a loop like the while to repeat a part of the code using a condition:

import random

opcao = "s"
while opcao == "s":
    numero_aleatorio = random.randint(1,10)
    tentativa = int(input("Advinhe o numero:"))
    while tentativa != numero_aleatorio:
        if tentativa < numero_aleatorio:
            print("Numero muito baixo")
        else:
            print("Numero muito alto")           
        tentativa = int(input("Advinhe o numero:"))
    print("Voce advinhou!")
    opcao = input("Você quer continuar jogando?")

In this example, to get out of the repetition, it is necessary that the condition opcao == "s" is broken, this will occur when the user enters another different letter in the input() of the end.

1

Good morning. You already have an answer, but I would still like to clarify what happened to your code.

A teacher taught me that in Python, we are writing a letter in English to the computer. Result of your error: "Unboundlocalerror: local variable 'z' referenced before assignment". So if we translate: "Linked Local Error: local variable 'z' referenced before assignment"

Because of this mistake, I believe that your z is not a global variable. That is he had been declared, inside another def What plays us for the encapsulation rule.

Possibly your problem should be solved z a global variable.

global z   # Colocar isso aqui, antes do seu if, pode resolver o problema.
if z == "s":
    numero_aleatorio= random.randint(1,10)
    x = numero_aleatorio
    y = input("Advinhe o numero ")
    y = int(y)
    ...

0

One of the main tips is on reply from @nosklo: you’re repeating code unnecessarily, which could use a loop (that’s why the loops serve, to perform something over and over again).

Another detail is that you have extra variables that you wouldn’t need. For example, when you do this:

numero_aleatorio= random.randint(1,10)
x = numero_aleatorio

You create the numero_aleatorio and then just use it to assign its value in x (and after that it is no longer used). There is no reason to create two variables for this, use only one of them. And in this case, I would choose to use only numero_aleatorio, for being a better name than x, since it indicates exactly what that variable means.

This goes for other variables as well. y and z are too many "generic" names and those who see the code cannot understand what they mean (unless they read the whole code, of course). It may seem like a silly detail, but giving meaningful names to everything (variables, functions, classes, etc.) makes the whole process of programming easier, because you don’t have to spend every waking hour remembering "What is this x same?" (already if you read numero_aleatorio, know immediately what it means).

That said, to solution proposed by @nosklo already greatly simplifies your code. See how you can call int(input(...)) directly, already keeping the numeric value in the variable, and also see how the while already eliminates the need to repeat the code, and checking the entered value is simplified with only one if/else within another while.


I propose a few more modifications. If you want, you don’t even need the variable to save the option to leave the game or not, because you can also do so:

while True:
    # lê a tentativa, verifica se está certa, etc
    ....

    # se a opção não for "s", sai do "while True"
    if input("Você quer continuar jogando? (s/n)") != 's':
        break

The while True indicates that the loop will run indefinitely. But if the entered option is different than 's', is called the break, interrupting the while.

Unless you’re going to use the typed option for something else, you don’t need to keep it in a variable. But if you want to use a variable for that, call it opcao or some other significant name instead of z or any other "generic" name that says nothing about its function in the code.

Another suggestion is to check the entered value. You are taking a typed value with input and then using int to try to convert to a number. Only that the user can type anything, including something that is not a number, so it would be interesting to check this too, getting a code more or less like this:

while True:
    try:
        # lê o valor e tenta converter para número
        tentativa = int(input("Adivinhe o número:"))
        break # se chegou aqui, é porque int() funcionou
    except ValueError:
        # se int() falhou, é porque não foi digitado um número, então tente novamente
        print("Digite um número válido")

If the int() fail (because no number has been entered), a ValueError, and in this case, the code within the except will be executed. In case, I inform you what happened, and how I am within a while, another number will be read.

But as in the code we are reading the attempt twice (one before checking if the number was guessed, and another later, if not), it is better to encapsulate all this logic of reading the number into a function. The final code stays like this:

import random

# função que lê o número e retorna o valor lido
def ler_numero(mensagem):
    while True:
        try:
            # lê o número e retorna o valor
            return int(input(mensagem))
        except ValueError:
            # se não foi digitado um número, int() lança um ValueError
            print("Digite um número válido")


while True:
    numero_aleatorio = random.randint(1, 10)

    tentativa = ler_numero("Advinhe o numero:")
    while tentativa != numero_aleatorio:
        if tentativa < numero_aleatorio:
            print("Numero muito baixo")
        else:
            print("Numero muito alto")

        tentativa = ler_numero("Advinhe o numero:")

    print("Voce advinhou!")

    # se a opção não for "s", sai do "while True"
    if input("Você quer continuar jogando? (s/n)") != 's':
        break

Note that within the function ler_numero I used return instead of break. Is that if int() work (ie, was typed a number and this was converted correctly), I can already return its value immediately (do not need to have a break to get out of while and then have a return).

If already the int() fail, I fall in the block except, the message informs that the entered value is not a number and the while continues running, asking to be typed another number.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.