alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" def unite_equation(operation_dict, opers): opers = opers[::-1] for i in range(len(opers)): if i == len(opers) - 1: for elemind in range(len(operation_dict[opers[i]][()])): operation_dict[opers[i]][()][elemind] = f"({operation_dict[opers[i]][()][elemind]})" eq = opers[i].join(operation_dict[opers[i]][()]) u_dict = operation_dict.pop(opers[i]) for key in u_dict.keys(): buff = u_dict[key] for elemind in range(len(buff)): buff[elemind] = f"({buff[elemind]})" for j in range(i + 1, len(opers)): if key[:-1] in operation_dict[opers[j]].keys(): operation_dict[opers[j]][key[:-1]][key[-1]] = opers[i].join(buff) return eq def make_brackets(eq): opers = [" == ", " <= ", " != ", " or ", " and "] ind = -1 buff = [] for i in range(len(opers)): if opers[i] in eq: buff.append(opers[i]) opers = buff del buff # A <= B == C == D != E <= F # [A <= B, C, D != E <= F] # {==: {(): [A <= B, C, D != E <= F]}, <=: {(0): [A, B], (2): [D != E, F]}, !=: {(2, 0)): D != E}} # B or C if opers: base_op = opers[0] parts = eq.split(base_op) f_p = False for p in parts: for op in opers: if op in p: f_p = True break if f_p: break if f_p: operation_dict = {base_op: {(): parts}} for i in range(1, len(opers)): if i - 1: prev_d = operation_dict[opers[i - 1]] new_d = {} for key in prev_d.keys(): for p_i in range(len(prev_d[key])): if opers[i] in prev_d[key][p_i]: new_d[key + (p_i, )] = prev_d[key][p_i].split(opers[i]) if new_d: operation_dict[opers[i]] = new_d else: break #end else: for p_i in range(len(parts)): if opers[i] in parts[p_i]: if opers[i] in operation_dict: operation_dict[opers[i]][(p_i, )] = parts[p_i].split(opers[i]) else: operation_dict[opers[i]] = {(p_i, ): parts[p_i].split(opers[i])} eq = unite_equation(operation_dict, opers) else: for i in range(len(parts)): parts[i] = f"({parts[i]})" eq = base_op.join(parts) return eq print(make_brackets("A or C ~ not (A -> B) or C".replace("->", "<=").replace("^", "!=").replace("~", "==")))