@@ -10,39 +10,45 @@ def __init__(
10
10
self ,
11
11
message : str = "Expression resolver exception" ,
12
12
expression : Expression | None = None ,
13
+ parent : Exception | None = None ,
13
14
):
14
- super ().__init__ (f"{ message } (expression={ expression } )" )
15
+ super ().__init__ (f"{ message } (expression={ expression } , parent={ parent } )" )
16
+ self ._parent = parent
15
17
16
18
17
19
class ExpressionResolverNotResolvable (ExpressionResolverException ):
18
20
def __init__ (
19
21
self ,
20
22
message : str = "Expression is not resolvable" ,
21
23
expression : Expression | None = None ,
24
+ parent : Exception | None = None ,
22
25
):
23
- super ().__init__ (message , expression = expression )
26
+ super ().__init__ (message , expression = expression , parent = parent )
24
27
25
28
26
29
class ExpressionResolverMaybeNotResolvable (ExpressionResolverException ):
27
30
def __init__ (
28
31
self ,
29
32
message : str = "Expression is maybe not resolvable" ,
30
33
expression : Expression | None = None ,
34
+ parent : Exception | None = None ,
31
35
):
32
- super ().__init__ (message , expression = expression )
36
+ super ().__init__ (message , expression = expression , parent = parent )
33
37
34
38
35
39
class ExpressionResolver :
36
40
def __init__ (self , validator : ExpressionValidator , number_factory : NumberFactory ):
37
41
self ._validator = validator
38
42
self ._number_factory = number_factory
39
- pass
43
+ self . _maximum_resolve_time_sec = 0.1
40
44
41
- def _fly_back (self , expression : Expression ):
42
- self ._number_factory .fly_back (expression .operand1 )
43
- self ._number_factory .fly_back (expression .operand2 )
44
- self ._number_factory .fly_back (expression .result )
45
- pass
45
+ def _fly_back (self , base : Expression , result : Expression ):
46
+ if base .operand1 is None :
47
+ self ._number_factory .fly_back (result .operand1 )
48
+ if base .operand2 is None :
49
+ self ._number_factory .fly_back (result .operand2 )
50
+ if base .result is None :
51
+ self ._number_factory .fly_back (result .result )
46
52
47
53
def _fix_result (self , expression : Expression ):
48
54
expression .operand1 = self ._number_factory .fix (expression .operand1 )
@@ -60,7 +66,7 @@ def _next_operator(self, expression: Expression) -> list[Operator]:
60
66
def _resolve_result_is_none (self , expression : Expression ) -> Expression :
61
67
start = time .time ()
62
68
operators = self ._next_operator (expression )
63
- while True :
69
+ while time . time () - start < self . _maximum_resolve_time_sec :
64
70
exp_result = expression .clone ()
65
71
if exp_result .operator is None :
66
72
try :
@@ -75,15 +81,27 @@ def _resolve_result_is_none(self, expression: Expression) -> Expression:
75
81
exp_result .operand1 = self ._number_factory .next ()
76
82
if exp_result .operand2 is None :
77
83
if exp_result .operator == Operator .SUB :
78
- exp_result .operand2 = self ._number_factory .next (
79
- maximum = exp_result .operand1
80
- )
84
+ try :
85
+ exp_result .operand2 = self ._number_factory .next (
86
+ maximum = exp_result .operand1
87
+ )
88
+ except ValueError as e :
89
+ raise ExpressionResolverNotResolvable (
90
+ expression = expression , parent = e
91
+ )
81
92
elif exp_result .operator == Operator .DIV :
82
- exp_result .operand2 = self ._number_factory .next (
83
- maximum = exp_result .operand1 ,
84
- dividable_by = exp_result .operand1 ,
85
- zero_allowed = False ,
86
- )
93
+ try :
94
+ exp_result .operand2 = self ._number_factory .next (
95
+ maximum = exp_result .operand1 ,
96
+ dividable_by = exp_result .operand1 ,
97
+ zero_allowed = False ,
98
+ )
99
+ except ValueError as e :
100
+ if expression .operator is None :
101
+ continue
102
+ raise ExpressionResolverNotResolvable (
103
+ expression = expression , parent = e
104
+ )
87
105
else :
88
106
exp_result .operand2 = self ._number_factory .next ()
89
107
exp_result .result = self ._number_factory .fix (
@@ -95,15 +113,15 @@ def _resolve_result_is_none(self, expression: Expression) -> Expression:
95
113
self ._check_result (expression , exp_result )
96
114
if not self ._validator .validate (exp_result ):
97
115
# TODO time or count limit
98
- time_diff = time .time () - start
99
- if time_diff > 1.0 :
100
- raise ExpressionResolverMaybeNotResolvable (
101
- message = f"Too slow: { time_diff :.1f} s" , expression = expression
102
- )
103
116
continue
104
- self ._fly_back (exp_result )
117
+ self ._fly_back (expression , exp_result )
105
118
return exp_result
106
119
120
+ time_diff = time .time () - start
121
+ raise ExpressionResolverMaybeNotResolvable (
122
+ message = f"Too slow: { time_diff :.1f} s" , expression = expression
123
+ )
124
+
107
125
def _resolve_only_operator_missing (self , expression : Expression ) -> Expression :
108
126
if (
109
127
expression .operand1 is None
@@ -133,13 +151,13 @@ def _resolve_only_operator_missing(self, expression: Expression) -> Expression:
133
151
self ._check_result (expression , exp_result )
134
152
if not self ._validator .validate (exp_result ):
135
153
continue
136
- self ._fly_back (exp_result )
154
+ self ._fly_back (expression , exp_result )
137
155
return exp_result
138
156
raise ExpressionResolverNotResolvable (expression = expression )
139
157
140
158
def _resolve_result_is_available (self , expression : Expression ) -> Expression :
141
159
start = time .time ()
142
- while True :
160
+ while time . time () - start < self . _maximum_resolve_time_sec :
143
161
exp_calc = expression .clone ()
144
162
exp_result = expression .clone ()
145
163
exp_result .result = expression .result
@@ -174,11 +192,19 @@ def _resolve_result_is_available(self, expression: Expression) -> Expression:
174
192
# ? * b = c -> c / b = a
175
193
exp_calc .operator = Operator .DIV
176
194
if not_has_operands :
177
- exp_result .operand1 = exp_calc .operand1 = self ._number_factory .next (
178
- dividable_by = exp_result .result ,
179
- zero_allowed = False ,
180
- )
181
- print (exp_calc )
195
+ try :
196
+ exp_result .operand1 = exp_calc .operand1 = (
197
+ self ._number_factory .next (
198
+ dividable_by = exp_result .result ,
199
+ zero_allowed = False ,
200
+ )
201
+ )
202
+ except ValueError as e :
203
+ if expression .operator is None :
204
+ continue
205
+ raise ExpressionResolverNotResolvable (
206
+ expression = expression , parent = e
207
+ )
182
208
elif operator == Operator .DIV :
183
209
# a / b = c
184
210
if not_has_operands :
@@ -219,15 +245,15 @@ def _resolve_result_is_available(self, expression: Expression) -> Expression:
219
245
220
246
if not self ._validator .validate (exp_result ):
221
247
# TODO time or count limit
222
- time_diff = time .time () - start
223
- if time_diff > 1.0 :
224
- raise ExpressionResolverMaybeNotResolvable (
225
- message = f"Too slow: { time_diff :.1f} s" , expression = expression
226
- )
227
248
continue
228
- self ._fly_back (exp_result )
249
+ self ._fly_back (expression , exp_result )
229
250
return exp_result
230
251
252
+ time_diff = time .time () - start
253
+ raise ExpressionResolverMaybeNotResolvable (
254
+ message = f"Too slow: { time_diff :.1f} s" , expression = expression
255
+ )
256
+
231
257
def resolve (self , expression : Expression ) -> Expression | None :
232
258
start_time = time .time ()
233
259
try :
0 commit comments