Flow of recursion in python roman to arabic - python

So I just solved the last quiz on recursion on codeacademy. But while I was trying to understand the flow of execution of this code on pythontutor.org, I just couldnt follow the flow of this code.
def rval(letr):
if(letr=='I'):
return 1
elif(letr=='V'):
return 5
elif(letr=='X'):
return 10
elif(letr=='L'):
return 50
elif(letr=='C'):
return 100
elif(letr=='D'):
return 500
elif(letr=='M'):
return 1000
else:
return "error"
def arabic(n):
if len(n)==0:
return 0
elif len(n)==1:
return rval(n)
elif len(n)==2:
if rval(n[0])>rval(n[1]):
return rval(n[0])+rval(n[1])
else:
return rval(n[1])-rval(n[0])
else:
return arabic(n[len(n)-2:])+arabic(n[:len(n)-2])
arabic('DXCVI')
======PROBLEM FACED======
My question is this --
Suppose I run arabic('DXCVI'), then how does this line arabic(n[len(n)-2:])+arabic(n[:len(n)-2]) get executed
Do both arabic(n[len(n)-2:]) & arabic(n[:len(n)-2]) start getting executed simultaneously or does the second term wait until the first is done/returns a value ?

The left part arabic(n[len(n)-2:]) is always called first. An easy way to find this out is to put a print statement in your arabic(n) function.
Try something like this:
def arabic(n):
print n
if len(n)==0:
return 0
elif len(n)==1:
return rval(n)
elif len(n)==2:
# more code
Which would output this:
DXCVI
VI
DXC
XC
D
Proving that the left side, arabic(n[len(n)-2:]), gets called before +arabic(n[:len(n)-2]).

First arabic(n[len(n)-2:]) (the left part) is executed, then arabic(n[:len(n)-2]) (the right part) is executed.
Remember that the first part may also have recursive calls, so the second one must wait until it returns a value to get executed.

Related

What is wrong with my python hyperoperation recursive function?

I tried to use the definition from Wikipedia for Hyperoperations and translate it into Python code.
My goal was to make it readable, making it fast was a task for later.
Here's the definition I used and below it is my code.
from Wikipedia: https://en.wikipedia.org/wiki/Hyperoperation#Definition
And now here's my code:
def hyperation(n, a, b):
if n == 0:
return b+1
if n == 1 and b == 0:
return a
if n == 2 and b == 0:
return 0
if n >= 3 and b == 0:
return 1
return hyperation(n-1, a, hyperation(n, a, b-1))
When I tried it with hyperation(n=1, a=3, b=3), what should basically be the same as
3 + 3
I always hit the recursion limit, doesn't matter how high I set it.
When trying this on paper by hand, it works perfectly fine. And while debugging I couldn't figure out what happens.
Thanks for every help!!!
In your last line the return keyword is missing.
First, your code was not formatted right, cause python is a indentation sensitive language.
Second, The last line of the error log indicates that the error is the addition of NoneType and int. You didn't return anything in the final else block, so that will return NoneType. Just add return at the beginning of the last sentence.
Third, you can delete every elif after return and just use if.

Creating a function with a condition in Python

I need to create a function named 'Bernoulli' that should take 2 input variables 'rr' and 'p' and should return a value of 1 if rr is less than or equal to p and a value of 0 if rr is greater than p.
The code I have produced so far is this:
rr=float(input())
p=float(input())
def bernoulli(rr,p):
if rr<=p:
return 'X=1'
else:
return 'X=0'
I am not sure how correct this is.
Upon running tests I get this feedback:
Your program took too long to execute.
Make sure that it isn't waiting for input and that there is no infinite loop.
rr=float(input())
p=float(input())
def bernoulli(rr,p):
if rr<=p:
return 1
else:
return 0
x = bernoulli(rr,p)
print(x)
However, if you are simply checking if one number is bigger than the other, it might make more sense down the line to use True and False because comparing them will be a shorter line of code later on. if x == False That being in the logical sense that we understand true to be positive and false to be negative. You might forget which way round the 1 and the 0 are ordered :)
Swift answered this in the same way I would approach this. The reason your code is not executing, is because it is never used. You must call a function to use it.
Here is how I did it:
rr=float(input())
p=float(input())
def bernoulli(rr,p):
if rr<=p:
return 'X=1'
else:
return 'X=0'
function_response = bernoulli(rr,p)
print(function_response)

Python fibonacci unexpecred indent

