Passing arguments to the function (Python, OOP, functions) - python

So here we are passing 2 arguments to the function: 1) a just created object from the class (counter) and 2) a number (0).
def increment(c, num):
c.count += 1
num += 1
class Counter:
def __init__(self):
self.count = 0
counter = Counter()
number = 0
for i in range(0, 100):
increment(counter, number)
print(
"counter is "
+ str(counter.count)
+ ", number of times is "
+ str(number)
)
The result of the code is the following:
# counter is 100, number of times is 0
Why the 'number' variable does not increase, if the function clearly says:
num += 1
???

Python passes parameters by object reference, which results basically in having references to mutable types and values for immutable types.
Counter is a mutable class that you have created, whereas number is an integer (immutable).
As described in the other answers and comments, the immutable integer is overriden but since it is a local variable you cannot see these changes outside the function except if you return the value of num from increment.
Alternatively, you could make number a class variable of Counter. Hereby, you could track how many times any instance of Counter has ever increased the count:
class Counter:
number_increases = 0
def __init__(self):
self.count = 0
def increase(self):
self.count += 1
Counter.number_increases += 1
c1 = Counter()
c2 = Counter()
for i in range(10):
c1.increase()
print(f"counters are {c1.count} and {c2.count}; " +
f"number of times is {Counter.number_increases}")
for i in range(20):
c2.increase()
print(f"counters are {c1.count} and {c2.count}; " +
f"number of times is {Counter.number_increases}")
Output:
counters are 10 and 0; number of times is 10
counters are 10 and 20; number of times is 30

Every time the function is called the value is assigned to a new variable called num. I will not modify the variable.
So,
You have to return the value of number from the increment function and assign it to the number variable.
def increment(c, num):
c.count += 1
return num+1
class Counter:
def __init__(self):
self.count = 0
counter = Counter()
number = 0
for i in range(0, 100):
number = increment(counter, number)
print(
"counter is "
+ str(counter.count)
+ ", number of times is "
+ str(number)
)
Output
counter is 100, number of times is 100
The best way is to add increment function in the Counter class. But If you want to do this with function this way works fine.

That is because whenever you pass an argument to a function in python, you are using a copy of that argument, so writing n += 1 will have no effect on the actual variable n outside of the function. You can try writing:
def increment(c, num):
c.count += 1
return num+1
and in the for loop you can do like this:
for i in range(100): # range(0, 100) is the same as range(100)
# because 0 is the default value for start
number = increment(counter, number)
That should work.

Related

recursive function affecting variable

I have a recursive function to count the number of way 8 queens can fit on an 8x8 chess board without intersecting each other (for a class). It works well and gives the correct permutations, the interesting thing happens when I have the program try to count the # of answers -it constantly returns my counter to zero. When I manually count the permutations it's 92 (which is correct).
def can_be_extended_to_solution(perm):
i = len(perm) - 1
for j in range(i):
if i - j == abs(perm[i] - perm[j]):
return False
return True
def extend(perm,count, n):
if len(perm)==n:
count=count+1
print "cycle counter= ",count
print(perm)
for k in range(n):
if k not in perm:
perm.append(k)
if can_be_extended_to_solution(perm): # if it works
extend(perm, count, n)
perm.pop()
extend(perm = [], count=0, n = 8)
The issue is that you never allow the recursive call to modify the value of count. You pass the count value in to the function, but then when the count = count + 1 line is called, it only modifies the local value of count for that function call, and does not modify the value in the call that recursively called it.
The following modification works just fine (the return value of extend is 92).
def can_be_extended_to_solution(perm):
i = len(perm) - 1
for j in range(i):
if i - j == abs(perm[i] - perm[j]):
return False
return True
def extend(perm, count, n):
if len(perm) == n:
count = count + 1
print("cycle counter= " + str(count))
print(perm)
for k in range(n):
if k not in perm:
perm.append(k)
if can_be_extended_to_solution(perm): # if it works
count = extend(perm, count, n)
perm.pop()
return count
print(extend(perm=[], count=0, n=8))

Python function unable to return result

Below is a function which is supposed to return longest palindromic substring of a string. Though the function itself looks alright but for some strange reason It is not returning the string. Any Idea what I am missing here?
def largest(string, repeat=None):
if len(string) <= 1 and repeat:
return repeat[max(repeat.keys())]
elif len(string) <= 1:
return string
list_str = list(string)
repeat = repeat or {}
end_index = -1
while len(list_str)+end_index:
construct = list_str[0:len(list_str)+end_index+1]
reversed_construct = construct.copy()
reversed_construct.reverse()
if construct == reversed_construct:
repeat[len(construct)] = ''.join(construct)
end_index -= 1
string = string[1:]
largest(string, repeat=repeat)
In a order to return a value from a recursive function, one must put return recursive_function(x) so that when a value is returned it is placed in a position where the data can be accessed by the function 'above' it, so to speak.
def Factorial(total,counter):
if counter == 0: #tests whether the counter is at 0
return(total) #if it is at 0 return the product of the consectutive numbers between 0 and starting counter
total *= counter #set the total to itself times the current pass counter
return Recursion(total,(counter-1)) #return the value of this function passing the total and the counter -1
You see that in this example for me to hold the value that was passed previously I have to return it so that after all the recursions are completed they will all pass the data back up the chain of function.

