how to use python to split a logical statement and verify it one by one?

58 Views Asked by At

For example, there is a given string

( a > b or a > c) and a < d

in python. I want to at first extract expression and logical operator from this statement, then check it one by one, such as

if a > b then check a < d, else check a > c then check a < d

I don‘t know how to extract it in the logical order. Thanks a lot for help.

1

There are 1 best solutions below

0
refik On

You can use Abstract Syntax Trees module to do this. It allows you to parse Python codes and work with its abstract syntax tree.

import ast

def evaluateComparison(node):
    left_operand = ast.literal_eval(node.left)
    right_operand = ast.literal_eval(node.comparators[0])
    comparison_operator = type(node.ops[0]).__name__

    if comparison_operator == 'Lt':
        return left_operand < right_operand
    elif comparison_operator == 'Gt':
        return left_operand > right_operand
    elif comparison_operator == 'LtE':
        return left_operand <= right_operand
    elif comparison_operator == 'GtE':
        return left_operand >= right_operand
    elif comparison_operator == 'Eq':
        return left_operand == right_operand
    elif comparison_operator == 'NotEq':
        return left_operand != right_operand
    else:
        raise ValueError(f"Unsupported comparison operator: {comparison_operator}")

def getOperatorSymbol(operator_name):
    operator_mapping = {
        'Lt': '<',
        'Gt': '>',
        'LtE': '<=',
        'GtE': '>=',
        'Eq': '==',
        'NotEq': '!='
    }
    return operator_mapping.get(operator_name, operator_name)

def processNode(node, indent=''):
    if isinstance(node, ast.BoolOp):
        # Logical operator (and/or)
        operator = type(node.op).__name__
        left_result = processNode(node.values[0], indent)
        right_result = processNode(node.values[1], '')
        return f"{left_result} {operator} {right_result}"

    elif isinstance(node, ast.Compare):
        # Comparison operator (<, >, <=, >=, ==, !=)
        result = evaluateComparison(node)
        left_operand = ast.unparse(node.left).strip()
        comparison_operator = getOperatorSymbol(type(node.ops[0]).__name__)
        right_operand = ast.unparse(node.comparators[0]).strip()
        return f"{indent}{left_operand} {comparison_operator} {right_operand} (Result: {result})"

Output for this code is:

# Example
logical_statement = "(3 > 2 or 3 > 4) and 3 < 5"
result = processNode(ast.parse(logical_statement, mode='eval').body)
print(f"The result is:\n{result}")

#Output
The result is:
3 > 2 (Result: True) Or 3 > 4 (Result: False) And 3 < 5 (Result: True)