- A Solver for Solving any Logical Expressions, shortly Reverse calculations of logical expressions for Analysis.
- Check out the example code in repo ( https://github.com/Palani-SN/LogExAn ) for reference
- Generate an Output of type Dict/Json from any Logical expression for direct solutions.
- Generate an Output of type Dataframe/MarkDown from any Logical expression for elaborate solutions
- Sample usage of the file is as given below (Refer Examples in the repo for detailed Usage)
from LogExAn.LogicalAnalyser import LogAn
Cond = "( ( Var_new_1 == 1 ) && ( ( Var_new_4 == 7 ) || ( Var_new_9 == 12 ) ) )";
LA = LogAn(Cond);
# Default Argument 'DICT' returns dict
asDict = LA.solution();
print('type :', type(asDict), end = '\n\n');
print(asDict, end = '\n\n');
# Argument 'JSON' returns json formatted string (from the Dict)
asJson = LA.solution('JSON');
print('type :', type(asJson), end = '\n\n');
print(asJson, end = '\n\n');
# Default Argument 'DATAFRAME' returns dataframe
asDataframe = LA.elaborate_solution();
print('type :', type(asDataframe), end = '\n\n');
print(asDataframe, end = '\n\n');
# Argument 'MARKDOWN' returns markdown formatted string (from the Dataframe)
asMarkdown = LA.elaborate_solution('MARKDOWN');
print('type :', type(asMarkdown), end = '\n\n');
print(asMarkdown, end = '\n\n');
- The Output of the above code looks as follows
type : <class 'dict'>
{'True': {'Var_new_1': [1], 'Var_new_4': [7], 'Var_new_9': [12]}, 'False': {'Var_new_1': [-4, -3, -2, -1, 0, 2, 3, 4, 5, 6], 'Var_new_4': [2, 3, 4, 5, 6, 8, 9, 10, 11, 12], 'Var_new_9': [7, 8, 9, 10, 11, 13, 14, 15, 16, 17]}}
type : <class 'str'>
{
"False": {
"Var_new_1": [
-4,
-3,
-2,
-1,
0,
2,
3,
4,
5,
6
],
"Var_new_4": [
2,
3,
4,
5,
6,
8,
9,
10,
11,
12
],
"Var_new_9": [
7,
8,
9,
10,
11,
13,
14,
15,
16,
17
]
},
"True": {
"Var_new_1": [
1
],
"Var_new_4": [
7
],
"Var_new_9": [
12
]
}
}
type : <class 'pandas.core.frame.DataFrame'>
Condition True False
0 Var_new_1 == 1 and Var_new_4 == 7 {'Var_new_1': [(1, 2)], 'Var_new_4': [(7, 8)]} {'Var_new_1': [(-4, 1), (2, 7)], 'Var_new_4': ...
1 Var_new_1 == 1 and Var_new_9 == 12 {'Var_new_1': [(1, 2)], 'Var_new_9': [(12, 13)]} {'Var_new_1': [(-4, 1), (2, 7)], 'Var_new_9': ...
type : <class 'str'>
| | Condition | True | False |
|---:|:-----------------------------------|:-------------------------------------------------|:-------------------------------------------------------------------|
| 0 | Var_new_1 == 1 and Var_new_4 == 7 | {'Var_new_1': [(1, 2)], 'Var_new_4': [(7, 8)]} | {'Var_new_1': [(-4, 1), (2, 7)], 'Var_new_4': [(2, 7), (8, 13)]} |
| 1 | Var_new_1 == 1 and Var_new_9 == 12 | {'Var_new_1': [(1, 2)], 'Var_new_9': [(12, 13)]} | {'Var_new_1': [(-4, 1), (2, 7)], 'Var_new_9': [(7, 12), (13, 18)]} |
- Gets the format to return the direct result of the analysis.(of type dict/json string)
## Definition
def solution(self, format = 'DICT'):
- Arguments
- Arg 1 - format (format of the return value)
- 'DICT' - default argument/returns output as type : <class 'dict'>
- 'JSON' - returns output as type : <class 'str'> (json formatted string of dictionary)
- Arg 1 - format (format of the return value)
- Returns
- Results
- the result as a dictionary ( if format == 'DICT' )
- the result as a json formatted string ( if format == 'JSON' )
- Results
- A dictionary with 'True' and 'False' as keys and the corresponding inputs as values
from LogExAn.LogicalAnalyser import LogAn
# entire condition to be enclosed in a bracket
Cond = " ( ( low_bnd > 2 && low_bnd < 7 ) || ( up_bnd > 15 && up_bnd < 21 ) ) ";
LA = LogAn(Cond);
# Accessing only values for the condition to pass (expected result : True)
values_for_true = LA.solution()['True'];
print(values_for_true, end = '\n\n')
# Access the results as a normal dictionary
for var, val in values_for_true.items():
print(var, val);
print(end = '\n')
# Accessing only values for the condition to fail (expected result : False)
values_for_false = LA.solution()['False'];
print(values_for_false, end = '\n\n')
# Access the results as a normal dictionary
for var, val in values_for_false.items():
print(var, val);
- The Output of the above code looks as follows
{'low_bnd': [3, 4, 5, 6], 'up_bnd': [16, 17, 18, 19, 20]}
low_bnd [3, 4, 5, 6]
up_bnd [16, 17, 18, 19, 20]
{'low_bnd': [-3, -2, -1, 0, 1, 2, 7, 8, 9, 10, 11, 12], 'up_bnd': [10, 11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 26]}
low_bnd [-3, -2, -1, 0, 1, 2, 7, 8, 9, 10, 11, 12]
up_bnd [10, 11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 26]
- Gets the format to return the elaborate result of the analysis.(of type dataframe/markdown string)
## Definition
def elaborate_solution(self, format = 'DATAFRAME'):
- Arguments
- Arg 1 - format (format of the return value)
- 'DATAFRAME' - default argument/returns output as type : <class 'pandas.core.frame.DataFrame'>
- 'MARKDOWN' - returns output as type : <class 'str'> (markdown formatted string of dataframe)
- Arg 1 - format (format of the return value)
- Returns
- Results
- the result as a dataframe ( if format == 'DATAFRAME' )
- the result as a markdown formatted string ( if format == 'MARKDOWN' )
- Results
- A dataframe with 'True' and 'False' as columns and the corresponding inputs as cells.
- For detailed usage of dataframe refer pandas documentation here 👇
( https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html ).
from LogExAn.LogicalAnalyser import LogAn
import ast
Cond = " ( ( low_bnd >= 2 || up_bnd == 3 ) && ( low_bnd == 4 || up_bnd <= 5 ) ) "
LA = LogAn(Cond);
# Accesing direct result
possible_values = LA.solution();
print(possible_values, end = '\n\n')
# Accesing result with explanation
asMarkdown = LA.elaborate_solution('MARKDOWN');
print(asMarkdown, end = '\n\n')
# Accessing elaborate results as elements of dataframe
asDf = LA.elaborate_solution();
# Accessing elements of dataframe
for idx, row in asDf.iterrows():
print('-> index : ', idx)
print(f'-> Condition {idx+1} : ', row['Condition'])
print('-> True : ', row['True'])
true_results_dict = ast.literal_eval(row['True'])
# Access the results as a normal dictionary
for var, val in true_results_dict.items():
print('---> variable : ', var);
# Expanding values from list of tuples
Expanded_Range = []
for tup in val:
Expanded_Range += [*range(tup[0],tup[1])];
print('---> values : ', Expanded_Range)
print('-> False : ', row['False'])
false_results_dict = ast.literal_eval(row['False'])
# Access the results as a normal dictionary
for var, val in false_results_dict.items():
print('---> variable : ', var);
# Expanding values from list of tuples
Expanded_Range = []
for tup in val:
Expanded_Range += [*range(tup[0],tup[1])];
print('---> values : ', Expanded_Range)
print();
- The Output of the above code looks as follows
{'True': {'low_bnd': [2, 3, 4, 5, 6, 7], 'up_bnd': [0, 1, 2, 3, 4, 5]}, 'False': {'low_bnd': [-1, 0, 1], 'up_bnd': [6, 7, 8]}}
| | Condition | True | False |
|---:|:------------------------------|:------------------------------------------|:-------------------------------------------------------------|
| 0 | low_bnd >= 2 and low_bnd == 4 | {'low_bnd': [(4, 5)]} | {'low_bnd': [(-3, 4), (5, 10)]} |
| 1 | low_bnd >= 2 and up_bnd <= 5 | {'low_bnd': [(2, 8)], 'up_bnd': [(0, 6)]} | {'low_bnd': [(-3, 2)], 'up_bnd': [(6, 11)]} |
| 2 | up_bnd == 3 and low_bnd == 4 | {'up_bnd': [(3, 4)], 'low_bnd': [(4, 5)]} | {'up_bnd': [(-2, 3), (4, 9)], 'low_bnd': [(-1, 4), (5, 10)]} |
| 3 | up_bnd == 3 and up_bnd <= 5 | {'up_bnd': [(3, 4)]} | {'up_bnd': [(-2, 3), (4, 11)]} |
-> index : 0
-> Condition 1 : low_bnd >= 2 and low_bnd == 4
-> True : {'low_bnd': [(4, 5)]}
---> variable : low_bnd
---> values : [4]
-> False : {'low_bnd': [(-3, 4), (5, 10)]}
---> variable : low_bnd
---> values : [-3, -2, -1, 0, 1, 2, 3, 5, 6, 7, 8, 9]
-> index : 1
-> Condition 2 : low_bnd >= 2 and up_bnd <= 5
-> True : {'low_bnd': [(2, 8)], 'up_bnd': [(0, 6)]}
---> variable : low_bnd
---> values : [2, 3, 4, 5, 6, 7]
---> variable : up_bnd
---> values : [0, 1, 2, 3, 4, 5]
-> False : {'low_bnd': [(-3, 2)], 'up_bnd': [(6, 11)]}
---> variable : low_bnd
---> values : [-3, -2, -1, 0, 1]
---> variable : up_bnd
---> values : [6, 7, 8, 9, 10]
-> index : 2
-> Condition 3 : up_bnd == 3 and low_bnd == 4
-> True : {'up_bnd': [(3, 4)], 'low_bnd': [(4, 5)]}
---> variable : up_bnd
---> values : [3]
---> variable : low_bnd
---> values : [4]
-> False : {'up_bnd': [(-2, 3), (4, 9)], 'low_bnd': [(-1, 4), (5, 10)]}
---> variable : up_bnd
---> values : [-2, -1, 0, 1, 2, 4, 5, 6, 7, 8]
---> variable : low_bnd
---> values : [-1, 0, 1, 2, 3, 5, 6, 7, 8, 9]
-> index : 3
-> Condition 4 : up_bnd == 3 and up_bnd <= 5
-> True : {'up_bnd': [(3, 4)]}
---> variable : up_bnd
---> values : [3]
-> False : {'up_bnd': [(-2, 3), (4, 11)]}
---> variable : up_bnd
---> values : [-2, -1, 0, 1, 2, 4, 5, 6, 7, 8, 9, 10]