vtlengine 1.0__py3-none-any.whl → 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of vtlengine might be problematic. Click here for more details.
- vtlengine/API/_InternalApi.py +153 -100
- vtlengine/API/__init__.py +109 -67
- vtlengine/AST/ASTConstructor.py +188 -98
- vtlengine/AST/ASTConstructorModules/Expr.py +306 -200
- vtlengine/AST/ASTConstructorModules/ExprComponents.py +172 -102
- vtlengine/AST/ASTConstructorModules/Terminals.py +158 -95
- vtlengine/AST/ASTEncoders.py +1 -1
- vtlengine/AST/ASTTemplate.py +8 -9
- vtlengine/AST/ASTVisitor.py +8 -12
- vtlengine/AST/DAG/__init__.py +43 -35
- vtlengine/AST/DAG/_words.py +4 -4
- vtlengine/AST/Grammar/lexer.py +732 -142
- vtlengine/AST/Grammar/parser.py +2188 -826
- vtlengine/AST/Grammar/tokens.py +128 -128
- vtlengine/AST/VtlVisitor.py +7 -4
- vtlengine/AST/__init__.py +22 -11
- vtlengine/DataTypes/NumericTypesHandling.py +5 -4
- vtlengine/DataTypes/TimeHandling.py +194 -301
- vtlengine/DataTypes/__init__.py +304 -218
- vtlengine/Exceptions/__init__.py +52 -27
- vtlengine/Exceptions/messages.py +134 -62
- vtlengine/Interpreter/__init__.py +781 -487
- vtlengine/Model/__init__.py +165 -121
- vtlengine/Operators/Aggregation.py +156 -95
- vtlengine/Operators/Analytic.py +115 -59
- vtlengine/Operators/Assignment.py +7 -4
- vtlengine/Operators/Boolean.py +27 -32
- vtlengine/Operators/CastOperator.py +177 -131
- vtlengine/Operators/Clause.py +137 -99
- vtlengine/Operators/Comparison.py +148 -117
- vtlengine/Operators/Conditional.py +149 -98
- vtlengine/Operators/General.py +68 -47
- vtlengine/Operators/HROperators.py +91 -72
- vtlengine/Operators/Join.py +217 -118
- vtlengine/Operators/Numeric.py +89 -44
- vtlengine/Operators/RoleSetter.py +16 -15
- vtlengine/Operators/Set.py +61 -36
- vtlengine/Operators/String.py +213 -139
- vtlengine/Operators/Time.py +334 -216
- vtlengine/Operators/Validation.py +117 -76
- vtlengine/Operators/__init__.py +340 -213
- vtlengine/Utils/__init__.py +195 -40
- vtlengine/__init__.py +1 -1
- vtlengine/files/output/__init__.py +15 -6
- vtlengine/files/output/_time_period_representation.py +10 -9
- vtlengine/files/parser/__init__.py +77 -52
- vtlengine/files/parser/_rfc_dialect.py +6 -5
- vtlengine/files/parser/_time_checking.py +46 -37
- vtlengine-1.0.1.dist-info/METADATA +236 -0
- vtlengine-1.0.1.dist-info/RECORD +58 -0
- {vtlengine-1.0.dist-info → vtlengine-1.0.1.dist-info}/WHEEL +1 -1
- vtlengine-1.0.dist-info/METADATA +0 -104
- vtlengine-1.0.dist-info/RECORD +0 -58
- {vtlengine-1.0.dist-info → vtlengine-1.0.1.dist-info}/LICENSE.md +0 -0
vtlengine/Operators/String.py
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import operator
|
|
2
|
-
import os
|
|
3
2
|
import re
|
|
4
|
-
|
|
5
3
|
from vtlengine.Exceptions import SemanticError
|
|
6
4
|
from vtlengine.Model import DataComponent, Dataset, Scalar
|
|
7
5
|
|
|
8
|
-
if os.environ.get("SPARK", False):
|
|
9
|
-
|
|
10
|
-
else:
|
|
11
|
-
|
|
6
|
+
# if os.environ.get("SPARK", False):
|
|
7
|
+
# import pyspark.pandas as pd
|
|
8
|
+
# else:
|
|
9
|
+
# import pandas as pd
|
|
10
|
+
import pandas as pd
|
|
12
11
|
|
|
13
12
|
from typing import Optional, Any, Union
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
from vtlengine.AST.Grammar.tokens import (
|
|
14
|
+
LEN,
|
|
15
|
+
CONCAT,
|
|
16
|
+
UCASE,
|
|
17
|
+
LCASE,
|
|
18
|
+
RTRIM,
|
|
19
|
+
SUBSTR,
|
|
20
|
+
LTRIM,
|
|
21
|
+
TRIM,
|
|
22
|
+
REPLACE,
|
|
23
|
+
INSTR,
|
|
24
|
+
)
|
|
25
|
+
from vtlengine.DataTypes import Integer, String, check_unary_implicit_promotion
|
|
18
26
|
import vtlengine.Operators as Operator
|
|
19
27
|
|
|
20
28
|
|
|
@@ -23,13 +31,14 @@ class Unary(Operator.Unary):
|
|
|
23
31
|
|
|
24
32
|
@classmethod
|
|
25
33
|
def op_func(cls, x: Any) -> Any:
|
|
34
|
+
|
|
26
35
|
x = "" if pd.isnull(x) else str(x)
|
|
27
36
|
return cls.py_op(x)
|
|
28
37
|
|
|
29
38
|
@classmethod
|
|
30
39
|
def apply_operation_component(cls, series: Any) -> Any:
|
|
31
40
|
"""Applies the operation to a component"""
|
|
32
|
-
return series.map(lambda x: cls.py_op(str(x)), na_action=
|
|
41
|
+
return series.map(lambda x: cls.py_op(str(x)), na_action="ignore")
|
|
33
42
|
|
|
34
43
|
@classmethod
|
|
35
44
|
def validate_dataset(cls, dataset: Dataset) -> None:
|
|
@@ -38,7 +47,7 @@ class Unary(Operator.Unary):
|
|
|
38
47
|
"""
|
|
39
48
|
measures = dataset.get_measures()
|
|
40
49
|
|
|
41
|
-
if
|
|
50
|
+
if len(measures) != 1:
|
|
42
51
|
raise SemanticError("1-1-18-1", op=cls.op, name=dataset.name)
|
|
43
52
|
|
|
44
53
|
|
|
@@ -109,40 +118,54 @@ class Concatenate(Binary):
|
|
|
109
118
|
class Parameterized(Unary):
|
|
110
119
|
|
|
111
120
|
@classmethod
|
|
112
|
-
def validate(cls,
|
|
113
|
-
|
|
121
|
+
def validate(cls, *args: Any) -> Any:
|
|
122
|
+
operand: Operator.ALL_MODEL_DATA_TYPES
|
|
123
|
+
param1: Optional[Scalar]
|
|
124
|
+
param2: Optional[Scalar]
|
|
125
|
+
operand, param1, param2 = (args + (None, None))[:3]
|
|
114
126
|
|
|
115
127
|
if param1 is not None:
|
|
116
128
|
cls.check_param(param1, 1)
|
|
117
129
|
if param2 is not None:
|
|
118
130
|
cls.check_param(param2, 2)
|
|
119
|
-
|
|
120
131
|
return super().validate(operand)
|
|
121
132
|
|
|
122
133
|
@classmethod
|
|
123
|
-
def op_func(cls,
|
|
124
|
-
|
|
134
|
+
def op_func(cls, *args: Any) -> Any:
|
|
135
|
+
x: Optional[Any]
|
|
136
|
+
param1: Optional[Any]
|
|
137
|
+
param2: Optional[Any]
|
|
138
|
+
x, param1, param2 = (args + (None, None))[:3]
|
|
139
|
+
|
|
125
140
|
x = "" if pd.isnull(x) else x
|
|
126
141
|
return cls.py_op(x, param1, param2)
|
|
127
142
|
|
|
128
143
|
@classmethod
|
|
129
|
-
def apply_operation_two_series(cls,
|
|
144
|
+
def apply_operation_two_series(cls, *args: Any) -> Any:
|
|
145
|
+
left_series, right_series = args
|
|
146
|
+
|
|
130
147
|
return left_series.combine(right_series, cls.op_func)
|
|
131
148
|
|
|
132
149
|
@classmethod
|
|
133
|
-
def apply_operation_series_scalar(cls,
|
|
150
|
+
def apply_operation_series_scalar(cls, *args: Any) -> Any:
|
|
151
|
+
series, param1, param2 = args
|
|
152
|
+
|
|
134
153
|
return series.map(lambda x: cls.op_func(x, param1, param2))
|
|
135
154
|
|
|
136
155
|
@classmethod
|
|
137
|
-
def dataset_evaluation(cls,
|
|
138
|
-
|
|
139
|
-
|
|
156
|
+
def dataset_evaluation(cls, *args: Any) -> Dataset:
|
|
157
|
+
operand: Dataset
|
|
158
|
+
param1: Optional[Union[DataComponent, Scalar]]
|
|
159
|
+
param2: Optional[Union[DataComponent, Scalar]]
|
|
160
|
+
operand, param1, param2 = (args + (None, None))[:3]
|
|
161
|
+
|
|
140
162
|
result = cls.validate(operand, param1, param2)
|
|
141
|
-
result.data = operand.data.copy()
|
|
163
|
+
result.data = operand.data.copy() if operand.data is not None else pd.DataFrame()
|
|
142
164
|
for measure_name in operand.get_measures_names():
|
|
143
165
|
if isinstance(param1, DataComponent) or isinstance(param2, DataComponent):
|
|
144
|
-
result.data[measure_name] = cls.apply_operation_series(
|
|
145
|
-
|
|
166
|
+
result.data[measure_name] = cls.apply_operation_series(
|
|
167
|
+
result.data[measure_name], param1, param2
|
|
168
|
+
)
|
|
146
169
|
else:
|
|
147
170
|
param_value1 = None if param1 is None else param1.value
|
|
148
171
|
param_value2 = None if param2 is None else param2.value
|
|
@@ -152,29 +175,35 @@ class Parameterized(Unary):
|
|
|
152
175
|
|
|
153
176
|
cols_to_keep = operand.get_identifiers_names() + operand.get_measures_names()
|
|
154
177
|
result.data = result.data[cols_to_keep]
|
|
155
|
-
|
|
156
178
|
cls.modify_measure_column(result)
|
|
157
179
|
return result
|
|
158
180
|
|
|
159
181
|
@classmethod
|
|
160
|
-
def component_evaluation(cls,
|
|
161
|
-
|
|
162
|
-
|
|
182
|
+
def component_evaluation(cls, *args: Any) -> DataComponent:
|
|
183
|
+
operand: DataComponent
|
|
184
|
+
param1: Optional[Union[DataComponent, Scalar]]
|
|
185
|
+
param2: Optional[Union[DataComponent, Scalar]]
|
|
186
|
+
operand, param1, param2 = (args + (None, None))[:3]
|
|
187
|
+
|
|
163
188
|
result = cls.validate(operand, param1, param2)
|
|
164
|
-
result.data = operand.data.copy()
|
|
189
|
+
result.data = operand.data.copy() if operand.data is not None else pd.Series()
|
|
165
190
|
if isinstance(param1, DataComponent) or isinstance(param2, DataComponent):
|
|
166
191
|
result.data = cls.apply_operation_series(result.data, param1, param2)
|
|
167
192
|
else:
|
|
168
193
|
param_value1 = None if param1 is None else param1.value
|
|
169
194
|
param_value2 = None if param2 is None else param2.value
|
|
170
|
-
result.data = cls.apply_operation_series_scalar(
|
|
171
|
-
|
|
195
|
+
result.data = cls.apply_operation_series_scalar(
|
|
196
|
+
operand.data, param_value1, param_value2
|
|
197
|
+
)
|
|
172
198
|
return result
|
|
173
199
|
|
|
174
200
|
@classmethod
|
|
175
|
-
def scalar_evaluation(cls,
|
|
176
|
-
|
|
177
|
-
|
|
201
|
+
def scalar_evaluation(cls, *args: Any) -> Scalar:
|
|
202
|
+
operand: Scalar
|
|
203
|
+
param1: Optional[Scalar]
|
|
204
|
+
param2: Optional[Scalar]
|
|
205
|
+
operand, param1, param2 = (args + (None, None))[:3]
|
|
206
|
+
|
|
178
207
|
result = cls.validate(operand, param1, param2)
|
|
179
208
|
param_value1 = None if param1 is None else param1.value
|
|
180
209
|
param_value2 = None if param2 is None else param2.value
|
|
@@ -182,27 +211,34 @@ class Parameterized(Unary):
|
|
|
182
211
|
return result
|
|
183
212
|
|
|
184
213
|
@classmethod
|
|
185
|
-
def evaluate(cls,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
214
|
+
def evaluate(cls, *args: Any) -> Union[Dataset, DataComponent, Scalar]:
|
|
215
|
+
param1: Optional[Union[DataComponent, Scalar]]
|
|
216
|
+
param2: Optional[Union[DataComponent, Scalar]]
|
|
217
|
+
operand, param1, param2 = (args + (None, None))[:3]
|
|
218
|
+
|
|
189
219
|
if isinstance(operand, Dataset):
|
|
190
220
|
return cls.dataset_evaluation(operand, param1, param2)
|
|
191
221
|
if isinstance(operand, DataComponent):
|
|
192
222
|
return cls.component_evaluation(operand, param1, param2)
|
|
193
|
-
|
|
194
|
-
return cls.scalar_evaluation(operand, param1, param2)
|
|
223
|
+
return cls.scalar_evaluation(operand, param1, param2)
|
|
195
224
|
|
|
196
225
|
@classmethod
|
|
197
|
-
def check_param(cls,
|
|
226
|
+
def check_param(cls, *args: Any) -> None:
|
|
198
227
|
raise Exception("Method should be implemented by inheritors")
|
|
199
228
|
|
|
200
229
|
@classmethod
|
|
201
|
-
def check_param_value(cls,
|
|
230
|
+
def check_param_value(cls, *args: Any) -> None:
|
|
202
231
|
raise Exception("Method should be implemented by inheritors")
|
|
203
232
|
|
|
204
233
|
@classmethod
|
|
205
|
-
def generate_series_from_param(cls,
|
|
234
|
+
def generate_series_from_param(cls, *args: Any) -> Any:
|
|
235
|
+
param: Optional[Union[DataComponent, Scalar]] = None
|
|
236
|
+
length: int
|
|
237
|
+
if len(args) == 2:
|
|
238
|
+
param, length = args
|
|
239
|
+
else:
|
|
240
|
+
length = args[0]
|
|
241
|
+
|
|
206
242
|
if param is None:
|
|
207
243
|
return pd.Series(index=range(length), dtype=object)
|
|
208
244
|
if isinstance(param, Scalar):
|
|
@@ -210,18 +246,14 @@ class Parameterized(Unary):
|
|
|
210
246
|
return param.data
|
|
211
247
|
|
|
212
248
|
@classmethod
|
|
213
|
-
def apply_operation_series(cls,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
249
|
+
def apply_operation_series(cls, *args: Any) -> Any:
|
|
250
|
+
param1: Optional[Union[DataComponent, Scalar]]
|
|
251
|
+
param2: Optional[Union[DataComponent, Scalar]]
|
|
252
|
+
data, param1, param2 = (args + (None, None))[:3]
|
|
253
|
+
|
|
217
254
|
param1_data = cls.generate_series_from_param(param1, len(data))
|
|
218
255
|
param2_data = cls.generate_series_from_param(param2, len(data))
|
|
219
|
-
|
|
220
|
-
df = pd.DataFrame([
|
|
221
|
-
data,
|
|
222
|
-
param1_data,
|
|
223
|
-
param2_data
|
|
224
|
-
]).T
|
|
256
|
+
df = pd.DataFrame([data, param1_data, param2_data]).T
|
|
225
257
|
n1, n2, n3 = df.columns
|
|
226
258
|
return df.apply(lambda x: cls.op_func(x[n1], x[n2], x[n3]), axis=1)
|
|
227
259
|
|
|
@@ -231,12 +263,12 @@ class Substr(Parameterized):
|
|
|
231
263
|
return_type = String
|
|
232
264
|
|
|
233
265
|
@classmethod
|
|
234
|
-
def validate_params(cls, params:
|
|
266
|
+
def validate_params(cls, params: Any) -> None:
|
|
235
267
|
if len(params) != 2:
|
|
236
268
|
raise SemanticError("1-1-18-7", op=cls.op, number=len(params), expected=2)
|
|
237
269
|
|
|
238
270
|
@classmethod
|
|
239
|
-
def py_op(cls, x: str, param1:
|
|
271
|
+
def py_op(cls, x: str, param1: Any, param2: Any) -> Any:
|
|
240
272
|
x = str(x)
|
|
241
273
|
param1 = None if pd.isnull(param1) else int(param1)
|
|
242
274
|
param2 = None if pd.isnull(param2) else int(param2)
|
|
@@ -251,16 +283,16 @@ class Substr(Parameterized):
|
|
|
251
283
|
if param2 is None or (param1 + param2) > len(x):
|
|
252
284
|
param2 = len(x)
|
|
253
285
|
else:
|
|
254
|
-
param2 =
|
|
286
|
+
param2 = param1 + param2
|
|
255
287
|
return x[param1:param2]
|
|
256
288
|
|
|
257
289
|
@classmethod
|
|
258
|
-
def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int):
|
|
290
|
+
def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int) -> None:
|
|
259
291
|
if not param:
|
|
260
292
|
return
|
|
261
293
|
if position not in (1, 2):
|
|
262
294
|
raise SemanticError("1-1-18-3", op=cls.op, pos=position)
|
|
263
|
-
data_type:
|
|
295
|
+
data_type: Any = param.data_type
|
|
264
296
|
|
|
265
297
|
if not check_unary_implicit_promotion(data_type, Integer):
|
|
266
298
|
raise SemanticError("1-1-18-4", op=cls.op, param_type=cls.op, correct_type="Integer")
|
|
@@ -272,11 +304,12 @@ class Substr(Parameterized):
|
|
|
272
304
|
cls.check_param_value(param.value, position)
|
|
273
305
|
|
|
274
306
|
@classmethod
|
|
275
|
-
def check_param_value(cls, param: Optional[
|
|
276
|
-
if
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
307
|
+
def check_param_value(cls, param: Optional[Any], position: int) -> None:
|
|
308
|
+
if param is not None:
|
|
309
|
+
if not pd.isnull(param) and not param >= 1 and position == 1:
|
|
310
|
+
raise SemanticError("1-1-18-4", op=cls.op, param_type="Start", correct_type=">= 1")
|
|
311
|
+
elif not pd.isnull(param) and not param >= 0 and position == 2:
|
|
312
|
+
raise SemanticError("1-1-18-4", op=cls.op, param_type="Length", correct_type=">= 0")
|
|
280
313
|
|
|
281
314
|
|
|
282
315
|
class Replace(Parameterized):
|
|
@@ -288,23 +321,25 @@ class Replace(Parameterized):
|
|
|
288
321
|
if pd.isnull(param1):
|
|
289
322
|
return ""
|
|
290
323
|
elif pd.isnull(param2):
|
|
291
|
-
param2 =
|
|
324
|
+
param2 = ""
|
|
292
325
|
x = str(x)
|
|
293
|
-
|
|
326
|
+
if param1 is not None and param2 is not None:
|
|
327
|
+
return x.replace(param1, param2)
|
|
328
|
+
return x
|
|
294
329
|
|
|
295
330
|
@classmethod
|
|
296
|
-
def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int):
|
|
331
|
+
def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int) -> None:
|
|
297
332
|
if not param:
|
|
298
333
|
return
|
|
299
334
|
if position not in (1, 2):
|
|
300
335
|
raise SemanticError("1-1-18-3", op=cls.op, pos=position)
|
|
301
|
-
data_type:
|
|
336
|
+
data_type: Any = param.data_type
|
|
302
337
|
|
|
303
338
|
if not check_unary_implicit_promotion(data_type, String):
|
|
304
339
|
raise SemanticError("1-1-18-4", op=cls.op, param_type=cls.op, correct_type="String")
|
|
305
340
|
|
|
306
341
|
@classmethod
|
|
307
|
-
def validate_params(cls, params:
|
|
342
|
+
def validate_params(cls, params: Any) -> None:
|
|
308
343
|
if len(params) != 2:
|
|
309
344
|
raise SemanticError("1-1-18-7", op=cls.op, number=len(params), expected=2)
|
|
310
345
|
|
|
@@ -314,13 +349,19 @@ class Instr(Parameterized):
|
|
|
314
349
|
return_type = Integer
|
|
315
350
|
|
|
316
351
|
@classmethod
|
|
317
|
-
def validate(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
352
|
+
def validate(
|
|
353
|
+
cls,
|
|
354
|
+
operand: Operator.ALL_MODEL_DATA_TYPES,
|
|
355
|
+
param1: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
|
|
356
|
+
param2: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
|
|
357
|
+
param3: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
|
|
358
|
+
) -> Any:
|
|
321
359
|
|
|
322
|
-
if
|
|
323
|
-
|
|
360
|
+
if (
|
|
361
|
+
isinstance(param1, Dataset)
|
|
362
|
+
or isinstance(param2, Dataset)
|
|
363
|
+
or isinstance(param3, Dataset)
|
|
364
|
+
):
|
|
324
365
|
raise SemanticError("1-1-18-10", op=cls.op)
|
|
325
366
|
if param1 is not None:
|
|
326
367
|
cls.check_param(param1, 1)
|
|
@@ -332,30 +373,33 @@ class Instr(Parameterized):
|
|
|
332
373
|
return super().validate(operand)
|
|
333
374
|
|
|
334
375
|
@classmethod
|
|
335
|
-
def validate_params(cls, params:
|
|
376
|
+
def validate_params(cls, params: Any) -> None:
|
|
336
377
|
if len(params) != 2:
|
|
337
378
|
raise SemanticError("1-1-18-7", op=cls.op, number=len(params), expected=2)
|
|
338
379
|
|
|
339
380
|
@classmethod
|
|
340
|
-
def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int):
|
|
381
|
+
def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int) -> None:
|
|
341
382
|
if not param:
|
|
342
383
|
return
|
|
343
384
|
if position not in (1, 2, 3):
|
|
344
385
|
raise SemanticError("1-1-18-9", op=cls.op)
|
|
345
|
-
data_type:
|
|
386
|
+
data_type: Any = param.data_type
|
|
346
387
|
|
|
347
388
|
if position == 1:
|
|
348
389
|
if not check_unary_implicit_promotion(data_type, String):
|
|
349
|
-
raise SemanticError(
|
|
350
|
-
|
|
390
|
+
raise SemanticError(
|
|
391
|
+
"1-1-18-4", op=cls.op, param_type="Pattern", correct_type="String"
|
|
392
|
+
)
|
|
351
393
|
elif position == 2:
|
|
352
394
|
if not check_unary_implicit_promotion(data_type, Integer):
|
|
353
|
-
raise SemanticError(
|
|
354
|
-
|
|
395
|
+
raise SemanticError(
|
|
396
|
+
"1-1-18-4", op=cls.op, param_type="Start", correct_type="Integer"
|
|
397
|
+
)
|
|
355
398
|
else:
|
|
356
399
|
if not check_unary_implicit_promotion(data_type, Integer):
|
|
357
|
-
raise SemanticError(
|
|
358
|
-
|
|
400
|
+
raise SemanticError(
|
|
401
|
+
"1-1-18-4", op=cls.op, param_type="Occurrence", correct_type="Integer"
|
|
402
|
+
)
|
|
359
403
|
if isinstance(param, DataComponent):
|
|
360
404
|
if param.data is not None:
|
|
361
405
|
param.data.map(lambda x: cls.check_param_value(x, position))
|
|
@@ -363,53 +407,58 @@ class Instr(Parameterized):
|
|
|
363
407
|
cls.check_param_value(param.value, position)
|
|
364
408
|
|
|
365
409
|
@classmethod
|
|
366
|
-
def check_param_value(cls, param:
|
|
410
|
+
def check_param_value(cls, param: Any, position: int) -> None:
|
|
367
411
|
if position == 2:
|
|
368
412
|
if not pd.isnull(param) and param < 1:
|
|
369
413
|
raise SemanticError("1-1-18-4", op=cls.op, param_type="Start", correct_type=">= 1")
|
|
370
414
|
elif position == 3:
|
|
371
415
|
if not pd.isnull(param) and param < 1:
|
|
372
|
-
raise SemanticError(
|
|
373
|
-
|
|
416
|
+
raise SemanticError(
|
|
417
|
+
"1-1-18-4", op=cls.op, param_type="Occurrence", correct_type=">= 1"
|
|
418
|
+
)
|
|
374
419
|
|
|
375
420
|
@classmethod
|
|
376
|
-
def apply_operation_series_scalar(
|
|
377
|
-
|
|
421
|
+
def apply_operation_series_scalar(
|
|
422
|
+
cls, series: Any, param1: Any, param2: Any, param3: Any
|
|
423
|
+
) -> Any:
|
|
378
424
|
return series.map(lambda x: cls.op_func(x, param1, param2, param3))
|
|
379
425
|
|
|
380
426
|
@classmethod
|
|
381
|
-
def apply_operation_series(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
427
|
+
def apply_operation_series(
|
|
428
|
+
cls,
|
|
429
|
+
data: Any,
|
|
430
|
+
param1: Optional[Union[DataComponent, Scalar]],
|
|
431
|
+
param2: Optional[Union[DataComponent, Scalar]],
|
|
432
|
+
param3: Optional[Union[DataComponent, Scalar]],
|
|
433
|
+
) -> Any:
|
|
387
434
|
param1_data = cls.generate_series_from_param(param1, len(data))
|
|
388
435
|
param2_data = cls.generate_series_from_param(param2, len(data))
|
|
389
436
|
param3_data = cls.generate_series_from_param(param3, len(data))
|
|
390
437
|
|
|
391
|
-
df = pd.DataFrame([
|
|
392
|
-
data,
|
|
393
|
-
param1_data,
|
|
394
|
-
param2_data,
|
|
395
|
-
param3_data
|
|
396
|
-
]).T
|
|
438
|
+
df = pd.DataFrame([data, param1_data, param2_data, param3_data]).T
|
|
397
439
|
n1, n2, n3, n4 = df.columns
|
|
398
440
|
return df.apply(lambda x: cls.op_func(x[n1], x[n2], x[n3], x[n4]), axis=1)
|
|
399
441
|
|
|
400
442
|
@classmethod
|
|
401
|
-
def dataset_evaluation(
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
443
|
+
def dataset_evaluation( # type: ignore[override]
|
|
444
|
+
cls,
|
|
445
|
+
operand: Dataset,
|
|
446
|
+
param1: Optional[Union[DataComponent, Scalar]],
|
|
447
|
+
param2: Optional[Union[DataComponent, Scalar]],
|
|
448
|
+
param3: Optional[Union[DataComponent, Scalar]],
|
|
449
|
+
) -> Dataset:
|
|
405
450
|
result = cls.validate(operand, param1, param2, param3)
|
|
406
|
-
result.data = operand.data.copy()
|
|
451
|
+
result.data = operand.data.copy() if operand.data is not None else pd.DataFrame()
|
|
407
452
|
for measure_name in operand.get_measures_names():
|
|
408
|
-
if
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
453
|
+
if (
|
|
454
|
+
isinstance(param1, DataComponent)
|
|
455
|
+
or isinstance(param2, DataComponent)
|
|
456
|
+
or isinstance(param3, DataComponent)
|
|
457
|
+
):
|
|
458
|
+
if operand.data is not None:
|
|
459
|
+
result.data[measure_name] = cls.apply_operation_series(
|
|
460
|
+
operand.data[measure_name], param1, param2, param3
|
|
461
|
+
)
|
|
413
462
|
else:
|
|
414
463
|
param_value1 = None if param1 is None else param1.value
|
|
415
464
|
param_value2 = None if param2 is None else param2.value
|
|
@@ -423,28 +472,38 @@ class Instr(Parameterized):
|
|
|
423
472
|
return result
|
|
424
473
|
|
|
425
474
|
@classmethod
|
|
426
|
-
def component_evaluation(
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
475
|
+
def component_evaluation( # type: ignore[override]
|
|
476
|
+
cls,
|
|
477
|
+
operand: DataComponent,
|
|
478
|
+
param1: Optional[Union[DataComponent, Scalar]],
|
|
479
|
+
param2: Optional[Union[DataComponent, Scalar]],
|
|
480
|
+
param3: Optional[Union[DataComponent, Scalar]],
|
|
481
|
+
) -> DataComponent:
|
|
430
482
|
result = cls.validate(operand, param1, param2, param3)
|
|
431
|
-
result.data = operand.data.copy()
|
|
432
|
-
if
|
|
433
|
-
|
|
483
|
+
result.data = operand.data.copy() if operand.data is not None else pd.Series()
|
|
484
|
+
if (
|
|
485
|
+
isinstance(param1, DataComponent)
|
|
486
|
+
or isinstance(param2, DataComponent)
|
|
487
|
+
or isinstance(param3, DataComponent)
|
|
488
|
+
):
|
|
434
489
|
result.data = cls.apply_operation_series(operand.data, param1, param2, param3)
|
|
435
490
|
else:
|
|
436
491
|
param_value1 = None if param1 is None else param1.value
|
|
437
492
|
param_value2 = None if param2 is None else param2.value
|
|
438
493
|
param_value3 = None if param3 is None else param3.value
|
|
439
|
-
result.data = cls.apply_operation_series_scalar(
|
|
440
|
-
|
|
494
|
+
result.data = cls.apply_operation_series_scalar(
|
|
495
|
+
operand.data, param_value1, param_value2, param_value3
|
|
496
|
+
)
|
|
441
497
|
return result
|
|
442
498
|
|
|
443
499
|
@classmethod
|
|
444
|
-
def scalar_evaluation(
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
500
|
+
def scalar_evaluation( # type: ignore[override]
|
|
501
|
+
cls,
|
|
502
|
+
operand: Scalar,
|
|
503
|
+
param1: Optional[Scalar],
|
|
504
|
+
param2: Optional[Scalar],
|
|
505
|
+
param3: Optional[Scalar],
|
|
506
|
+
) -> Scalar:
|
|
448
507
|
result = cls.validate(operand, param1, param2, param3)
|
|
449
508
|
param_value1 = None if param1 is None else param1.value
|
|
450
509
|
param_value2 = None if param2 is None else param2.value
|
|
@@ -453,11 +512,13 @@ class Instr(Parameterized):
|
|
|
453
512
|
return result
|
|
454
513
|
|
|
455
514
|
@classmethod
|
|
456
|
-
def evaluate(
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
515
|
+
def evaluate(
|
|
516
|
+
cls,
|
|
517
|
+
operand: Operator.ALL_MODEL_DATA_TYPES,
|
|
518
|
+
param1: Optional[Any] = None,
|
|
519
|
+
param2: Optional[Any] = None,
|
|
520
|
+
param3: Optional[Any] = None,
|
|
521
|
+
) -> Any:
|
|
461
522
|
if isinstance(operand, Dataset):
|
|
462
523
|
return cls.dataset_evaluation(operand, param1, param2, param3)
|
|
463
524
|
if isinstance(operand, DataComponent):
|
|
@@ -466,33 +527,46 @@ class Instr(Parameterized):
|
|
|
466
527
|
return cls.scalar_evaluation(operand, param1, param2, param3)
|
|
467
528
|
|
|
468
529
|
@classmethod
|
|
469
|
-
def op_func(
|
|
470
|
-
|
|
530
|
+
def op_func( # type: ignore[override]
|
|
531
|
+
cls,
|
|
532
|
+
x: Any,
|
|
533
|
+
param1: Optional[Any],
|
|
534
|
+
param2: Optional[Any],
|
|
535
|
+
param3: Optional[Any],
|
|
536
|
+
) -> Any:
|
|
537
|
+
|
|
471
538
|
if pd.isnull(x):
|
|
472
539
|
return None
|
|
473
540
|
return cls.py_op(x, param1, param2, param3)
|
|
474
541
|
|
|
475
542
|
@classmethod
|
|
476
|
-
def py_op(
|
|
477
|
-
|
|
543
|
+
def py_op(
|
|
544
|
+
cls,
|
|
545
|
+
str_value: str,
|
|
546
|
+
str_to_find: Optional[str],
|
|
547
|
+
start: Optional[int],
|
|
548
|
+
occurrence: Optional[int],
|
|
549
|
+
) -> Any:
|
|
478
550
|
str_value = str(str_value)
|
|
479
551
|
if not pd.isnull(start):
|
|
480
|
-
if isinstance(start, int) or start
|
|
552
|
+
if isinstance(start, int) or isinstance(start, float):
|
|
481
553
|
start = int(start - 1)
|
|
482
554
|
else:
|
|
483
555
|
# OPERATORS_STRINGOPERATORS.92
|
|
484
|
-
raise SemanticError(
|
|
485
|
-
|
|
556
|
+
raise SemanticError(
|
|
557
|
+
"1-1-18-4", op=cls.op, param_type="Start", correct_type="Integer"
|
|
558
|
+
)
|
|
486
559
|
else:
|
|
487
560
|
start = 0
|
|
488
561
|
|
|
489
562
|
if not pd.isnull(occurrence):
|
|
490
|
-
if isinstance(occurrence, int) or occurrence
|
|
563
|
+
if isinstance(occurrence, int) or isinstance(occurrence, float):
|
|
491
564
|
occurrence = int(occurrence - 1)
|
|
492
565
|
else:
|
|
493
566
|
# OPERATORS_STRINGOPERATORS.93
|
|
494
|
-
raise SemanticError(
|
|
495
|
-
|
|
567
|
+
raise SemanticError(
|
|
568
|
+
"1-1-18-4", op=cls.op, param_type="Occurrence", correct_type="Integer"
|
|
569
|
+
)
|
|
496
570
|
else:
|
|
497
571
|
occurrence = 0
|
|
498
572
|
if pd.isnull(str_to_find):
|