Python program that takes the factorial from odd numbers to the one typed by the user

I should ask the user to type an odd number and return on the screen the sum of the factorial of all the odd ones up to the one typed by the user.

I made the part that validates if the number typed is odd and the function that calculates the factorial of the number typed. But I don't know how to do the rest. I couldn't even think of the logic of the other function. I made this Code:

def fatorial(x):
    result=1
    for i in range(x):
        result=result*(x-i)    
    return result

'''def fatorial(x):
    x=x-2
    while x>1:
        fat=fat*a
        a-=1 - Não deu certo'''
a=int(input("Digite o número: "))
while a%2!=1:
    a=int(input("Número não impar, digite outro número: "))
    while a<0:
        a=int(input("Número menor que zero, digite outro número: "))
else:
    b=fatorial(a)
print(b)
Author: Aline de Paula, 2020-05-06

1 answers

Having the function that calculates the factorial and the number typed N, just make a for for the odd numbers from 1 to N, and go adding the factorial of them:

def fatorial(x):
    result = 1
    for i in range(2, x + 1):
        result *= i
    return result

while True:
    n = int(input('digite o número'))
    if n % 2 == 0 or n <= 0:
        print('número deve ser impar e maior que zero, digite outro')
    else: break

soma = 0
for i in range(1, n + 1, 2):
    soma += fatorial(i)

print(soma)

Notice that to check if the number typed is odd I made a loop infinite (while True), which is only interrupted if the number is odd (if it is even, prints the message and asks to type again). I also included the check if it is negative, since it seems to only be able to accept positives.

Then I made a for using a range, which starts at 1 and goes to n, jumping from 2 to 2 (so I know it will go through only the odd ones to n). I had to put n + 1 because the final value is not included in range.

I understand that because it is an exercise, can be who want you to iterate from 1 to 1 and test if the number is odd, something like this:

for i in range(1, n + 1):
    if i % 2 != 0:
        soma += fatorial(i)

But honestly, unless it's requirement of the 1-on-1 iterate exercise and use the % operator, that's unnecessary, because if I start from an odd number and just want to iterate through the odd ones, just jump from 2 to 2.

See also that I changed the function that calculates the factorial, to start the range with 2 (starting with 1 is unnecessary because multiplying by 1 is redundant). The way you did it even works, but in a range it is possible to control the initial and final value, so I think it looks better that way. If n is 1, it doesn't even enter for and the result is 1.

Oh yeah, you said that was trying to make a function to calculate the sum. In this case it would be:

def soma_fat(n):
    soma = 0
    for i in range(1, n + 1, 2):
        soma += fatorial(i)
    return soma

n = # ler valor do n
print(soma_fat(n))

If you want, you can also calculate the sum using sum together with a expression generator, much more succinct and Pythonic:

soma = sum(fatorial(i) for i in range(1, n + 1, 2))

It is also possible to give a small "optimized". When calculating the factorial of 3, for example, we multiply 1 * 2 * 3, and then we have to calculate the factorial of 5, doing 1 * 2 * 3 * 4 * 5 (that is, the first multiplications will be made again).

You can avoid this rework by saving the factorial of the last calculated number, and only make the missing multiplications:

# ler n usando o while True acima

soma = 1
fat = 1
for i in range(3, n + 1, 2):
    fat *= i * (i - 1)
    soma += fat
print(soma)

If n is less than 3 (that is, if it is 1), it does not even enter for and the result is 1. If it is greater than or equal to 3, the loop will update the factorial (multiplying the missing values) and add to the total.

 2
Author: hkotsubo, 2020-05-06 19:22:07