onetick-py 1.170.0__py3-none-any.whl → 1.171.0__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.
onetick/py/math.py CHANGED
@@ -1,32 +1,11 @@
1
- from typing import Optional
2
1
  from onetick.py.core.column_operations.base import _Operation
3
-
4
-
5
- class _MaxOperator(_Operation):
6
-
7
- def __init__(self, objs):
8
- from onetick.py.types import get_type_by_objects
9
-
10
- super().__init__(dtype=get_type_by_objects(objs))
11
-
12
- def _str_max(l_val, r_val):
13
- if isinstance(r_val, list):
14
- if len(r_val) > 1:
15
- r_val = _str_max(r_val[0], r_val[1:])
16
- else:
17
- r_val = r_val[0]
18
- # CASE should be uppercased because it can be used in per-tick script
19
- return 'CASE({0} > {1}, 1, {0}, {1})'.format(str(l_val), str(r_val))
20
-
21
- self._repr = _str_max(objs[0], objs[1:])
22
-
23
- def __str__(self):
24
- return self._repr
2
+ from onetick.py.types import value2str, nsectime, get_type_by_objects
25
3
 
26
4
 
27
5
  def max(*objs):
28
6
  """
29
7
  Returns maximum value from list of ``objs``.
8
+ The objects must be of the same type.
30
9
 
31
10
  Parameters
32
11
  ----------
@@ -44,34 +23,30 @@ def max(*objs):
44
23
  Time A MAX
45
24
  0 2003-12-01 1 5
46
25
  """
47
- return _MaxOperator(list(objs))
26
+ if len(objs) < 2:
27
+ raise ValueError("otp.math.max expects at least 2 values to compare")
48
28
 
29
+ def _max_func(*objs):
30
+ dtype = get_type_by_objects(objs)
31
+ onetick_params = map(value2str, objs)
32
+ if dtype is nsectime:
33
+ onetick_params = [f'NSECTIME_TO_LONG({param})' for param in onetick_params]
34
+ onetick_params_str = ', '.join(onetick_params)
35
+ return f"NSECTIME(MAX({onetick_params_str}))", dtype
36
+ else:
37
+ onetick_params_str = ', '.join(onetick_params)
38
+ return f"MAX({onetick_params_str})", dtype
49
39
 
50
- class _MinOperator(_Operation):
51
-
52
- def __init__(self, objs):
53
- from onetick.py.types import get_type_by_objects
54
-
55
- super().__init__(dtype=get_type_by_objects(objs))
56
-
57
- def _str_min(l_val, r_val):
58
- if isinstance(r_val, list):
59
- if len(r_val) > 1:
60
- r_val = _str_min(r_val[0], r_val[1:])
61
- else:
62
- r_val = r_val[0]
63
- # CASE should be uppercased because it can be used in per-tick script
64
- return 'CASE({0} < {1}, 1, {0}, {1})'.format(str(l_val), str(r_val))
65
-
66
- self._repr = _str_min(objs[0], objs[1:])
67
-
68
- def __str__(self):
69
- return self._repr
40
+ return _Operation(
41
+ op_func=_max_func,
42
+ op_params=list(objs),
43
+ )
70
44
 
71
45
 
72
46
  def min(*objs):
73
47
  """
74
48
  Returns minimum value from list of ``objs``.
49
+ The objects must be of the same type.
75
50
 
76
51
  Parameters
77
52
  ----------
@@ -89,32 +64,27 @@ def min(*objs):
89
64
  Time A MIN
90
65
  0 2003-12-01 1 -5
91
66
  """
92
- return _MinOperator(list(objs))
93
-
94
-
95
- class _RandomFunc(_Operation):
96
- """
97
- It implements the `rand` built-in function.
98
- """
99
-
100
- def __init__(self, min_value: int, max_value: int, seed: Optional[int] = None):
101
- super().__init__(dtype=int)
67
+ if len(objs) < 2:
68
+ raise ValueError("otp.math.min expects at least 2 values to compare")
102
69
 
