Function calling function in python - python

def one_good_turn(n):
return n + 1
def deserves_another(n):
return one_good_turn(n) + 2
print(one_good_turn(1))
print(deserves_another(2))
Since I have two function one_good_turn(n) and deserves_another(n) while calling function I had passed parameter 1 and 2:
I expected the output to be:
2
4
but its shows:
2
5
Why is the output not what I had expected?

I believe you assume that one_good_turn(n) in deserves_another(n) will return the value that is previously computed. No. It gets the current input n which is 2, call the function again, do 2+1 which is 3. Then you add 3 + 2 = 5.
Maybe to get your desired output, you should pass 1 to deserves_another:
def one_good_turn(n):
return n + 1
def deserves_another(n):
return one_good_turn(n) + 2
print(one_good_turn(1)) # 2
print(deserves_another(1)) # 4
A better way is to return the value from one_good_turn and pass it to deserves_another. So you don't need to call one_good_turn again inside deserves_another:
def one_good_turn(n):
n = n + 1
print(n) # 2
return n
def deserves_another(n):
return n + 2
n = one_good_turn(1)
print(deserves_another(n)) # 4

one_good_turn(2) returns 2+1=3.
Then the result is passed to deserves_another, which returns 3+2=5.

Related

How does this function for Hamming numbers work?

I was trying to write a function to generate Hamming numbers and encountered this code on www.w3resource.com.
The code is very easy but I can't seem to understand the order of output values.
def is_hamming_numbers(x):
if x==1:
return True
if x%2==0:
return is_hamming_numbers(x/2)
if x%3==0:
return is_hamming_numbers(x/3)
if x%5==0:
return is_hamming_numbers(x/5)
return False
def hamming_numbers_sequence(x):
if x==1:
return 1
hamming_numbers_sequence(x - 1)
if is_hamming_numbers(x)==True:
print('%s'%x,end=' ')
hamming_numbers_sequence(10)
I expected the output to be:
10 9 8 8 5 4 3 2
The output would be:
2 3 4 5 6 8 9 10
Could anyone please explain why is the order of numbers reversed? I tried to change the order in the code like this:
if is_hamming_numbers(x)==True:
print('%s'%x,end=' ') #this first
hamming_numbers_sequence(x - 1) #then this line
And it would give the output in the order I expected.
def hamming_numbers_sequence(x):
if x==1:
return 1
hamming_numbers_sequence(x - 1) // repeated here
if is_hamming_numbers(x)==True: // means x=2
print('%s'%x,end=' ')
this function hamming_numbers_sequence(x - 1) will repeat it self until reaching x=1 the blocking instruction if x==1: so the second function will enter with the value of x=2 is_hamming_numbers(2)==True:
so you have the out put you're having if you want to change it try it this way
def hamming_numbers_sequence(x):
print('%s'%x,end=' ')
if x==1:
return 1
hamming_numbers_sequence(x - 1)
if is_hamming_numbers(x)==True:
// do what ever you want here

Question on multiplication in function in python

I am trying to create a simple function that returns multiplier output as shown below.
The question i want to ask is when print(times3), it does not gives a value but instead it shows
".multiplier at 0x00000236884B3558>" which I am unsure why. Is there a way to print the number instead?
Another question is since def multiplier(n) returns n*n, shouldn't it gives 5*5=25? Therefore if I were to print(times5(times3(2))), it should give me 25*81?
def make_multiplier_of(n):
def multiplier(n):
return n*n
return multiplier
# Multiplier of 3
times3 = make_multiplier_of(3)
print(times3)
# Multiplier of 5
times5 = make_multiplier_of(5)
# Output: 81
print(times3(9))
# Output: 9
print(times5(3)) #shouldn't it be 25?
# Output: 16 #shouldn't it be 81 x 25?
print(times5(times3(2)))
updated code:
def make_multiplier_of(n):
def multiplier(m):
return m*n
return multiplier
# Multiplier of 3
times3 = make_multiplier_of(3)
#trying to print out times3 value here but it doesnt work
times3.__closure__[0].cell_contents
[cell.cell_contents for cell in times3.__closure__]
# Multiplier of 5
times5 = make_multiplier_of(5)
# Output: 27
print(times3(9))
# Output: 15
print(times5(3)) #shouldn't it be 25?
# Output: 30
print(times5(times3(2)))
You need to use different variables for the parameters of the inner and outer functions.
def make_multiplier_of(m):
def multiplier(n):
return m*n
return multiplier
Your function is ignoring the argument to make_multiplier_of() because n only refers to the argument to multiplier().

Count number of function calls for distinct input argument values

