The reason one code worked, but the other one didn’t, is very simple.
In the while
, the condition serves to indicate whether it will continue performing or not. As long as the condition is true, it continues.
So you did:
while (sexo != 'f' or sexo != 'm'):
sexo = input('Digite seu sexo (m / f): ')
The condition of while
is sexo != 'f' or sexo != 'm'
, which are actually two conditions plus the operator or
. In the end, this whole expression checks whether sexo
is different from "f" or is different from "m". The result of or
is true (True
) if either of the two conditions is true (only one of them already serves). That is, if sexo
is different from "f", the result is True
. But if it’s different from "m," it’s also True
.
So what happens if you type "f"? It won’t be different from "f", but it will be different from "m". Like the or
just needs one of the conditions to be true, the result is True
, and therefore the while
continues to perform.
What if you type "m"? It will be different from "f", which is already enough for the result of or
be it True
, and therefore the while
continues to perform.
In fact, this condition will always be true: any value other than "f" will fall into the first condition and the result will be True
. And if you type "f", the first condition is false, but the second ("f" is different from "m") is true, also resulting in True
. So you created a loop infinite.
Valor |
sexo != 'f' |
sexo != 'm' |
sexo != 'f' or sexo != 'm' |
"f" |
False |
True |
True |
"m" |
True |
False * |
True |
is not "f" or "m" |
True |
True * |
True |
I mean, the condition will always be True
, regardless of the value of sexo
. That’s why the while
continues running, regardless of what is typed.
* In fact, if the first expression is True
, the second is not even assessed, since operators boolean sane Circuit short (only assess the minimum necessary: as in or
just that one of them is True
, if the first is, the second is not evaluated).
So what you want is that the loop continue running only if the sexo
not "f" or "m" (that is, if you type something that is not "f" and also is not "m", I continue, but if it is one of the two, I stop). Therefore the correct operator to be used is the and
:
sexo = ''
while sexo != 'f' and sexo != 'm': # repare que não precisa dos parênteses
sexo = input('Digite seu sexo (m / f): ')
The and
only results in True
if both conditions are true. That is, if I type "f", the first condition is false (no different than "f") and the result will be False
. And if you type "m", the first condition is true (it’s different from "f"), but the second one is false (it’s no different than "m"), and the result will also be False
. So if I type "f" or "m," it comes out of the while
. For any other value, the loop continues.
See the difference:
Valor |
sexo != 'f' |
sexo != 'm' |
sexo != 'f' and sexo != 'm' |
"f" |
False |
True |
False |
"m" |
True |
False |
False |
is not "f" or "m" |
True |
True |
True |
I mean, now the condition is only true if I don’t type "f" or "m," and then the while
continues. If I type any of them, the result is False
and the while
is interrupted.
I particularly don’t like this solution of giving an arbitrary value to the variable before the loop, just so he can get in there once. I’d rather do as his second code:
while True:
sexo = input('Digite seu sexo (m / f): ')
if sexo == 'f' or sexo == 'm':
break
It works because instead of !=
(different), you used ==
(equal), so now the condition checks whether it was typed "f" or "m" (if sexo
is equal to "f" or equal to "m"). If I type "f" or "m", it enters the if
and the break
interrupts the while
. For any other value, it does not enter the if
and the loop continues.
So now it’s like this:
Valor |
sexo == 'f' |
sexo == 'm' |
sexo == 'f' or sexo == 'm' |
"f" |
True |
False |
True |
"m" |
False |
True |
True |
is not "f" or "m" |
False |
False |
False |
That is, if you type "f" or "m", you enter if
and interrupts the loop. If you type anything other than "f" or "m," you don’t enter if
and the while
continues to perform.
That’s why the second code worked, but the first one didn’t.
Of course, you can implement in other ways, as the other answers suggest (if sexo in ('m', 'f')
, etc), but there is no longer the focus of the question. The important thing is to understand how conditionals work and apply them correctly.
In short:
- an expression with
or
results in True
if any one of the conditions is true
- an expression with
and
results in True
if all the conditions are true
Change of
while (sexo != 'f' or sexo != 'm'):
forwhile (sexo != 'f' and sexo != 'm'):
– Paulo Marques