2010-10-30 2 views
0

, что я борюсь с тестируют предопределенные условия, которые принимают пользователь предусмотренных параметров, как в примере ниже:python: как проверить пользовательское условие?

 
cond = "if (1 is yes and 2 is no) or (1 is yes and 2 is no)" 
cond2 = "if (3 is no or 1 is no)" 
vars = [] 

lst = cond.split() 
lst += cond2.split() 

for l in lst: 
    if l.isdigit(): 
     if l not in vars: 
     vars.append(l) 
# ... sort 
# ... read user answers => x = no, y = no, y = yes 
# ... replace numbers with input (yes or no) 

# ... finally I have 

cond = "if (no is yes and no is no) or (no is yes and no is no)" 
cond2 = "if (yes is no or no is no)" 

Прежде всего, это правильный подход?
Во-вторых, как я могу проверить выше условия, если True или False?

Благодарю вас заранее.

+0

Вы, возможно, хотите анализировать булевы выражения? Подумайте о создании этого - парсера - с одной из существующих библиотек (я влюблен в LEPL). – delnan

ответ

0

Все ответы пользователя, взятые вместе, могут быть использованы для формирования уникального двоичного числа (состоящего только из нулей и единиц). Вы можете составить таблицу (список) для каждого условия, проиндексированного каждой из возможных комбинаций ответа в каждой позиции, сохранить значение, которое данное условие, выраженное как лямбда-функция, будет иметь для этого набора.

Как только эти таблицы настроены, вы можете определить, истинно ли какое-либо условие, если посмотреть значение в соответствующей таблице, проиндексированной данной комбинацией ответов. Ниже приведен пример того, как это можно настроить.

NUM_ANSWERS = 4 
NUM_COMBOS = 2**NUM_ANSWERS 
NO,YES = 'no','yes' 

def index(answers): 
    """ Convert a list of yes/no answers into binary number. """ 
    binstr = ''.join([('1' if a is 'yes' else '0') for a in answers]) 
    return int(binstr, 2) 

def answers(index): 
    """ Convert binary value of number into list of yes/no answers. """ 
    masks = [2**p for p in range(NUM_ANSWERS-1, -1, -1)] 
    bits = [((index & m)/m) for m in masks] 
    return [[NO,YES][b] for b in bits] 

# condition expressions 
cond_expr1 = lambda a1,a2,a3,a4: a1 is YES and a2 is NO # a3,a4 ignored 
cond_expr2 = lambda a1,a2,a3,a4: (
       (a1 is YES and a2 is NO) or (a3 is YES and a4 is NO) 
      ) 
# build tables for each condition 
cond1 = [] 
cond2 = [] 
for i in range(NUM_COMBOS): 
    ans_combo = answers(i) 
    cond1.append(cond_expr1(*ans_combo)) 
    cond2.append(cond_expr2(*ans_combo)) 

# once tables are built, you can lookup the corresponding conditional 
print cond1[ index(['yes', 'no', 'no', 'yes']) ] # True 
print cond2[ index(['yes', 'no', 'yes', 'no']) ] # True 
1

Используйте Python's language services для разбора и компиляции строки, затем выполните полученный АСТ.

+0

Я смотрел на него, но все равно не могу пройти. не могли бы вы привести пример кода? – m1k3y3

0

поэтому, после некоторого чтения на основе подсказки Игнасио, я думаю, что у меня есть это после некоторых строковых модификаций. Тем не менее, все еще не совсем уверен, что это правильный подход.
Итак, моя переменная состояние определяется как показано ниже

 
cond = """if ('no' is 'yes' and 'no' is 'no'): 
    result.append[1] 
else: 
    result.append[0] 
""" 

Кроме того, я создать переменную для хранения результата условие, чтобы оценить его позже

 
result = [] 

Я бегу Exec на моей строке

 
exec(cond) 

Наконец, я могу оценить результат.

 
if result[0] == 1 
    print "Condition was met" 
else: 
    print "Condition wasn't met" 

Любые мысли или комментарии, высоко оцененные.

+0

Если вам нужно всего лишь оценить одно выражение, логическое или другое, вы можете использовать 'eval()' - сказать что-то вроде 'result = eval (cond)' где 'cond' содержит только выражение для оценки, такие как 'cond =" 'no' is 'yes' и 'no' is 'no' "'. Вы также можете использовать 'result.append [eval (cond)]' для хранения нескольких за раз. – martineau

 Смежные вопросы

  • Нет связанных вопросов^_^