What does 'state' mean regarding Django apps? - python

I'm new to django (and programming in general) and I am trying to create a Reviewboard extension.
This extension will display the fullname of the user in a column. The code works for the most part, however I don't understand what the state variable in this method does.
# renders column to display
def render_data(self, state, review_request):
# returns user's fullname (or username if fullname does not exist)
user = review_request.submitter
return user.get_full_name() or user.username
This code works, however when I remove the 'state' argument, the field shows 'None' instead of the fullname of the user. I tried looking online but I could not find an explanation for what that variable does.
I dont even call it in my method, yet it still affects the result.
I don't like having code that I don't fully understand (harder to debug), so could someone shed some light on this?
What I think it means
I think state refers to the instance of the object. In this case it would be the review_request that the fullname is being rendered for. Without this instance, one review request can't be differentiated from all of them. I still don't know how it affects the code without me even calling it.
Edit: C14L was right, I renamed state to foobar and my code still functioned properly. I dug a bit more into the source of the djblets/django code where it calls the function.
rendered_data = self.render_data(state, obj)

In the code you posted, state isn't used at all. But, if you remove it, then review_request will be the second argument. But this function is called, expecting review_request to be the third argument. You can't just change the number or order of arguments, because the callers don't know about that. Try renaming state to foobar and the function will still work as before.
You can just leave state there, that's perfectly fine. The interface of the function/method shouldn't change only because one of the arguments isn't used (anymore) inside the function or method.

Related

Nuke ChannelMask_Knob required argument

I am trying to figure out what the required string argument for the nuke.ChannelMask_Knob() function corresponds to. On some other knob constructors the first argument seems to be the name/label, but that does not seem to be the case for the ChannelMask_Knob...
I have looked at the Nuke Python API, but I am unsure how to follow it back to the appropriate function definition to answer my question. My line of thinking is that this has to do with the init function which is overridden by the ChannelMask_Knob class, but the parameter list according to the API is just "..." which I believe means it has to do with a builtin function. Since I can't see the body of the init function, I have no idea what that argument is used for, thus my problem...
Here is an example of my issue:
test_knob = nuke.ChannelMask_Knob("required_argument")
node.addKnob(test_knob)
This works just fine, but I would like to know what the "required_argument" is used for since it is apparently not the name or label for the knob.
You must intentionally leave a blank space for parameter in ChannelMask_Knob('') method. It doesn't work. But for assigning a name and a label you need to use .setName('name') and .setLabel('label') methods respectively. It works fine.
Here is a code:
import nuke
noop = nuke.nodes.NoOp()
### maskKnob = nuke.ChannelMask_Knob('name', 'label', False)
maskKnob = nuke.ChannelMask_Knob('')
maskKnob.setName('name')
maskKnob.setLabel('label')
noop.addKnob(maskKnob)
For selection of channel in this dropdown menu it's better to use the following method:
nuke.selectedNode().knob('name').setValue('alpha')
nuke.selectedNode().knob('name').setValue('disparity')

Python 3.3 - Game - Hint System

I want to make it so it prints different hints dependent on where the player is in the game. I tried it by setting the value of 'Hint' every time the player went somewhere. Obviously I came across a flaw (as I'm here). The value of Hint = 1 was first in one def and I couldn't manage to summon it when writing the Help/Hint def. My pathetic example:
def Room_Choice():
Hint = 1
(60 lines down)
def Hint():
Choice = input("What would you like?\n")
if Choice == ("Hint"):
if Room_Choice(Hint = 1):
print_normal("blah blah blah\n")
else:
print_normal("HINT-ERROR!\n")
Help_Short()
And obviously as the game developed more and more values of hint would be added.
As you can see I'm relatively new to Python and need help.
You are trying to reach a value that exists in a function scope, and you're doing it wrong (as you're here).
Imagine scopes as boxes of one-way mirrors : when you're inside one, you can see what's in the box and what's outside of the box. But you can't see what's in a box you are not in.
Here, Hint exists within the box of Room_Choice, but not in the box of H... oh wait.
You've called your function Hint too ! If you want to reach Hint in a function called Hint with no Hint defined inside the function, you'll probably get the function. Let's call the function DoHint()
So you can't see Hint from within DoHint, because it's in another box. You have to put it somewhere (over the rainboooow... sorry for that) you can see it.
You might want to put it at the module level (not within a def), or make it an object's attribute (but you'll have to know bits of Oriented Object Programming to understand that).
This is really basic programming skills, I can't really explain further without knowing what you're trying to do and showing you how I would do it, but I hope that helped.
Just one more thing on this line : if Room_Choice(Hint = 1):, here you're trying to check if the result of the Room_Choice function with a value of 1 for the Hint parameter is True. I don't know what you wanted to do, but the Room_Choice function doesn't show it can handle any parameters (you should get an error on that), and will not return a boolean value (it will implicitly return None, which is evaluated as a logical False).

