% operator on chars and event handling in tkinter - python

While reading about event handling with Tkinter, I found out the piece of code below.
Can somebody explain to me what is the purpose of the modulo operator here and how it works, assuming the following declaration of show_event_details function:
def show_event_details(event):
event_name = {"2": "KeyPress", "4": "ButtonPress", "6": "Motion", "9":"FocusIn"}
print ('='*50)
print ("EventName=" + event_name[str(event.type)])
print ("EventKeySymbol=" + str(event.keysym))
print ("EventType=" + str(event.type))
print ("EventWidgetId=" + str(event.widget))
print ("EventCoordinate (x,y)=(" + str(event.x)+","+str(event.y)+")")
print ("Time:", str(event.time))
The code:
alphanum = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789'
for i in alphanum:
mye.bind("<KeyPress-%s>"%i, show_event_details)
keysyms = ['Alt_L', 'Alt_R','BackSpace', 'Cancel', 'Caps_Lock','Control_L',
'Control_R','Delete', 'Down', 'End', 'Escape', 'Execute','F1',
'F2', 'Home', 'Insert', 'Left','Linefeed','KP_0','KP_1','KP_2',
'KP_3','KP_4','KP_5','KP_6','KP_7','KP_8','KP_9','KP_Add',
'KP_Decimal','KP_Divide']
for i in keysyms:
mye.bind("<KeyPress-%s>"%i, show_event_details)

In the code block you have, the % operator is being used to format the string. If you notice, the following line:
mye.bind("<KeyPress-%s>"%i, show_event_details)
Has "%s inside the string, and the % operator afterwards. This is essentially telling Python that it will be given an argument, which should be converted into a string and placed there.
It is a convenient way of representing variables in strings with different presentations. In this case, it is converting the variable "i" to a string.

% doubles as a string-formatting operator. The expression
"<KeyPress-%s>" % i
evaluates to a string in which %s is replaced by the value of i. (This explanation glosses over a few details, such as why %s is used and how things change if the right-hand operand of % is a tuple instead of a single value. See the documentation for more information.)

Related

Comparing string including decimal in Python

I have question here:
How do I compare variable that has string+decimal in Python.
Example :
a = "2.11.22-abc-def-ghi"
if a == (2.11*) :
print "ok"
I want it only compare the first 2 decimal point only and it doesn't care the rest of it value. How can I do that?
Thanks
Here's the most direct answer to your question, I think...a way to code what your pseudocode is getting at:
a = "2.11.22-abc-def-ghi"
if a.startswith("2.11"):
print("ok")
If you want to grab the numeric value off the front, turn it into a true number, and use that in a comparison, no matter what the specific value, you could do this:
import re
a = "2.11.22-abc-def-ghi"
m = re.match(r"(\d+\.\d+).*", a)
if m:
f = float(m.group(1))
if (f == 2.11):
print("ok")
If you want to compare part of a string, you can always slice it with the syntax str[start_index: end_index] and then compare the slice. Please note the start_index is inclusive and end_index is exclusive. For example
name = "Eric Johnson"
name[0:3] #value of the slice is "Eri" no "Eric".
in your case, you can do
if a[0:4] == "2.11":
#stuff next

Issues with adding a variable to python gspread

I have started to use the gspread library and have sheet already that I'd like to append after the last row that has data in it. I'll retrieve the values between A1 and maxrows to loop through them and check if they are empty. However, I am unable to add a variable to the second line here. But perhaps I am just not escaping it correct? I bet this is very simple:
maxrows = "A" + str(worksheet.row_count)
cell_list = worksheet.range('A1:A%s') % (maxrows)
Your variable maxrows already is in the form of "An", the concatenation already contains the letter and the number
But you are adding an extra A to it here worksheet.range('A1:A%s')
Also you're not using the string interpolation correctly with % (in your code you are not applying % to the range string)
It should have been one of these
maxrows = "A" + str(worksheet.row_count)
worksheet.range('A1:%s' % maxrows)
or
worksheet.range('A1:A%d' % worksheet.row_count)
(among other possible solutions)

String indices must be integers, new to python

I hope I won't get trashed for this question. This is my first day with Python and all I've done so far is copy pasting and deducing from other snippets of code. I have no experience with code. I'm trying my hardest however this one I can't get past for the past few hours.
I'm currently adjusting an Editorial (iOS app) workflow to fit my needs — namely: posting to my WordPress site, including the ability to choose from a list of all possible post formats (I have "standard" and "link" enabled).
Here is the faulty bit from the relevant Python script:
console.show_activity('Fetching formats...')
server = xmlrpclib.ServerProxy(wp_url)
format = server.wp.getPostFormats(wp_blogid, wp_username, wp_password, 'post_format')
i = 0
for x in format:
formats += '\n' + x['name'] + " " + str(i)
i = i+1
workflow.set_variable("formats", formats)
console.hide_activity()
I'm getting the error: "string indices must be integers, not str"
What is this supposed to do is later show me in a list my available formats. I've done this successfully with server.wp.getPostFormats(wp_blogid, wp_username, wp_password, 'post_tag') and server.wp.getTerms(wp_blogid, wp_username, wp_password, 'category')
I know my problem is where the line with the i starts, I just have no idea how to solve it. I'm assuming by reading other topics that I need to cast, but I'm not even sure what getPostFormats returns, or how to do that.
Thanks in advance!
Edit: I've now concluded that server.wp.getPostFormats returns a dictionary, but I have not a slightest idea on how to retrieve only one set of data (either the key or value) of this dictionary. Please help.
You're getting that error because "string indices must be integers, not str".
formats += '\n' + x['name'] + " " + str(i)
Here, you are accessing the 'name'th element of x, where 'name' is of course a string and x is a string too, since server.wp.getPostFormats obviously returns a list of strings.
So simply look at format and you should immediately see how to obtain the required data.
UPDATE:
OK, so you figured out that format is a dictionary (returned from server.wp.getPostFormats). In Python, if you iterate over a dictionary (your for-loop), you iterate through its keys. This is the standard behaviour.
Look at this example:
>>> foo = {'a': 1, 'c': 3, 'b': 2}
>>> for x in foo: print(x)
...
a
c
b
Of course you also need the values, not only the keys (you seem to look for an entry with the key name). One way is to iterate though the keys and items in one shot:
>>> for key, value in foo.iteritems():
... print(key + ":" + str(value))
...
a:1
c:3
b:2
So the .iteritems() method of a dictionary returns for every iteration a key/value-pair, which you can unpack within the for loops definition.
In your case, you can do the following:
for key, value in format.iteritems():
formats += 'key: ' + key + ', value: ' + value + '\n'
Given that you are new, I would also suggest using the enumerate method and refactoring your code:
for i, x in enumerate(format):
formats += '\n' + x[idx_for_name] + " " + str(i)
The idx_for_name would be the index for the name.
If you wanna go even further, you can use the join method too:
formats = '\n'.join(x[idx_for_name] + " " + str(i) \
for i, x in enumerate(format))
warning: This code is untested.
Read:
http://python-wordpress-xmlrpc.readthedocs.org/en/latest/ref/methods.html#wordpress_xmlrpc.methods.posts.GetPostFormats
GetPostFormats return a dictionary so x iterates among the keys which are strings.
Try:
x= format['all']:

