I do not know if it is a requirement of exercise to do everything in a separate function, and even more recursive functions, whereas there is no none need to use recursion and still can do everything in one loop:
tupla = (1, 2, -1, 0, 3, 7, 9, -3, -4, 0)
soma = qtd_impares = qtd_positivos = 0
posicoes = []
for i, n in enumerate(tupla):
if n % 2 == 0: # número par, guarda posição
posicoes.append(i)
else: # número ímpar, atualiza quantidade
qtd_impares += 1
if n > 0: # número positivo, atualiza soma e quantidade, para calcular a média no final
soma += n
qtd_positivos += 1
media = soma / qtd_positivos
print("quantidade de números ímpares", qtd_impares)
print("posições dos números pares", posicoes)
print("média dos números positivos", media)
The use of enumerate
is to iterate by numbers at the same time as I get the index (which is the position of the index). That is, with each iteration of the for
, the variable n
will be one of the numbers and the variable i
shall be its index (i.e., the position of the).
Within the loop just test each condition and do what you need in each case:
- if the number is even, I hold the position (i.e., the
i
). Since you may have more than one even number, I am using a list to store all positions
- if the number is odd, I update the quantity
- if the number is positive, update their sum and quantity (since I will need both to calculate the average at the end)
If you want to separate each thing into a function, you can do so:
tupla = (1, 2, -1, 0, 3, 7, 9, -3, -4, 0)
def qtd_impares(tupla):
return len([n for n in tupla if n % 2 != 0])
def posicoes_pares(tupla):
return [i for i, n in enumerate(tupla) if n % 2 == 0]
def media_positivos(tupla):
positivos = [n for n in tupla if n > 0]
return sum(positivos) / len(positivos)
print("quantidade de números ímpares", qtd_impares(tupla))
print("posições dos números pares", posicoes_pares(tupla))
print("média dos números positivos", media_positivos(tupla))
I used the syntax of comprehensilist on, much more succinct and pythonic. But as it is an exercise, perhaps it is "required" to be done manually:
def qtd_impares(tupla):
qtd = 0
for n in tupla:
if n % 2 != 0:
qtd += 1
return qtd
def posicoes_pares(tupla):
posicoes = []
for i, n in enumerate(tupla):
if n % 2 == 0:
posicoes.append(i)
return posicoes
def media_positivos(tupla):
soma = qtd = 0
for n in tupla:
if n > 0:
soma += n
qtd += 1
return soma / qtd
Another detail is that you’re passing tupla[0:]
for the functions, but does not need it. The Slice [0:]
takes all elements of the tuple, then do funcao(tupla)
or funcao(tupla[0:])
is the same.
Another point is that each of the above functions runs through all the numbers in the tuple, so by calling them, you’re running through it 3 times. Already using the first code above, the tuple is covered only once (it’s okay that for an exercise, and for few values, it doesn’t make so much difference).
If you really want to use recursion (which makes no sense in this case, nor is it the best solution), an alternative would be:
tupla = (1, 2, -1, 0, 3, 7, 9, -3, -4, 0)
def qtd_impares(tupla):
if not tupla:
return 0
# se for ímpar, qtd é 1, senão é 0
qtd = 1 if tupla[0] % 2 != 0 else 0
return qtd + qtd_impares(tupla[1:])
def posicoes_pares(tupla, posicao=0):
if posicao >= len(tupla):
return []
posicoes = []
if tupla[posicao] % 2 == 0:
posicoes.append(posicao)
return posicoes + posicoes_pares(tupla, posicao + 1)
def media_recursiva(tupla, n = None):
if n is None:
n = len(tupla)
if n == 1:
return tupla[0]
return (tupla[n - 1] + ((n - 1) * media_recursiva(tupla, n - 1))) / n
def media_positivos(tupla):
return media_recursiva(tuple(filter(lambda n: n > 0, tupla)))
print("quantidade de números ímpares", qtd_impares(tupla))
print("posições dos números pares", posicoes_pares(tupla))
print("média dos números positivos", media_positivos(tupla))
Besides not being the best solution for this case, recursion can cause a pile overflow if the tuple is too big (already using loops, there is no such problem). Not to mention that the code becomes unnecessarily more complicated.