If sentence with a text condition in python - python

I need to write an if loop in pyhon. My condition is related to a text (dict_keys). in particular, i have:
condition = f.get_best().keys()
When i read the condition element, it returns:
dict_keys(['laplace'])
Where i can have 'laplace' or 'gumbel'.
My goal is to perform different calculation if laplace or gumbel is returned.
My attempt so far:
condition = f.get_best().keys()
if condition == dict_keys(['laplace']):
print('Laplace case')
elif condition == dict_keys(['gumbel']):
print('gumbel case')
But it doesn't work. i also tried with:
if condition == laplace:
if condition == 'laplace':
But none of these seem to work. How can i do it?

dict_keys can't be used explicitly, it's internal of a dictionary. Use the following instead:
best_keys = f.get_best().keys()
if 'laplace' in best_keys:
print('Laplace case')
elif 'gumbel' in best_keys:
print('gumbel case')

You can change condition to a list and then compare the list with what you want it to be.
Would be done like this.
if list(condition) == ['laplace']:
(if the dictionary has multiple keys you should use in).

One could use match. This makes addition of new cases fairly easy.
>>> def lagumbl(cnd):
... match cnd:
... case "laplace":
... print(f["laplace"])
... case "gumbel":
... print(f["gumbel"])
...
>>> for cond in f.get_best().keys():
... lagumbl(cnd=cond)
...
laplace here
gumbel here

Related

Error when trying to build logical parser

So i have these strings stored in database and i want to convert them to python expression to use them with if statement. I will store these strings into list and will loop over them.
For example:
string = "#apple and #banana or #grapes"
i am able to convert this string by replacing # with "a==" and # with "b==" to this :
if a == apple and b == banana or b == grapes
hash refers to a
# refers to b
But when i use eval it throws up error "apple is not defined" because apple is not in quotes. so what i want is this:
if a == "apple" and b == "banana" or b == "grapes"
Is there any way i can do this ?
The strings stored in DB can have any type of format, can have multiple and/or conditions.
Few examples:
string[0] = "#apple and #banana or #grapes"
string[1] = "#apple or #banana and #grapes"
string[2] = "#apple and #banana and #grapes"
There will be else condition where no condition is fullfilled
Thanks
If I understand correctly you are trying so setup something of a logical parser - you want to evaluate if the expression can possibly be true, or not.
#word or #otherword
is always true since it's possible to satisfy this with #=word for example, but
#word and #otherword
is not since it is impossible to satisfy this. The way you were going is using Python's builtin interpreter, but you seem to "make up" variables a and b, which do not exist. Just to give you a starter for such a parser, here is one bad implementation:
from itertools import product
def test(string):
var_dict = {}
word_dict = {}
cur_var = ord('a')
expression = []
for i,w in enumerate(string.split()):
if not i%2:
if w[0] not in var_dict:
var_dict[w[0]] = chr(cur_var)
word_dict[var_dict[w[0]]] = []
cur_var += 1
word_dict[var_dict[w[0]]].append(w[1:])
expression.append('{}=="{}"'.format(var_dict[w[0]],w[1:]))
else: expression.append(w)
expression = ' '.join(expression)
result = {}
for combination in product(
*([(v,w) for w in word_dict[v]] for v in word_dict)):
exec(';'.join('{}="{}"'.format(v,w) for v,w in combination)+';value='+expression,globals(),result)
if result['value']: return True
return False
Beyond not checking if the string is valid, this is not great, but a place to start grasping what you're after.
What this does is create your expression in the first loop, while saving a hash mapping the first characters of words (w[0]) to variables named from a to z (if you want more you need to do better than cur_var+=1). It also maps each such variable to all the words it was assigned to in the original expression (word_dict).
The second loop runs a pretty bad algorithm - product will give all the possible paring of variable and matching word, and I iterate each combination and assign our fake variables the words in an exec command. There are plenty of reasons to avoid exec, but this is easiest for setting the variables. If I found a combination that satisfies the expression, I return True, otherwise False. You cannot use eval if you want to assign stuff (or for if,for,while etc.).
Not this can drastically be improved on by writing your own logical parser to read the string, though it will probably be longer.
#Evaluted as (#apple and #banana) or #grapes) by Python - only #=apple #=banana satisfies this.
>>> test("#apple and #banana or #grapes")
True
#Evaluted as #apple or (#banana and #grapes) by Python - all combinations satisfy this as # does not matter.
>>> test("#apple or #banana and #grapes")
True
#demands both #=banana and #=grapes - impossible.
>>> test("#apple and #banana and #grapes")
False
I am not sure of what you are asking here, but you can use the replace and split functions :
string = "#apple and #banana"
fruits = string.replace("#", "").split("and")
if a == fruits[0] and b == fruits[1]:
Hope this helps

Is there a short way to switch between 'any' and 'all' in condition in function?

I have a function where I check several list of parameters:
def check_function(some_input_parameters):
#do_smth
...
if all(bet_res[i] for i in res_number_list):
good_row_list.append(row_dict)
else:
bad_row_list.append(row_dict)
#do_smth
...
In some cases I need "all" and sometimes I need "any".
Is there a nice short way to change all/any by some input param?
I can do smth like this, but I don't like it:
if any_all_flag = 'all':
if all(bet_res[i] for i in res_number_list):
good_row_list.append(row_dict)
else:
bad_row_list.append(row_dict)
else:
if any(bet_res[i] for i in res_number_list):
good_row_list.append(row_dict)
else:
bad_row_list.append(row_dict)
The all and any functions accept iterables, so you don't need to loop over the iterator again, unless you only want to apply the functions on certain number of items. One neat approach here is to use a dictionary like following for preserve the function and their names so that you can access to the respective function by a simple indexing.
functions = {'all': all,
'any': any}
if functions[any_all_flag](bet_res):
# do stuff
Just use a functor (a variable that is holding a function):
if any_all_flag = 'all':
my_functor = all
else:
my_functor = any
if my_functor(bet_res[i] for i in res_number_list):
good_row_list.append(row_dict)
else:
bad_row_list.append(row_dict)

