I have a recursive function like this:
b=4
def someFunction(x,y,z):
global b
b += x
if...#something
else:
someFunction(x,y,z)
...
Theres a lot to it, but thats the general idea. My issue is that when running my program on cmd, I cant keep calling 'someFunction' with different parameters as there is no reset for b, however if I reset b within the function It won't work as I intend it to. So I could write this in two functions with the recursion in a sub function, but is there some other way to have b reset when I call the function without this being a problem when it starts recursion?
What I usually do is use an optional keyword argument, like this.
def someFunction(x,y,z, b=None):
if b is None:
b = 4
b += x
if...#something
else:
someFunction(x,y,z,b=b)
This way you can initialize the b on the first call to any value (and avoid usage of global variables).
This also has the positive that now someFunction is a pure function (no side effects and same input always gives same output) and much easier to work with. (Testing, refactoring, ..)
You can add an optional parameter of the function with the reset value:
def someFunction(x,y,z, reset = None):
if reset is not None:
b=reset
...
b += x
if...#something
else:
someFunction(x,y,z)
then the first time just call f(x,y,z, reset=4)
Related
I have to execute the following code wherein I will be calling the function main again and again.
so here as I need to use i = i+1, I need to declare and initialize i in the first place right, but when i call the main function it again defines i=0 and the whole purpose of i = i+1 is lost.
How can I solve this error?
I have given the condition just as an example.
Basically what I want is i should be initialized only once, inspite of how many number of times main is called.
def main():
i = 0
if 0<1:
i = i+1
y = i
There are a couple ways to do this that don't involve globals. One is capture the value of i in a closure and return a new function that increments this. You will need to call the initial function once to get the returned function:
def main():
i = 0
def inner():
nonlocal i
i += 1
return i
return inner
f = main()
f()
# 1
f()
# 2
You can also create a generator which is a more pythonic way to do this. The generator can be iterated over (although use caution since it iterates forever) or you can get a single value by passing it to next():
def main():
i = 1
while True:
yield i
i += 1
f = main()
next(f)
# 1
next(f)
# 2
You can also use itertools.count
So you haven't declared i as a global variable
Do something like this
global i
i = 0
def main():
if 0<1:
global i
i = i+1
y = i
The reason behind this is because inside a function all the variables are local meaning they only exist inside the function while the function is called, so if you want a function to be able to change a variable for the whole code, you'll need to announce it as a global so python knows to change the value of it for the entire code
I'm not sure exactly what you are trying to do, but I believe there is an easier way to do whatever it is you are doing
It looks like you want to maintain state in a function call which is a good reason to convert it to a class.
class MyClass:
def __init__(self):
self.i = 0
def main(self):
self.i += 1
y = self.i
myclass = MyClass()
myclass.main()
myclass.main()
print(myclass.i)
I have tried to write a Merge Sort function as you can see below. But when I try to test it I receive an error:
the name mergesort is not defined
Can anyone point out the cause for this error?
def merge(self,a,b):
sorted_list=[]
while len(a)!=0 and len(b)!=0:
if a[0].get_type()<b[0].get_type():
sorted_list.append(a[0])
a.remove(a[0])
else:
sorted_list.append(b[0])
b.remove(b[0])
if len(a)==0:
sorted_list+=b
else:
sorted_list+=a
return sorted_list
def mergesort(self,lis):
if len(lis) == 0 or len(lis) == 1:
return lis
else:
middle = len(lis)// 2
a = mergesort(lis[middle:]) #in pycharm the next 3 lines are with red underlined
b = mergesort(lis[middle:])
return merge(a,b)
The fact that self is one of the parameters to these methods means that they're most likely part of a class (one you've omitted from your post).
If that's correct, you need to invoke using self.mergesort(l), where l is a list.
As a pre-emptive measure against the next error you'll discover, you need to replace return merge(a, b) with return self.merge(a, b) for similar reasons.
Finally, I have to ask why you're defining all of these functions as methods of a class. They don't seem to rely on any shared data. Are you confident that they wouldn't be more appropriately declared at the module scope?
I am implementing a recursive function in which I need to remember a global value. I will decrement this value in every recursive call and want it to reflect in other recursive calls also.
Here's a way I've done it.
First way:
global a
a = 3
def foo():
global a
if a == 1:
print 1
return None
print a
a -= 1 # This new 'a' should be available in the next call to foo()
foo()
The output:
3
2
1
But I want to use another way because my professor says global variables are dangerous and one should avoid using them.
Also I am not simply passing the variable 'a' as argument because 'a' in my actual code is just to keep track of some numbers, that is to track the numbering of nodes I am visiting first to last. So, I don't want to make my program complex by introducing 'a' as argument in every call.
Please suggest me whatever is the best programming practice to solve the above problem.
Don't use a global; just make a a parameter to the function:
def foo(a):
print a
if a == 1:
return None
foo(a-1)
foo(3)
Try this :
Use a parameter instead of a global variable.
Example code
a = 3
def foo(param):
if param == 1:
print 1
return None
print param
foo(param - 1)
foo(a)
I'm new to programming.
def start():
x = 4
def addition():
n = 3
def exponential():
z = 2
def multiplication():
l = 2
print(x + n ** z * l)
return multiplication
equals = start()
equals()
why am I getting a "Nonetype" object is not callable error?
You're confusing a bunch of programming concepts:
Don't declare a function whenever you only need a statement
You're confusing function declaration with function call (invocation), and also the nesting is pointless. Declaring nested fn2 inside of fn1 doesn't magically also call fn2 and also transmit its return-value back to fn1. You still have to use an explicit return-statement from each fn.(If you forget that, you're implicitly returning None, which is almost surely not what you want)
For now, just don't ever nest functions at all.
Functions with no arguments are essentially useless, they can't take inputs and compute a result. Figure out what their arguments should be.
Specifically for the code you posted, addition(), multiplication() don't have any return value at all, i.e. None. exponential() returns multiplication, i.e. a function which only returns None. But then, both addition() and start() ignore that anyway, since they don't have a return-statement either, hence they implicitly return None.
Calling start() just gives you None, so you're just assigning equals = None. Not the result of some mathematical expression like you intended.
So:
reduce every unnecessary function to just a statement
declare each of your functions separately (non-nested)
each fn must have args (in this case at least two args, to make any sense)
each fn must have a return statement returning some value
only declaring a function and never calling it means it never gets run.
put an empty line in between function declarations (Then it's obvious if you forgot the return-statement)
Credits goes to #BrenBarn for being first to answer this. But I wanna post the code to make it more clear, and point out to some ways to make it better.
def start():
x = 4
def addition():
n = 3
def exponential():
z = 2
def multiplication():
l = 2
print (x + n ** z * l)
return multiplication()
return exponential()
return addition()
equals = start()
print equals #Output: 22
However, this is not the best way to list different methods. You should learn how to use a class in your python code.
I am going to define a class called "mathOperations". I will define three methods (functions): addition,exponential, multiplication. These functions are reusable.
class mathOperations():
def addition(self,x,y):
return x+y
def exponential(self,x,y):
return x**y
def multiplication(self,x,y):
return x*y
m= mathOperations()
z=2
l=2
x=4
n=3
result= m.addition(x,m.multiplication(m.exponential(n,z),l))
print result #Output:22
You should learn how to make your code reusable, try to google "procedural programming"; "Oriented Object Programming", or check "Learn Python the hard way" book. These are first and most used approach to make your code reusable. Think of it like a generic mathematical function to solve problems.
#!/usr/bin/python3
class BubbleSort:
def __init__(self):
self.x=[]
self.limit=0
def getElements(self):
self.limit=int(input("Enter the limit:"))
print("Enter {} number".format(self.limit))
for i in range(1,self.limit+1):
self.x.append(int(input()))
def sort(self):
for i in range(0,self.limit):
for j in range(0,(self.limit-1)-i):
if self.x[j+1] < self.x[j]:
temp1=self.x[j+1]
temp2=self.x[j]
del self.x[j]
del self.x[j+1]
self.x.insert(j+1,temp2)
self.x.insert(j,temp1)
print(self.x)
print("Sorted list is")
for i in self.x:
print(i)
def main():
b=BubbleSort()
b.getElements()
b.sort()
if __name__=="__main__":main()
This is a simple bubble sort program.
Problem 1: If I run the program, two same numbers come , for example, when i enter say -> 3 6 5 1 2
output -> 1 2 2 5 6
The 3 gets replaced by 2.
2: why do I see a lot of 'self' as parameter to a function in python? then what does self.x=[] and self.limit=0 do?
I am super new to methods as a concept and I tried reading, they do not help.
3.In the function getElements, what is self.limit ? why is it even required? we can just use a normal variable like 'x'
Ex: x= int(input("enter the limit:"))
print("enter {} number".format(x))
3.Explain the self.x.append(int(input())))
Doesnt append(int(something)) will add the value of something in the end of a list?
Check the for loop, say the self.limit is 5(entered value). then the loop requires 6 numbers right? equivalence in c++
for(i=1;i<=6;i++)
Assuming the left most number is not considered in python in the range function. right?
Mainly explain 'self' parameter in every function.
When you delete x[j], x[j+1] becomes x[j]. Replace:
del self.x[j]
del self.x[j+1]
with:
del self.x[j+1]
del self.x[j]
However, like #IanAuld said, deleting elements of an array while iterating over it is poor programming practice. Instead, try making a new array and copying the elements to the new array, leaving the original array unchanged in the process. Afterward, if you want, you can replace the old array with the new array.
And to answer your second question, self refers to the class so you can access other variables from the same class your function is in. For example, if you have:
#!/usr/bin/python3
class Foo:
bar = 3
def getValueOfBar(self):
return self.bar
x = Foo()
print( x.getValueOfBar() )
self refers to the parent class, so you can retrieve variables from the class that aren't in the scope of the function.