Factorial in Python using while - python

why this function doesn't work as a factorial function?
def Factor(n):
while n>=1:
print n*(n-1)
return 1

This will work
def Factor(n):
val=1
while n>=1:
val = val * n
n = n-1
return val

You have recursion and iteration mixed. Take a look at these two:
def factor_recursion(n):
while n>=1:
return n * factor_recursion(n-1)
return 1
def factor_iteration_for(n):
factor = 1
for i in range(n):
factor *= i+1
return factor
def factor_iteration_while(n):
factor = 1
while n >= 1:
factor *= n
n -= 1
return factor
print factor_iteration_for(4)
print factor_iteration_while(4)
print factor_recursion(4)

You never change the value of n to anything other than what is passed into the function.
I don't think this is going to do what you think it will. Looks like you've mixed recursion and iteration.

First of all, none of your code changes the value of n, so the loop will run indefinitely unless n == 1 when the function is called.
Secondly, you aren't accumulating a partial product inside the loop (hint: before the loop set result =, then inside it multiply the current value of result by the value of n.
Finally, you should then return the accumulated result rather than one.

def factorial(num):
if num == 0:
return 1
else:
return num * factorial(num - 1)
print factorial(5)

Related

How do I write a function that finds the sum of factorial of even numbers?

I've got a question- how do I write a function sum_even_factorials that finds the sum of the factorials of the even numbers that are less than or equal to n.
Eg:
sum_even_factorials(1)=
1
sum_even_factorials (3)=
3
sum_even_factorials (6)=
747
This is my current code:
Is there a logical error in the current code?
Is there a logical error in the current code?
To begin with, function sum_even_factorial doesn't return a value in every execution flow:
if cond1:
return val1
elif cond2:
return val2
else: # this part is missing in your code
return val3
In addition, note that when you call this function, you are not doing anything with the value that it returns:
sum_even_factorial(6)
Finally, although parts of your code are not visible in your question, I tend to guess that you cannot recursively compute the factorials of even numbers the way you did it, because the factorial of an even number n depends on the factorial of the odd number n - 1.
I think the code needs a loop. I'd write it like so:
def factorial(n):
if n == 0 or n == 1:
return 1;
else:
return n * factorial(n-1)
def sum_even_factorial(n):
current_sum = 0
while n >= 0:
if n % 2 == 0:
current_sum += factorial(n)
n -= 1
return current_sum
print(sum_even_factorial(6))
If you return tuples from the function, you can do it with one single function. See the comments in the code on how it works ...
def factorial_with_sum(n):
if n < 2:
return 1, 0 # first item of the tuple is the factorial, second item is the sum
else:
f, s = factorial_with_sum(n - 1) # calc factorial and sum for n - 1
f = f * n # factorial = n * factorial (n - 1)
if n % 2 == 0:
s = s + f # if n is even, add the current factorial to the sum
return f, s
fact, sum = factorial_with_sum(6)
print(fact)
print(sum)
You can also do it iteratively with a simple for loop as follows
def factorial_with_sum_iterative(n):
s = 0 # initialize sum
f = 1 # and factorial
for i in range(2, n + 1): # iterate from 2 to n
f = f * i # calculate factorial for current i
if i % 2 == 0:
s = s + f # if current i is even, add it to sum
return f, s

Why am I getting nonetype when calling a function within a function in Python?

I'm tying to do a Collatz sequence with python code. I'm supposed to make a function that, given n, calculates the next number in the sequence. I want the next function "write" to print each number within the sequence.
My code so far:
def collatz(n):
while n != 1:
if n % 2 == 0:
n = n/2
return write(n)
else:
n = 3*n+1
return write(n)
def write(n):
print(n)
print(collatz(n))
write(6)
It gives me the right sequence, which should be 6, 3,10,5,16,8,4,2,1, but also gives me 9 "nones".
I'm new to programming, it should probably be something easy, but I can't figure out what.
write() is a function that executes two print() statements, and then implicitly returns None (since there are no return statements in the function).
You can simplify the code by using print() directly in collatz(), and eliminating the mutual recursion:
def collatz(n):
while n != 1:
if n % 2 == 0:
n = n//2
print(n)
else:
n = 3*n+1
print(n)
collatz(6)
#Here this will help you understand.
#When n becomes 1, the while loop is not executed,
#collatz does not return write(n)... thus returns None
def collatz(n):
while n != 1:
if n % 2 == 0:
n = n/2
return write(n)
else:
n = 3*n+1
return write(n)
#return None.... there is no return type, so this is implied
def write(n):
print(n)
result = collatz(n)
if result != None:
print(collatz(n))

