What is missing (while loop)? - python

I'm trying to sum a number like: n -> n + (n-1) + (n-2) + ... + 1. My code is working, but not doing what I wanted it to do. I would like to know if I'm missing a parameter or something like this.
def s(n):
a = n-1
r = 0
while a != 1:
r = r + a
a = a - 1
return r
print (s(10))

A good way to debug code is to try walking through its execution with a simple example.
Let's try 4. We would expect to get the answer 4+3+2+1 = 10.
s(4)
Before the loop starts, a=3, r=0.
After the first iteration,
a=2, r=3.
After the second iteration, a=1, r=5.
a != 1 is now False, so the loop ends, and we return r, which is 5. We only ever added 3 and 2 to it, and forgot to add 4 and 1.
Looking at this a level higher, your function is always missing the first (n) and the last (1) values of the sum. Fix both of these mistakes and your function should work how you expect. These are both examples of the classic fencepost error - your fence is missing posts at both ends.

Related

Finding the Maximum Pyramidal Number by recursion in Python

I'm given the task to define a function to find the largest pyramidal number. For context, this is what pyramidal numbers are:
1 = 1^2
5 = 1^2 + 2^2
14 = 1^2 + 2^2 + 3^2
And so on.
The first part of the question requires me to find iteratively the largest pyramidal number within the range of argument n. To which, I successfully did:
def largest_square_pyramidal_num(n):
total = 0
i = 0
while total <= n:
total += i**2
i += 1
if total > n:
return total - (i-1)**2
else:
return total
So far, I can catch on.
The next part of the question then requires me to define the same function, but this time recursively. That's where I was instantly stunned. For the usual recursive functions that I have worked on before, I had always operated ON the argument, but had never come across a function where the argument was the condition instead. I struggled for quite a while and ended up with a function I knew clearly would not work. But I simply could not wrap my head around how to "recurse" such function. Here's my obviously-wrong code:
def largest_square_pyramidal_num_rec(n):
m = 0
pyr_number = 0
pyr_number += m**2
def pyr_num(m):
if pyr_number >= n:
return pyr_number
else:
return pyr_num(m+1)
return pyr_number
I know this is erroneous, and I can say why, but I don't know how to correct it. Does anyone have any advice?
Edit: At the kind request of a fellow programmer, here is my logic and what I know is wrong:
Here's my logic: The process that repeats itself is the addition of square numbers to give the pyr num. Hence this is the recursive process. But this isn't what the argument is about, hence I need to redefine the recursive argument. In this case, m, and build up to a pyr num of pyr_number, to which I will compare with the condition of n. I'm used to recursion in decrements, but it doesn't make sense to me (I mean, where to start?) so I attempted to recall the function upwards.
BUT this clearly isn't right. First of all, I'm sceptical of defining the element m and pyr_num outside of the pyr_num subfunction. Next, m isn't pre-defined. Which is wrong. Lastly and most importantly, the calling of pyr_num will always call back pyr_num = 0. But I cannot figure out another way to write this logic out
Here's a recursive function to calculate the pyramid number, based on how many terms you give it.
def pyramid(terms: int) -> int:
if terms <=1:
return 1
return terms * terms + pyramid(terms - 1)
pyramid(3) # 14
If you can understand what the function does and how it works, you should be able to figure out another function that gives you the greatest pyramid less than n.
def base(n):
return rec(n, 0, 0)
def rec(n, i, tot):
if tot > n:
return tot - (i-1)**2
else:
return rec(n, i+1, tot+i**2)
print(base(NUMBER))
this output the same thing of your not-recursive function.

I'm brand new and working on Project Euler #2 in python