103
- def _repr(min_value, max_value, seed):
104
- result = f'rand({str(min_value)}, {str(max_value)}'
105
- if seed is not None:
106
- result += f',{str(seed)})'
107
- else:
108
- result += ')'
109
- return result
70
+ def _min_func(*objs):
71
+ dtype = get_type_by_objects(objs)
72
+ onetick_params = map(value2str, objs)
73
+ if dtype is nsectime:
74
+ onetick_params = [f'NSECTIME_TO_LONG({param})' for param in onetick_params]
75
+ onetick_params_str = ', '.join(onetick_params)
76
+ return f"NSECTIME(MIN({onetick_params_str}))", dtype
77
+ else:
78
+ onetick_params_str = ', '.join(onetick_params)
79
+ return f"MIN({onetick_params_str})", dtype
110
80
 
111
- self._repr = _repr(min_value, max_value, seed)
81
+ return _Operation(
82
+ op_func=_min_func,
83
+ op_params=list(objs),
84
+ )
112
85
 
113
- def __str__(self):
114
- return self._repr
115
86
 
116
-
117
- def rand(min_value: int, max_value: int, seed: Optional[int] = None):
87
+ def rand(min_value, max_value, seed=None):
118
88
  """
119
89
  Returns a pseudo-random value in the range between ``min_value`` and ``max_value`` (both inclusive).
120
90
  If ``seed`` is not specified, the function produces different values each time a query is invoked.
@@ -135,6 +105,9 @@ def rand(min_value: int, max_value: int, seed: Optional[int] = None):
135
105
  --------
136
106
  >>> data = otp.Tick(A=1)
137
107
  >>> data['RAND'] = otp.math.rand(1, 1000)
108
+ >>> otp.run(data) # doctest: +SKIP
109
+ Time A RAND
110
+ 0 2003-12-01 1 155
138
111
  """
139
112
 
140
113
  if isinstance(min_value, int) and min_value < 0:
@@ -142,29 +115,67 @@ def rand(min_value: int, max_value: int, seed: Optional[int] = None):
142
115
  if isinstance(min_value, int) and isinstance(max_value, int) and min_value >= max_value:
143
116
  raise ValueError("The `max_value` parameter should be more than `min_value`")
144
117
 
145
- return _RandomFunc(min_value, max_value, seed)
118
+ def _random_func(min_value, max_value, seed=None):
119
+ result = f'RAND({value2str(min_value)}, {value2str(max_value)}'
120
+ if seed is not None:
121
+ result += f', {value2str(seed)})'
122
+ else:
123
+ result += ')'
124
+ return result, int
146
125
 
126
+ return _Operation(
127
+ op_func=_random_func,
128
+ op_params=[min_value, max_value, seed],
129
+ )
147
130
 
148
- class _Now(_Operation):
149
131
 
150
- def __init__(self):
151
- from onetick.py.types import nsectime
132
+ def frand(min_value=0, max_value=1, *, seed=None):
133
+ """
134
+ Returns a pseudo-random value in the range between ``min_value`` and ``max_value``.
152
135
 
153
- super().__init__(dtype=nsectime)
136
+ Parameters
137
+ ----------
138
+ min_value: float, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
139
+ max_value: float, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
140
+ seed: int, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
141
+ If not specified, the function produces different values each time a query is invoked.
142
+ If specified, for this seed the function produces the same sequence of values
143
+ each time a query is invoked.
154
144
 
155
- def _repr():
156
- return 'now()'
145
+ Returns
146
+ -------
147
+ :py:class:`~onetick.py.Operation`
157
148
 
158
- self._repr = _repr()
149
+ Examples
150
+ --------
151
+ >>> data = otp.Tick(A=otp.math.frand())
152
+ >>> otp.run(data) # doctest: +SKIP
153
+ Time A FRAND
154
+ 0 2003-12-01 1 0.667519
155
+ """
159
156
 
160
- def __str__(self):
161
- return self._repr
157
+ if isinstance(min_value, (int, float)) and min_value < 0:
158
+ raise ValueError("It is not possible to use negative values for the `min_value`")
159
+ if isinstance(min_value, (int, float)) and isinstance(max_value, (int, float)) and min_value >= max_value:
160
+ raise ValueError("The `max_value` parameter should be more than `min_value`")
161
+
162
+ def _frand_func(min_value, max_value, seed=None):
163
+ func_args = [min_value, max_value]
164
+ if seed is not None:
165
+ func_args.append(seed)
166
+ onetick_args_str = ', '.join(value2str(arg) for arg in func_args)
167
+ return f'FRAND({onetick_args_str})', float
168
+
169
+ return _Operation(
170
+ op_func=_frand_func,
171
+ op_params=[min_value, max_value, seed],
172
+ )
162
173
 
