Count number of function calls for distinct input argument values - python

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

Related

Function does not modify variable in python

I create two lists, a, b with 10 random numbers from 0 to 61 and then I compare the lists if they have common numbers or not.
I store the common numbers in a separate list.
If the list does have numbers in it the commonCount is going up and if the list is empty the noCommonCount is going up.
But when I want to print the counts after I rand the function 10 times it prints out 0.
I don't know why because I declared the variables commonCount and noCommonCount outside the function.
import random
noCommonCount = 0
commonCount = 0
def list_overlap():
a = []
b = []
count = 0
while count < 10:
count = count + 1
a.append(random.randint(0, 61))
b.append(random.randint(0, 61))
commonNumbers = []
for i in a:
if i in b:
if i not in commonNumbers:
commonNumbers.append(i)
if not commonNumbers:
noCommonCount + 1
else:
commonCount + 1
functionCount = 0
while functionCount < 10:
functionCount = functionCount + 1
list_overlap()
print(noCommonCount)
print(commonCount)
For a function modifying a variable declared on outer scope additionally a declaration of the form
global variable_name
is required in the function (typically directly after function declaration.

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.

randomly choosing a function from a list then apply conditions to the result

In the code below, a, b, and c are pre-defined functions that are a part of much bigger code. The code is always returning the elif part even if the choice is enemy_def. I have tried printing each one but nothing happens.
a = enemy_hit
b = enemy_def
c = enemy_sphit
d = [a,b,c]
enemyresponse = random.choice(d)()
#print(enemyresponse)
if enemyresponse == b :
thing.health = thing.health - 0.25
#print(enemyresponse)
elif enemyresponse != b :
#print(enemyresponse)
thing.health = thing.health - 1
enemy_reponse will never be equal to b*, because enemy_reponse is the return value of the function, not the function itself. Note how you call the function immediately after randomly choosing it:
random.choice(d)()
# ^Called it
Save the function that was chosen in a variable called chosen_function (or something similar), then check against that.
You probably meant something like this (untested):
a = enemy_hit
b = enemy_def
c = enemy_sphit
d = [a,b,c]
# Randomly get function from list
chosen_function = random.choice(d)
# Call it to get the return value
func_return = chosen_function()
print(func_return)
if chosen_function == b:
thing.health = thing.health - 0.25
else:
thing.health = thing.health - 1
*Unless b returns itself, which seems unlikely.

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

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