Is it better to assign a name to a throwaway object in Python, or not?

This is not a "why doesn't my code run" question. It is a "how / why does my code work" question. I am looking to generalize from this specific case to learn what broad rules apply to similar situations in the future.
I have done some searching (Google and StackOverflow) for this, but haven't seen anything that answers this question directly. Of course, I'm not entirely sure how best to ask this question, and may be using the wrong terms. I welcome suggested edits for the question title and labels.
I have the following function (which makes use of the requests module):
def make_session(username,password,login_url):
#The purpose of this function is to create a requests.Session object,
#update the state of the object to have all of the cookies and other
#session data necessary to act as a logged in user at a website, and
#return the session to the calling function.
new_session = requests.Session()
login_page = new_session.get(login_url)
#The function get_login_submit_page takes the previously
#created login_page, extracts the target of the login form
#submit, and returns it as a unicode string.
submit_page_URL = get_login_submit_page_URL(login_page)
payload = {u'session_name': username, u'session_password': password}
new_session.post(submit_page_URL,data=payload,allow_redirects=True)
return new_session
And what I really want to know is whether or not how I do this line matters:
new_session.post(submit_page_URL,data=payload,allow_redirects=True)
According to the requests documentation, the Session.post method returns a Response object.
However, this method also has side-effects which update the Session object. It is those side effects that I care about. I have no use for the Response object this method creates.
I have tested this code in practice, both assigning the Response to a label, and leaving it as presented above. Both options appear to work equally well for my purposes.
The actual question I am asking is: since, reasonably, whether I assign a label or not, the Requests object created by my call to Session.post falls out of scope as soon as the Session is returned to the calling function, does it matter whether I assign a label or not?
Rather, do I save any memory/processing time by not making the assignment? Do I create potential unforeseen problems for myself by not doing so?
If you are not using the return value of a call, there is little point in assigning it to a local name.
The returned response object will then not be referenced anywhere and freed two bytecodes earlier than if you assigned it to a name, and ignored that name before returning from the function.

How to add arguments next to 'self' in a python function?

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.

Updating a binding that is bound to object[property] (Binding.IndexerName weirdness)

This emerged from my related question. I currently have the following binding:
myBinding = Binding("[foo]")
myBinding.Mode = System.Windows.Data.BindingMode.TwoWay
myBinding.Source = obj
acheckbox.SetBinding(CheckBox.IsCheckedProperty, myBinding)
acheckbox.DataContext = obj
This will look at obj[foo]. The UI will update the source just fine - I can check the checkbox and obj[foo] is changed. However, the reverse is not working. Changing obj[foo] in code does not update the UI, even with this code manually calling OnPropertyChanged:
obj[foo] = False
obj._OnPropertyChanged(obj, System.ComponentModel.PropertyChangedEventArgs("[foo]"))
The problem likely lies with the arguments to OnPropertyChanged. Some digging (and help from H.B.) revealed this post:
http://10rem.net/blog/2010/03/08/wpf---silverlight-quick-tip-inotifypropertychanged-for-indexer
If you're creating the data source for
those (for example, you are building
your own ObservableDictionary), you
may wonder how on earth you fire the
appropriate
INotifyPropertyChanged.PropertyChanged
event to let the binding system know
that the item with that field name or
index has changed.
The binding system
is looking for a property named
"Item[]", defined by the constant
string Binding.IndexerName.
In other words, Binding.IndexerName is a constant, "Item[]", that tells the binding engine to rescan the whole source dictionary.
obj._OnPropertyChanged(obj, System.ComponentModel.PropertyChangedEventArgs(Binding.IndexerName))
# equivalent to:
obj._OnPropertyChanged(obj, System.ComponentModel.PropertyChangedEventArgs("Item[]"))
Unfortunately, scanning the entire source dictionary happens to be an expensive operation in my code; so that post also talks about using "Item[foo]" as the argument. This is exactly what I need - and it doesn't work! Only Item[] works. Why?
According to mamadero2 in this thread Item[index] only works in Silverlight 4.
(I never would have imagined that Silverlight supports something that WPF does not)

Categories