Type error: not all strings converted during formatting

Asked

Viewed 252 times

1

I’m trying to make a match or a match. The problem is that every time the sum of my move and that of the computer is 'even' this error message appears. I have tried other types of formatting and always appears the same error. Also, this line is pretty much the same as the one above, but the line above doesn’t go wrong, but for some reason, this line does. It follows the code

from random import randint

pc = randint(0,10)

print(' =-'*20)
print('VAMOS JOGAR PAR OU ÍMPAR')
print(' =-'*20)

vitoria = 0


while True:
    vc = int(input('Diga um valor: '))
    j = str(input('Par ou Ímpar? [P/I]: '))
    while vc < 0 or vc > 10:
        vc = int(input('Jogada inválida. Digite um número de 1 a 10: '))
        j = str(input('Par ou Ímpar? [P/I]: '))
    soma = vc + pc
    if soma % 2 == 0:
        print(f'Você jogou {vc} e o computador jogou {pc}.Total de {soma} deu PAR')
        soma = 'p'
    if soma %2  != 0:
        print(f'Você jogou {vc} e o computador jogou {pc}.Total de {soma} deu IMPAR')
        soma = 'i'
    if j != soma:
        break
    vitoria = vitoria + 1
print('VOCÊ PERDEU!')
print('=-'*20)
print(f'GAME OVER! Você venceu {vitoria} vezes')

Error print

inserir a descrição da imagem aqui

Edit: I managed to get around the problem by putting an 'Else' instead of another 'if' condition. But I’d still like to know why this happened

  • When the result is even, it enters the first condition, where you define soma equal to 'p', which doesn’t seem to make much sense, but the error occurs just below when you try to recalculate the rest of the split by 2. How much is the rest of splitting P by 2 worth? Remember that the error message it gives is about formatting string

  • I define sum = p (even) if the sum of my move + that of the CPU is even and sum = i (odd) if my move (vc) + CPU move (pc) gives an odd result. The rest of the division p by 2 is zero. But the value p is set after it is stated that the rest of the division by 2 is zero. When the program asks if I want pair or odd, I must answer with 'p' (pair) or 'i' (odd). This string must match the sum so that I win the match

  • But you check again on the bottom line... And no, split "p" rest by 2 does not exist. You cannot divide a letter by an integer.

  • But it is 'sum / 2', not 'p/2'. The variable 'sum 'has a numeric value assigned to it. Now that I have seen

  • And on the line soma = 'p'?

  • On this line, the sum value was assigned to a letter after it was checked whether this variable gave an integer division by 2. I did not divide a string by 2. But I fixed this problem by putting ONE ELSE.

  • On the bottom line, you do it again soma % 2. At this point soma is a letter, not an integer.

Show 2 more comments

1 answer

0

Your error is in using the same object, soma, to store both the result of the sum of numbers and the letter identifying the result. Not only is it a bad approach because it doesn’t make the code legible, it makes room to make mistakes like you did.

When the result of the sum of the values is even, the condition of the first if, line 19, is satisfied and its code block runs. On line 21, inside the if, you change the value of soma for 'p', in order to indicate that the result was even, however, on the line immediately below you try to calculate again the rest of the division of soma by 2; at the moment, soma is no longer an integer value, but a string 'p' and, in Python, the rest operator serves for formatting string, which explains the error message. This Python incoherence has already been corrected, but not omitted, by implementing the method str.format, as I described in this question:

Character formatting

For your problem, the simplest solution is to change the name of the object at one point in the program; for example, instead of doing soma = 'p', do something like resultado = 'p' and at the end check whether j != resultado.

An alternative to your code would be:

from random import randint

print('=-'*20)
print('VAMOS JOGAR PAR OU ÍMPAR')
print('=-'*20)

vitorias = 0

while True:
    while True:
        voce = int(input("Que número entre 0 e 10 você jogará? "))
        if not 0 < voce < 10:
            print("Valor inválido, diga um número entre 0 e 10")
            continue
        break
    while True:
        resposta = input("[P]ar ou [I]mpar?").upper()
        if resposta not in ('P', 'I'):
            print("Entre com P para par ou I para ímpar")
            continue
        break
    computador = randint(0, 10)
    soma = voce + computador
    resultado = 'P' if soma % 2 == 0 else 'I'
    print(f"Você: {voce} / Computador: {computador} / Soma: {soma}")
    if resultado == resposta:
        vitorias += 1
    else:
        break
print('=-'*20)
print(f'GAME OVER! Você venceu {vitorias} vezes')

See working on Repl.it

Considerations

To explain the differences between the codes, let’s see:

  1. Reading the value the player wants is done within an infinite loop; this is because we don’t know how many times he will enter with an invalid value and prevents you from knowing the value in advance - that is, you only read in one place of the code only, you don’t need to call twice input() for the same thing (redundancy);

  2. The validation of the value is done with not 0 < voce < 10, instead of voce < 0 or voce > 10, which makes the code much more readable (Readability Counts);

  3. Reading the user’s odd or even response is also validated, ensuring it indicates a response that the program can handle - which its original code does not. The logic is exactly the same to read the whole value, but checking if the player’s response was 'P' or 'I'. I also used the method str.upper() to ensure that the player’s input is always high, which allows him to enter with 'p' or 'i' also;

  4. As I commented earlier, I used a different object to store the game result and kept the object soma to store the sum of the values. The object resultado will receive 'P' when the sum is even and 'I' when odd, just like in your code, but in a simpler way;

  5. Another important detail was that I put the function randint() into the infinite loop, so that the computer’s response is different with each round. The way you did, the value will be the same in all of them;

  • I think I get it now. Thank you for the reply.

  • 1

    @Guilhermem.P. I added a solution of my own to the problem as an alternative and commented on the main differences. I recommend that you read.

  • Thank you @Anderson Carlos Woss will read it. The program is already working. I put an Else in place of the second if and assign the values 'p' and 'i' to the result variable. But it has some modifications that I hadn’t made.

Browser other questions tagged

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