163
174
 
164
175
  # TODO: this is not math, let's move it somewhere else
165
176
  def now():
166
177
  """
167
- Returns the current time expressed as the number of milliseconds since the UNIX epoch.
178
+ Returns the current time expressed as the number of milliseconds since the UNIX epoch in a GMT timezone.
168
179
 
169
180
  Returns
170
181
  -------
@@ -174,25 +185,13 @@ def now():
174
185
  --------
175
186
  >>> data = otp.Tick(A=1)
176
187
  >>> data['NOW'] = otp.now()
188
+ >>> otp.run(data) # doctest: +SKIP
189
+ Time A NOW
190
+ 0 2003-12-01 1 2025-09-29 09:09:00.158
177
191
  """
178
- return _Now()
179
-
180
-
181
- class _Ln(_Operation):
182
- """
183
- Compute the natural logarithm.
184
- """
185
-
186
- def __init__(self, value):
187
- super().__init__(dtype=float)
188
-
189
- def _repr(value):
190
- return f'LOG({str(value)})'
191
-
192
- self._repr = _repr(value)
193
-
194
- def __str__(self):
195
- return self._repr
192
+ return _Operation(
193
+ op_func=lambda: ('NOW()', nsectime),
194
+ )
196
195
 
197
196
 
198
197
  def ln(value):
@@ -217,26 +216,15 @@ def ln(value):
217
216
 
218
217
  See Also
219
218
  --------
220
- onetick.py.math.exp
221
- """
222
- return _Ln(value)
223
-
224
-
225
- class _Log10(_Operation):
226
- """
227
- Compute the base-10 logarithm.
219
+ :py:func:`onetick.py.math.exp`
228
220
  """
221
+ return _Operation(
222
+ op_func=lambda v: (f'LOG({value2str(v)})', float),
223
+ op_params=[value],
224
+ )
229
225
 
230
- def __init__(self, value):
231
- super().__init__(dtype=float)
232
-
233
- def _repr(value):
234
- return f'LOG10({str(value)})'
235
226
 
236
- self._repr = _repr(value)
237
-
238
- def __str__(self):
239
- return self._repr
227
+ log = ln
240
228
 
241
229
 
242
230
  def log10(value):
@@ -259,24 +247,10 @@ def log10(value):
259
247
  Time A LOG10
260
248
  0 2003-12-01 1 2.0
261
249
  """
262
- return _Log10(value)
263
-
264
-
265
- class _Exp(_Operation):
266
- """
267
- Compute the natural exponent.
268
- """
269
-
270
- def __init__(self, value):
271
- super().__init__(dtype=float)
272
-
273
- def _repr(value):
274
- return f'EXP({str(value)})'
275
-
276
- self._repr = _repr(value)
277
-
278
- def __str__(self):
279
- return self._repr
250
+ return _Operation(
251
+ op_func=lambda v: (f'LOG10({value2str(v)})', float),
252
+ op_params=[value],
253
+ )
280
254
 
281
255
 
282
256
  def exp(value):
@@ -301,26 +275,12 @@ def exp(value):
301
275
 
302
276
  See Also
303
277
  --------
304
- onetick.py.math.ln
305
- """
306
- return _Exp(value)
307
-
308
-
309
- class _Sqrt(_Operation):
310
- """
311
- Compute the square root.
278
+ :py:func:`onetick.py.math.ln`
312
279
  """
313
-
314
- def __init__(self, value):
315
- super().__init__(dtype=float)
316
-
317
- def _repr(value):
318
- return f'SQRT({str(value)})'
319
-
320
- self._repr = _repr(value)
321
-
322
- def __str__(self):
323
- return self._repr
280
+ return _Operation(
281
+ op_func=lambda v: (f'EXP({value2str(v)})', float),
282
+ op_params=[value],
283
+ )
324
284
 
325
285
 
326
286
  def sqrt(value):
@@ -343,24 +303,10 @@ def sqrt(value):
343
303
  Time A SQRT
344
304
  0 2003-12-01 1 2.0
345
305
  """
