Recursive function to calculate sum of 1 to n? - python

This is what I've got and I'm not sure why it's not working:
def sum(n):
if n > 0:
print(n)
return sum(n) + sum(n-1)
else:
print("done doodly")
number = int(input(": "))
sum(number)
For example if the user inputs 5, I want the program to calculate the sum of 5+4+3+2+1. What am I doing wrong?
For the non-recursive version of this question, see Sum of the integers from 1 to n

Two things:
Calling sum(n) when computing sum for n won't do you much good because you'll recurse indefinitely. So the line return sum(n)+sum(n-1) is incorrect; it needs to be n plus the sum of the n - 1 other values. This also makes sense as that's what you want to compute.
You need to return a value for the base case and for the recursive case.
As such you can simplify your code to:
def sum(n):
if n == 0:
return 0
return n + sum(n - 1)

You forgot to return when n==0 (in your else)
>>> def Sum(n):
... if not n:
... return 0
... else:
... return n + Sum(n-1)
...
>>> Sum(5)
15

Recursion is a wrong way to calculate the sum of the first n number, since you make the computer to do n calculations (This runs in O(n) time.) which is a waste.
You could even use the built-in sum() function with range(), but despite this code is looking nice and clean, it still runs in O(n):
>>> def sum_(n):
... return sum(range(1, n+1))
...
>>> sum_(5)
15
Instead recursion I recommend using the equation of sum of arithmetic series, since It runs in O(1) time:
>>> def sum_(n):
... return (n + n**2)//2
...
>>> sum_(5)
15

