I've been constantly coding in Python using this inefficient style
checkbox = self.request.get(u'checkbox') # get data from a web form
if checkbox == u'yes':
someclass.enabled = True
else:
someclass.enabled = False
how do I shorten this?
someclass.enabled = self.request.get(u'checkbox') == u'yes'
You can do this without an if statement:
someclass.enabled = (checkbox == u'yes')
You can just set the value to the outcome of the statement:
checkbox = self.request.get(u'checkbox') # get data from a web form
someclass.enabled = checkbox == u'yes'
As checkbox == u'yes' returns a boolean value you can simply assign this result to the variable directly.
someclass.enabled = (checkbox == u'yes')
Perhaps you could split it into a different function:
def getCheckboxValue(name):
return (self.request.get(name) == u'yes')
Python eval the statement and return the output to the statement. So you can use the assign variable in right side.
like
variable = eval_statment
so your example will be
someclass.enabled = self.request.get(u'checkbox') == u'yes'
It's a little unclear if you used booleans in your example because they were inherent to your problem or because they were a convenient example. If you want to assign to variables more complicated types than booleans, you may also want to check out Python's ternary operator (if you're using version 2.5 or greater):
someclass.int_val = 1 if checkbox == u'yes' else 2
which translates to
if checkbox == u'yes':
someclass.int_val = 1
else
someclass.int_val = 2
For boolean variables, I'd recommend using Yuushi's solution, but for completeness, this is what it would look like:
someclass.enabled = True if checkbox == u'yes' else False
It's about the same amount of typing, but saves some vertical space, which can be useful.
If you ever need more than a boolean value, you should consider using the dispatch pattern:
targets = {
'yes': do_yes,
'no': do_no,
'maybe': do_maybe,
}
targets[self.request.get(u'tricheckbox')]()
# where do_yes, do_no, and do_maybe are the functions to call for each state.
As pointed-out in another answer you could use dispatch table to do different things based on a value. However using a dictionary's get() method rather than \performing a direct lookup would allow you to also easily handle cases where nothing matches. Since the mapping won't be used again it can be temporary and anonymous.
This approach is very generic and can expanded as necessary, but usually requires extra functions to be written. Because of the latter, for very simple cases like your example, one of the other answers would probably require the least effort.
def do_yes(): print 'do_yes'
def do_no(): print 'do_no'
def do_maybe(): print 'do_maybe'
def no_match(): print 'no_match'
{
u'yes': do_yes,
u'no': do_no,
u'maybe': do_maybe,
}.get(self.request.get(u'checkbox'), no_match) ()
Related
I have a json dictionary and I need to check the values of the data and see if there is a match. I am using multiple if statements and the in operator like so:
"SomeData":
{
"IsTrue": true,
"ExtraData":
{
"MyID": "1223"
}
}
json_data = MYAPI.get_json()
if 'SomeData' in json_data:
some_data = json_data['SomeData']
if 'IsTrue' in some_data:
if some_data['IsTrue'] is True:
if 'ExtraData' in some_data:
if 'MyID' in some_data['ExtraData']:
if some_data['ExtraData']['MyID'] == "1234":
is_a_match = True
break
I know that in python3 the in operator should be used, but I am thinking there must be a better way than using multiple if statements like I am using.
Is there a better way to parse json data like this?
Yes, you can assume that the keys are present, but catch a KeyError if they aren't.
try:
some_data = json_data['SomeData']
is_a_match = (
some_data['IsTrue'] is True and
some_data['ExtraData']['MyID'] == "1234"
)
except KeyError:
is_a_match = False
This style is called easier to ask for forgiveness than permission (EAFP) and it's used a lot in Python. The alternative is look before you leap (LBYL), which you use in your solution.
I would suggest writing a path function to access values in your nested dictionary. Something along the lines of this (pseudocode):
def get_path_value(json_dict, path):
"""
json_dict - dictionary with json keys and values
path - list of key sequences, e.g. ['SomeData', 'IsTrue']
you can make this a helper function and use an entry point that
splits paths, e.g. "SomeData/IsTrue"
"""
if len(path) == 1:
# last tag, base case
return json_dict[path[0]]
else:
return get_path_value(json_dict[path[0]], path[1:])
Add try/catch if you want something other than bad key, but this will let you navigat the dictionary a little more eloquently. Then you have things like:
if get_path_value(json_dict, ["SomeData", "IsTrue"]) == True and ...
You could even write a nice little class to wrap this all up, e.g. json["SomeData/IsTrue"] == True
Best of luck,
Marie
Let's say i have a this button:
tl.config(bd=0 ,image=photo1 ,width="100",height="100",command=lambda: functionPlus(tl))
The function is :
def functionPlus(button):
global turn
if (turn==1 or turn==3 or turn==5 or turn==7 or turn==9):
button.config(image=photo2,width="100",height="100")
turn +=1
elif (turn==2 or turn==4 or turn==6 or turn==8) :
button.config(image=photo3,width="100",height="100")
turn+=1
I would like to add an 'if' in the function, that would have as condition the image of the button. For exemple :
if button.config(image=photo2 == True) :
anotherFunction()
Thanks in advance.
First, never use the expression pattern something=something else == True!
Second, take a look at this related (but not duplicate) question.
As you can see there, the cget method will return the current value for an option. As this manual page mentions, cget is analogous to widget["option"].
So, to answer your question directly, the if condition you need would be along the lines of:
if button['image']==photo2:
anotherFunction()
I'm new here and couldn't comment. I hope I'm not flaunting SO policy by resorting to answering instead.
#Tersosauros
"First, never use the expression pattern something=something else ==
True!"
Where do you see this pattern and why should it be avoided? What could replace it? (I know you're a tersosaurus but "never use X" just seems TOO terse and uninformative).
#Arwan Credoz I know you got your answer but... If you simply want to check whether the value of "turn" is a an even/odd number and is within a given range, use a bounds check followed by modulus instead (maybe this is what #Tersosauros was hinting at?).
Also, the value of "turn" will always be incremented if it's within range(0,10) so there's no need to write "turn+=1" twice. If I've understood your intentions correctly, you could probably rewrite "functionPlus" to something like this and add Tersosaurus' addition where appropriate:
def functionPlus(button):
global turn
if 0 < turn < 10:
if turn % 2 == 0:
button.config(image=photo3,width="100",height="100")
else:
button.config(image=photo2,width="100",height="100")
turn += 1
I have the following dictionary:
In [32]: mydict
Out[32]:
{'Foo': {'DendriticCells': {'LV.ip': [15.14,1.003],
'SP.ip': [16.0282,3.001]},
'Macrophages': {'LV.ip': [32.137260000000005],
'SP.ip': [34.020810000000004]},
'NKCells': {'LV.ip': [4.89852], 'SP.ip': [5.18562]}}}
Given a string that correspond to key level 3, what I want to do to have a construct
to check the existence in the dictionary based on choices below.
What's the way to do it. I tried this but failed.
choice1 = "LV.ip"
choice2 = "KK.ip"
choices = [choice1,choice2]
celltypes = ["DendriticCells", "Macrophages", "NKCells"]
for ch in choices:
for ct in celltypes:
if mydict["Foo"][ct][choices]:
print "THERE\n"
else:
print "Not there\n"
Your if statement should use ch, not choices
You should break up the test in that if; for example, make sure that mydict["Foo"][ct] exists before trying to see if it contains anything.
Consider using dict.get.
You might want to do something like mydict.get("Foo", {}).get(ct, {}).get(ch):. Essentially get a default empty dict that will default onto nothing towards the end.
Alternatively, use in to verify the keys. You might have something like
if ct in mydict['foo'] and ch in mydict['foo'][ct]:
Which should not fail due to lazy evaluation in Python.
You can use any function and in operator to check if the key exists in the dictionary or not.
for choice in choices:
for key in my_dict:
if any(choice in my_dict[key][key1] for key1 in my_dict[key]):
print "{} is there".format(choice)
Output
LV.ip is there
You are using the wrong variable name
choice1 = "LV.ip"
choice2 = "KK.ip"
choices = [choice1,choice2]
celltypes = ["DendriticCells", "Macrophages", "NKCells"]
for ch in choices:
for ct in celltypes:
if mydict["Foo"][ct][ch]: // change choices to ch
print "THERE\n"
else:
print "Not there\n"
I was wondering if i could use a subroutine here instead if so how do i or is there a another way to shorten this piece of code.
if currency1=='GBP':
if currency2=='USD':
number=float(1.64)
elif currency2=='EUR':
number=float(1.20552)
elif currency2=='JPY':
number=float(171.181)
You could certainly make a dictionary:
currencies = {}
currencies['USD'] = 1.64
currencies['EUR'] = 1.20552
currencies['JPY'] = 171.181
currencies['GBP'] = 1.
number = currencies[currency2]
what's great about this is you can also do:
other_number = currencies[currency1]
exchange_rate = number / other_number # exchange rate BETWEEN the two currencies
How about:
Brit_converter: {'USD':1.64, 'EUR':1.20552}
if currency1=='GBP':
multiplier = converter[currency2]
or, assuming this does what I expect:
converted_currency = currency1 * converter[currency2]
Subroutines - in Python the accepted term is function - cannot replace if operator for a very simple reason - they serve different purpose:
Functions are used to break down code into small, manageable units and consolidate functionality required in more than one place
if operator changes the control flow
As it was pointed out above, dictionary is one of excellent solutions to multiple fixed choices.
I would use a dictionary like so*:
if currency1 == 'GBP':
number = {'USD':1.64, 'EUR':1.20552, 'JPY':171.181}.get(currency2, 1)
Also, notice that I used dict.get here. If currency2 is not found in the dictionary, number will be assigned to 1 and a KeyError will not be raised. However, you can choose anything you want for the default value (or omit it entirely and have None be the default).
Finally, you should note that putting float literals inside the float built-in is unnecessary.
*Note: If you plan to use the dictionary in multiple places, don't keep recreating it. Instead, save it in a variable like so:
my_dict = {'USD':1.64, 'EUR':1.20552, 'JPY':171.181}
if currency1 == 'GBP':
number = my_dict.get(currency2, 1)
I am trying to compare values from 2 Dictionaries in Python. I want to know if a value from one Dictionary exists anywhere in another Dictionary. Here is what i have so far. If it exists I want to return True, else False.
The code I have is close, but not working right.
I'm using VS2012 with Python Plugin
I'm passing both Dictionary items into the functions.
def NameExists(best_guess, line):
return all (line in best_guess.values() #Getting Generator Exit Error here on values
for value in line['full name'])
Also, I want to see if there are duplicates within best_guess itself.
def CheckDuplicates(best_guess, line):
if len(set(best_guess.values())) != len(best_guess):
return True
else:
return False
As error is about generator exit, I guess you use python 3.x. So best_guess.values() is a generator, which exhaust for the first value in line['full name'] for which a match will not be found.
Also, I guess all usage is incorrect, if you look for any value to exist (not sure, from which one dictinary though).
You can use something like follows, providing line is the second dictionary:
def NameExists(best_guess, line):
vals = set(best_guess.values())
return bool(set(line.values()).intersection(vals))
The syntax in NameExists seems wrong, you aren't using the value and best_guess.values() is returning an iterator, so in will only work once, unless we convert it to a list or a set (you are using Python 3.x, aren't you?). I believe this is what you meant:
def NameExists(best_guess, line):
vals = set(best_guess.values())
return all(value in vals for value in line['full name'])
And the CheckDuplicates function can be written in a shorter way like this:
def CheckDuplicates(best_guess, line):
return len(set(best_guess.values())) != len(best_guess)