I'm asked to write a function that should return the sum of the following series 1000 + 1/1**2 + 1/2**2 + 1/3**2 + 1/4**2 + ... + 1/n**2
for the given integer n.
For example, for n = 0, the function should return 1000, for n = 1,
the function should return 1001, for n = 2, the function should return 1001.25, for n = 3, the function should return 1001.3611111111111, etc.
I know for sure this needs to be done by for loops and range functions.
Here's my code
if n<0:
return None
if n>0 or n==0:
for i in range(1,n-1):
result=1000+1/(i**2)
return result
But it keeps return None when n=o,1,2,3
I'm not sure how to fix this code...
In each iteration, you are not updating result using the previous value of it. (Also you are returning result prematurely.) Update the variable by using result = result + 1 / (i ** 2), or equivalently, result += 1 / (i ** 2).
def foo(n):
result = 1000
for i in range(1, n+1):
result += 1 / (i ** 2)
return result
print(foo(0), foo(1), foo(2), foo(3)) # 1000 1001.0 1001.25 1001.3611111111111
Or, using (generator) comprehension,
def foo(n):
return 1000 + sum(1 / (i ** 2) for i in range(1, n + 1))
You don't need any if statements. What you're doing right now is calculating result, then immediately returning the result on step 1.
result = 1000
for i in range(1,n+1):
result += 1/(i**2)
return result
Comment if anything doesn't make sense
First, you can only return from within a function, but your code has no function definition included - maybe you forgot. Second, if this code is part of a function, the first iteration of the loop will throw you out of the function as soon as it hits return, so this function, if implemented, will not complete the intended loop iterations. Since this is a homework question, I will not complete the code, but I hope this gives you a start.
Related
Here is a code that finds the value of the function T given by the recurrence relation for a given value of n:
def T(n):
if n <= 0:
return 1
else:
return T(n-1) + (n-1) * T(n-2)
print T(3)
#output
2
However, the code invokes the function T twice. I have added the print statement before the second return to show this:
def T(n):
if n <= 0:
return 1
else:
print (T(n-1) + (n-1) * T(n-2))
return T(n-1) + (n-1) * T(n-2)
print T(3)
#output
1
2
1
2
Is there an efficient way of invoking the function T only once? I'm using Python 2. I'd like something short and simple, nothing too complicated.
You're going to call T 2^(n-1) times, for n >1, and there is no way to reduce that to only once without removing the recursion.
If you meant to say that you want to reduce the repetitive calls, such as T(3) calls T(2) and T(1) while T(2) also calls T(1), then you need to use a process called memoization
For example, using a dictionary of inputs to results.
seen = dict()
def T(n):
if n <= 0:
return 1
else:
if n in seen:
return seen[n]
else:
result = T(n-1) + (n-1) * T(n-2)
seen[n] = result
return result
print(T(3))
You can redefine the function from T(n) = T(n-1) + (n-1)*T(n-2) to T(n+1) = T(n) + n*T(n-1) which will allow the recursion to move forward rather than backward provided you give it the current n and previous values. By only needing the previous value instead of the two previous values, the recursive progression is easier to grasp.
def T(N,n=1,Tm=1,Tn=1): # n,Tm,Tn represent n,T(n-1),T(n)
if n>N: return Tm # stop at n=N+1 and return T(n-1)
return T(N,n+1,Tn,Tn+n*Tm)
note: the function returns a when n>N in order to cover the case where N is zero.
Actually, this could also have been written without transposing the function by moving the stop condition to N+2 instead of N+1:
def T(N,n=2,Tn_2=1,Tn_1=1): # n,Tn_2,Tn_1 represent n,T(n-2),T(n-1)
if n==N+2: return Tn_2 # stop at n=N+2 and return T(n-2)
return T(N,n+1,Tn_1,Tn_1+(n-1)*Tn_2)
which can be further simplified to:
def T(N,n=1,a=1,b=1): return T(N-1,n+1,b,a*n+b) if N else a
Need help proving the time complexity of a recursive function.
Supposedly it's 2^n. I need to prove that this is the case.
def F(n):
if n == 0:
return 0
else:
result = 0
for i in range(n):
result += F(i)
return n*result+n`
Here's another version that does the same thing. The assignment said to use an array to store values in an attempt to reduce the time complexity so what I did was this
def F2(n,array):
if n < len(array):
answer = array[n]
elif n == 0:
answer = 0
array.append(answer)
else:
result = 0
for i in range(n):
result += F2(i,array)
answer = n*result+n
array.append(answer)
return answer
Again what I am looking for is the explanation of how to find the complexities of the two snippets of code, not interested in just knowing the answer.
All and any help greatly appreciated.
PS: for some reason, I can't get "def F2" to stay in the code block...sorry about that
Okay, the first function you wrote is an example of Exhaustive Search where you are exploring every possible branch that can be formed from a set of whole numbers up to n (which you have passed in the argument and you are using for loop for that). To explain you the time complexity I am going to consider the recursion stack as a Tree (to represent a recursive function call stack you can either use a stack or use an n-ary Tree)
Let's call you first function F1:
F1(3), now three branches will be formed for each number in the set S (set is the whole numbers up to n). I have taken n = 3, coz it will be easy for me to make the diagram for it. You can try will other larger numbers and observe the recursion call stack.
3
/| \
0 1 2 ----> the leftmost node is returns 0 coz (n==0) it's the base case
| /\
0 0 1
|
0 ----> returns 0
So here you have explored every possibility branches. If you try to write the recursive equation for the above problem then:
T(n) = 1; n is 0
= T(n-1) + T(n-2) + T(n-3) + ... + T(1); otherwise
Here,
T(n-1) = T(n-2) + T(n-3) + ... T(1).
So, T(n-1) + T(n-2) + T(n-3) + ... + T(1) = T(n-1) + T(n-1)
So, the Recursive equation becomes:
T(n) = 1; n is 0
= 2*T(n-1); otherwise
Now you can easily solve this recurrence relation (or use can use Masters theorem for the fast solution). You will get the time complexity as O(2^n).
Solving the recurrence relation:
T(n) = 2T(n-1)
= 2(2T(n-1-1) = 4T(n-2)
= 4(2T(n-3)
= 8T(n-3)
= 2^k T(n-k), for some integer `k` ----> equation 1
Now we are given the base case where n is 0, so let,
n-k = 0 , i.e. k = n;
Put k = n in equation 1,
T(n) = 2^n * T(n-n)
= 2^n * T(0)
= 2^n * 1; // as T(0) is 1
= 2^n
So, T.C = O(2^n)
So this is how you can get the time complexity for your first function. Next, if you observe the recursion Tree formed above (each node in the tree is a subproblem of the main problem), you will see that the nodes are repeating (i.e. the subproblems are repeating). So you have used a memory in your second function F2 to store the already computed value and whenever the sub-problems are occurring again (i.e. repeating subproblems) you are using the pre-computed value (this saves time for computing the sub-problems again and again). The approach is also known as Dynamic Programming.
Let's now see the second function, here you are returning answer. But, if you see your function you are building an array named as array in your program. The main time complexity goes there. Calculating its time complexity is simple because there is always just one level of recursion involved (or casually you can say no recursion involved) as every number i which is in range of number n is always going to be less than the number n, So the first if condition gets executed and control returns from there in F2. So each call can't go deeper than 2 level in the call stack.
So,
Time complexity of second function = time taken to build the array;
= 1 comparisions + 1 comparisions + 2 comparisions + ... + (n-1) comparisions
= 1 + 2 + 3 + ... + n-1
= O(n^2).
Let me give you a simple way to observe such recursions more deeply. You can print the recursion stack on the console and observe how the function calls are being made. Below I have written your code where I am printing the function calls.
Code:
def indent(n):
for i in xrange(n):
print ' '*i,
# second argument rec_cnt is just taken to print the indented function properly
def F(n, rec_cnt):
indent(rec_cnt)
print 'F(' + str(n) + ')'
if n == 0:
return 0
else:
result = 0
for i in range(n):
result += F(i, rec_cnt+1)
return n*result+n
# third argument is just taken to print the indented function properly
def F2(n, array, rec_cnt):
indent(rec_cnt)
print 'F2(' + str(n) + ')'
if n < len(array):
answer = array[n]
elif n == 0:
answer = 0
array.append(answer)
else:
result = 0
for i in range(n):
result += F2(i, array, rec_cnt+1)
answer = n*result+n
array.append(answer)
return answer
print F(4, 1)
lis = []
print F2(4, lis, 1)
Now observe the output:
F(4)
F(0)
F(1)
F(0)
F(2)
F(0)
F(1)
F(0)
F(3)
F(0)
F(1)
F(0)
F(2)
F(0)
F(1)
F(0)
96
F2(4)
F2(0)
F2(1)
F2(0)
F2(2)
F2(0)
F2(1)
F2(3)
F2(0)
F2(1)
F2(2)
96
In the first function call stack i.e. F1, you see that each call is explored up to 0, i.e. we are exploring each possible branch up to 0 (the base case), so, we call it Exhaustive Search.
In the second function call stack, you can see that the function calls are getting only two levels deep, i.e. they are using the pre-computed value to solve the repeated subproblems. Thus, it's time complexity is lesser than F1.
Okay, this question is a little strange, but I was wondering if I could do it like this.
I'm working on a simple Fibonacci number generator for fun since I was interested in programming it.
So I wrote this out:
def f(n):
if n == 1: return 1
if n == 2: return 2
else:
return f(n-1) + f(n-2)
and that ran very slowly, taking 15 seconds to do f(30) on my computer.
So then I wrote this:
def f(n):
global a
if n == 1: return 1
if n == 2: return 1
else:
if "fib(%s)" % n in a:
return a["fib(%s)" % n]
else:
z = f(n-1) + f(n-2)
a["fib(%s)" % n] = z
return z
which basically stores previous results in a dictionary like so:
{'f(1)':1,'f(2)':2,'f(3)':3,'f(4)':5} and so on. In the function it would check if that result was in that dictionary, then just use that instead of having to redo all the calculations.
This made it tons faster. I could do f(100) and it instantly appear. Going by intervals of 500, I got to f(4000) and it was still instantaneous. The one problem was that the dictionary was getting stupidly big.
So I added a = {} to the end of the function, and that didn't work; it still left a as a massive dict.
So doing this:
def f(n):
global a
if n == 1: return 1
if n == 2: return 1
else:
if "fib(%s)" % n in a:
return a["fib(%s)" % n]
else:
z = f(n-1) + f(n-2)
a["fib(%s)" % n] = z
return z
a = {}
didn't work. but if I do this:
def f(n):
global a
if n == 1: return 1
if n == 2: return 1
else:
if "fib(%s)" % n in a:
return a["fib(%s)" % n]
else:
z = f(n-1) + f(n-2)
a["fib(%s)" % n] = z
return z
# now run the function
f(100)
a = {}
a gets reset to an empty dictionary. Why does this happen and how can I fix it?
Your a = {} statement inside the function was never being executed; every possible path of execution reaches a return before then. If it WAS executed, you wouldn't have liked the results - it would have executed in every single recursive call to the function, meaning that your dictionary would never hold more than one item! You would somehow have to detect the outermost call and only clear the dict there, or (much simpler) clear it outside of the recursion as in your second example.
Note that much of the size of your dictionary is coming from the strange decision to use a long string key. Keying it with the number itself (as in a[n] = z) would make it much more compact.
(For future reference: the technique you've come up with here, of saving the results from previous function calls, is known as "memoization".)
Despite your question, what you really want is a faster way of calculating Fibonacci sequence, right? The problem with your original approach is that recurrence, despite being very elegant and quick to code, is quite slow. Fibonacci sequence has a close form solution. You should do this math directly to speed up your code.
As convention, consider the Fibonacci sequence F(i) as: F(0) = 0, F(1) = 1, F(k) = F(k-1) + F(k-2) k = 2, 3, ... The solution for this sequence is (I will not demonstrate it here, because is not the place for that) F(k) = (1/sqrt(5))*(a^k - b^k), where a = (1 + sqrt(5))/2 and b = (1 - sqrt(5))/2.
Thus, you code could be implemented like this:
def f(n):
a = (1 + 5**.5)/2
b = (1 - 5**.5)/2
F = (a**n - b**n)/5**.5
F = int(round(F)) #necessary to get an integer without the decimal part of the approximation. Afterall, you are working with irrational numbers.
return F
This code scale very well for large values of n.
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
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