All a user's answers taken together can be used to form a unique binary number (one composed of only zeros and ones). You could make a table (list) for each condition indexed by the each of the possible combinations of answer in each position store the value a given condition -- expressed as a lambda function -- would have for that set.
Once these tables are set up, you could determine whether any condition is true by looking up the value in the corresponding table indexed by a given combination of answers. Below is an example of how this might be set up.
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