I'm trying to fix up a little program, but looks like I'm in a bit over my head. The whole code is too long to copy here, so I'm just gonna paste the problematic part.
def kontroll(self):
count=IntVar()
sisend=sisendivaartus.get()
print(count)
if count==1:
kast.delete(0.0,END)
sisend.delete(0.0,END)
count=0
else:
kast.delete(0.0,END)
if sisend=="õige" or sisend=="ÕIGE" or sisend=="Õige":
if oige==sonake:
if tahendus==" ":
kast.insert(END,"Tubli, õige!"+"\n"+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Tubli, õige!"+"\n"+str(oige)+"\n:"+str(tahendus))
count=1
#skoor+=1
#skoor=skoor+1
else:
if tahendus==" ":
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+":\n"+str(tahendus))
count=1
#vale=vale+1
#skoor=skoor-1
else:
if sisend==oige:
if tahendus==" ":
kast.insert(END,"Tubli, õige!\n"+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Tubli, õige!\n"+str(oige)+":\n"+str(tahendus))
count=1
#skoor=skoor+1
else:
if tahendus==" ":
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+":\n"+str(tahendus))
count=1
#vale=vale+1
#skoor=skoor-1
#if skoor<0:
# skoor=0
Now the problem is that I have to add arguments to kontroll() but I don't know how to do that with 'self' being there. To be honest, I don't even understand why I need that 'self' there, 'cause I'm not using classes which usually use the 'self' argument... So anyway, I googled the error I recieved without having 'self' there and after adding 'self' it started working, but I can't add 'skoor' and 'vale' in brackets...
Right now I just start kontroll with nothing in brackets, like this: kontroll().
So how should I start the function and how should I add the arguments to it? I can't use global variables either, 'cause this 'skoor=skoor+1' messes everything up (can't have global variable on the left side of equals sign).
Thanks.
EDIT:
GUI part of my program looks like this:
raam=Tk()
raam.title("MÄNG")
raam.geometry("430x450")
valik=IntVar()
valik2=IntVar()
C2=Checkbutton(raam,text="f",variable=valik2,command=lambda:ok.config(state=ACTIVE)).place(x=5,y=10)
ok=Button(raam,text="Alusta!",command=alusta,state=DISABLED)
ok.place(x=230,y=20,width=80)
C1=Checkbutton(raam,text="š",variable=valik,command=lambda:ok.config(state=ACTIVE)).place(x=5,y=30)
sisendivaartus=StringVar()
sisend=Entry(raam,textvariable=sisendivaartus)
sisend.place(x=10,y=250,width=200)
sisend.bind("<Return>",kontroll(skoor,vale))
credit=Label(raam,text="2013",font=("Verdana","7"))
credit.place(x=0,y=430)
score=Label(raam,text="Skoor:",font=("Verdana","7"))
score.place(x=380,y=430)
nupp=Button(raam,text="Seaded",command=seaded)
nupp.config()
nupp.place(x=330,y=20,width=80)
kast=Text(raam,wrap=WORD,font=("Verdana",10))
kast.config()
app=App(raam)
kast.place(x=10,y=60,width=400,height=180)
raam.mainloop()
For Henry's suggestion (how to use the function when not in class), I start getting different errors that have no basis, for example "NameError: global name 'oige' is not defined". Despite what the error says, global name 'oige' is defined and works fine without arguments. If I replace 'skoor' and 'vale' in the functions definition with just 'self' and recall it without any arguments, everything works just fine. I guess this is kind of hard to understand without seeing the whole piece, so I uploaded it here, if anyone has a minute.
PS. what I said earlier about having 0 classes in my code - that has changed since I constantly keep working on this. Also please keep in mind that this is a beta version of a beta, so many things are not supposed to work yet.
(For trivia: it tests and trains person's capabilities in Estonian orthography)
Writing Your Function
It's very easy to add more arguments to a function; simply change your function definition to
def kontroll(self, skoor, vale):
# Your code here.
Then skoor and vale become variable names local to the kontroll function and you can use them like any other variable.
As to why you need self in the function definition, that's because (presumably) this method is actually an instance method of some class you've defined. Instance methods always receive the object they're bound to as their first argument. This argument is called self, which is why you have to have an argument reserved for it. See this question for a more complete explanation.
If this is not actually an instance method of some class, mind you, then you don't actually need self. And generally speaking, if the method doesn't need a reference to a specific object instance, then there's no reason to make it an instance method!
Calling Your Function
Calling your function is just as simple, but it depends on the answer to the other question: is this actually an instance method? If it's defined inside a class (which it sounds like it is) then you need to do something like the following:
class C(object):
def kontroll(self, skoor, vale):
pass # Your code goes here.
c = C() # Create an instance of the class!
c.kontroll(skoor, vale) # The instance (c) is automatically passed to the method.
If, on the other hand, your function is not defined inside a class, your code should look like this:
def kontroll(skoor, vale):
pass # Your code goes here.
kontroll(skoor, vale)
You need self because this is almost certainly a method of a class, and you need to pass the object to the method when it is called. Self is just a convention, technically you can use some other name for this just as easily. That being said, it seems like you need to do some reading about classes in python and really try to understand the way an object instance works. I recommend starting with the docs:
http://docs.python.org/2/tutorial/classes.html
There appear to be a lot of globals in your code snippet that should probably be class variables, and you really need to understand how things like the __init__ method work before going to deep into this.
Related
I am looking for a way in python to stop certain parts of the code inside a function but only when the output of the function is assigned to a variable. If the the function is run without any assignment then it should run all the inside of it.
Something like this:
def function():
print('a')
return ('a')
function()
A=function()
The first time that I call function() it should display a on the screen, while the second time nothing should print and only store value returned into A.
I have not tried anything since I am kind of new to Python, but I was imagining it would be something like the if __name__=='__main__': way of checking if a script is being used as a module or run directly.
I don't think such a behavior could be achieved in python, because within the scope of the function call, there is no indication what your will do with the returned value.
You will have to give an argument to the function that tells it to skip/stop with a default value to ease the call.
def call_and_skip(skip_instructions=False):
if not skip_instructions:
call_stuff_or_not()
call_everytime()
call_and_skip()
# will not skip inside instruction
a_variable = call_and_skip(skip_instructions=True)
# will skip inside instructions
As already mentionned in comments, what you're asking for is not technically possible - a function has (and cannot have) any knowledge of what the calling code will do with the return value.
For a simple case like your example snippet, the obvious solution is to just remove the print call from within the function and leave it out to the caller, ie:
def fun():
return 'a'
print(fun())
Now I assume your real code is a bit more complex than this so such a simple solution would not work. If that's the case, the solution is to split the original function into many distinct one and let the caller choose which part it wants to call. If you have a complex state (local variables) that need to be shared between the different parts, you can wrap the whole thing into a class, turning the sub functions into methods and storing those variables as instance attributes.
I just realized there is something mysterious (at least for me) in the way you can add vertex instructions in Kivy with the with Python statement. For example, the way with is used goes something like this:
... some code
class MyWidget(Widget)
... some code
def some_method (self):
with self.canvas:
Rectangle(pos=self.pos, size=self.size)
At the beginning I thought that it was just the with Python statement that I have used occasionally. But suddenly I realize it is not. Usually it looks more like this (example taken from here):
with open('output.txt', 'w') as f:
f.write('Hi there!')
There is usually an as after the instance and something like and alias to the object. In the Kivy example we don't define and alias which is still ok. But the part that puzzles me is that instruction Rectangle is still associated to the self.canvas. After reading about the with statement, I am quite convinced that the Kivy code should be written like:
class MyWidget(Widget)
... some code
def some_method (self):
with self.canvas as c:
c.add (Rectangle(pos=self.pos, size=self.size))
I am assuming that internally the method add is the one being called. The assumption is based that we can simply add the rectangles with self.add (Rectangle(pos=self.pos, size=self.size))
Am I missing something about the with Python statement? or is this somehow something Kivy implements?
I don't know Kivy, but I think I can guess how this specific construction work.
Instead of keeping a handle to the object you are interacting with (the canvas?), the with statement is programmed to store it in some global variable, hidden to you. Then, the statements you use inside with use that global variable to retrieve the object. At the end of the block, the global variable is cleared as part of cleanup.
The result is a trade-off: code is less explicit (which is usually a desired feature in Python). However, the code is shorter, which might lead to easier understanding (with the assumption that the reader knows how Kivy works). This is actually one of the techniques of making embedded DSLs in Python.
There are some technicalities involved. For example, if you want to be able to nest such constructions (put one with inside another), instead of a simple global variable you would want to use a global variable that keeps a stack of such objects. Also, if you need to deal with threading, you would use a thread-local variable instead of a global one. But the generic mechanism is still the same—Kivy uses some state which is kept in a place outside your direct control.
There is nothing extra magical with the with statement, but perhaps you are unaware of how it works?
In order for any object to be used in a with statement it must implement two methods: __enter__ and __exit__. __enter__ is called when the with block is entered, and __exit__ is called when the block is exited for any reason.
What the object does in its __enter__ method is, of course, up to it. Since I don't have the Kivy code I can only guess that its canvas.__enter__ method sets a global variable somewhere, and that Rectangle checks that global to see where it should be drawing.
Can you please help me guys. I believe I've got pretty easy questions but don't want to stuff up with my assignment. I'm going to have Class in my module, this class will have few functions.
I just want to be sure it works alright and this is a not ugly code practice.
I.e. my first function test_info accepts one parameter test_code and returns something and the second function check_class accepts two parameter, one of them is called test_code as well
Can I use same argument name: test_code? Is it normal code practice?
def test_info (self, test_code):
my_test_code = test_code
#here we'll be using my_test_code to get info from txt file and return other info
def check_class (self, test_code, other_arg):
my_test_code = test_code
#here some code goes
Also is it fine to use my_test_code in both functions to get argument value or is it better to use different ones like my_test_code_g etc.
Many thanks
Yes you may.
The two variables test_code are defined only in the scope of their respective functions and therefore will not interfere with one another since the other functions lie outside their scope.
Same goes for my_test_code
Read online about variable scopes. Here is a good start
There is no technical reason to resolve this one way or another. But if the variables don't serve exactly the same purpose in both functions, it's confusing for a human reader if they have the same name.
I just realized there is something mysterious (at least for me) in the way you can add vertex instructions in Kivy with the with Python statement. For example, the way with is used goes something like this:
... some code
class MyWidget(Widget)
... some code
def some_method (self):
with self.canvas:
Rectangle(pos=self.pos, size=self.size)
At the beginning I thought that it was just the with Python statement that I have used occasionally. But suddenly I realize it is not. Usually it looks more like this (example taken from here):
with open('output.txt', 'w') as f:
f.write('Hi there!')
There is usually an as after the instance and something like and alias to the object. In the Kivy example we don't define and alias which is still ok. But the part that puzzles me is that instruction Rectangle is still associated to the self.canvas. After reading about the with statement, I am quite convinced that the Kivy code should be written like:
class MyWidget(Widget)
... some code
def some_method (self):
with self.canvas as c:
c.add (Rectangle(pos=self.pos, size=self.size))
I am assuming that internally the method add is the one being called. The assumption is based that we can simply add the rectangles with self.add (Rectangle(pos=self.pos, size=self.size))
Am I missing something about the with Python statement? or is this somehow something Kivy implements?
I don't know Kivy, but I think I can guess how this specific construction work.
Instead of keeping a handle to the object you are interacting with (the canvas?), the with statement is programmed to store it in some global variable, hidden to you. Then, the statements you use inside with use that global variable to retrieve the object. At the end of the block, the global variable is cleared as part of cleanup.
The result is a trade-off: code is less explicit (which is usually a desired feature in Python). However, the code is shorter, which might lead to easier understanding (with the assumption that the reader knows how Kivy works). This is actually one of the techniques of making embedded DSLs in Python.
There are some technicalities involved. For example, if you want to be able to nest such constructions (put one with inside another), instead of a simple global variable you would want to use a global variable that keeps a stack of such objects. Also, if you need to deal with threading, you would use a thread-local variable instead of a global one. But the generic mechanism is still the same—Kivy uses some state which is kept in a place outside your direct control.
There is nothing extra magical with the with statement, but perhaps you are unaware of how it works?
In order for any object to be used in a with statement it must implement two methods: __enter__ and __exit__. __enter__ is called when the with block is entered, and __exit__ is called when the block is exited for any reason.
What the object does in its __enter__ method is, of course, up to it. Since I don't have the Kivy code I can only guess that its canvas.__enter__ method sets a global variable somewhere, and that Rectangle checks that global to see where it should be drawing.
is it possible to add a local varible to a function, just before calling it ? if yes how ?
EDIT:REASON
i noticed that all my views in django are using
render_to_response(template_name,locals())
now i created a middleware and i wanted to add one more local variable using the
def process_view():
method of it .so that i don't have to modify the views .
The local scope for a function does not exist until the function is called, so it's not possible to do this. You could do this for a closure, but the next person to have to maintain the code would hunt you down and kill you.
Although I also think it is pretty useless, I thought that you may enclose the function in either a 'with' statement or another function, like the code below. Of course, this approach can be accomplished directly within the function of interest. In fact, you are adding the local variable 'during' the function declaration. See if this fits your needs!
#!/usr/bin/python
def my_funct(_local):
"""My function of interest
"""
print "Local argument was %s" % str(_local)
return "Finished"
def localize(fct, local_var):
"""
"""
return fct(_local = local_var)
## Use function to 'localize' variable
localize(my_funct, local_var="LOCAL_VARIABLE")
## Same effect without supplementary function :
my_funct(_local="LOCAL_VARIABLE")
try:
print local_var
except:
print "No such global variable"
Just some thoughts :)
Cheers
So if you’re one of those lazy
programmers and you like keeping code
particularly concise, you can take
advantage of a built-in Python
function called locals(). It returns a
dictionary mapping all local variable
names to their values, where “local”
means all variables that have been
defined within the current scope.
source
It is a trick in order to not have to explicitly list all of the variables you need to pass in to the function. In this case, you need to explicitly state a variable to pass in. Therefore, you should not be using locals() in the calls you are making in your middle-ware, as the trick was not designed to be used like that.
i mangaged to do that using decorators.