The goal is to sum up every even number up to 4 million.
I thought this would work but the program gets stuck running. Think it has to do with the if statement, but lost otherwise. Here's what I have.
list = []
a, b = 0, 1
while b <40:
if b%2 == 0:
list.append(b)
a, b = b, a+b
t=sum(list)
print(t)
This here is your biggest problem:
a, b = b, a+b
It has so much potential to mess up your loop! And like others mentioned it doesn't even update anything when b is odd, only when it is even, and then you're stuck.
Why not do this the simple way, with range:
mysum = sum([i for i in range(0, 40, 2)])
Will take care of everything with one line (and of course, replace 40 with 4,000,001 for your question, if you want to include the number 4,000,000 as well. If you just want everything up to it but not to include it, use just 4,000,000)
a, b = b, a+b
This line only runs if b % 2 == 0. I think you meant to run it every time. It should be indented one layer further out.
One can also use the mathematics rule where the sum of integers between 1 and n is equal to n*(n+1)/2. If we want to sum only even numbers, it is like considering only half the number to sum and multiply the result with two.
fSumEvenNumbers = lambda x: (x//2)*(x//2+1)
This would give
fSumEvenNumbers(40000000)
which is equivalent to
(2e7)**2 + 2e7
4e14 + 2e7
400000020000000

Python: Nesting an "If" statement inside a "while" loop?

I'm new to Python, which is why I'm having trouble on a problem which others might find easy.
Background to this problem: Euler Project, question 2. The problem essentially asks us to add all the even terms in the Fibonacci sequence, so long that each term is under 4,000,000. I decided to do the problem a little differently than what many solutions online show, by calculating the nth Fibonacci term from a closed formula. For now, suppose this function is called Fibonacci(n).
What I'd essentially like to do is loop through an unknown amount of integers that represent the indexes of the Fibonacci set (i.e., 1, 2, 3, 4... etc) and plug each value into Fibonacci(n). If the result has no remainder when divided by 2, then add this Fibonacci number to some value initially set at 0.
Here's what I have so far:
def Fibonacci(n):
return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
i=0
FibSum = 0
nFib = 0
while (nFib <= 10):
nFib = Fibonacci(i)
if(nFib%2==0):
FibSum += nFib
i += 1
print FibSum
(Yes, as you can see, I'm constraining the Fibonacci sequence to end at 10 as opposed to 4,000,000; this is done merely for testing's sake.)
Now, here's my problem: when I run this code, I get 2.0 instead of 10.0 (2 and 8 are the two Fibonacci numbers that should be added together).
How come? My guess is that the loop stops after it gets to the third Fibonacci number (2) and doesn't continue beyond that. Does anyone see something wrong with my code?
Please comment if you have any further questions. Thanks in advance.
Solution provided by Gal Dreiman is fine but, conversion with in function is more better, below is your revised code:
def Fibonacci(n):
return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n)))
You have a floating point problem (which you can read on here)- the returned value 'nFib' is not an integer and not a rounded value. I ran your code and added print for this value in every iteration and got:
0.0
1.0
1.0
2.0
3.0000000000000004
5.000000000000001
8.000000000000002
13.000000000000002
The solution for this is to modify your code as the following:
nFib = int(Fibonacci(i))
After that I got the output: 10
The problem is with nFib%2==0 comparison. Here you try to compare the float LHS with integer 0. So either modify the if loop as below or modify the return as return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))).
>>> def Fibonacci(n):
... return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
...
>>> i=0
>>> FibSum = 0
>>> nFib = 0
>>> while (nFib <= 10):
... nFib = Fibonacci(i)
... if(int(nFib%2)==0):
... FibSum += nFib
... i += 1
...
>>> print FibSum
10.0

Recursion function in Python

