I wanted to make a dictionary that looks like this:
example = dict(C# = "o.ooo.")
Because there is '#' symbol, the rest greys out.
I know I can fix this problem by doing this:
test = [("C#"), ("o.ooo.")]
example = dict(test)
I was wondering if there was something that could fix my problem such as:
example = dict(r(C#) = "o.ooo.") - which obviously doesn't work.
Like in other programming language Python has some ways of reusing the same code in different position of the program. One of them is function concept (called procedure in same languages) that we can classify by type of arguments/parameters in:
Positional Function Parameters
In this category a value for the parameter is assigned by position. So if we have the following function definition
def newLengths(bridge1,bridge2,bridge3):
#updating lengths
and we call it like this newLenghts(1200,1001,1110) the parameter bridge2 will take for value 1001 meters because it was in the second position.
Named/Keyword Python Functional Parameters
In this case we are explicitly telling to python which variable we want to assign a value and not let's implicitly determine by position.
So now for the previous function we can do newLenghts(1200,bridge2 = 1001, 1110). This way of using named parameters is useful in different situations, especially for default values of parameters when not indicated.
The important part of keyword parameters is the fact the the keyword need to be a valid variable identifier in Python to be used like so, otherwise python will think it's something else, like a number and so one. In your case you try using # that have the specializing of line comment and can't be combined to create an identifier.
So I can say that there is no way of using the hashtag unless you modify Python syntax so it's a valid character for variable's name.
However there are some ways to create "C#" key:
Use the string directly like key in the dictionary {"C#":"O.OOO."}
Create an iterable object and pass it when calling dict()
The simplest way to make an iterable for this is to use the function zip() that take two lists and combine them one element of the first list with the one in the same position of the second list.
keys = ["C#","Java","Python"]
values = ["Book1","Book1","Book0"]
example = dict(zip(keys,values))
Passing keywords to the dict() built-in function is problematic here, because the # in your key is being
misinterpreted as the beginning of a comment.
Instead, use the literal syntax:
example = {"C#": "o.ooo."}
Related
I have a dataset with several columns of which I want to convert from categorical to numerical dtype.
I have defined the following function:
def create_num_column(df,column):
df[str(column)]=df[str(column)].astype('category')
df[str(column)+'_cat']=df[str(column)].cat.codes
dictionary{}.format(str(column)+'_cat')=dict(zip(df[column],df[str(column)+'_cat']))
return dictionary{}.format(str(column)+'_cat')
I also want this function to create a dictionary so I will be able to understand what label was assigned to what value.
The problem here arises with naming of a dictionary as I have tried to use '.format()' and it has shown syntax error.
dictionary{}.format(str(column)+'_cat')=dict(zip(df.column,df[str(column)+'_cat']))
>SyntaxError: invalid syntax
I understand that this particular method works with strings but is there any way to 'automate' the naming of variable?
Thanks in advance.
You cannot "dynamically" name a variable, and there is no need to do so. Simply return the dictionary:
def create_num_column(df,column):
df[str(column)]=df[str(column)].astype('category')
df[str(column)+'_cat']=df[str(column)].cat.codes
return dict(zip(df.column,df[str(column)+'_cat']))
(There is a way to create variables or more generally objects with dynamic names in Python, but that's only very rarely useful.)
I wrote a function (testFunction) with four return values in Python:
diff1, diff2, sameCount, vennPlot
where the first 3 values (in the output tuple) were used to plot "vennPlot" inside of the function.
A similar questions was asked : How can I plot output from a function which returns multiple values in Python?, but in my case, I also want to know two additional things:
I will likely to use this function later, and seems like I need to memorize the order of the returns so that I can extract the correct return for downstream work. Am I correct here? If so, is there better ways to refer to the tuple return than do output[1], or output[2]? (output=testFunction(...))
Generally speaking, is it appropriate to have multiple outputs from a function? (E.g. in my case, I could just return the first three values and draw the venn diagram outside of the function.)
Technically, every function returns exactly one value; that value, however, can be a tuple, a list, or some other type that contains multiple values.
That said, you can return something that uses something other than just the order of values to distinguish them. You can return a dict:
def testFunction(...):
...
return dict(diff1=..., diff2=..., sameCount=..., venn=...)
x = testFunction(...)
print(x['diff1'])
or you can define a named tuple:
ReturnType = collections.namedtuple('ReturnType', 'diff1 diff2 sameCount venn')
def testFunction(...):
...
return ReturnType(diff1=..., diff2=..., sameCount=..., venn=...)
x = testFunction(...)
print(x.diff1) # or x[0], if you still want to use the index
To answer your first question, you can unpack tuples returned from a function as such:
diff1, diff2, samecount, vennplot = testFunction(...)
Secondly, there is nothing wrong with multiple outputs from a function, though using multiple return statements within the same function is typically best avoided if possible for clarity's sake.
I will likely to use this function later, and seems like I need to memorize the order of the returns so that I can extract the correct return for downstream work. Am I correct here?
It seems you're correct (depends on your use case).
If so, is there better ways to refer to the tuple return than do output[1], or output[2]? (output=testFunction(...))
You could use a namedtuple: docs
or - if order is not important - you could just return a dictionary, so you can acess the values by name.
Generally speaking, is it appropriate to have multiple outputs from a function? (E.g. in my case, I could just return the first three values and draw the venn diagram outside of the function.)
Sure, as long as it's documented, then it's just what the function does and the programmer knows then how to handle the return values.
Python supports direct unpacking into variables. So downstream, when you call the function, you can retrieve the return values into separate variables as simply as:
diff1, diff2, sameCount, vennPlot= testFunction(...)
EDIT: You can even "swallow" the ones you don't need. For example:
diff1, *stuff_in_the_middle, vennPlot= testFunction(...)
in which case stuff_in_the_middle will contain a tuple of 2.
It is quite appropriate AFAIK, even standard library modules return tuples.
For example - Popen.communicate() from the subprocess module.
How would I go about making reference to an element from a list inside that list? For example,
settings = ["Exposure", "0", random_time(settings[0])]
Where the third element makes reference to the first. I could verbosely state "Exposure" but I am trying to set it up so that even if the first element is changed the third changes with it.
Edit:
I think maybe my question wasn't clear enough. There will be more than one setting each using the generic function "random_time", hence the need to pass the keyword of the setting. The reference to the first element is so I only have to make modifications to the code in one place. This value will not change once the script is running.
I will try and use a list of keywords that the settings list makes reference to.
The right-hand expression is evaluated first, so when you evaluate
["Exposure", "0", random_time(settings[0])]
the variable settings is not defined yet.
A little example:
a = 1 + 2
First 1 + 2 is evaluated and the result is 3, after it's evaluated, then the assignment is done:
a = 3
One way you could handle this is storing the "changing" string to a variable:
var1 = "Exposure"
settings = [var1 , "0", random_time(var1)]
this will work in the list definition, but if, after declaring the list settings, you change var1, it won't change its third element. If you want this to happen, you can try implementing a class Settings, which will be a lot more flexible.
AFAIK you can't. This is common to most programming languages because when you're running your function there the item hasn't been completely created yet.
You can't directly.
You could have both refer to something else, though, and use an attribute of that.
class SettingObj:
name = "Exposure"
settings = [SettingObj, "0", random_time(SettingObj)]
Now, change the way you work with your settings list so that you look for your name attribute for 1st and 3rd items on the list.
As others have told you, the syntax you've chosen will try to reference settings before it is created, and therefore it will not work (unless settings already exists because another object was assigned to it on a previous line).
More importantly, in Python, assigning a string to two places will not make it so that changing it in one place will change it in the other. This applies to all forms of binding, including variable names, lists and object attributes.
Strings are immutable in Python -- they cannot be changed, only rebinded. And rebinding only affects a single name (or list position or etc.) at a time. This is different from, say, C, where two names can contain pointers that reference the same spot in memory, and you can edit that spot in memory and affect both places.
If you really need to do this, you can wrap the string in an object (custom class, presumably). You could even make the object's interface look like a string in all respects, except that it's not a string primitive but an object with an attribute (say contents) that's bound to a string. Then when you want to change the string, you rebind the object's attribute (that is, obj.contents or whatever). Since you are not reassigning the names bound to the object itself, but only a name inside the object, it will change in both places.
In this particular case you don't just have the same string in both places but you actually have a string in the first position but the result of a function performed on the string in the third position. So even if you use an object wrapper, it won't work the way you seem to want it to, because the function needs to be re-run every time.
There are ways to design your program so that this is not a problem, but without knowing more about your ultimate goal I can't say what they are.
This is a first step for my in Python on a Linux web-server using mod-WSGI.
I'm trying to get all of the cell parameters from the URL in a list like this:
...&cell=&cell=1&cell=2&cell=3&cell=4&cell=5&cell=6&cell=7&cell=8&...
So I started with code like this:
def application(environment, start_response):
import cgi
form = cgi.FieldStorage(fp = environment['wsgi.input'], environ = environment)
temp_table_inputs=form.getlist('cell')
But I found that the first cell parameter is missing from the list (I presume because getlist removes it as the content is blank).
Two questions:
How can I get a list including the blank values?
How can I find which positions in the list are skipped by getlist?
Note: I know the cell stuff has a positional dependency but I'd rather look for a way to cope with that before naming the parameters according to their position (I inherited the code and quite a bit depends on the positional stuff, so renaming things will take a lot of effort).
According to the documentation:
The FieldStorage instance can be indexed like a Python dictionary. It allows membership testing with the in operator, and also supports the standard dictionary method keys() and the built-in function len(). Form fields containing empty strings are ignored and do not appear in the dictionary; to keep such values, provide a true value for the optional keep_blank_values keyword parameter when creating the FieldStorage instance.
Does it solve your problem?
so i know this is a bit of a workaround and theres probably a better way to do this, but heres the deal. Ive simplified the code from where tis gathering this info from and just given solid values.
curSel = nuke.selectedNodes()
knobToChange = "label"
codeIn = "[value in]"
kcPrefix = "x"
kcStart = "['"
kcEnd = "']"
changerString = kcPrefix+kcStart+knobToChange+kcEnd
for x in curSel:
changerString.setValue(codeIn)
But i get the error i figured i would - which is that a string has no attribute "setValue"
its because if i just type x['label'] instead of changerString, it works, but even though changer string says the exact same thing, its being read as a string instead of code.
Any ideas?
It looks like you're looking for something to evaluate the string into a python object based on your current namespace. One way to do that would be to use the globals dictionary:
globals()['x']['label'].setValue(...)
In other words, globals()['x']['label'] is the same thing as x['label'].
Or to spell it out explicitly for your case:
globals()[kcPrefix][knobToChange].setValue(codeIn)
Others might suggest eval:
eval('x["label"]').setValue(...) #insecure and inefficient
but globals is definitely a better idea here.
Finally, usually when you want to do something like this, you're better off using a dictionary or some other sort of data structure in the first place to keep your data more organized
Righto, there's two things you're falling afoul of. Firstly, in your original code where you are trying to do the setValue() call on a string you're right in that it won't work. Ideally use one of the two calls (x.knob('name_of_the_knob') or x['name_of_the_knob'], whichever is consistent with your project/facility/personal style) to get and set the value of the knob object.
From the comments, your code would look like this (my comments added for other people who aren't quite as au fait with Nuke):
# select all the nodes
curSel = nuke.selectedNodes()
# nuke.thisNode() returns the script's context
# i.e. the node from which the script was invoked
knobToChange = nuke.thisNode()['knobname'].getValue()
codeIn = nuke.thisNode()['codeinput'].getValue()
for x in curSel:
x.knob(knobToChange).setValue(codeIn)
Using this sample UI with the values in the two fields as shown and the button firing off the script...
...this code is going to give you an error message of 'Nothing is named "foo"' when you execute it because the .getValue() call is actually returning you the evaluated result of the knob - which is the error message as it tries to execute the TCL [value foo], and finds that there isn't any object named foo.
What you should ideally do is instead invoke .toScript() which returns the raw text.
# select all the nodes
curSel = nuke.selectedNodes()
# nuke.thisNode() returns the script's context
# i.e. the node from which the script was invoked
knobToChange = nuke.thisNode()['knobname'].toScript()
codeIn = nuke.thisNode()['codeinput'].toScript()
for x in curSel:
x.knob(knobToChange).setValue(codeIn)
You can sidestep this problem as you've noted by building up a string, adding in square brackets etc etc as per your original code, but yes, it's a pain, a maintenance nightmare, and starting to go down that route of building objects up from strings (which #mgilson explains how to do in both a globals() or eval() method)
For those who haven't had the joy of working with Nuke, here's a small screencap that may (or may not..) provide more context: