The question implies that you want to go through the digits of a number, see which one is bigger and which one is smaller, add them up and calculate the average. So let’s go...
In his another question me already answered on the use of isdigit
to check if a string contains a number.
Basically, if the user can type anything, then nothing prevents him from typing characters like the ²
(SUPERSCRIPT TWO), returning True
for isdigit()
, but when trying to convert it to number with int()
, makes a mistake:
print('²'.isdigit()) # True
print(int('²')) # ValueError
See here this code running
May be a corner case ""rare, that "will never happen", but at first you should not trust anything the user types, and always validate what you receive. And in your case, if you use isdigit
and then try to convert to number with int
, there are cases where it may be wrong. See here all characters falling in this situation.
So if you want to check if a string contains a number, instead of using isdigit()
, try to convert it using int()
and capture the ValueError
(for cases where conversion to number gives error):
def ler_numero():
while True:
try:
n = int(input('Digite um número menor que 20 que seja positivo: '))
if 0 < n < 20:
return n # se o valor está correto, retorna
else:
print('O número deve ser positivo e menor que 20')
except ValueError: # não foi digitado um número
print('Digite um número válido')
This function has a loop infinite (while True
) which is only interrupted if a positive number less than 20 is entered (the return
exits the function and returns the value as a number).
Of course use isdigit()
and then int()
also works for most cases, but if you will have to check if the number is less than 20, why not try using int
right away? The use of isdigit()
becomes redundant, because if the string is not a number, I can already detect it in the block except
. So in the end you don’t even need isdigit()
.
Then just use this function to read the number, make a loop by their digits and calculate what they need:
n = ler_numero()
maior = -1
menor = 10
soma = 0
qtd = 0
pares = 0
impares = 0
while n > 0:
digito = n % 10
if digito > maior:
maior = digito
if digito < menor:
menor = digito
if digito % 2 == 0:
pares += 1
else:
impares += 1
soma += digito
qtd += 1
n //= 10
media = soma / qtd
In case, I make one while
considering the numerical value, pick the last digit using the rest of the division by 10 (n % 10
), I compare this digit with the highest and lowest current value, update the sum and number of digits (in addition to the number of pairs and odd ones - just check the rest of the division by 2 to see if it is even or odd). Finally, I divide the number by 10, because in the next loop iteration it will take the penultimate digit, and so on, until you go through all the digits of the number.
Notice that as I’m comparing digits, I know they’ll always be between 0 and 9, so the maior
is initialized with -1
and menor
with 10
(the idea is to initialize with a value that is respectively smaller and larger than all possible values, ensuring that the algorithm always finds the highest and lowest value among the existing ones).
This approach is different from yours, because as I explained earlier in another answer (to your other question already quoted), there is a difference between the numerical value and the representation of that numerical value. For example, if the user type 02
, the string contains 2 digits, but the numeric value is 2 (a number with only one digit).
If you use your algorithm (or the proposed in the other answer), will be considered that the number has two digits, the smallest is zero, and the average is 1. Already if using my algorithm above, the number has only one digit, so the smallest is 2 and the average is also 2.
Which is right? Depends what you want: if you will consider the numeric value, use the code above. If you are going to consider the textual representation of the numeric value (the exact string typed by the user), use the code of the other answer.
Another difference is that the above algorithm only goes through the digits of the number once, while the other solution goes through several times. The calls to max
and min
, for example: each one goes through all the digits, so you are doing 2 loops (just because you didn’t make a loop explicit, does not mean that there is not one being done elsewhere). Then you still do another loop to calculate the sum. But this is not necessary, because as we saw above, you can do everything in one loop only.
Of course, in this particular case, since the number can only be between zero and 20, it doesn’t make that much difference. But if you consider bigger numbers, then it starts to make a difference.
Natanael, the average would be the number typed, divided by the number of digits? How do you want to calculate the average?
– Daniel Mendes