You can complicate your code to:
def my_sum(n, first=0):
if n == first:
return 0
else:
return n + my_sum(n-1, (n+first)//2) + my_sum((n+first)//2, first)
The advantage is that now you only use log(n) stack instead of nstack

I think you can use the below mathematical function(complexity O(1)) instead of using recursion(complexity O(n))
def sum(n):
return (n*(n+1))/2

Using Recursion
def sum_upto(n):
return n + sum_upto(n-1) if n else 0
sum_upto(100)
5050

Please have a look at the below snippet in regards to your request. I certainly hope this helps. Cheers!
def recursive_sum(n):
return n if n <= 1 else n + recursive_sum(n-1)
# Please change the number to test other scenarios.
num = 100
if num < 0:
print("Please enter a positive number")
else:
print("The sum is",recursive_sum(num))

Related

Is there a function to multiply the result of all iterations of a loop in python? [duplicate]

How do I go about computing a factorial of an integer in Python?
The easiest way is to use math.factorial (available in Python 2.6 and above):
import math
math.factorial(1000)
If you want/have to write it yourself, you can use an iterative approach:
def factorial(n):
fact = 1
for num in range(2, n + 1):
fact *= num
return fact
or a recursive approach:
def factorial(n):
if n < 2:
return 1
else:
return n * factorial(n-1)
Note that the factorial function is only defined for positive integers, so you should also check that n >= 0 and that isinstance(n, int). If it's not, raise a ValueError or a TypeError respectively. math.factorial will take care of this for you.
On Python 2.6 and up, try:
import math
math.factorial(n)
Existing solution
The shortest and probably the fastest solution is:
from math import factorial
print factorial(1000)
Building your own
You can also build your own solution. Generally you have two approaches. The one that suits me best is:
from itertools import imap
def factorial(x):
return reduce(long.__mul__, imap(long, xrange(1, x + 1)))
print factorial(1000)
(it works also for bigger numbers, when the result becomes long)
The second way of achieving the same is:
def factorial(x):
result = 1
for i in xrange(2, x + 1):
result *= i
return result
print factorial(1000)
def factorial(n):
if n < 2:
return 1
return n * factorial(n - 1)
For performance reasons, please do not use recursion. It would be disastrous.
def fact(n, total=1):
while True:
if n == 1:
return total
n, total = n - 1, total * n
Check running results
cProfile.run('fact(126000)')
4 function calls in 5.164 seconds
Using the stack is convenient (like recursive call), but it comes at a cost: storing detailed information can take up a lot of memory.
If the stack is high, it means that the computer stores a lot of information about function calls.
The method only takes up constant memory (like iteration).
Or using a 'for' loop
def fact(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
Check running results
cProfile.run('fact(126000)')
4 function calls in 4.708 seconds
Or using the built-in function math
def fact(n):
return math.factorial(n)
Check running results
cProfile.run('fact(126000)')
5 function calls in 0.272 seconds
If you are using Python 2.5 or older, try
from operator import mul
def factorial(n):
return reduce(mul, range(1, n+1))
For newer versions of Python, there is factorial in the math module as given in other answers here.
def fact(n):
f = 1
for i in range(1, n + 1):
f *= i
return f
Another way to do it is to use np.prod shown below:
def factorial(n):
if n == 0:
return 1
else:
return np.prod(np.arange(1,n+1))
Non-recursive solution, no imports:
def factorial(x):
return eval(' * '.join(map(str, range(1, x + 1))))
You can also make it in one line recursively if you like it. It is just a matter of personal choice. Here we are using inline if else in Python, which is similar to the ternary operator in Java:
Expression1 ? Expression2 : Expression3
One line function call approach:
def factorial(n): return 1 if n == 0 else n * factorial(n-1)
One line lambda function approach:
(although it is not recommended to assign lambda functions directly to a name, as it is considered a bad practice and may bring inconsistency to your code. It's always good to know. See PEP8.)
factorial = lambda n: 1 if n == 0 else n * factorial(n-1)

This program i am creating for Fibonacci but it return none.Kindly solve this problem

def fibonacci(n):
for i in range(n,1):
fab=0
if(i>1):
fab=fab+i
i=i-1
return fab
elif i==0:
return 0
else:
return 1
n1 = int(input("enter the nth term: "))
n2=fibonacci(n1)
print(n2)
The only way your code can return none is if you enter an invalid range, where the start value is greater than or equal to the stop value (1)
you probably just need range(n) instead of range(n, 1)
You can do this too:
def fibonacci(n):
return 0 if n == 1 else (1 if n == 2 else (fibonacci(n - 1) + fibonacci(n - 2) if n > 0 else None))
print(fibonacci(12))
You may need to use recursion for for nth Fibonacci number:
ex:
def Fibonacci(n):
if n==1:
return 0
elif n==2:
return 1
else:
return Fibonacci(n-1)+Fibonacci(n-2)
print(Fibonacci(9))
# output:21
If you do not plan to use large numbers, you can use the easy and simple typical recursive way of programming this function, although it may be slow for big numbers (>25 is noticeable), so take it into account.
def fibonacci(n):
if n<=0:
return 0
if n==1:
return 1
return fibonacci(n-1)+fibonacci(n-2)
You can also add a cache for the numbers you already stepped in, in order to make it run much faster. It will consume a very small amount of extra memory but it allows you to calculate larger numbers instantaneously (you can test it with fibonacci(1000), which is almost the last number you can calculate due to recursion limitation)
cache_fib = {}
def fibonacci(n):
if n<=0:
return 0
if n==1:
return 1
if n in cache_fib.keys():
return cache_fib[n]
result = fibonacci(n-1)+fibonacci(n-2)
cache_fib[n] = result
return result
In case you really need big numbers, you can do this trick to allow more recursion levels:
cache_fib = {1:1}
def fibonacci(n):
if n<=0:
return 0
if n in cache_fib.keys():
return cache_fib[n]
max_cached = max(cache_fib.keys())
if n-max_cached>500:
print("max_cached:", max_cached)
fibonacci(max_cached+500)
result = fibonacci(n-1)+fibonacci(n-2)
cache_fib[n] = result
return result
range(n,1) creates a range starting with n, incrementing in steps of 1 and stopping when n is larger or equal to 1. So, in case n is negative or zero, your loop will be executed. But in case n is 1 or larger, the loop will never be executed and the function just returns None.
If you would like a range going from n downwards to 1, you can use range(n,1,-1) where -1 is the step value. Note that when stepping down, the last number is included range(5,1,-1) is [5,4,3,2,1] while when stepping upwards range(1,5) is [1,2,3,4] the last element is not included. range(n) with only one parameter also exists. It is equivalent to range(0, n) and goes from 0 till n-1, which means the loop would be executed exactly n times.
Also note that you write return in every clause of the if statement. That makes that your function returns its value and interrupts the for loop.
Further, note that you set fab=0 at the start of your for loop. This makes that it is set again and again to 0 each time you do a pass of the loop. Therefore, it is better to put fab=0 just before the start of the loop.
As others have mentioned, even with these changes, your function will not calculate the Fibonacci numbers. A recursive function is a simple though inefficient solution. Some fancy playing with two variables can calculate Fibonacci in a for loop. Another interesting approach is memorization or caching as demonstrated by #Ganathor.
Here is a solution that without recursion and without caching. Note that Fibonacci is a very special case where this works. Recursion and caching are very useful tools for more real world problems.
def fibonacci(n):
a = 0
b = 1
for i in range(n):
a, b = a + b, a # note that a and b get new values simultaneously
return a
print (fibonacci(100000))
And if you want a really, really fast and fancy code:
def fibonacci_fast(n):
a = 1
b = 0
p = 0
q = 1
while n > 0 :
if n % 2 == 0 :
p, q = p*p + q*q, 2*p*q + q*q
n = n // 2
else:
a, b = b*q + a*q + a*p, b*p + a*q
n = n - 1
return b
print (fibonacci_fast(1000000))
Note that this relies on some special properties of the Fibonacci sequence. It also gets slow for Python to do calculations with really large numbers. The millionth Fibonacci number has more than 200,000 digits.

How to fix this problem of while loop in the factorial procedure>

I try to define a factorial procedure with these codes, but the result I get is the n^2, not n*(n-1)*(n-2)......1. It seems the in has only been implemented once when i=n. I am confused and What is the problem?
def factorial(n):
i = 1
while n >=i:
result = i * n
i = i + 1
return result
You should keep aggregating the operation over result instead:
def factorial(n):
result = 1
while n > 1:
result *= n
n -= 1
return result
so that factorial(4) returns: 24
If you want to alter your logic, see #blhsing' answer.
An easier way to implement factorial is like so:
def factorial(n):
if not n:
return 1
else:
return n * factorial(n-1)
Remember that math.factorial also exists. This is the best solution you're not required to build the function yourself.

Recursion function to find sum of digits in integers using python

def sumdigits(number):
if number==0:
return 0
if number!=0:
return (number%10) + (number//10)
this is the function that I have. However its only give the proper sum of 2 digit numbers. How can i get the sum of any number.
Also would my function count as recursion
def main():
number=int(input("Enter a number :"))
print(sumdigits(number))
main()
No, it is not recursive as you are not calling your function from inside your function.
Try:
def sumdigits(number):
if number == 0:
return 0
else:
return (number%10) + sumdigits(number//10)
Recursion is a way of programming or coding a problem, in which a function calls itself one or more times in its body.
Usually, it is returning the return value of this function call. If a function definition fulfils the condition of recursion, we call this function a recursive function.
A recursive function has to terminate to be used in a program.
Usually, it terminates, if with every recursive call the solution of the problem is downsized and moves towards a base case.
A base case is a case, where the problem can be solved without further recursion. (a recursion can lead to an infinite loop, if the base case is not met in the calls).
For this problem, the "base case" is:
if number == 0:
return 0
A simple recursive function for sum all the digits of a number is:
def sum_digits(number):
""" Return the sum of digits of a number.
number: non-negative integer
"""
# Base Case
if number == 0:
return 0
else:
# Mod (%) by 10 gives you the rightmost digit (227 % 10 == 7),
# while doing integer division by 10 removes the rightmost
# digit (227 // 10 is 22)
return (number % 10) + sumdigits(number // 10)
If we run the code we have:
>>>print sum_digits(57) # (5 + 7) = 12
12
>>>print sum_digits(5728) # (5 + 7 + 2 + 8) = 22
22
For a function to be recursive, it must call itself within itself. Furthermore, since your current one does not do this, it is not recursive.
Here is a simple recursive function that does what you want:
>>> def sumdigits(n):
... return n and n%10 + sumdigits(n//10)
...
>>> sumdigits(457)
16
>>> sumdigits(45)
9
>>> sumdigits(1234)
10
>>>
You don't make a recursive step (calling sumdigits() inside)!
I believe this is what you are looking for:
def sum_digits(n):
if n < 10:
return n
else:
all_but_last, last = n // 10, n % 10
return sum_digits(all_but_last) + last
While recursion is a clever way to go, I'd generally stay away from it for performance and logic reasons (it can get complex pretty quick). I know it's not the answer you are looking for but I'd personally stick to something like this or some kind of loop:
def sumdigits(number):
return sum(map(int, str(number)))
Good luck!
I was working on this recently hope it will help someone in future
def digit(n):
p=0
for i in str(n):
p += int(i)
return p
def superDigit(n):
if n==0:
return 0
return digit(digit(digit(digit(n))))
Here's a solution to summing a series of integer digits that uses ternary operators with recursion and some parameter checking that only happens the first time through the function. Some python coders may consider this less pythonic (using ternary expressions), however, it demonstrates how to use recursion, answering the original question, while introducing ternary operators to combine a few multi-line if/else statements into simple math.
Note that:
int * True = int, whereas int * False = 0
float * True = Float, whereas float * False = 0
"Text" * True = "Text", but "Text" * False = ""; but also
"Text" * 0 = "", whereas "Text" * 3 = "TextTextText"
"Text" * float = Error; whereas "Text" * int = Error
The one-line if/else statement reads as follows:
Expression_if_True if Condition_to_Check else Expression_if_False
def digitSum2(n = 0, first = True):
if first:
first = False
if type(n) != int or n < 0:
return "Only positive integers accepted."
return (n * (n < 10) + (n % 10 + digitSum2(n // 10, first)) * (n >= 10)) if (n > 0) else 0

How do I return the product of a while loop

I don't get the concept of loops yet. I got the following code:
x=0
while x < n:
x = x+1
print x
which prints 1,2,3,4,5.
That's fine, but how do I access the computation, that was done in the loop? e.g., how do I return the product of the loop( 5*4*3*2*1)?
Thanks.
Edit:
That was my final code:
def factorial(n):
result = 1
while n >= 1:
result = result *n
n=n-1
return result
You want to introduce one more variable (total) which contains accumulated value of a bunch of actions:
total = 1
x = 1
while x <= 5:
total *= x
x += 1
print x, total
print 'total:', total
Actually, more pythonic way:
total = 1
n = 5
for x in xrange(1, n + 1):
total *= x
print total
Note, that the initial value of total must be 1 and not 0 since in the latter case you will always receive 0 as a result (0*1*.. is always equals to 0).
By storing that product and returning that result:
def calculate_product(n):
product = 1
for x in range(n):
product *= x + 1
return product
Now we have a function that produces your calculation, and it returns the result:
print calculate_product(5)
A "one-liner"
>>> import operator
>>> reduce(operator.mul, xrange(1, n + 1))
120
>>>
Alternately you could use the yield keyword which will return the value from within the while loop. For instance:
def yeild_example():
current_answer = 1
for i in range(1,n+1):
current_answer *= i
yield current_answer
Which will lazily evaluate the answers for you. If you just want everything once this is probably the way to go, but if you know you want to store things then you should probably use return as in other answers, but this is nice for a lot of other applications.
This is called a generator function with the idea behind it being that it is a function that will "generate" answers when asked. In contrast to a standard function that will generate everything at once, this allows you to only perform calculations when you need to and will generally be more memory efficient, though performance is best evaluated on a case-by-case basis. As always.
**Edit: So this is not quite the question OP is asking, but I think it would be a good introduction into some of the really neat and flexible things about python.
use a for loop:
sum_ = 1
for i in range(1, 6):
sum_ *= i
print sum_
If you prefer to keep your while loop structure, you could do it like (there are 1000 +1 ways to do it ...):
x=1
result = 1
while x <= n:
x += 1
result *= x
Where result will store the factorial. You can then just return or print out result, or whatever you want to do with it.
to access the computation done in the loop, you must use counter(with useful and understandable name), where you will store the result of computation. After computation you just return or use the counter as the product of the loop.
sum_counter=0
x=0
while x < 10:
sum_counter +=x
x+=1
print sum_counter

Categories