Im new to code and learning python . I got homework to make print Fibonacci
numbers for N = 11 and N = 200 using method called Memoization . I found solution but when im running the code i getting two things : 1 .
Traceback (most recent call last):
**File "python", line 7
if n== 1:
^**
**IndentationError: unexpected indent**
and second i got empty result sometime when im running. what is wrong which the code :
def fibonacci (n) :
# If we have cached the value, then return it
if n in fibonacci_cache:
return fibonacci_cache[n]
# Compute the Nth term
if n== 1:
value = 1
elif n == 2:
value = 1
elif n > 2:
value = fibonacci(n-1) + fibonacci(n-2)
# Cache the value and return it
fibonacci_cache[n] = value
return value
print(n, ":", fibonacchi(11))
See #Alexis Drakopoulos for a direct fix to your code. If you want to simplify implementing memoization you can use a decorator called lru_cache.
from functools import lru_cache
#lru_cache(maxsize=None)
def fibonacci(n):
if n<= 2:
return 1
return fibonacci(n-1)+fibonacci(n-2)
def fibonacci(n):
# If we have cached the value, then return it
if n in fibonacci_cache:
return fibonacci_cache[n]
# Compute the Nth term
if n == 1:
value = 1
elif n == 2:
value = 1
elif n > 2:
value = fibonacci(n-1) + fibonacci(n-2)
# Cache the value and return it
fibonacci_cache[n] = value
return value
print(n, ":", fibonacchi(11))
in Python indentation is everything, I am not sure if this is correct with the last lines with the cache.
I suggest using 4 spaces (using tabs) in order to be consistent.
Python looks at indentations to understand what you are trying to do.
Welcome to programming in Python and to StackOverflow :-)
There are three problems with your code:
1. The indentation: Python needs you to pay attention to the indentation, such that code at a particular level is indented the same amount.
For code that runs after something like an if statement, you need to put the next block of code indented. Then when you have the elif (which is at the same level as the if statement) you need to bring the indenting back out to match the level of the if.
You can indent with spaces or tabs, but you need to be consistent (ie stick to one)
It's possible that the editor you're using has messed up the intenting when you pasted the code in, and it's also possible that some of the indenting got messed up when you put it into StackOverflow too, but you need it to look like that below. In this case, each intent is two spaces (so indenting is first no spaces, then two spaces, then four spaces etc.)
2. Typos: The final statement has a typo (so you're not actually calling the function you define!)
3. Fibbonacci_cache: it isn't defined, so that's been added at the top
Hope that helps - good luck with the rest of your journey into programming... it will need perseverance but you'll get the hang in time I'm sure!
fibonacci_cache = {}
def fibonacci (n) :
# If we have cached the value, then return it
if n in fibonacci_cache:
return fibonacci_cache[n]
# Compute the Nth term
if n== 1:
value = 1
elif n == 2:
value = 1
elif n > 2:
value = fibonacci(n-1) + fibonacci(n-2)
# Cache the value and return it
fibonacci_cache[n] = value
return value
print("n:", fibonacci(11))

Can return only be used once in a block of code?

I'm in the process of learning python, and I can't wrap my head around a piece of code in the book:
def find_value(List, value):
for i in range(len(List)):
if List[i] == value:
return i
return -1
I've tried running the code, and it returns the index if the value is in it, and returns -1 if it isn't, but what I don't understand is since the 'return -1' is outside the for loop, and if statement, should it not be run every time the code is executed?
Or does return only get processed once, the first time it is called?
I just want to make sure I understand this concept before moving on.
Thanks in advance
No, you can have as many return statements in as many places as you like:
def function():
... # do something
return 1
return
return [3, 4, 5]
return next(__import__('os').walk('.'))[-1:-1000000000:-1]
Though the important thing to keep in mind that only the first return that your function encounters will count, and anything else that would've succeeded it is not touched.
In the function above, you'll get 1 as the result and nothing else.
This sort of "flow of control" is why you can even do weird stuff like this -
def foo():
return True
whatIsThisIdontEven__somethingWeird.jpg # would ordinarily throw RuntimeErrors anywhere else
print(foo())
# True
In your case, it entirely depends on your code flow at runtime, but you'll still end up encountering only one return, and consequently returning only once.
Note that one difference is in the case of try-except-finally, where the return in the final clause always wins.
def function():
try:
... # do something
return 1
except SomeException:
... # do something else
finally:
return 2
In the case of normal execution, you'll encounter return 1 in try, but because of the semantics of the finally clause, you'd still end up returning 2. I believe this is the only exception.
Now, yield, on the other hand, is a different matter...
Once the function sees a return statement, the function will end and return the variable in the return statement. So the rest of the function will not be executed once the function comes across a return statement.
The return statement causes your function to exit and hand back a
value to its caller. The point of functions in general is to take in
inputs and return something.
Keep in mind : function return one at a time by memory .
So when you start the loop and then 'if' condition goes true so function return and exit.
if List[i] == value:
return i
and if you have to return many items then don't return the output instead of store the output in a list and return that list at last .
def find_value(List, value):
return_list=[]
for i in range(len(List)):
if List[i] == value:
return_list.append(i)
return return_list
In you code you wanted two return so you can try conditional return like this:
def find_value(List, value):
return_list=[]
for i in range(len(List)):
if List[i] == value:
return_list.append(i)
if return_list:
return return_list
else:
return -1
print(find_value([1,2,3,4,5,6],4))

Return and assignment in recursive function in python: None type given, expected an int value

I am fairly new to python but worked with recursion previously. I came across this problem while working with recursive functions.
archive = {1: 0}
def engine(base, chain=0):
if base in archive:
return archive[base]
else:
if base == 1:
return chain
elif base % 2 == 0:
get = engine(base/2)
meaning = 1 + get
archive[base] = meaning
else:
next = 3 * base + 1
get = engine(next)
meaning = 1 + get
archive[base] = meaning
print archive(13)
I worked with scheme recently. So, I expected it to work.
I want the code to evaluate till the case bool(base==1) becomes true and then work it's way up ward making a new entry to the dictionary on each level of recursion.
How can I achieve that? I am just counting the level of recursion until the fore-mentioned condition becomes True with the variable 'chain'.
[Solved]: I missed the return statement in two clauses of if-else statement. The scheme would pass the function itself and the last return statement would do the work but not with python. I understand it now.
Thanks everyone who responded. It was helpful.
Your last two elif and else clauses have no return statements and Python returns None by default.

Categories