There is an option on the backend of a website that I use that allows me to customize the data sent in a CSV file when an order has been placed for a product. There are two columns, the left column is where you assign the header and the right column is where you input the variable. The syntax for the existing variables is similar to %(order.random_variable)s or %(item.random_variable)s This looks similar to the string placeholder %s in Python and I'm fairly confident that it is related, if not the same, but I don't quite understand the syntax. Could someone please elaborate on the purpose of this code?
Oh, and for the record, I don't plan on going in and changing variables around right away. Just looking for a good jumping off point for my research into this.
That is similar to %s. The part inside the parenthesis is optional.
The only difference is that, for the first one, your values must be a
tuple with exactly the number of items specified by the format string,
and for the 2nd one, it must be a single mapping object (for example,
a dictionary)
It's clearly listed in String formatting documentation: -
A conversion specifier contains two or more characters and has the
following components, which must occur in this order:
The '%' character, which marks the start of the specifier.
Mapping key (optional), consisting of a parenthesised sequence of characters (for
example, (somename)).
.. and there are some more
Also: -
When the right argument is a dictionary (or other mapping type), then
the formats in the string must include a parenthesised mapping key
into that dictionary inserted immediately after the '%' character. The
mapping key selects the value to be formatted from the mapping
An example from the docs: -
>>> print '%(language)s has %(number)03d quote types.' % \
... {"language": "Python", "number": 2}
Python has 002 quote types.
So, the text inside the () after % and before s is a key in the dictionary.
Yes, this is similar to %s. The part inside the () is referencing a key of a python dict. For example:
mydict = {'yay':'boo'}
print '%(yay)s'%mydict
# boo
Related
I'm using a library called unit-convert. The interface looks like this:
# Bytes to terabytes
>>> UnitConvert(b=19849347813875).tb
Suppose I have strings taken from user input (omitting the input code) like so:
input_value_unit = 'b'
output_value_unit = 'tb'
How can I substitute these into the call?
I tried using UnitConvert(input_value_unit=user_input_value).output_value_unit, but this doesn't use the string values.
Code like function(x=1) doesn't care if there's a variable named x naming a string; the x literally means x, not the x variable. Similarly for attributes: x.y doesn't care if there is a y variable naming a string; it will just get the y attribute of x.
However, we can use strings to specify both of these things "dynamically".
To replace the b in the example, we need to use a string as a keyword argument name. We can do this by making a dictionary for the keyword arguments, and then using ** to pass them. With a literal string, that looks like: UnitConvert(**{'b': ...}).
To replace the tb, we need to use a string as an attribute name. We can do this by using the built-in getattr to look up an attribute name dynamically. With a literal string, that looks like: getattr(UnitConvert(...), 'tb').
These transformations let us use a literal string instead of an identifier name.
Putting it together:
# suppose we have read these from user input:
input_value_unit = 'b'
output_value_unit = 'tb'
input_amount = 19849347813875
# then we use them with the library:
getattr(UnitConvert(**{input_value_unit: input_amount}), output_value_unit)
Edit again - perhaps I still misunderstand. You're using an existing module that you downloaded?
Now that your code has been pared back to look nothing like the original, my first answer no longer applies. I'll leave it below the underline because you should still be aware.
Usually in your situation the second unit would be passed as a second parameter to the function. Then the function can do the appropriate conversion.
UnitConvert(user_input_value, output_value_unit)
There's an alternative that looks a little closer to what you had in mind. If your function returns a dictionary with all the possible conversions, you can select the one you need.
UnitConvert(user_input_value)[output_value_unit]
The old irrelevant answer. Your statement:
if user_input_convert == ["kilometres", "miles", "nanometres", "metres"]:
is comparing a single string to a list of strings. They will never be equal. What you probably want is:
if user_input_convert in ["kilometres", "miles", "nanometres", "metres"]:
That checks to see if your string is equal to one of the strings in the list.
I want to accomplish:
Appending a Dictionary to an existing list of dictionaries and updating a value in that new dictionary.
What my problem is:
When I read in my Dictionary from the .yaml RobotFramework puts double qoutes around the keywords and values as below.
in the .yaml I have
Vlan2: { u'IP': u'1.1.1.1',
u'DNS': {u'SN': u's2', u'PN': u's1'},
u'SRoute': [{u'IF': u'eth0', u'Mask': u'0.0.0.0'}]
}
but when I do
Collections.Set To Dictionary ${Vlan2} IP=2.2.2.2
and I log to console
Log To Console ${Vlan2}
I get
[{ "u'IP'": "u'1.1.1.1'",
u'IP': '2.2.2.2',
"u'DNS'": {"u'SN'": "u's2'", "u'PN'": "u's1'"},
"u'SRoute'": [{"u'IF'": "u'eth0'", "u'Mask'": "u'0.0.0.0'"}]
}]
I think this is happening because Robot Framework is adding double qoutes when it reads in the values from the .yaml cause it to appear as a different keyword, but I cannot find out how to fix this.
It would be ideal to avoid the double qoutes all together since the JSON the info is going to is single qoute based as in the .yaml.
Any help is appreciated!
There is quite a lot confusion going on here. This part of your YAML:
{ u'IP': u'1.1.1.1',
Starts a mapping ({) and gives a key-value pair. both key and value are scalars. The first scalar starts with a u and ends before the key indicator (:), so the content of the scalar is u'IP'. Note that this probably is not what you want, because you say:
since the JSON the info is going to is single qoute based as in the .yaml.
You seem to think that you are using single-quoted scalars in your YAML when in fact, you are using unquoted scalars. In YAML, if a scalar does not start with a quotation mark (' or "), it is a plain scalar and further quotation marks inside it are parsed as content. Your scalars start with a u making them unquoted scalars. Your YAML should probably look like this:
Vlan2: { IP: 1.1.1.1,
DNS: {SN: s2, PN: s1},
SRoute: [{IF: eth0, Mask: 0.0.0.0}]
}
Another important thing to remember is that when loaded into Python, the representation style of a scalar is lost – it does not make a difference if it was single-quoted, double-quoted or unquoted in the YAML file.
Now let's look at the output: Here again, the strings are represented in textual form. This means that they are quoted by some means. The representation "u'IP'" matches exactly your input, the double quotes are not added to the string; they are just used as a means to tell you that the enclosed characters form a string.
Then there's this representation in the output: u'IP'. This is still a quoted string, just with the Python-specific representation of having a u in front indicating that this is a unicode string – its content is IP. The u-prefixed representation does not exist in YAML and this is why your input does not work correctly. In YAML, all input is unicode, usually encoded as UTF-8. The u'IP' in the output is the IP value you have set with your code. And because it did not match any existing dict key (as your original key, as explained, has the content u'IP', represented in the output as "u'IP'"), it has been added as additional key to the dict.
Which of these Python string interpolations is proper (not a trick question)?
'%s' % my_string
'%s' % (my_string)
'%s' % (my_string, )
If it varies by version, please summarize.
Old format
The first one is the most common one. The third has unnecessary parenthesis and doesn't help the legibility if you've only one object you want to use in your format-string. The second is just plain silly, because that's not even a tuple.
New format
Nowadays starting with Python 2.6, there's a new and recommended way of formatting strings using the .format-method:
In your case you would use:
'{}'.format(my_string)
The advantage of the new format-syntax are that you enter more advanced formattings in the format string.
All three of these are equivalent.
The first two are exactly equivalent, in fact. Putting brackets around something does not make it a tuple: putting a comma after it does that. So the second one evaluates to the first.
The third is also valid: using a tuple is the normal way of doing string substitution, but as a special case Python allows a single value if there is only one element to be substituted.
I've been searching on this but am coming up a little short on exactly how to do specifically what i am trying to do.. I want to concatentate a string (I guess it would be a string in this case as it has a variable and string) such as below, where I need to use a variable consisting of a string to call a listname that has an index (from another variable).. I simplified my code below to just show the relevant parts its part of a macro that is replacing values:
toreplacetype = 'type'
toreplace_indx = 5
replacement_string = 'list'+toreplacetype[toreplace_indx]
so... I am trying to make the string on the last line equal to the actual variable name:
replacement_string = listtype[5]
Any advice on how to do this is appreciated
EDIT:
To explain further, this is for a macro that is sort of a template system where I am indicating things in a python script that I want to replace with specific values so I am using regex to do this. So, when I match something, I want to be able to replace it from a specific value within a list, but, for example, in the template I have {{type}}, so I extract this, but then I need to manipulate it as above so that I can use the extracted value "type" to call a specific value from within a list (such as from a list called "listtype") (there is more than 1 list so I need to find the one called "listtype" so I just want to concatenate as above to get this, based on the value I extracted using regex
This is not recommended. Use a dict instead.
vars['list%s' % toreplacetype][5] = ...
Hrm...
globals()['list%s'% toreplacetype][toreplace_indx]
replacement_string = 'list'+toreplacetype+'['+str(toreplace_indx)+']'
will yield listtype[5] when you print it.
You need to basically break it into 5 parts: 1 string variable, 3 strings and an int casted to a string.
I think this is what you are asking?
I have a dictionary which store a string as the key, and an integer as the value. In my output I would like to have the key displayed as a string without parenthesis or commas. How would I do this?
for f_name,f_loc in dict_func.items():
print ('Function names:\n\n\t{0} -- {1} lines of code\n'.format(f_name, f_loc))
output:
Enter the file name: test.txt
line = 'def count_loc(infile):'
There were 19 lines of code in "test.txt"
Function names:
('count_loc(infile)',) -- 15 lines of code
Just incase it wasn't clear, I would like the last line of the output to be displayed as:
count_loc(infile) -- 15 lines of code
EDIT
name = re.search(func_pattern, line).groups()
name = str(name)
Using type() before my output, I verified it remains a string, but the output is as it was when name was a tuple
I don't have Python 3 so I can't test this, but the output of f_name makes it look like it is a tuple with one element in it. So you would change .format(f_name, f_loc) to .format(f_name[0], f_loc)
EDIT:
In response to your edit, try using .group() instead of .groups()
To elaborate on Peter's answer, It looks to me like you're assigning a one-item tuple as the key of your dictionary. If you're evaluating an expression in parentheses somewhere and using that as the key, be sure you don't have a stray comma in there.
Looking at your further edited answer, it's indeed because you're using the groups() method of your regex match. That returns a tuple of (the entire matched section + all the matched groups), and since you have no groups, you want the entire thing. group() with no parameters will give you that.
I expect you have a problem with your parsing code. The lines as written should work as expected.
Since the key is some type of tuple, you may want to join the different elements before printing. We can't really tell what the significance of the key is from the snippet shown.
So you could do something like such:
.format(", ".join(f_name), f_loc)