Make sure that there are two values in a Dictionaries Key Python

I have a simple dictionary. I am able to check if one value is true. My problem arises when I need to check if two are correct. I want it to return false if one of the two are correct. But it returs True in this case
mydict = {}
mydict['Car'] = ['Diesel','Hatchback','2,ltr']
mydict['Bri'] = ['Hatchback','2ltr']
print(mydict.get('Car'))
if 'Diesel' in mydict.get('Car'):
print('Found')
else:
print('This is false')
if 'Diesel' and 'Hatchback' in mydict.get('Bri'):# Here it needs these two values to be true.
print('Found')
else:
print('This is false')
This is not being evaluated the way you think it is:
'Diesel' and 'Hatchback' in mydict.get('Bri')
But like this
'Diesel' and ('Hatchback' in mydict.get('Bri'))
So 'Diesel' evaluates to True and the second part too.
What you want is something like this:
data = mydict.get('Bri')
if 'Diesel' in data and 'Hatchback' in data:
...
PS: Although this question might be a duplicate of this one as marked above, the answers there are way more complex than needed for this simple case

Working on basic recursion- trying to recursively look through a string for two characters

I'm super new to python, and trying to create a very simple function to be used in a larger map coloring program.
The idea of the function is to have a set of variables attributed to different regions (string1) with colors assigned to them, (r,g,b) and then test if the regions touch another region of the same color by recursively looking through a set of region borders (string2) to find variables+colors that match.
The input format would look like this:
("Ar, Bg, Cb", "AB,CB,CA")
Would return True, meaning no two regions of the same color touch.
Here's my code segment so far:
def finding_double_char_function(string1, string2):
if string2=="":
return True
elif string2[0]+"r" and string2[1]+"r" in string1 or string1[::-1]:
return False
elif string2[0]+"g" and string2[1]+"g" in string1 or string1[::-1]:
return False
elif string2[0]+"b" and string2[1]+"b" in string1 or string1[::-1]:
return False
else:
return finding_double_char_function(string1, (string2[3:]))
I keep getting false when I expected True. Can anyone help? Thanks a lot.
You have several problems in this, but your main problem is that you don't seem to know the order of bindings in an expression. What you've written is a little more readable like this:
elif string2[0]+"r" and
((string2[1]+"r" in string1) or
string1[::-1]) :
In other words, you've used strings as boolean values. The value you get from this is not what you expected. I think what you're trying to do is to see whether either constructed string (such as "Ar") is in string 1, either forward or backward.
"in" can join only one pair of strings; there's no distributive property of "and" and "or" over "in".
Here's the first part rewritten properly:
elif (string2[0]+"r" in string1) and
(string2[1]+"r" in string1)
Does this get you going?
Also, stick in print statements to trace your execution and print out useful values along the way.
If I undestood correctly your problem could be solved like this:
def intersect(str1, str2):
if (not str2):
return True
if (str1[str1.find(str2[0]) + 1] == str1[str1.find(str2[1]) + 1]):
return False
else:
return intersect(str1, str2[3:])

Compare Two Lists and Create a List

I'm still trying to learn programming so please help me simplify this. I'm trying to run something that looks through the indices in my list and if it finds a 1 returns "yay" (just for debugging purposes). Here's what I have so far:
def replaceValues(distList, indexList):
for i in range (1,len(indexList)):
if indexList[i] = 1
return "yay!"
However, I get a syntax error whenever I run this, which underlines the 1. Please help!
Thanks!
Apart from incorrect indentation(fixed below), you are using = when you should be using ==, and you left out a colon from your if statement.
= is used to assign values
== evaluates equality(returning a boolean i.e True or False)
You left out a : in your if statement.
Corrected code:
def replaceValues(distList, indexList):
for i in range (1,len(indexList)):
if indexList[i] == 1:
return "yay!"
If you don't understand exactly how Python uses whitespace/indentation as an integral part of it's syntax/structure and other syntax basics, then you need to get on that i.e tutorials.. A quick google should turn up many. I recommend Udacity or Codeacademy
There are three syntax errors that I see.
First, you're using the = sign (assignment) when you need == (comparison).
Second, you're missing a colon at the end of your if statement.
Finally, you must* have an indented block after your if statement.
All together, it should read like this:
if indexList[i] == 1: # double-equals and colon
return "yay!" # This must be indented to the proper level
You should really go have a look at the tutorials; this is all stuff that's laid out very well there, and it's all critical to doing pretty much anything in Python.
*Technically, you can also follow an if statement with an expression on the same line (e.g. if 1: pass). However, I personally think this is hideous in almost every case.
= is an assignment statement. Example:
name = "tyler"
You should use == to check for equality of primitives (you're comparing integers, which are primitives).
Switch :
if indexList[i] = 1
to:
if indexList[i] == 1
Try it like this:
def replaceValues(distList, indexList):
for k in range(1, len(indexList)):
if indexList[k] == 1:
return "yay!"

Categories