346
- return _Sqrt(value)
347
-
348
-
349
- class _Sign(_Operation):
350
- """
351
- Get the sign of value.
352
- """
353
-
354
- def __init__(self, value):
355
- super().__init__(dtype=int)
356
-
357
- def _repr(value):
358
- return f'SIGN({str(value)})'
359
-
360
- self._repr = _repr(value)
361
-
362
- def __str__(self):
363
- return self._repr
306
+ return _Operation(
307
+ op_func=lambda v: (f'SQRT({value2str(v)})', float),
308
+ op_params=[value],
309
+ )
364
310
 
365
311
 
366
312
  def sign(value):
@@ -385,24 +331,10 @@ def sign(value):
385
331
  Time A SIGN_POS SIGN_ZERO SIGN_NEG
386
332
  0 2003-12-01 1 1 0 -1
387
333
  """
388
- return _Sign(value)
389
-
390
-
391
- class _Power(_Operation):
392
- """
393
- Compute the ``base`` to the power of the ``exponent``.
394
- """
395
-
396
- def __init__(self, base, exponent):
397
- super().__init__(dtype=float)
398
-
399
- def _repr(base, exponent):
400
- return f'POWER({str(base)}, {str(exponent)})'
401
-
402
- self._repr = _repr(base, exponent)
403
-
404
- def __str__(self):
405
- return self._repr
334
+ return _Operation(
335
+ op_func=lambda v: (f'SIGN({value2str(v)})', int),
336
+ op_params=[value],
337
+ )
406
338
 
407
339
 
408
340
  def pow(base, exponent):
@@ -426,21 +358,10 @@ def pow(base, exponent):
426
358
  Time A RES
427
359
  0 2003-12-01 2 1024.0
428
360
  """
429
- return _Power(base, exponent)
430
-
431
-
432
- class _Pi(_Operation):
433
-
434
- def __init__(self):
435
- super().__init__(dtype=float)
436
-
437
- def _repr():
438
- return 'PI()'
439
-
440
- self._repr = _repr()
441
-
442
- def __str__(self):
443
- return self._repr
361
+ return _Operation(
362
+ op_func=lambda b, e: (f'POWER({value2str(b)}, {value2str(e)})', float),
363
+ op_params=[base, exponent],
364
+ )
444
365
 
445
366
 
446
367
  def pi():
@@ -459,24 +380,9 @@ def pi():
459
380
  Time A PI
460
381
  0 2003-12-01 1 3.141593
461
382
  """
462
- return _Pi()
463
-
464
-
465
- class _Sin(_Operation):
466
- """
467
- Returns the value of trigonometric function `sin` for the given angle number expressed in radians.
468
- """
469
-
470
- def __init__(self, value):
471
- super().__init__(dtype=float)
472
-
473
- def _repr(value):
474
- return f'SIN({str(value)})'
475
-
476
- self._repr = _repr(value)
477
-
478
- def __str__(self):
479
- return self._repr
383
+ return _Operation(
384
+ op_func=lambda: ('PI()', float),
385
+ )
480
386
 
481
387
 
482
388
  def sin(value):
@@ -501,27 +407,13 @@ def sin(value):
501
407
 
502
408
  See Also
503
409
  --------
504
- :py:data:`onetick.py.math.pi`
410
+ :py:func:`onetick.py.math.pi`
505
411
  :py:func:`onetick.py.math.asin`
506
412
  """
507
- return _Sin(value)
508
-
509
-
510
- class _Cos(_Operation):
511
- """
512
- Returns the value of trigonometric function `cos` for the given angle number expressed in radians.
513
- """
514
-
515
- def __init__(self, value):
516
- super().__init__(dtype=float)
517
-
518
- def _repr(value):
519
- return f'COS({str(value)})'
520
-
521
- self._repr = _repr(value)
522
-
523
- def __str__(self):
524
- return self._repr
413
+ return _Operation(
414
+ op_func=lambda v: (f'SIN({value2str(v)})', float),
415
+ op_params=[value],
416
+ )
525
417
 
526
418
 
527
419
  def cos(value):
@@ -546,27 +438,13 @@ def cos(value):
546
438
 
547
439
  See Also
548
440
  --------
549
- :py:data:`onetick.py.math.pi`
441
+ :py:func:`onetick.py.math.pi`
550
442
  :py:func:`onetick.py.math.acos`
