Why doesn't this recursive GCD function work? [duplicate] - python

This question already has answers here:
Why does my recursive function return None?
(4 answers)
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 5 months ago.
I'm currently playing with recursive functions and I have a question.
I don't understand why this one work
a, b = map(int, input().split())
def gcd(a,b):
if a%b == 0:
return b
else:
return gcd(b,a%b)
print(gcd(a,b))
but this one doesn't
a, b = map(int, input().split())
def gcd(a,b):
if a%b == 0:
return b
gcd(b,a%b)
print(gcd(a,b))

Though the answer appears in the comments, I thought this is an opportunity to demonstrate how python tools can help you find similar errors like this in the future.
$ pylint --disable=invalid-name,redefined-outer-name,missing-function-docstring,missing-module-docstring main.py
************* Module Downloads.main
main.py:2:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
-------------------------------------------------------------------
Your code has been rated at 8.33/10 (previous run: 10.00/10, -1.67)
So here you see pylint points your attention to implicit return values from some path(s) in your function. Note that some of pylint's reports (the ones I disabled for instance) may generate "noise" rather than be helpful). Still, using this tool (and mypy and others) may sure help you

Related

After recursion list not emptying [duplicate]

This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 2 years ago.
I'm doing some discrete mathematics stuff for a teacher, he asked me to try and do everything recursively. For some strange reason the list i'm using for a function is the same as it was the last time I called the function.
Here's my code:
def extended_euclidean_algorithm(a:int, b:int, equations=list()):
#This line is just for debugging and checking that my hipothesis was correct
print (len(equations))
if b==0:
return
if a<b:
b,a=a,b
quotient=a//b
remainder=a%b
equations.append(f"{a}={quotient}*{b}+{remainder}")
if extended_euclidean_algorithm(b, remainder, equations):
return equations
for i, equation in enumerate(equations):
equations[i]=equation.split('+')
equations[i][0]=equations[i][0].split('=')
equations[i][0]="-".join(equations[i][0])
equations[i]='='.join(equations[i])
return True
First time I call it, it's Ok. But second time I call it includes the numbers from the last time I called it.
Since you set the list in the arguments, by default the list exists and can be appended to.
You better use:
def extended_euclidean_algorithm(a:int, b:int, equations=None):
equations = equations if equations else []
In this way, equations - if not set - is None rather than an empty list.
Check out the pythontutor visualization here:

is Python return always necessary [duplicate]

This question already has answers here:
return, return None, and no return at all?
(5 answers)
Closed 7 years ago.
I just stumbled across several python programs written by different people and I noticed that every function had a return at the end of it
def function01():
# function
# events
# here
return
I was wondering if it's good python programming practice to include return at the end of functions even if it is not returning anything (purely as a way of ending the function)
Or is it not needed and nothing different will happen in the background?
No, it is not necessary. The function returns after the last line. There is no difference between a simple return and no return.
def foo():
pass
def bar():
pass
return
f = foo()
print(f)
b = bar()
print(b)
Output:
None
None

Understanding Function Closures [duplicate]

This question already has answers here:
Why aren't python nested functions called closures?
(10 answers)
Closed 8 years ago.
I'm struggling to understand Function closures properly. For example in the code below I am unclear as to how the function knows that in the statement times3(2) that x=2? Also, after reading documentations I still can't fully understand the purpose of closures.
def make_multiplier_of(n):
def multiplier(x):
return x * n
return multiplier
times3 = make_multiplier_of(3)
times3(2) #How does the function know that x=2 here?
Thanks a lot
When you are calling make_multiplier_of(3), the function is returning multiplier such that
def multiplier(x):
return x*3
So times3 = make_multipiler(3) is assigning this particular multiplier function to times3. The same way that when you are doing myLength=len, myLength is the len function and you can call myLength("foo")
times3 is thus this multiplier function. So when you times3(2), you are doing (this particular) multiplier(2)

How do return values work? [duplicate]

This question already has answers here:
I need help wrapping my head around the return statement with Python and its role in this recursive statement
(2 answers)
Closed 8 years ago.
def fudz(n):
if n <= 2:
return 1
print("nom" * n)
return fudz(n-1) + fudz(n//2)
result = fudz(4)
Can someone give me a step by step of this function?
This is a recursive function, which means it calls an instance of itself on a simplified instance of the problem until it gets to a base case for which it already knows the answer. Remember that any call to a function occurs in its own stack frame, so it's going to have its own value for n.
You can walk through it yourself. First, think about what happens when n==2. Then think about n==3, and increase n until it makes sense to you.

Single Statement Exception Checking [duplicate]

This question already has answers here:
How to handle exceptions in a list comprehensions?
(7 answers)
Closed 9 years ago.
I'm just curious if this exists. After programming python for the better part of a year I've never come across it.
Is there a python function that is c-compiled (for faster access in comprehensions) that checks an exception:
A function like the following:
def no_exception(function, *args, **kwargs):
try:
function(*args, **kwargs)
except Exception:
return False
return True
You could use it in this case
# values is full of data
new_values = [float(n) if no_exception(float, n) else n for n in values]
No
at least not in the standard library. Otherwise the assertRaises method in the Python unittest module would use it. See: http://pythonhosted.org/gchecky/unittest-pysrc.html#TestCase.failUnlessRaises
You can of course write your own c implementation easily.

Categories