Obtain the quantity of odd numbers, positions of the pairs and average of the positives, from a tuple of numbers

Asked

Viewed 368 times

0

I have to declare a tuple with 10 integers and I need to find the amount of odd numbers (already done), the positions of even numbers (need help for this logic) and the average of positive numbers (need help in logic to calculate the sum of positive numbers).

tupla = (1, 2, -1, 0, 3, 7, 9, -3, -4, 0)

#a) Quantidade de números ímpares
def impares(tupla):
    if not tupla:
        return 0

    impar = (tupla[0] % 2 != 0)

    if impar:
        return 1 + impares(tupla[1:])
    else:
        return impares(tupla[1:])
print ("Quantidade de números ímpares: ", impares(tupla[0:]))     

#b) Posição dos números pares

#preciso de ajuda na lógica desse ítem



#c) Média dos números positivos

#quantidade de positivos pra calcular a média
def posit(tupla):
    if not tupla:
        return 0

    pos = (tupla[0] > 0)

    if pos:
        return 1 + posit(tupla[1:])
    else:
        return posit(tupla[1:])
#print (posit(tupla[0:]))

#soma números positivos
#preciso de ajuda para calcular a soma
def somaPos(tupla):
  soma = 0
  for elemento in tupla:
    if elemento >0:
     soma = soma+elemento
  print(soma)

media = somap/posit(tupla[0:])      
print ("Média dos números positivos", media)

1 answer

2

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.

Browser other questions tagged

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