551
443
  """
552
- return _Cos(value)
553
-
554
-
555
- class _Tan(_Operation):
556
- """
557
- Returns the value of trigonometric function `tan` for the given angle number expressed in radians.
558
- """
559
-
560
- def __init__(self, value):
561
- super().__init__(dtype=float)
562
-
563
- def _repr(value):
564
- return f'TAN({str(value)})'
565
-
566
- self._repr = _repr(value)
567
-
568
- def __str__(self):
569
- return self._repr
444
+ return _Operation(
445
+ op_func=lambda v: (f'COS({value2str(v)})', float),
446
+ op_params=[value],
447
+ )
570
448
 
571
449
 
572
450
  def tan(value):
@@ -591,27 +469,13 @@ def tan(value):
591
469
 
592
470
  See Also
593
471
  --------
594
- :py:data:`onetick.py.math.pi`
472
+ :py:func:`onetick.py.math.pi`
595
473
  :py:func:`onetick.py.math.atan`
596
474
  """
597
- return _Tan(value)
598
-
599
-
600
- class _Cot(_Operation):
601
- """
602
- Returns the value of trigonometric function `cot` for the given angle number expressed in radians.
603
- """
604
-
605
- def __init__(self, value):
606
- super().__init__(dtype=float)
607
-
608
- def _repr(value):
609
- return f'COT({str(value)})'
610
-
611
- self._repr = _repr(value)
612
-
613
- def __str__(self):
614
- return self._repr
475
+ return _Operation(
476
+ op_func=lambda v: (f'TAN({value2str(v)})', float),
477
+ op_params=[value],
478
+ )
615
479
 
616
480
 
617
481
  def cot(value):
@@ -636,27 +500,13 @@ def cot(value):
636
500
 
637
501
  See Also
638
502
  --------
639
- :py:data:`onetick.py.math.pi`
503
+ :py:func:`onetick.py.math.pi`
640
504
  :py:func:`onetick.py.math.acot`
641
505
  """
642
- return _Cot(value)
643
-
644
-
645
- class _Asin(_Operation):
646
- """
647
- Returns the value of inverse trigonometric function `arcsin`.
648
- """
649
-
650
- def __init__(self, value):
651
- super().__init__(dtype=float)
652
-
653
- def _repr(value):
654
- return f'ASIN({str(value)})'
655
-
656
- self._repr = _repr(value)
657
-
658
- def __str__(self):
659
- return self._repr
506
+ return _Operation(
507
+ op_func=lambda v: (f'COT({value2str(v)})', float),
508
+ op_params=[value],
509
+ )
660
510
 
661
511
 
662
512
  def asin(value):
@@ -689,32 +539,18 @@ def asin(value):
689
539
 
690
540
  See Also
691
541
  --------
692
- :py:data:`onetick.py.math.pi`
542
+ :py:func:`onetick.py.math.pi`
693
543
  :py:func:`onetick.py.math.sin`
694
544
  """
695
- return _Asin(value)
545
+ return _Operation(
546
+ op_func=lambda v: (f'ASIN({value2str(v)})', float),
547
+ op_params=[value],
548
+ )
696
549
 
697
550
 
698
551
  arcsin = asin
699
552
 
700
553
 
701
- class _Acos(_Operation):
702
- """
703
- Returns the value of inverse trigonometric function `arccos`.
704
- """
705
-
706
- def __init__(self, value):
707
- super().__init__(dtype=float)
708
-
709
- def _repr(value):
710
- return f'ACOS({str(value)})'
711
-
712
- self._repr = _repr(value)
713
-
714
- def __str__(self):
715
- return self._repr
716
-
717
-
718
554
  def acos(value):
719
555
  """
720
556
  Returns the value of inverse trigonometric function `arccos`.
@@ -745,32 +581,18 @@ def acos(value):
745
581
 
746
582
  See Also
747
583
  --------
748
- :py:data:`onetick.py.math.pi`
584
+ :py:func:`onetick.py.math.pi`
749
585
  :py:func:`onetick.py.math.cos`
750
586
  """
751
- return _Acos(value)
587
+ return _Operation(
588
+ op_func=lambda v: (f'ACOS({value2str(v)})', float),
589
+ op_params=[value],
590
+ )
752
591
 
753
592
 
754
593
  arccos = acos
755
594
 
756
595
 
