Function does not modify variable in python - 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.

Related

Generating random numbers using LCG method

I'm trying to generate random numbers between 0 and 1 using the LCG method but it keeps giving me the error "local variable 's' referenced before assignment" How do I fix it without using a global variable?
def set_seed(S):
return S
def pseudo():
S = (S*a + c) % m/m
return S
m = 233280 # modulus
a = 9301 # multiplier
c = 49297 # increment
set_seed(1234)
VALUE_1 = pseudo()
set_seed(4321)
VALUE_2 = pseudo()
print(VALUE_1)
print(VALUE_2)

How do you use an incremented variable outside of function in python?

This could be a foolish question; maybe my though process is totally wrong (if so, please point it out), but how do you extract the three incremented variables (c_char, c_word, c_sentence) inside a custom function and use it for other uses?
def length_finder(x):
#variables counting character,word,sentnece
c_char = 0
c_word = 1
c_sentence = 0
for i in x:
if (i >= 'a' and i <= 'z') or (i >= 'A' and i <= 'Z'):
c_char += 1
if i == " ":
c_word += 1
if i == '.' or i == '!' or i == '?' :
c_sentence += 1
length_finder(input("Enter the text you wish to analyze: "))
L = 100/c_word*c_char
S = 100/c_word*c_sentence
#formula to get readability
index = 0.0588 * L - 0.296 * S - 15.8
print("This text is suitable for grade " + str(index))
You can return multiple variables from within the function:
def length_finder(x):
...
return (c_char, c_word, c_sentence)
(c_char, c_word, c_sentence) = length_finder('input string')
You have two options.
Make those three variables global, and reference them in the function. You can make them global, then reference them as global within the function.
Return them from the function. You can return all 3 values as a dictionary or list.

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

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.

How to toggle between two values?

I want to toggle between two values in Python, that is, between 0 and 1.
For example, when I run a function the first time, it yields the number 0. Next time, it yields 1. Third time it's back to zero, and so on.
Sorry if this doesn't make sense, but does anyone know a way to do this?
Use itertools.cycle():
from itertools import cycle
myIterator = cycle(range(2))
myIterator.next() # or next(myIterator) which works in Python 3.x. Yields 0
myIterator.next() # or next(myIterator) which works in Python 3.x. Yields 1
# etc.
Note that if you need a more complicated cycle than [0, 1], this solution becomes much more attractive than the other ones posted here...
from itertools import cycle
mySmallSquareIterator = cycle(i*i for i in range(10))
# Will yield 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 0, 1, 4, ...
You can accomplish that with a generator like this:
>>> def alternate():
... while True:
... yield 0
... yield 1
...
>>>
>>> alternator = alternate()
>>>
>>> alternator.next()
0
>>> alternator.next()
1
>>> alternator.next()
0
You can use the mod (%) operator.
count = 0 # initialize count once
then
count = (count + 1) % 2
will toggle the value of count between 0 and 1 each time this statement is executed. The advantage of this approach is that you can cycle through a sequence of values (if needed) from 0 - (n-1) where n is the value you use with your % operator. And this technique does not depend on any Python specific features/libraries.
e.g.
count = 0
for i in range(5):
count = (count + 1) % 2
print(count)
gives:
1
0
1
0
1
You may find it useful to create a function alias like so:
import itertools
myfunc = itertools.cycle([0,1]).next
then
myfunc() # -> returns 0
myfunc() # -> returns 1
myfunc() # -> returns 0
myfunc() # -> returns 1
In python, True and False are integers (1 and 0 respectively). You could use a boolean (True or False) and the not operator:
var = not var
Of course, if you want to iterate between other numbers than 0 and 1, this trick becomes a little more difficult.
To pack this into an admittedly ugly function:
def alternate():
alternate.x=not alternate.x
return alternate.x
alternate.x=True #The first call to alternate will return False (0)
mylist=[5,3]
print(mylist[alternate()]) #5
print(mylist[alternate()]) #3
print(mylist[alternate()]) #5
from itertools import cycle
alternator = cycle((0,1))
next(alternator) # yields 0
next(alternator) # yields 1
next(alternator) # yields 0
next(alternator) # yields 1
#... forever
var = 1
var = 1 - var
That's the official tricky way of doing it ;)
Using xor works, and is a good visual way to toggle between two values.
count = 1
count = count ^ 1 # count is now 0
count = count ^ 1 # count is now 1
To toggle variable x between two arbitrary (integer) values,
e.g. a and b, use:
# start with either x == a or x == b
x = (a + b) - x
# case x == a:
# x = (a + b) - a ==> x becomes b
# case x == b:
# x = (a + b) - b ==> x becomes a
Example:
Toggle between 3 and 5
x = 3
x = 8 - x (now x == 5)
x = 8 - x (now x == 3)
x = 8 - x (now x == 5)
This works even with strings (sort of).
YesNo = 'YesNo'
answer = 'Yes'
answer = YesNo.replace(answer,'') (now answer == 'No')
answer = YesNo.replace(answer,'') (now answer == 'Yes')
answer = YesNo.replace(answer,'') (now answer == 'No')
Using the tuple subscript trick:
value = (1, 0)[value]
Using tuple subscripts is one good way to toggle between two values:
toggle_val = 1
toggle_val = (1,0)[toggle_val]
If you wrapped a function around this, you would have a nice alternating switch.
If a variable is previously defined and you want it to toggle between two values, you may use the
a if b else c form:
variable = 'value1'
variable = 'value2' if variable=='value1' else 'value1'
In addition, it works on Python 2.5+ and 3.x
See Expressions in the Python 3 documentation.
Simple and general solution without using any built-in. Just keep the track of current element and print/return the other one then change the current element status.
a, b = map(int, raw_input("Enter both number: ").split())
flag = input("Enter the first value: ")
length = input("Enter Number of iterations: ")
for i in range(length):
print flag
if flag == a:
flag = b;
else:
flag = a
Input:
3 835Output:38383
Means numbers to be toggled are 3 and 8
Second input, is the first value by which you want to start the sequence
And last input indicates the number of times you want to generate
One cool way you can do in any language:
variable = 0
variable = abs(variable - 1) // 1
variable = abs(variable - 1) // 0

Categories