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?
Related
I have a function like the following:
def do_something(thing):
pass
def foo(everything, which_things):
"""Do stuff to things.
Args:
everything: Dict of things indexed by thing identifiers.
which_things: Iterable of thing identifiers. Something is only
done to these things.
"""
for thing_identifier in which_things:
do_something(everything[thing_identifier])
But I want to extend it so that a caller can do_something with everything passed in everything without having to provide a list of identifiers. (As a motivation, if everything was an opaque container whose keys weren't accessible to library users but only library internals. In this case, foo can access the keys but the caller can't. Another motivation is error prevention: having a constant with obvious semantics avoids a caller mistakenly passing the wrong set of identifiers in.) So one thought is to have a constant USE_EVERYTHING that can be passed in, like so:
def foo(everything, which_things):
"""Do stuff to things.
Args:
everything: Dict of things indexed by thing identifiers.
which_things: Iterable of thing identifiers. Something is only
done to these things. Alternatively pass USE_EVERYTHING to
do something to everything.
"""
if which_things == USE_EVERYTHING:
which_things = everything.keys()
for thing_identifier in which_things:
do_something(everything[thing_identifier])
What are some advantages and limitations of this approach? How can I define a USE_EVERYTHING constant so that it is unique and specific to this function?
My first thought is to give it its own type, like so:
class UseEverythingType:
pass
USE_EVERYTHING = UseEverythingType()
This would be in a package only exporting USE_EVERYTHING, discouraging creating any other UseEverythingType objects. But I worry that I'm not considering all aspects of Python's object model -- could two instances of USE_EVERYTHING somehow compare unequal?
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."}
I need to invoke Django's reverse() method to construct a URL for a certain view function style_specific. Its entry in urls.py is below:
Figure 1
url(r'^(?P<jewelry_type>[A-Za-z0-9]+)/(?P<jewelry_style_user>[A-Za-z0-9]+)/(?P<jewelry_id>[0-9]+)/$',views.style_specific,name="style_specific"),
I'm also using Algolia, (a search engine) that plugs its own parameters into the constructed URLS, so I need to use reverse() to insert placeholders that can then be manipulated by Algolia. This previously worked when I called reverse twice --
Figure 2
specific_url = (reverse('jewelry:specific_method',args=[model_name,177013,1337]).replace('1337','{{objectID}}')).replace('177013','{{jewelry_style}}')
where model_name is a parameter passed into the view function constructing style_specific's URLs, and 177013 and 1337 are placeholders that get replaced eventually. However, this approach is a hackish one that will get hard to maintain later. To that end, I wanted to replace this solution with something more flexible, along the lines of this SO answer. Ideally, the placeholders/replacements would be determined by a dictionary replace_parameters defined like
Figure 3
replace_parameters={'placeholder_1':'replacement_1','placeholder_2':replcement_2} #and so on
Unfortunately this is where my problem comes in. In Figure 2, the parameters is passed into args a hard-coded list. (Or at least that's what the syntax appears as) The solution I attempted to overcome this obstacle was to call replace_parameters's keys as a list -- that is, list(replace_parameters.keys()) par this SO answer. (See below)
Figure 4
specific_url = reverse('jewelry:specific_method',args=list(replace_parameters.keys()))
This approach yielded this NoReverseMatchspecifically:
Figure 5
Reverse for 'style_specific' with arguments '('jewelry_type', 'jewelry_style_user', 'jewelry_id')' not found. 1 pattern(s) tried: ['jewelry/(?P<jewelry_type>[A-Za-z0-9]+)/(?P<jewelry_style_user>[A-Za-z0-9]+)/(?P<jewelry_id>[0-9]+)/$']
where jewelry_type,jewelry_style_user and jewelry_id are the keys from replace_parameters.
As part of my debugging, I double-checked Figure 1's regex and verified it passed using a different view function. I also verified list(replace-parameters.keys()) by testing isinstance(list(replace_parameters.keys()),list). I also tried placing brackets around list(replace_parameters.keys()) but that did nothing either. Django's documentation on reverse() implies args should have a list passed into it, but this is not made clear. Thus my question is: does reverse() allow a list object to be passed into args or must it be hard-coded?
replace_parameters.keys() means keys, not values.
Why don't you use kwargs which are more specific for named placeholders matching? Especially when replace_parameters is already a dict.
specific_url = reverse('jewelry:specific_method', kwargs=replace_parameters)
And someone must evaluate 'jewelry_style_user': '{{ jewelry_style }}', 'jewelry_id': '{{objectID}}' placeholders within {{}}. Reverse function can see only {{ jewelry_style }} as string, as it is, which truly does not match [A-Za-z0-9_-]+ pattern.
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:
I'm trying to use Beaker's caching library but I can't get it working.
Here's my test code.
class IndexHandler():
#cache.cache('search_func', expire=300)
def get_results(self, query):
results = get_results(query)
return results
def get(self, query):
results = self.get_results(query)
return render_index(results=results)
I've tried the examples in Beaker's documentation but all I see is
<type 'exceptions.TypeError'> at /
can't pickle generator objects
Clearly I'm missing something but I couldn't find a solution.
By the way this problem occurs if the cache type is set to "file".
If you configure beaker to save to the filesystem, you can easily see that each argument is being pickled as well. Example:
tp3
sS'tags <myapp.controllers.tags.TagsController object at 0x103363c10> <MySQLdb.cursors.Cursor object at 0x103363dd0> apple'
p4
Notice that the cache "key" contains more than just my keyword, "apple," but instance-specific information. This is pretty bad, because especially the 'self' won't be the same across invocations. The cache will result in a miss every single time (and will get filled up with useless keys.)
The method with the cache annotation should only have the arguments to correspond to whatever "key" you have in mind. To paraphrase this, let's say that you want to store the fact that "John" corresponds to value 555-1212 and you want to cache this. Your function should not take anything except a string as an argument. Any arguments you pass in should stay constant from invocation to invocation, so something like "self" would be bad.
One easy way to make this work is to inline the function so that you don't need to pass anything else beyond the key. For example:
def index(self):
# some code here
# suppose 'place' is a string that you're using as a key. maybe
# you're caching a description for cities and 'place' would be "New York"
# in one instance
#cache_region('long_term', 'place_desc')
def getDescriptionForPlace(place):
# perform expensive operation here
description = ...
return description
# this will either fetch the data or just load it from the cache
description = getDescriptionForPlace(place)
Your cache file should resemble the following. Notice that only 'place_desc' and 'John' were saved as a key.
tp3
sS'place_desc John'
p4
I see that the beaker docs do not mention this explicitly, but, clearly, the decorate function must pickle the arguments it's called with (to use as part of the key into the cache, to check if the entry is present and to add it later otherwise) -- and, generator objects are not pickleable, as the error message is telling you. This implies that query is a generator object, of course.
What you should be doing in order to use beaker or any other kind of cache is to pass around, instead of a query generator object, the (pickleable) parameters from which that query can be built -- strings, numbers, dicts, lists, tuples, etc, etc, composed in any way that is easy to for you to arrange and easy to build the query from "just in time" only within the function body of get_results. This way, the arguments will be pickleable and caching will work.
If convenient, you could build a simple pickleable class whose instances "stand for" queries, emulating whatever initialization and parameter-setting you require, and performing the just-in-time instantiation only when some method requiring an actual query object is called. But that's just a "convenience" idea, and does not alter the underlying concept as explained in the previous paragraph.
Try return list(results) instead of return results and see if it helps.
The beaker file cache needs to be able to pickle both cache keys and values; most iterators and generators are unpickleable.