Using String Formatting to pull data from a dictionary

How do I use string formatting to call information from a dictionary?
Here's what I attempted so far (probably quite bad...)
value = raw_input("Indicate a number: ")
print number_stats["chm%"] % (value,)
The dictionary number_stats holds information about values "chm1", "chm2", etc.
I get a key error, which confuses me because the item chm1 is definitely stored in my dictionary.
Is there a better way to do this?
When you do number_stats["chm%"] % (value,), you are doing number_stats["chm%"] first and then applying % (value,) to the result. What you want is to apply the % directly to the string:
number_stats["chm%s" % (value,)]
Note that you need %s; % by itself is not a valid string substitution.
However, there is probably a better way to do it. Why does your dictionary have keys like "chm1" and "chm2" instead of just having the numbers be the keys themselves (i.e., have keys 1 and 2)? Then you could just do number_stats[value]. (Or if you read value from raw_input you'd need number_stats[int(value)]
Use like this. You have to use string formatting inside square brackets
>>> number_stats={'a1': 1}
>>>
>>> print number_stats['a%s' % 1]
1
>>>
print number_stats["chm%s" % (value)]
should work.
But you should do this instead:
print number_stats.get("chm%s" % (value), "some_default_value")
To avoid crashing if the user enters an invalid key. See this for more info on the get method.
As an alternative you could use the string format method...
value = input("Indicate a number: ")
print number_stats["chm{}".format(value)]

Iterate a tuple of dictionaries and pass the nested dictionaries to a function

#!/usr/bin/python -tt
# A dictionary Of Each New SSID
WirelessNetwork = {}
WirelessNetwork['name'] = 'baz'
WirelessNetwork['type'] = 'bar'
WirelessNetwork['pass'] = 'foo'
# A list of all SSIDs
networkAddList = (WirelessNetwork)
def addWireless(passedDict={}):
print 'Adding SSID: %s' % passedDict['name']
print 'Of type: %s' % passedDict['type']
print 'With Password: %s' % passedDict['pass']
for networkDict in networkAddList:
addWireless(networkDict)
So I have a List "networkAddList" full of dictionaries ,i.e. "WirelessNetwork".
I want to iterate that list "for networkDict in networkAddList"
and pass the dictionary itself to my function "addWireless"
When I run the sample code above I get the following error:
TypeError: 'string indices must be integers, not str'
Which makes me think that python thinks passedDict is a string, thus thinking I want string indices i.e. 0 or something rather then the key 'name'. I'm new to python but I am going to have to do this kind of thing a lot so I hope somebody can point me in the right direction as I think its pretty simple. But I can't change the basic idea , i.e. a list of dictionaries.
When debugging in python you can confirm your suspicion that the value being passed is a string with the type function:
print type(passedDict)
When you create your tuple with one element, you need a trailing ",". Also note that a tuple is different from a list in python. The primary difference is that tuples are immutable and lists are not.
#!/usr/bin/python -tt
# A dictionary Of Each New SSID
WirelessNetwork = {}
WirelessNetwork['name'] = 'baz'
WirelessNetwork['type'] = 'bar'
WirelessNetwork['pass'] = 'foo'
# A list of all SSIDs
networkAddList = (WirelessNetwork,)
def addWireless(passedDict={}):
print 'Adding SSID: %s' % passedDict['name']
print 'Of type: %s' % passedDict['type']
print 'With Password: %s' % passedDict['pass']
for networkDict in networkAddList:
addWireless(networkDict)
this is not a list, is the value itself
# A list of all SSIDs
networkAddList = (WirelessNetwork)
with a comma becomes a list
# A list of all SSIDs
networkAddList = (WirelessNetwork,)
Actually it's not a list, even with a comma. It's a tuple, which is immutable. I bring this up in case your code is wanting to append anything to this later.
networkAddList = [WirelessNetwork] # or, list(WirelessNetwork)
Just ran a quick check of the types being referenced, and I'm believing that you were only missing a serial comma (in WirelessNetwork).
So, your code would look something like this:
networkAddList = (WirelessNetwork,)
Your for loop will then properly iterate over the dictionaries.

Categories

Resources