vtlengine 1.0__py3-none-any.whl → 1.0.2__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 +159 -102
- vtlengine/API/__init__.py +110 -68
- vtlengine/AST/ASTConstructor.py +188 -98
- vtlengine/AST/ASTConstructorModules/Expr.py +402 -205
- vtlengine/AST/ASTConstructorModules/ExprComponents.py +248 -104
- vtlengine/AST/ASTConstructorModules/Terminals.py +158 -95
- vtlengine/AST/ASTEncoders.py +1 -1
- vtlengine/AST/ASTTemplate.py +24 -9
- vtlengine/AST/ASTVisitor.py +8 -12
- vtlengine/AST/DAG/__init__.py +43 -35
- vtlengine/AST/DAG/_words.py +4 -4
- vtlengine/AST/Grammar/Vtl.g4 +49 -20
- vtlengine/AST/Grammar/VtlTokens.g4 +13 -1
- vtlengine/AST/Grammar/lexer.py +2012 -1312
- vtlengine/AST/Grammar/parser.py +7524 -4343
- vtlengine/AST/Grammar/tokens.py +140 -128
- vtlengine/AST/VtlVisitor.py +16 -5
- vtlengine/AST/__init__.py +41 -11
- vtlengine/DataTypes/NumericTypesHandling.py +5 -4
- vtlengine/DataTypes/TimeHandling.py +196 -301
- vtlengine/DataTypes/__init__.py +304 -218
- vtlengine/Exceptions/__init__.py +96 -27
- vtlengine/Exceptions/messages.py +149 -69
- vtlengine/Interpreter/__init__.py +817 -497
- vtlengine/Model/__init__.py +172 -121
- vtlengine/Operators/Aggregation.py +156 -95
- vtlengine/Operators/Analytic.py +167 -79
- 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 +290 -98
- vtlengine/Operators/General.py +68 -47
- vtlengine/Operators/HROperators.py +91 -72
- vtlengine/Operators/Join.py +217 -118
- vtlengine/Operators/Numeric.py +129 -46
- vtlengine/Operators/RoleSetter.py +16 -15
- vtlengine/Operators/Set.py +61 -36
- vtlengine/Operators/String.py +213 -139
- vtlengine/Operators/Time.py +467 -215
- vtlengine/Operators/Validation.py +117 -76
- vtlengine/Operators/__init__.py +340 -213
- vtlengine/Utils/__init__.py +232 -41
- 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 +79 -52
- vtlengine/files/parser/_rfc_dialect.py +6 -5
- vtlengine/files/parser/_time_checking.py +48 -37
- vtlengine-1.0.2.dist-info/METADATA +245 -0
- vtlengine-1.0.2.dist-info/RECORD +58 -0
- {vtlengine-1.0.dist-info → vtlengine-1.0.2.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.2.dist-info}/LICENSE.md +0 -0
vtlengine/Operators/Numeric.py
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
|
+
import _random
|
|
1
2
|
import math
|
|
2
3
|
import operator
|
|
4
|
+
import warnings
|
|
3
5
|
from decimal import getcontext, Decimal
|
|
4
6
|
from typing import Any, Optional, Union
|
|
5
7
|
|
|
6
8
|
import vtlengine.Operators as Operator
|
|
7
9
|
import pandas as pd
|
|
8
|
-
from vtlengine.DataTypes import Integer, Number
|
|
10
|
+
from vtlengine.DataTypes import Integer, Number, binary_implicit_promotion
|
|
9
11
|
from vtlengine.Operators import ALL_MODEL_DATA_TYPES
|
|
10
12
|
|
|
11
|
-
from vtlengine.AST.Grammar.tokens import
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
from vtlengine.AST.Grammar.tokens import (
|
|
14
|
+
ABS,
|
|
15
|
+
CEIL,
|
|
16
|
+
DIV,
|
|
17
|
+
EXP,
|
|
18
|
+
FLOOR,
|
|
19
|
+
LN,
|
|
20
|
+
LOG,
|
|
21
|
+
MINUS,
|
|
22
|
+
MOD,
|
|
23
|
+
MULT,
|
|
24
|
+
PLUS,
|
|
25
|
+
POWER,
|
|
26
|
+
ROUND,
|
|
27
|
+
SQRT,
|
|
28
|
+
TRUNC,
|
|
29
|
+
RANDOM,
|
|
30
|
+
)
|
|
14
31
|
from vtlengine.Exceptions import SemanticError
|
|
15
32
|
from vtlengine.Model import DataComponent, Dataset, Scalar
|
|
16
33
|
|
|
@@ -19,6 +36,7 @@ class Unary(Operator.Unary):
|
|
|
19
36
|
"""
|
|
20
37
|
Checks that the unary operation is performed with a number.
|
|
21
38
|
"""
|
|
39
|
+
|
|
22
40
|
type_to_check = Number
|
|
23
41
|
|
|
24
42
|
|
|
@@ -26,6 +44,7 @@ class Binary(Operator.Binary):
|
|
|
26
44
|
"""
|
|
27
45
|
Checks that the binary operation is performed with numbers.
|
|
28
46
|
"""
|
|
47
|
+
|
|
29
48
|
type_to_check = Number
|
|
30
49
|
|
|
31
50
|
@classmethod
|
|
@@ -35,7 +54,8 @@ class Binary(Operator.Binary):
|
|
|
35
54
|
if isinstance(x, int) and isinstance(y, int):
|
|
36
55
|
if cls.op == DIV and y == 0:
|
|
37
56
|
raise SemanticError("2-1-15-6", op=cls.op, value=y)
|
|
38
|
-
|
|
57
|
+
if cls.op == RANDOM:
|
|
58
|
+
return cls.py_op(x, y)
|
|
39
59
|
x = float(x)
|
|
40
60
|
y = float(y)
|
|
41
61
|
# Handles precision to avoid floating point errors
|
|
@@ -52,8 +72,9 @@ class Binary(Operator.Binary):
|
|
|
52
72
|
|
|
53
73
|
class UnPlus(Unary):
|
|
54
74
|
"""
|
|
55
|
-
`Plus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=94&zoom=100,72,142> `_ unary operator
|
|
75
|
+
`Plus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=94&zoom=100,72,142> `_ unary operator # noqa E501
|
|
56
76
|
"""
|
|
77
|
+
|
|
57
78
|
op = PLUS
|
|
58
79
|
py_op = operator.pos
|
|
59
80
|
|
|
@@ -64,24 +85,27 @@ class UnPlus(Unary):
|
|
|
64
85
|
|
|
65
86
|
class UnMinus(Unary):
|
|
66
87
|
"""
|
|
67
|
-
`Minus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=95&zoom=100,72,414> `_unary operator
|
|
88
|
+
`Minus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=95&zoom=100,72,414> `_unary operator # noqa E501
|
|
68
89
|
"""
|
|
90
|
+
|
|
69
91
|
op = MINUS
|
|
70
92
|
py_op = operator.neg
|
|
71
93
|
|
|
72
94
|
|
|
73
95
|
class AbsoluteValue(Unary):
|
|
74
96
|
"""
|
|
75
|
-
`Absolute <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=112&zoom=100,72,801> `_ unary operator
|
|
97
|
+
`Absolute <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=112&zoom=100,72,801> `_ unary operator # noqa E501
|
|
76
98
|
"""
|
|
99
|
+
|
|
77
100
|
op = ABS
|
|
78
101
|
py_op = operator.abs
|
|
79
102
|
|
|
80
103
|
|
|
81
104
|
class Exponential(Unary):
|
|
82
105
|
"""
|
|
83
|
-
`Exponential <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=114&zoom=100,72,94>`_ unary operator
|
|
106
|
+
`Exponential <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=114&zoom=100,72,94>`_ unary operator # noqa E501
|
|
84
107
|
"""
|
|
108
|
+
|
|
85
109
|
op = EXP
|
|
86
110
|
py_op = math.exp
|
|
87
111
|
return_type = Number
|
|
@@ -89,9 +113,10 @@ class Exponential(Unary):
|
|
|
89
113
|
|
|
90
114
|
class NaturalLogarithm(Unary):
|
|
91
115
|
"""
|
|
92
|
-
`Natural logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=115&zoom=100,72,394> `_
|
|
116
|
+
`Natural logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=115&zoom=100,72,394> `_ # noqa E501
|
|
93
117
|
unary operator
|
|
94
118
|
"""
|
|
119
|
+
|
|
95
120
|
op = LN
|
|
96
121
|
py_op = math.log
|
|
97
122
|
return_type = Number
|
|
@@ -99,9 +124,10 @@ class NaturalLogarithm(Unary):
|
|
|
99
124
|
|
|
100
125
|
class SquareRoot(Unary):
|
|
101
126
|
"""
|
|
102
|
-
`Square Root <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=119&zoom=100,72,556> '_
|
|
127
|
+
`Square Root <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=119&zoom=100,72,556> '_ # noqa E501
|
|
103
128
|
unary operator
|
|
104
129
|
"""
|
|
130
|
+
|
|
105
131
|
op = SQRT
|
|
106
132
|
py_op = math.sqrt
|
|
107
133
|
return_type = Number
|
|
@@ -109,8 +135,9 @@ class SquareRoot(Unary):
|
|
|
109
135
|
|
|
110
136
|
class Ceil(Unary):
|
|
111
137
|
"""
|
|
112
|
-
`Ceilling <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=110&zoom=100,72,94> `_ unary operator
|
|
138
|
+
`Ceilling <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=110&zoom=100,72,94> `_ unary operator # noqa E501
|
|
113
139
|
"""
|
|
140
|
+
|
|
114
141
|
op = CEIL
|
|
115
142
|
py_op = math.ceil
|
|
116
143
|
return_type = Integer
|
|
@@ -118,8 +145,9 @@ class Ceil(Unary):
|
|
|
118
145
|
|
|
119
146
|
class Floor(Unary):
|
|
120
147
|
"""
|
|
121
|
-
`Floor <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=111&zoom=100,72,442> `_ unary operator
|
|
148
|
+
`Floor <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=111&zoom=100,72,442> `_ unary operator # noqa E501
|
|
122
149
|
"""
|
|
150
|
+
|
|
123
151
|
op = FLOOR
|
|
124
152
|
py_op = math.floor
|
|
125
153
|
return_type = Integer
|
|
@@ -127,8 +155,9 @@ class Floor(Unary):
|
|
|
127
155
|
|
|
128
156
|
class BinPlus(Binary):
|
|
129
157
|
"""
|
|
130
|
-
`Addition <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=96&zoom=100,72,692> `_ binary operator
|
|
158
|
+
`Addition <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=96&zoom=100,72,692> `_ binary operator # noqa E501
|
|
131
159
|
"""
|
|
160
|
+
|
|
132
161
|
op = PLUS
|
|
133
162
|
py_op = operator.add
|
|
134
163
|
type_to_check = Number
|
|
@@ -136,8 +165,9 @@ class BinPlus(Binary):
|
|
|
136
165
|
|
|
137
166
|
class BinMinus(Binary):
|
|
138
167
|
"""
|
|
139
|
-
`Subtraction <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=98&zoom=100,72,448> `_ binary operator
|
|
168
|
+
`Subtraction <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=98&zoom=100,72,448> `_ binary operator # noqa E501
|
|
140
169
|
"""
|
|
170
|
+
|
|
141
171
|
op = MINUS
|
|
142
172
|
py_op = operator.sub
|
|
143
173
|
type_to_check = Number
|
|
@@ -145,18 +175,20 @@ class BinMinus(Binary):
|
|
|
145
175
|
|
|
146
176
|
class Mult(Binary):
|
|
147
177
|
"""
|
|
148
|
-
`Multiplication <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=100&zoom=100,72,254>`_
|
|
178
|
+
`Multiplication <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=100&zoom=100,72,254>`_ # noqa E501
|
|
149
179
|
binary operator
|
|
150
180
|
"""
|
|
181
|
+
|
|
151
182
|
op = MULT
|
|
152
183
|
py_op = operator.mul
|
|
153
184
|
|
|
154
185
|
|
|
155
186
|
class Div(Binary):
|
|
156
187
|
"""
|
|
157
|
-
`Division <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=102&zoom=100,72,94>`_
|
|
188
|
+
`Division <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=102&zoom=100,72,94>`_ # noqa E501
|
|
158
189
|
binary operator
|
|
159
190
|
"""
|
|
191
|
+
|
|
160
192
|
op = DIV
|
|
161
193
|
py_op = operator.truediv
|
|
162
194
|
return_type = Number
|
|
@@ -164,8 +196,9 @@ class Div(Binary):
|
|
|
164
196
|
|
|
165
197
|
class Logarithm(Binary):
|
|
166
198
|
"""
|
|
167
|
-
`Logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=118&zoom=100,72,228>`_ operator
|
|
199
|
+
`Logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=118&zoom=100,72,228>`_ operator # noqa E501
|
|
168
200
|
"""
|
|
201
|
+
|
|
169
202
|
op = LOG
|
|
170
203
|
return_type = Number
|
|
171
204
|
|
|
@@ -181,16 +214,18 @@ class Logarithm(Binary):
|
|
|
181
214
|
|
|
182
215
|
class Modulo(Binary):
|
|
183
216
|
"""
|
|
184
|
-
`Module <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=104&zoom=100,72,94>`_ operator
|
|
217
|
+
`Module <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=104&zoom=100,72,94>`_ operator # noqa E501
|
|
185
218
|
"""
|
|
219
|
+
|
|
186
220
|
op = MOD
|
|
187
221
|
py_op = operator.mod
|
|
188
222
|
|
|
189
223
|
|
|
190
224
|
class Power(Binary):
|
|
191
225
|
"""
|
|
192
|
-
`Power <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=116&zoom=100,72,693>`_ operator
|
|
226
|
+
`Power <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=116&zoom=100,72,693>`_ operator # noqa E501
|
|
193
227
|
"""
|
|
228
|
+
|
|
194
229
|
op = POWER
|
|
195
230
|
return_type = Number
|
|
196
231
|
|
|
@@ -198,26 +233,30 @@ class Power(Binary):
|
|
|
198
233
|
def py_op(cls, x: Any, param: Any) -> Any:
|
|
199
234
|
if pd.isnull(param):
|
|
200
235
|
return None
|
|
201
|
-
return x
|
|
236
|
+
return x**param
|
|
202
237
|
|
|
203
238
|
|
|
204
239
|
class Parameterized(Unary):
|
|
205
240
|
"""Parametrized class
|
|
206
|
-
|
|
207
|
-
|
|
241
|
+
Inherits from Unary class, to validate the data type and evaluate if it is the correct one to
|
|
242
|
+
perform the operation. Similar to Unary, but in the end, the param validation is added.
|
|
208
243
|
"""
|
|
209
244
|
|
|
210
245
|
@classmethod
|
|
211
|
-
def validate(
|
|
212
|
-
|
|
246
|
+
def validate(
|
|
247
|
+
cls,
|
|
248
|
+
operand: Operator.ALL_MODEL_DATA_TYPES,
|
|
249
|
+
param: Optional[Union[DataComponent, Scalar]] = None,
|
|
250
|
+
) -> Any:
|
|
213
251
|
|
|
214
252
|
if param is not None:
|
|
215
253
|
if isinstance(param, Dataset):
|
|
216
254
|
raise SemanticError("1-1-15-8", op=cls.op, comp_type="Dataset")
|
|
217
255
|
if isinstance(param, DataComponent):
|
|
218
256
|
if isinstance(operand, Scalar):
|
|
219
|
-
raise SemanticError(
|
|
220
|
-
|
|
257
|
+
raise SemanticError(
|
|
258
|
+
"1-1-15-8", op=cls.op, comp_type="DataComponent and an Scalar operand"
|
|
259
|
+
)
|
|
221
260
|
cls.validate_type_compatibility(param.data_type)
|
|
222
261
|
else:
|
|
223
262
|
cls.validate_scalar_type(param)
|
|
@@ -233,17 +272,19 @@ class Parameterized(Unary):
|
|
|
233
272
|
return None if pd.isnull(x) else cls.py_op(x, param)
|
|
234
273
|
|
|
235
274
|
@classmethod
|
|
236
|
-
def apply_operation_two_series(cls, left_series:
|
|
275
|
+
def apply_operation_two_series(cls, left_series: Any, right_series: Any) -> Any:
|
|
237
276
|
return left_series.combine(right_series, cls.op_func)
|
|
238
277
|
|
|
239
278
|
@classmethod
|
|
240
|
-
def apply_operation_series_scalar(cls, series:
|
|
279
|
+
def apply_operation_series_scalar(cls, series: Any, param: Any) -> Any:
|
|
241
280
|
return series.map(lambda x: cls.op_func(x, param))
|
|
242
281
|
|
|
243
282
|
@classmethod
|
|
244
|
-
def dataset_evaluation(
|
|
283
|
+
def dataset_evaluation(
|
|
284
|
+
cls, operand: Dataset, param: Optional[Union[DataComponent, Scalar]] = None
|
|
285
|
+
) -> Dataset:
|
|
245
286
|
result = cls.validate(operand, param)
|
|
246
|
-
result.data = operand.data.copy()
|
|
287
|
+
result.data = operand.data.copy() if operand.data is not None else pd.DataFrame()
|
|
247
288
|
for measure_name in result.get_measures_names():
|
|
248
289
|
try:
|
|
249
290
|
if isinstance(param, DataComponent):
|
|
@@ -251,49 +292,56 @@ class Parameterized(Unary):
|
|
|
251
292
|
result.data[measure_name], param.data
|
|
252
293
|
)
|
|
253
294
|
else:
|
|
254
|
-
param_value =
|
|
295
|
+
param_value = param.value if param is not None else None
|
|
255
296
|
result.data[measure_name] = cls.apply_operation_series_scalar(
|
|
256
297
|
result.data[measure_name], param_value
|
|
257
298
|
)
|
|
258
299
|
except ValueError:
|
|
259
|
-
raise SemanticError(
|
|
260
|
-
|
|
300
|
+
raise SemanticError(
|
|
301
|
+
"2-1-15-1", op=cls.op, comp_name=measure_name, dataset_name=operand.name
|
|
302
|
+
) from None
|
|
261
303
|
result.data = result.data[result.get_components_names()]
|
|
262
304
|
return result
|
|
263
305
|
|
|
264
306
|
@classmethod
|
|
265
|
-
def component_evaluation(
|
|
307
|
+
def component_evaluation(
|
|
308
|
+
cls, operand: DataComponent, param: Optional[Union[DataComponent, Scalar]] = None
|
|
309
|
+
) -> DataComponent:
|
|
266
310
|
result = cls.validate(operand, param)
|
|
311
|
+
if operand.data is None:
|
|
312
|
+
operand.data = pd.Series()
|
|
267
313
|
result.data = operand.data.copy()
|
|
268
314
|
if isinstance(param, DataComponent):
|
|
269
315
|
result.data = cls.apply_operation_two_series(operand.data, param.data)
|
|
270
316
|
else:
|
|
271
|
-
param_value =
|
|
317
|
+
param_value = param.value if param is not None else None
|
|
272
318
|
result.data = cls.apply_operation_series_scalar(operand.data, param_value)
|
|
273
319
|
return result
|
|
274
320
|
|
|
275
321
|
@classmethod
|
|
276
|
-
def scalar_evaluation(cls, operand: Scalar, param: Scalar
|
|
322
|
+
def scalar_evaluation(cls, operand: Scalar, param: Optional[Any] = None) -> Scalar:
|
|
277
323
|
result = cls.validate(operand, param)
|
|
278
|
-
param_value =
|
|
324
|
+
param_value = param.value if param is not None else None
|
|
279
325
|
result.value = cls.op_func(operand.value, param_value)
|
|
280
326
|
return result
|
|
281
327
|
|
|
282
328
|
@classmethod
|
|
283
|
-
def evaluate(
|
|
284
|
-
|
|
329
|
+
def evaluate(
|
|
330
|
+
cls, operand: ALL_MODEL_DATA_TYPES, param: Optional[Union[DataComponent, Scalar]] = None
|
|
331
|
+
) -> Union[DataComponent, Dataset, Scalar]:
|
|
285
332
|
if isinstance(operand, Dataset):
|
|
286
333
|
return cls.dataset_evaluation(operand, param)
|
|
287
|
-
|
|
334
|
+
elif isinstance(operand, DataComponent):
|
|
288
335
|
return cls.component_evaluation(operand, param)
|
|
289
|
-
|
|
336
|
+
else:
|
|
290
337
|
return cls.scalar_evaluation(operand, param)
|
|
291
338
|
|
|
292
339
|
|
|
293
340
|
class Round(Parameterized):
|
|
294
341
|
"""
|
|
295
|
-
`Round <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=106&zoom=100,72,94>`_ operator
|
|
342
|
+
`Round <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=106&zoom=100,72,94>`_ operator # noqa E501
|
|
296
343
|
"""
|
|
344
|
+
|
|
297
345
|
op = ROUND
|
|
298
346
|
return_type = Integer
|
|
299
347
|
|
|
@@ -301,7 +349,7 @@ class Round(Parameterized):
|
|
|
301
349
|
def py_op(cls, x: Any, param: Any) -> Any:
|
|
302
350
|
multiplier = 1.0
|
|
303
351
|
if not pd.isnull(param):
|
|
304
|
-
multiplier = 10
|
|
352
|
+
multiplier = 10**param
|
|
305
353
|
|
|
306
354
|
if x >= 0.0:
|
|
307
355
|
rounded_value = math.floor(x * multiplier + 0.5) / multiplier
|
|
@@ -316,15 +364,16 @@ class Round(Parameterized):
|
|
|
316
364
|
|
|
317
365
|
class Trunc(Parameterized):
|
|
318
366
|
"""
|
|
319
|
-
`Trunc <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=108&zoom=100,72,94>`_ operator.
|
|
367
|
+
`Trunc <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=108&zoom=100,72,94>`_ operator. # noqa E501
|
|
320
368
|
"""
|
|
369
|
+
|
|
321
370
|
op = TRUNC
|
|
322
371
|
|
|
323
372
|
@classmethod
|
|
324
373
|
def py_op(cls, x: float, param: Optional[float]) -> Any:
|
|
325
374
|
multiplier = 1.0
|
|
326
375
|
if not pd.isnull(param):
|
|
327
|
-
multiplier = 10
|
|
376
|
+
multiplier = 10**param
|
|
328
377
|
|
|
329
378
|
truncated_value = int(x * multiplier) / multiplier
|
|
330
379
|
|
|
@@ -332,3 +381,37 @@ class Trunc(Parameterized):
|
|
|
332
381
|
return truncated_value
|
|
333
382
|
|
|
334
383
|
return int(truncated_value)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
class PseudoRandom(_random.Random):
|
|
387
|
+
|
|
388
|
+
def __init__(self, seed: Union[int, float]) -> None:
|
|
389
|
+
super().__init__()
|
|
390
|
+
self.seed(seed)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
class Random(Parameterized):
|
|
394
|
+
|
|
395
|
+
op = RANDOM
|
|
396
|
+
return_type = Number
|
|
397
|
+
|
|
398
|
+
@classmethod
|
|
399
|
+
def validate(cls, seed: Any, index: Any = None) -> Any:
|
|
400
|
+
if index.data_type != Integer:
|
|
401
|
+
index.data_type = binary_implicit_promotion(index.data_type, Integer)
|
|
402
|
+
if index.value < 0:
|
|
403
|
+
raise SemanticError("2-1-15-2", op=cls.op, value=index)
|
|
404
|
+
if index.value > 10000:
|
|
405
|
+
warnings.warn("Random: The value of 'index' is very big. This can affect "
|
|
406
|
+
"performance.", UserWarning)
|
|
407
|
+
return super().validate(seed, index)
|
|
408
|
+
|
|
409
|
+
@classmethod
|
|
410
|
+
def py_op(cls,
|
|
411
|
+
seed: Union[int, float],
|
|
412
|
+
index: int
|
|
413
|
+
) -> float:
|
|
414
|
+
instance: PseudoRandom = PseudoRandom(seed)
|
|
415
|
+
for _ in range(index):
|
|
416
|
+
instance.random()
|
|
417
|
+
return instance.random().__round__(6)
|
|
@@ -1,43 +1,42 @@
|
|
|
1
|
-
import os
|
|
2
1
|
from copy import copy
|
|
2
|
+
from typing import Any, Union
|
|
3
3
|
|
|
4
4
|
from vtlengine.Exceptions import SemanticError
|
|
5
5
|
|
|
6
|
-
if os.environ.get("SPARK", False):
|
|
7
|
-
|
|
8
|
-
else:
|
|
9
|
-
|
|
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
|
|
10
11
|
|
|
11
12
|
from vtlengine.Model import DataComponent, Role, Scalar
|
|
12
13
|
from vtlengine.Operators import Unary
|
|
13
14
|
|
|
14
|
-
ALLOWED_MODEL_TYPES = [DataComponent, Scalar]
|
|
15
|
+
ALLOWED_MODEL_TYPES = Union[DataComponent, Scalar]
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class RoleSetter(Unary):
|
|
18
|
-
role
|
|
19
|
+
role: Role
|
|
19
20
|
|
|
20
21
|
@classmethod
|
|
21
|
-
def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0):
|
|
22
|
+
def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0) -> DataComponent:
|
|
22
23
|
if isinstance(operand, Scalar):
|
|
23
|
-
|
|
24
24
|
nullable = True
|
|
25
25
|
if cls.role == Role.IDENTIFIER or operand.value is not None:
|
|
26
26
|
nullable = False
|
|
27
|
-
|
|
28
27
|
return DataComponent(
|
|
29
28
|
name=operand.name,
|
|
30
29
|
data_type=operand.data_type,
|
|
31
30
|
role=cls.role,
|
|
32
31
|
nullable=nullable,
|
|
33
|
-
data=None
|
|
32
|
+
data=None,
|
|
34
33
|
)
|
|
35
34
|
operand.role = cls.role
|
|
36
35
|
return copy(operand)
|
|
37
36
|
|
|
38
37
|
@classmethod
|
|
39
|
-
def evaluate(cls, operand:
|
|
40
|
-
if isinstance(operand, DataComponent):
|
|
38
|
+
def evaluate(cls, operand: Any, data_size: int = 0) -> DataComponent:
|
|
39
|
+
if isinstance(operand, DataComponent) and operand.data is not None:
|
|
41
40
|
if not operand.nullable and any(operand.data.isnull()):
|
|
42
41
|
raise SemanticError("1-1-1-16")
|
|
43
42
|
result = cls.validate(operand, data_size)
|
|
@@ -52,14 +51,16 @@ class Identifier(RoleSetter):
|
|
|
52
51
|
role = Role.IDENTIFIER
|
|
53
52
|
|
|
54
53
|
@classmethod
|
|
55
|
-
def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0):
|
|
54
|
+
def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0) -> DataComponent:
|
|
56
55
|
result = super().validate(operand)
|
|
57
56
|
if result.nullable:
|
|
58
57
|
raise SemanticError("1-1-1-16")
|
|
59
58
|
return result
|
|
60
59
|
|
|
61
60
|
@classmethod
|
|
62
|
-
def evaluate(
|
|
61
|
+
def evaluate( # type: ignore[override]
|
|
62
|
+
cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0
|
|
63
|
+
) -> DataComponent:
|
|
63
64
|
if isinstance(operand, Scalar):
|
|
64
65
|
if operand.value is None:
|
|
65
66
|
raise SemanticError("1-1-1-16")
|