Question on multiplication in function in python - 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().

Related

Long multiplication of two numbers given as strings

I am trying to solve a problem of multiplication. I know that Python supports very large numbers and it can be done but what I want to do is
Enter 2 numbers as strings.
Multiply those two numbers in the same manner as we used to do in school.
Basic idea is to convert the code given in the link below to Python code but I am not very good at C++/Java. What I want to do is to understand the code given in the link below and apply it for Python.
https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings/
I am stuck at the addition point.
I want to do it it like in the image given below
So I have made a list which stores the values of ith digit of first number to jth digit of second. Please help me to solve the addition part.
def mul(upper_no,lower_no):
upper_len=len(upper_no)
lower_len=len(lower_no)
list_to_add=[] #saves numbers in queue to add in the end
for lower_digit in range(lower_len-1,-1,-1):
q='' #A queue to store step by step multiplication of numbers
carry=0
for upper_digit in range(upper_len-1,-1,-1):
num2=int(lower_no[lower_digit])
num1=int(upper_no[upper_digit])
print(num2,num1)
x=(num2*num1)+carry
if upper_digit==0:
q=str(x)+q
else:
if x>9:
q=str(x%10)+q
carry=x//10
else:
q=str(x%10)+q
carry=0
num=x%10
print(q)
list_to_add.append(int(''.join(q)))
print(list_to_add)
mul('234','567')
I have [1638,1404,1170] as a result for the function call mul('234','567') I am supposed to add these numbers but stuck because these numbers have to be shifted for each list. for example 1638 is supposed to be added as 16380 + 1404 with 6 aligning with 4, 3 with 0 and 8 with 4 and so on. Like:
1638
1404x
1170xx
--------
132678
--------
I think this might help. I've added a place variable to keep track of what power of 10 each intermediate value should be multiplied by, and used the itertools.accumulate function to produce the intermediate accumulated sums that doing so produces (and you want to show).
Note I have also reformatted your code so it closely follows PEP 8 - Style Guide for Python Code in an effort to make it more readable.
from itertools import accumulate
import operator
def mul(upper_no, lower_no):
upper_len = len(upper_no)
lower_len = len(lower_no)
list_to_add = [] # Saves numbers in queue to add in the end
place = 0
for lower_digit in range(lower_len-1, -1, -1):
q = '' # A queue to store step by step multiplication of numbers
carry = 0
for upper_digit in range(upper_len-1, -1, -1):
num2 = int(lower_no[lower_digit])
num1 = int(upper_no[upper_digit])
print(num2, num1)
x = (num2*num1) + carry
if upper_digit == 0:
q = str(x) + q
else:
if x>9:
q = str(x%10) + q
carry = x//10
else:
q = str(x%10) + q
carry = 0
num = x%10
print(q)
list_to_add.append(int(''.join(q)) * (10**place))
place += 1
print(list_to_add)
print(list(accumulate(list_to_add, operator.add)))
mul('234', '567')
Output:
7 4
7 3
7 2
1638
6 4
6 3
6 2
1404
5 4
5 3
5 2
1170
[1638, 14040, 117000]
[1638, 15678, 132678]

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])

Function calling function in 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.

Running a loop to return a value that is greater than 15

I need to run a loop that will double the initial value until it is greater than 15. I can't figure out how to get it to stop at the value I want. This is the code I have so far.
def while1(initial):
total = 1
while initial < 15:
total = initial * 2
return total
print while1(3) # -> 24
print while1(2) # -> 16
print while1(15) # -> 15
It isn't returning the values I want.
initial never change, so your while loop never quits, use total as condition variable:
def while1(initial):
total = initial
while total < 15:
total = total * 2
return total
The code you have there is constantly checking whether or not initial is less than 15, but then changing total, and not initial. Python has a nice 'command' *=, which can be used to multiply a variable by some number, and then save the answer back in the variable. You can use this as follows:
def while1(initial):
while initial < 16: #Are we done yet? (Remember to run when initial is equal to 15)
initial *= 2 #Double initial
return initial #This will only run when initial is greater than 15
Hope this helps!
Just for fun, you can calculate the result directly, without any loop:
import math
def double_until_greater_than_15(x):
return x * 2**math.ceil(max(math.log2(16 / x), 0))
print(double_until_greater_than_15(3)) # 24
print(double_until_greater_than_15(2)) # 16
print(double_until_greater_than_15(15)) # 30

Returning multiple integers as separate variables

I am trying to make a program that grabs 5 integers from the user, and then finds the average of them. I have it set up to take in the 5 numbers, but how do I return them all as separate variables so I can use them later on? Thanks!
def main():
x = 0
testScoreNumber = 1
while x < 5:
getNumber_0_100(testScoreNumber)
x += 1
testScoreNumber += 1
calcAverage(score1, score2, score3, score4, score5)
print(calculatedAverage)
def getNumber_0_100(testnumber):
test = int(input("Enter test score " + str(testnumber) + ":"))
testcount = 0
while testcount < 1:
test = int(input("Enter test score " + str(testnumber) + ":"))
if test > 0 or test < 100:
testcount += 1
return test
^Here is the problem, the everytime this function runs, I want it to return a different value to a different variable. Ex. test1, test2, test3.
def calcAverage(_score1,_score2,_score3,_score4,_score5):
total = _score1 + _score2 + _score3 + _score4 + _score5
calculatedAverage = total/5
return calculatedAverage
You need to store the result somewhere. It is usually (always?) a bad idea to dynamically create variable names (although it is possible using globals). The typical place to store the results is in a list or a dictionary -- in this case, I'd use a list.
change this portion of the code:
x = 0
testScoreNumber = 1
while x < 5:
getNumber_0_100(testScoreNumber)
x += 1
testScoreNumber += 1
to:
results = []
for x in range(5):
results.append( getNumber_0_100(x+1) )
which can be condensed even further:
results = [ getNumber_0_100(x+1) for x in range(5) ]
You can then pass that results list to your next function:
avg = get_ave(results[0],results[1],...)
print(avg)
Or, you can use the unpacking operator for shorthand:
avg = get_ave(*results)
print(avg)
It isn't the responsibility of the returning function to say what the caller does with its return value. In your case, it would be simple to let main have a list where it adds the return values. You could do this:
scores = []
for i in range(5):
scores.append(getNumber_0_100(i))
calcAverage(*scores)
Note that *scores is to pass a list as arguments to your calcAverage function. It's probably better to have calculateAverage be a general function which takes a list of values and calculates their average (i.e. doesn't just work on five numbers):
def calcAverage(numbers):
return sum(numbers) / len(numbers)
Then you'd call it with just calcAverage(scores)
A more Pythonic way to write the first part might be scores = [getNumber_0_100(i) for i in range(5)]
Python allows you to return a tuple, and you can unroll this tuple when you receive the return values. For example:
def return_multiple():
# do something to calculate test1, test2, and test3
return (test1, test2, test3)
val1, val2, val3 = return_multiple()
The limitation here though is that you need to know how many variables you're returning. If the number of inputs is variable, you're better off using lists.

Categories