I need to convert a Tree with the following class structure:
Class Tree:
def __init__(self, data):
self.data = data
self.and_objects = []
self.or_objects = []
Where the data is:
Class Data:
def __init__(self, var, operator, value):
self.var = var
self.operator = operator
self.value = value
def to_json(self):
return {"var": self.var, "operator": self.operator, "value": self.value}
A simplified example of the data structure:
Root
andChildren
x = 0
andChildren
a = 1
b = 2
y = 10
andChildren
a = 3
orChildren
y = 3
andChildren
a = 2
orChildren
Empty
evaluates to:
((x == 0 and (a == 1 and b == 2)) and ((y == 10 and (a == 3)) or (y == 3 and a == 2))
I need to convert the tree data structure to:
{
"Search":{
"Root":{
"compare_operator":"and",
"values":[
{
"compare_operator":"and",
"values":[
{
"var":"x",
"operator":"=",
"value":"0"
},
{
"compare_operator":"and",
"values":[
{
"var":"a",
"operator":"=",
"value":"1"
},
{
"var":"b",
"operator":"=",
"value":"2"
}
]
}
]
},
{
"compare_operator":"or",
"values":[
{
"compare_operator":"and",
"values":[
{
"var":"y",
"operator":"=",
"value":"10"
},
{
"var":"a",
"operator":"=",
"value":"3"
}
]
},
{
"compare_operator":"and",
"values":[
{
"var":"y",
"operator":"=",
"value":"3"
},
{
"var":"a",
"operator":"=",
"value":"2"
}
]
}
]
}
]
}
}
}
Does anyone have any tips/methods on how to transform this tree data structure to this json structure?
I've tried a couple recursive algorithms, but I can not get them to yield the JSON output needed.
The script that recreates this structure:
Class Tree:
def __init__(self, data="root"):
self.data = data
self.and_objects = []
self.or_objects = []
Class Data:
def __init__(self, var, operator, value):
self.var = var
self.operator = operator
self.value = value
def to_json(self):
return {"var": self.var, "operator": self.operator, "value": self.value}
def create_search(var, operator, value, parent, comparision="and")
data = Data(var, operator, value)
child = Tree(data)
if comparision == "and":
parent.and_objects.append(child)
else:
parent.or_objects.append(child)
return child
if __name__ == "__main__":
root_tree = Tree()
x_temp = create_search("x", "=", "0", root_tree)
create_search("a", "=", "1", x_temp)
create_search("b", "=", "2", x_temp)
y_temp = create_search("y", "=", "10", root_tree)
create_search("a", "=", "3", root_tree, y_temp)
nested_y_temp = create_search("y", "=", "3", root_tree, y_temp, "or")
create_search("a", "=", "2", root_tree, nested_y_temp)
# tree data is on root_tree
CodePudding user response:
I would go for a different initial structure. In your structure an AND or OR operator needs to have a Data instance as parent. And a Data instance is combined with both and AND and OR list that depends on it.
I would suggest to allow for a top-level AND or OR operator that has all its operands as children. You could also create separate classes for AND and OR operators, and for EQUALITY operator as well.
Here is how that would look:
class Logical():
def __init__(self, operator, operands):
self.operands = operands
self.operator = operator
def __str__(self):
return f" {self.operator} ".join(map(str, self))
def asdict(self):
return {
"compare_operator": self.operator,
"values": [operand.asdict() for operand in self.operands]
}
class And(Logical):
def __init__(self, *operands):
super().__init__("and", operands)
class Or(Logical):
def __init__(self, *operands):
super().__init__("or", operands)
class Condition:
def __init__(self, var, operator, value):
self.var = var
self.operator = operator
self.value = value
def asdict(self):
return {
"var": self.var,
"operator": self.operator,
"value": self.value
}
class Equal(Condition):
def __init__(self, var, value):
super().__init__(var, "=", value)
Example creation of a structure:
expression = And(
And(
Equal("x", 0),
And(
Equal("a", 1),
Equal("b", 2),
),
),
Or(
And(
Equal("y", 10),
Equal("a", 3)
),
And(
Equal("y", 3),
Equal("a", 2)
)
)
)
Turning it to JSON:
import json
result = {
"Search": {
"Root": expression.asdict()
}
}
print(json.dumps(result, indent=4))
This prints:
{
"Search": {
"Root": {
"compare_operator": "and",
"values": [
{
"compare_operator": "and",
"values": [
{
"var": "x",
"operator": "=",
"value": 0
},
{
"compare_operator": "and",
"values": [
{
"var": "a",
"operator": "=",
"value": 1
},
{
"var": "b",
"operator": "=",
"value": 2
}
]
}
]
},
{
"compare_operator": "or",
"values": [
{
"compare_operator": "and",
"values": [
{
"var": "y",
"operator": "=",
"value": 10
},
{
"var": "a",
"operator": "=",
"value": 3
}
]
},
{
"compare_operator": "and",
"values": [
{
"var": "y",
"operator": "=",
"value": 3
},
{
"var": "a",
"operator": "=",
"value": 2
}
]
}
]
}
]
}
}
}