Consider this basic recursion in Python:
def fibonacci(number):
if number == 0: return 0
elif number == 1:
return 1
else:
return fibonacci(number-1) + fibonacci(number-2)
Which makes sense according to the (n-1) + (n-2) function of the Fibonacci series.
How does Python execute recursion that contains another recursion not within but inside the same code line? Does the 'finobacci(number-1)' complete all the recursion until it reaches '1' and then it does the same with 'fibonacci(number-2)' and add them?
For comparison, the following recursive function for raising a number 'x' into power 'y', I can understand the recursion, def power calling itself until y==0 , since there's only one recursive call in a single line. Still shouldn't all results be '1' since the last command executed is 'return 1' when y==0, therefore x is not returned?
def power(x, y):
if y == 0:
return 1
else:
return x*power(x, y-1)
Short Answer
Each time Python "sees" fibonacci() it makes another function call and doesn't progress further until it has finished that function call.
Example
So let's say it's evaluating fibonacci(4).
Once it gets to the line return fibonacci(number-1) + fibonacci(number-2), it "sees" the call fibonacci(number-1).
So now it runs fibonacci(3) - it hasn't seen fibonacci(number-2) at all yet. To run fibonacci(3), it must figure out fibonacci(2)+fibonacci(1). Again, it runs the first function it sees, which this time is fibonacci(2).
Now it finally hits a base case when fibonacci(2) is run. It evaluates fibonacci(1), which returns 1, then, for the first time, it can continue to the + fibonacci(number-2) part of a fibonacci() call. fibonacci(0) returns 0, which then lets fibonacci(2) return 1.
Now that fibonacci(3) has gotten the value returned from fibonacci(2), it can progress to evaluating fibonacci(number-2) (fibonacci(1)).
This process continues until everything has been evaluated and fibonacci(4) can return 3.
To see how the whole evaluation goes, follow the arrows in this diagram:
In the expression fibonacci(number-1) + fibonacci(number-2) the first function call will have to complete before the second function call is invoked.
So, the whole recursion stack for the first call has to be complete before the second call is started.
does the 'finobacci(number-1)' completes all the recursion until it reaches '1' and then it does the same with 'fibonacci(number-2)' and add them?
Yes, that's exactly right. In other words, the following
return fibonacci(number-1) + fibonacci(number-2)
is equivalent to
f1 = fibonacci(number-1)
f2 = fibonacci(number-2)
return f1 + f2
You can use the rcviz module to visualize recursions by simply adding a decorator to your recursive function.
Here's the visualization for your code above:
The edges are numbered by the order in which they were traversed by the execution. The edges fade from black to grey to indicate order of traversal: black edges first, grey edges last.
(I wrote the rcviz module on GitHub.)
I would really recommend that you put your code in the Python tutor.
You will the be able to get it on the fly. See the stackframe, references, etc.
You can figure this out yourself, by putting a print function in the function, and adding a depth so we can print it out prettier:
def fibonacci(number, depth = 0):
print " " * depth, number
if number == 0:
return 0
elif number == 1:
return 1
else:
return fibonacci(number-1, depth + 1) + fibonacci(number-2, depth + 1)
Calling fibonacci(5) gives us:
5
4
3
2
1
0
1
2
1
0
3
2
1
0
1
We can see that 5 calls 4, which goes to completion, and then it calls 3, which then goes to completion.
Matthew and MArtjin are right but I thought I might elaborate:
Python does stuff from left to right whenever it can. Exceptions to this rule are implied by brackets.
in x*power(x, y-1): x is evaluated then power is evaluated
While in fibonacci(number-1) + fibonacci(number-2), fibonacci(number-1) is evaluated (recursively, til it stops) and then fibonacci(number-1) is evaluated
Your second recursion functions does this (example), so 1 will not be returned.
power(2, 3)
2 * power(2, 2)
2 * 2 * power(1,2)
2 * 2 * 2 * power(0,2) # Reaching base case
2 * 2 * 2 * 1
8
def fib(x):
if x == 0 or x == 1:
return 1
else:
return fib(x-1) + fib(x-2)
print(fib(4))
def fib(n):
if n <= 1:
return n
else :
return fib(n - 1) + fib(n - 2)

Recursion Extracting Digits Using a Base

Homework help needed here.
Im really struggling to get my head around recursion and the way it works.
The problem is, write a recursive function dec2base(n,b) that returns the list of base b digits in the positive integer n
exmaple:
dec2base(120, 10) => [1,2,0] (1*10*2 + 2/10**1 + 0*10**0)
I understand there should be a stop case but i cant think of what it might be.
So at the moment, all my code looks like is:
def dec2base(n, b):
if
And that's it. Any guidance would be amazing. Thankyou!
EDIT: tired a code for somehting like this:
def dec2base(n, b):
if n < 10:
return [n]
else:
return getdigits(n/b) + [n%b]
but that doesnt get me anwyehre...
To understand recursion, one has to first understand recursion.
You stated the stop case by yourself, it's of course when it's reached base**0
Edit: #your Edit: you almost got it, do not give up. how many arguments does dec2base take? think!
The key element to this task is understanding (or devising)
Horner's method.
We can write numbers in your way:
1234 = 1*103 + 2*102 + 3*101 + 4*100
But after thinking a bit we come up with this representation:
1234 = 123*10 + 4 = (12*10 + 3)*10 + 4 = ((1*10 + 2)*10 + 3)*10 + 4
I hope you can see recursion more clearly. In each step, check if number can be divided mod 10. If so, remainder is next digit and quotient can be worked on recursively.
def dec2base(n,b):
if n < b:
return [n]
else:
return dec2base(n//b, b) + [n%b]

Categories