a (recursive) function that will calculate sum for a given n

How to write a recursive function that will calculate this sum for a given n?
n
∑ 1/k
k=1
My code:
def sum(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return sum(1/n) + sum(1/n+1)
print(sum(3))
For n = 3 the output should be: 1.8333333333333333
You should avoid declaring a new function with the name sum as there already exists a built-in function with this name.
You can recursively calculate
n n-1
∑ 1/k == 1/n + ∑ 1/k
k=1 for n > 0 k=1
with
def my_recursive_sum(n):
if n <= 0:
return 0
if n == 1:
return 1
return 1/n + my_recursive_sum(n-1)
print(my_recursive_sum(3))
Your solution would easily reach the maximum recursion limit.
when you call again the function using 1/n and 1/n+1 you would use the same n and increase it, so you would never reach the end condition.
the next couple of sum would never have an n value equal to 0 or 1.
Also you should not call again the function with 1/n otherwise you would endup looping forever in the function recall
you should use something like:
>>> def my_sum(n):
... if n < 1:
... return 0
... return 1/n + my_sum(n-1)
...
>>> print(my_sum(3))
1.8333333333333333
>>> 11/6
1.8333333333333333
>>>
edit:
Like mentioned in another answer you should avoid using sum as a name of a function because it's a name already use by python

base cases for recursive functions

What would be a possible base case for a recursive function that takes in any integer p and a non-negative integer j. the function should return the result when 11 is subtracted from the number j repeatedly n times.
I have my attempts below but am not sure if they are correct.
def subtract(p,j):
if n < 0:
raise ValueError ('Eexpecting non-negative n')
if x == 11 and n == 0:
return 11
while n >= 0:
x = x-11
n-=1
return x
The function that you have posted isn't a recursive function and you don't one. The definition of the recursive function says:
A recursive function is a function that calls itself during its execution.
Try this:
def sub_eleven(x, n):
return x - n * 11
However, if you have some reason to implement it using recursion, try this:
def sub_eleven(x, n):
if n <= 0: # Base Condition
return x
return sub_eleven(x - 11, n - 1) # Calling itself with different arguments/state

a recursive function to calculate sum of a number digits

i have to write a recursive function which calculates sum of a number digits,here's the code i tried :
def sum_digit(n):
sum=0
a = n % 10
n //= 10
sum += a
while n > 0 :
sum = sum + sum_digit(n)
return sum
print(sum_digit(67154))
i don't know why i don't get the 23 as answer...my program doesn't come to an end
for example 23 number(please correct me if I'm wrong,I'm a newbie in python),the 3 goes to sum, and n become2,since its > 0 then it should go to while,so now it should calculate sum digit(2),the a become 2 and 2 goes to sum and n become 0 and sum digit(2) returns 2,then it sum with the 3 and i must get 5.
i appreciate your help.
You have an infinite loop because n never changes within the loop. Note that assigning a new value to n in the scope of the called function will not change n in the outer scope.
Also, it seems you are mixing an iterative solution with a recursive one. If you do the recursive call, you do not need the loop, and vice versa.
You can either do it recursively:
def sum_digit(n):
if n > 0:
return sum_digit(n // 10) + n % 10
else:
return 0
Or in an iterative way:
def sum_digit(n):
s = 0
while n > 0:
s += n % 10
n //= 10
return s
Or just using bultin functions (probably not what your teacher wants to see):
def sum_digit(n):
return sum(map(int, str(n)))
i must change the while with a if, and it works,thanks for your comments and sorry for posting such a question here.
This will do the trick:
def sum_digit(n, current_sum=0):
if n == 0:
return current_sum
else:
digit = n % 10
current_sum += digit
n //= 10
return sum_digit(n, current_sum)
The output:
print(sum_digit(67154))
> 23
You were mixing up an iterative method (the while loop) and the recursive method (the function call).
In a recursive function, must make sure you get these things right:
The end condition (in our case, we return the sum when the digit is 0)
and
The recursive call (in our case, going down one digit each time)
Change your code as following:
def sum_digit(n):
sum=0
a = n % 10
n //= 10
sum += a
if n > 0 :
sum = sum + sum_digit(n)
return sum
The reason is n is assigned new reference inside function, but it's invisible outside. so while part is loop died. In fact, while part is executed at most once, so code was changed as above.

Categories

Resources