757
- class _Atan(_Operation):
758
- """
759
- Returns the value of inverse trigonometric function `arctan`.
760
- """
761
-
762
- def __init__(self, value):
763
- super().__init__(dtype=float)
764
-
765
- def _repr(value):
766
- return f'ATAN({str(value)})'
767
-
768
- self._repr = _repr(value)
769
-
770
- def __str__(self):
771
- return self._repr
772
-
773
-
774
596
  def atan(value):
775
597
  """
776
598
  Returns the value of inverse trigonometric function `arctan`.
@@ -801,32 +623,18 @@ def atan(value):
801
623
 
802
624
  See Also
803
625
  --------
804
- :py:data:`onetick.py.math.pi`
626
+ :py:func:`onetick.py.math.pi`
805
627
  :py:func:`onetick.py.math.tan`
806
628
  """
807
- return _Atan(value)
629
+ return _Operation(
630
+ op_func=lambda v: (f'ATAN({value2str(v)})', float),
631
+ op_params=[value],
632
+ )
808
633
 
809
634
 
810
635
  arctan = atan
811
636
 
812
637
 
813
- class _Acot(_Operation):
814
- """
815
- Returns the value of inverse trigonometric function `arccot`.
816
- """
817
-
818
- def __init__(self, value):
819
- super().__init__(dtype=float)
820
-
821
- def _repr(value):
822
- return f'ACOT({str(value)})'
823
-
824
- self._repr = _repr(value)
825
-
826
- def __str__(self):
827
- return self._repr
828
-
829
-
830
638
  def acot(value):
831
639
  """
832
640
  Returns the value of inverse trigonometric function `arccot`.
@@ -857,35 +665,21 @@ def acot(value):
857
665
 
858
666
  See Also
859
667
  --------
860
- :py:data:`onetick.py.math.pi`
668
+ :py:func:`onetick.py.math.pi`
861
669
  :py:func:`onetick.py.math.cot`
862
670
  """
863
- return _Acot(value)
671
+ return _Operation(
672
+ op_func=lambda v: (f'ACOT({value2str(v)})', float),
673
+ op_params=[value],
674
+ )
864
675
 
865
676
 
866
677
  arccot = acot
867
678
 
868
679
 
869
- class _Mod(_Operation):
870
- """
871
- Implements the remainder from dividing ``value1`` by ``value2``
872
- """
873
-
874
- def __init__(self, value1, value2):
875
- super().__init__(dtype=int)
876
-
877
- def _repr(value1, value2):
878
- return f'MOD({str(value1)}, {str(value2)})'
879
-
880
- self._repr = _repr(value1, value2)
881
-
882
- def __str__(self):
883
- return self._repr
884
-
885
-
886
680
  def mod(value1, value2):
887
681
  """
888
- Computes the remainder from dividing ``value1`` by ``value2``
682
+ Computes the remainder from dividing ``value1`` by ``value2``.
889
683
 
890
684
  Parameters
891
685
  ----------
@@ -904,29 +698,69 @@ def mod(value1, value2):
904
698
  Time A MOD
905
699
  0 2003-12-01 100 28
906
700
  """
907
- return _Mod(value1, value2)
701
+ return _Operation(
702
+ op_func=lambda v1, v2: (f'MOD({value2str(v1)}, {value2str(v2)})', int),
703
+ op_params=[value1, value2],
704
+ )
908
705
 
909
706
 
910
- class _Floor(_Operation):
707
+ def div(value1, value2):
911
708
  """
912
- Returns a long integer value representing the largest integer that is less than or equal to the `value`.
709
+ Computes the quotient by dividing ``value1`` by ``value2``.
710
+
711
+ Parameters
712
+ ----------
713
+ value1: int, float, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
714
+ value2: int, float, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
715
+
716
+ Returns
717
+ -------
718
+ :py:class:`~onetick.py.Operation`
719
+
720
+ Examples
721
+ --------
722
+ >>> data = otp.Tick(A=100)
723
+ >>> data['DIV'] = otp.math.div(data['A'], 72)
724
+ >>> otp.run(data)
725
+ Time A DIV
726
+ 0 2003-12-01 100 1
913
727
  """
728
+ return _Operation(
729
+ op_func=lambda v1, v2: (f'DIV({value2str(v1)}, {value2str(v2)})', int),
730
+ op_params=[value1, value2],
731
+ )
914
732
 
915
- def __init__(self, value):
916
- super().__init__(dtype=int)
917
733
 
