Min
Min

Reputation: 13

How to filter out conditional logic elements in a nested list

I have a list of pre-requisites for a given task. The list consists of other tasks (using letters as place holders) which make up a logical expression. Example shown below:

prereqList = [["A", "|", "B"], "&", [["C", "&", "D"], "|", "E"], "&", "F"]

I also have a list of completed tasks:

completedTasks = ["A", "C", "F"]

I am trying to remove the completed tasks from the prereqList while following the conditional logic. For the aforementioned example, I would expect the output to be:

filtered_list = ["D", "|", "E"]

What I have so far:

def filter_prereqs(prereqList, completedTasks):
    ops = {
            "&": (lambda a, b: a in completedTasks and b in completedTasks),
            "|": (lambda a, b: a in completedTasks or b in completedTasks)
        }
        for i in range(prereqList):
            if isinstance(prereqList[i], list):
                filter_prereqs(prereqList[i], completedTasks)
            else:
                if prereqList[i] not in ops.keys():
                    pass
                else:
                    conditionMet = ops[prereqList[i]](prereqList[i-1],prereqList[i+1])
                    if conditionMet:

Been stuck trying to figure this out for a while. Any help will be greatly appreciated!

Upvotes: 1

Views: 67

Answers (1)

Kevin
Kevin

Reputation: 76254

Partial solution:

This works, but only on expressions that are "conservatively bracketed". In other words, it can parse [["A", "&", "B"], "&", "C"], but not ["A", "&", "B", "&", "C"]. So I can't parse the exact expression in your question, but I can parse a logically equivalent version of it that has an extra pair of brackets.

#sentinel value that gets returned for an expression that's 100% completed
complete = object()

def remove_completed(expression, completed):
    if isinstance(expression, str):
        if expression in completed:
            return complete
        else:
            return expression
    left, operator, right = expression
    left = remove_completed(left, completed)
    right = remove_completed(right, completed)
    if operator == "|":
        if left is complete or right is complete:
            return complete
        else:
            return [left, "|", right]
    elif operator == "&":
        if left is complete:
            return right
        elif right is complete:
            return left
        else:
            return [left, "&", right]

prereqList = [[["A", "|", "B"], "&", [["C", "&", "D"], "|", "E"]], "&", "F"]
result = remove_completed(prereqList, ["A", "C", "F"])
print(result)

Result:

['D', '|', 'E']

Upvotes: 1

Related Questions