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:
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);
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);
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;
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;
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;
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– Woss
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
– Guilherme Matos Passarini
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.
– Woss
But it is 'sum / 2', not 'p/2'. The variable 'sum 'has a numeric value assigned to it. Now that I have seen
– Guilherme Matos Passarini
And on the line
soma = 'p'
?– Woss
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.
– Guilherme Matos Passarini
On the bottom line, you do it again
soma % 2
. At this pointsoma
is a letter, not an integer.– Woss