With the code
def myfunction():
myfunction.counter += 1
myfunction.counter = 0
from https://stackoverflow.com/a/21717084/2729627 you can keep track of the number of times the function is called.
But how do I keep track of the number of times a function is called when (one of) its input arguments takes on a certain value?
So for instance
def myfunction(a):
# Do some calculations...
b = a**2
# Increase counter for specific value of 'a'.
myfunction.counter[a] += 1
# Return output argument.
return b
myfunction.counter[5] = 0
myfunction.counter[79648763] = 0
print(myfunction.counter[5])
print(myfunction.counter[79648763])
myfunction(5)
myfunction(79648763)
myfunction(79648763)
print(myfunction.counter[5]) # Should return 1.
print(myfunction.counter[79648763]) # Should return 2.
How should I modify this code to get it to work?
You can use a dictionary to keep this information:
counter_dict={} #new line
def myfunction(a):
b = a**2
if a in counter_dict.keys():
counter_dict[a] = counter_dict[a]+1 #increment the previous value
else:
counter_dict[a] = 1 #if the value is not present then initialize it with 1
return b
myfunction(5)
myfunction(79648763)
myfunction(79648763)
print(counter_dict[5]) # Should return 1.
print(counter_dict[79648763]) # Should return 2.
If you don't want to use global dict then you can write this:
def myfunction(a):
b = a**2
if a in myfunction.my_dict.keys():
myfunction.my_dict[a] = myfunction.my_dict[a]+1
else:
myfunction.my_dict[a] = 1
return b
myfunction.my_dict={}
myfunction(5)
myfunction(79648763)
myfunction(79648763)
print(myfunction.my_dict[5])
print(myfunction.my_dict[79648763])

How to return a value from a function and print it in the while loop in python?

I have the following code:
A = 3
def Calculation():
global A
B = 2 * A
return B
print B
I get the error:
NameError: name 'B' is not defined
How can I fix this error? What is the right code? Thanks in advance!
You example makes no sense.
Either print the return value of the function...
A = 3
def Calculation():
global A
B = 2 * A
return B
print Calculation()
Or don't use a function:
A = 3
B = 2 * A
print B
Or globalize B in your function as well and call the function before printing B:
A = 3
def Calculation():
global A, B
B = 2 * A
Calculation()
print B
You don't need to use the global variable A though, but you should pass it as argument to Calculation instead. Example:
A = 3
def Calculation(a):
B = 2 * A
return B
print Calculation(A)
You should also use "snake-case" names for functions (all lower case, separate words with underscores "_").
How your code example could be written best (in my opinion) is:
a = 3
def calculation(factor):
return = 2 * factor
print calculation(a)
you can simply print your function call like so ::
A = 3
def Calculation(a):
B = 2 * A
return B
print Calculation(A)
The reason you were getting the error that B was not defined is because your variable B is a local variable to the function Calculation. Its scope is only visible within that method.
A = 3
def Calculation():
global A
B = 2 * A
return B
B = Calculation()
print B

While Loop to produce Mathematical Sequences?

I've been asked to do the following:
Using a while loop, you will write a program which will produce the following mathematical sequence:
1 * 9 + 2 = 11(you will compute this number)
12 * 9 + 3 = 111
123 * 9 + 4 = 1111
Then your program should run as far as the results contain only "1"s. You can build your numbers as string, then convert to ints before calculation. Then you can convert the result back to a string to see if it contains all "1"s.
Sample Output:
1 * 9 + 2 = 11
12 * 9 + 3 = 111
123 * 9 + 4 = 1111
1234 * 9 + 5 = 11111
Here is my code:
def main():
Current = 1
Next = 2
Addition = 2
output = funcCalculation(Current, Addition)
while (verifyAllOnes(output) == True):
print(output)
#string concat to get new current number
Current = int(str(Current) + str(Next))
Addition += 1
Next += 1
output = funcCalculation(Current, Next)
def funcCalculation(a,b):
return (a * 9 + b)
def verifyAllOnes(val):
Num_str = str(val)
for ch in Num_str:
if(str(ch)!= "1"):
return False
return True
main()
The bug is that the formula isn't printing next to the series of ones on each line. What am I doing wrong?
Pseudo-code:
a = 1
b = 2
result = a * 9 + b
while string representation of result contains only 1s:
a = concat a with the old value of b, as a number
b = b + 1
result = a * 9 + b
This can be literally converted into Python code.
Testing all ones
Well, for starters, here is one easy way to check that the value is all ones:
def only_ones(n):
n_str = str(n)
return set(n_str) == set(['1'])
You could do something more "mathy", but I'm not sure that it would be any faster. It would much more easily
generalize to other bases (than 10) if that's something you were interested in though
def only_ones(n):
return (n % 10 == 1) and (n == 1 or only_ones2(n / 10))
Uncertainty about how to generate the specific recurrence relation...
As for actually solving the problem though, it's actually not clear what the sequence should be.
What comes next?
123456
1234567
12345678
123456789
?
Is it 1234567890? Or 12345678910? Or 1234567900?
Without answering this, it's not possible to solve the problem in any general way (unless in fact the 111..s
terminate before you get to this issue).
I'm going to go with the most mathematically appealing assumption, which is that the value in question is the
sum of all the 11111... values before it (note that 12 = 11 + 1, 123 = 111 + 11 + 1, 1234 = 1111 + 111 + 11 + 1, etc...).
A solution
In this case, you could do something along these lines:
def sequence_gen():
a = 1
b = 1
i = 2
while only_ones(b):
yield b
b = a*9 + i
a += b
i += 1
Notice that I've put this in a generator in order to make it easier to only grab as many results from this
sequence as you actually want. It's entirely possible that this is an infinite sequence, so actually running
the while code by itself might take a while ;-)
s = sequence_gen()
s.next() #=> 1
s.next() #=> 11
A generator gives you a lot of flexibility for things like this. For instance, you could grab the first 10 values of the sequence using the itertools.islice
function:
import itertools as it
s = sequence_gen()
xs = [x for x in it.islice(s, 10)]
print xs

Categories