918
- def _repr(val):
919
- return f'FLOOR({str(val)})'
734
+ def gcd(value1, value2):
735
+ """
736
+ Computes the greatest common divisor between ``value1`` and ``value2``.
737
+
738
+ Parameters
739
+ ----------
740
+ value1: int, float, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
741
+ value2: int, float, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
920
742
 
921
- self._repr = _repr(value)
743
+ Returns
744
+ -------
745
+ :py:class:`~onetick.py.Operation`
922
746
 
923
- def __str__(self):
924
- return self._repr
747
+ Examples
748
+ --------
749
+ >>> data = otp.Tick(A=99)
750
+ >>> data['GCD'] = otp.math.gcd(data['A'], 72)
751
+ >>> otp.run(data)
752
+ Time A GCD
753
+ 0 2003-12-01 99 9
754
+ """
755
+ return _Operation(
756
+ op_func=lambda v1, v2: (f'GCD({value2str(v1)}, {value2str(v2)})', int),
757
+ op_params=[value1, value2],
758
+ )
925
759
 
926
760
 
927
761
  def floor(value):
928
762
  """
929
- Returns a long integer value representing the largest integer that is less than or equal to the `value`.
763
+ Returns a long integer value representing the largest integer that is less than or equal to the ``value``.
930
764
 
931
765
  Parameters
932
766
  ----------
@@ -938,10 +772,55 @@ def floor(value):
938
772
 
939
773
  Examples
940
774
  --------
941
- >>> data = otp.Tick(A=1.2)
775
+ >>> data = otp.Ticks(A=[-1.7, -1.5, -1.2, -1, 0 , 1, 1.2, 1.5, 1.7])
942
776
  >>> data['FLOOR'] = otp.math.floor(data['A'])
943
777
  >>> otp.run(data)
944
- Time A FLOOR
945
- 0 2003-12-01 1.2 1
778
+ Time A FLOOR
779
+ 0 2003-12-01 00:00:00.000 -1.7 -2
780
+ 1 2003-12-01 00:00:00.001 -1.5 -2
781
+ 2 2003-12-01 00:00:00.002 -1.2 -2
782
+ 3 2003-12-01 00:00:00.003 -1.0 -1
783
+ 4 2003-12-01 00:00:00.004 0.0 0
784
+ 5 2003-12-01 00:00:00.005 1.0 1
785
+ 6 2003-12-01 00:00:00.006 1.2 1
786
+ 7 2003-12-01 00:00:00.007 1.5 1
787
+ 8 2003-12-01 00:00:00.008 1.7 1
788
+ """
789
+ return _Operation(
790
+ op_func=lambda v: (f'FLOOR({value2str(v)})', int),
791
+ op_params=[value],
792
+ )
793
+
794
+
795
+ def ceil(value):
946
796
  """
947
- return _Floor(value)
797
+ Returns a long integer value representing the smallest integer that is greater than or equal to the ``value``.
798
+
799
+ Parameters
800
+ ----------
801
+ value: int, float, :py:class:`~onetick.py.Operation`, :py:class:`~onetick.py.Column`
802
+
803
+ Returns
804
+ -------
805
+ :py:class:`~onetick.py.Operation`
806
+
807
+ Examples
808
+ --------
809
+ >>> data = otp.Ticks(A=[-1.7, -1.5, -1.2, -1, 0 , 1, 1.2, 1.5, 1.7])
810
+ >>> data['CEIL'] = otp.math.ceil(data['A'])
811
+ >>> otp.run(data)
812
+ Time A CEIL
813
+ 0 2003-12-01 00:00:00.000 -1.7 -1
814
+ 1 2003-12-01 00:00:00.001 -1.5 -1
815
+ 2 2003-12-01 00:00:00.002 -1.2 -1
816
+ 3 2003-12-01 00:00:00.003 -1.0 -1
817
+ 4 2003-12-01 00:00:00.004 0.0 0
818
+ 5 2003-12-01 00:00:00.005 1.0 1
819
+ 6 2003-12-01 00:00:00.006 1.2 2
820
+ 7 2003-12-01 00:00:00.007 1.5 2
821
+ 8 2003-12-01 00:00:00.008 1.7 2
822
+ """
823
+ return _Operation(
824
+ op_func=lambda v: (f'CEIL({value2str(v)})', int),
825
+ op_params=[value],
826
+ )