For loop should loop 9 times, instead loops once

The following code should be taking two numbers from the user and then state which number is higher, 9 times, thus "counter <10 " except it only takes the two numbers once, and then the loop is finished. I thought I could increment the loop by using "counter=counter +1" in my loop, but it doesnt seem to work. Any help would be appreciated, thanks!
counter = 0
for counter in range(counter < 10):
num1 = float(input("Enter number 1: "))
num2 = float(input("Enter number 2: "))
if num1 > num2:
print(num1)
else:
print(num2)
counter = counter + 1
counter < 10 returns True which is equal to 1:
>>> counter = 0
>>> counter < 10
True
>>> True == 1
True
In turn, range(1) yields 0 (single item):
>>> list(range(counter < 10))
[0]
That's why it loop once.
Instead of range(counter < 10), you should use range(9). You don't need to declare counter = 0 and to increment yourself counter = counter + 1. for statement take care of it:
>>> for i in range(3):
... print(i)
...
0
1
2
counter<10 is equivalent to 1. That is why, the loop runs just once ( range(1) = {0} ).
You can use either :
for counter in range(10):
...
or
counter = 0
while( counter<10 ):
...
counter+=1
for your purpose.
To make it more clear to you, the expression within the brackets are evaluated at first place. If you want to use for, then you need to pass a sequence, over which the for will loop through. The range() is used to generate the sequence . But here you are passing (count < 10) to range(), which is a condition. So while evaluated, it returns True since counter is 0 (initialized in the first line) and is less than 10. And this returned True is equivalent to 1, so the rest goes as described by falsetru
If you want to pass a condition, then you should use while loop, instead of for. In for, you don't even need to initialize the variable counter separately. If you write :-
for counter in range(9):
this will initialize counter variable and it would be incremented in each iteration.
For your question you can use either of the following:-
for counter in range(9):
# No need to initialize counter
do_stuff
or
# Initialize counter
counter = 0
while(counter <10):
do_stuff

How to define a Global variable in python?

I am newbee in Python . JUst wandering if it is possible to define a Global variable in Python.
I have this python code to compute total number of times Fib(2) has been accessed. But count is printing 0 when called.
import sys
def fib(n):
"""Takes input a natural number n > 0.
Returns n! """
global count
count = 0
if n == 1 or n == 0:
return 1
else:
if n == 2:
print 'encountered here::: '
count += 1
return fib(n-1) + fib(n-2)
def main():
x = int(raw_input('Enter a natural number > 0 :'))
print 'Fibonacci(%d) = %d' % (x, fib(x))
print 'Count =', count
if 1:
main()
A variable defined in the module outside of any function is considered a global variable. To modify a global variable inside of a function, you must write global variableName inside of the function.
You did this, however, that variable is only defined in your function, it must also be declared outside of the function to be considered a global variable. If not, it will be local to your function, despite the global in front of it.
TL;DR Also declare the variable outside of your function.
EDIT (I was wrong):
By writing global variableName in a function and executing said function, it does make the variable a global variable; if not you would be getting a NameError when you tried to print it.
The reason that you're getting a 0, however, is because everytime you call your function, you initialize count to 0. Nonetheless, the solution about still holds.
Move count = 0 outside your fib(n) function. You only need to declare it as global count once inside the function, while the initialization should be outside. What you're doing is that you are re-initializing it with 0 every time the function is called.
import sys
count = 0
def fib(n):
"""Takes input a natural number n > 0.
Returns n! """
global count
if n == 1 or n == 0:
return 1
else:
if n == 2:
print 'encountered here::: '
count += 1
return fib(n-1) + fib(n-2)
def main():
x = int(raw_input('Enter a natural number > 0 :'))
print 'Fibonacci(%d) = %d' % (x, fib(x))
print 'Count =', count
if 1:
main()
Although, you should avoid global variables.
global foo
foo = [1,2,3]
Now foo can be used anywhere in the program
Put the count = 0 outside the function.

Return outside function error in Python

This is the problem:
Given the following program in Python, suppose that the user enters the number 4 from the keyboard. What will be the value returned?
N = int(input("enter a positive integer:"))
counter = 1
while (N > 0):
counter = counter * N
N = N - 1
return counter
Yet I keep getting a outside function error when I run the system
what am I doing wrong?
Thanks!
You can only return from inside a function and not from a loop.
It seems like your return should be outside the while loop, and your complete code should be inside a function.
def func():
N = int(input("enter a positive integer:"))
counter = 1
while (N > 0):
counter = counter * N
N -= 1
return counter # de-indent this 4 spaces to the left.
print func()
And if those codes are not inside a function, then you don't need a return at all. Just print the value of counter outside the while loop.
You have a return statement that isn't in a function. Functions are started by the def keyword:
def function(argument):
return "something"
print function("foo") #prints "something"
return has no meaning outside of a function, and so python raises an error.
You are not writing your code inside any function, you can return from functions only. Remove return statement and just print the value you want.
As already explained by the other contributers, you could print out the counter and then replace the return with a break statement.
N = int(input("enter a positive integer:"))
counter = 1
while (N > 0):
counter = counter * N
N = N - 1
print(counter)
break
It basically occours when you return from a loop you can only return from function

Categories

Resources