Skip to content

Commit 12c774a

Browse files
jdrakens-circle-ci
andauthored
LEXIO-37885 Adds math functions (#3)
* Adds math functions * Adds math functions * Version bumped to 0.4.0 Co-authored-by: ns-circle-ci <[email protected]>
1 parent d310330 commit 12c774a

File tree

5 files changed

+158
-3
lines changed

5 files changed

+158
-3
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "pysaql"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
description = "Python SAQL query builder"
55
authors = ["Jonathan Drake <[email protected]>"]
66
license = "BSD-3-Clause"

pysaql/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Python SAQL query builder"""
22

3-
__version__ = "0.3.0"
3+
__version__ = "0.4.0"

pysaql/function.py

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from typing import Any, Optional, Sequence
44

55
from .scalar import Scalar
6+
from .util import stringify
67

78

89
class Function(Scalar):
@@ -18,7 +19,7 @@ def __init__(self, *args: Any) -> None:
1819

1920
def to_string(self) -> str:
2021
"""Cast the function to a string"""
21-
args = [str(arg) for arg in self._args if arg is not None]
22+
args = [stringify(arg) for arg in self._args if arg is not None]
2223
name = self._name or self.__class__.__name__
2324
return f"{name}({', '.join(args)})"
2425

@@ -38,3 +39,106 @@ class coalesce(Function):
3839
"""
3940

4041
pass
42+
43+
44+
class abs_(Function):
45+
"""Get the absolute value of a number
46+
47+
See: https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_saql.meta/bi_dev_guide_saql/bi_saql_functions_math_abs.htm
48+
"""
49+
50+
_name = "abs"
51+
52+
def __init__(self, value: Scalar) -> None:
53+
"""Initializer
54+
55+
Args:
56+
value: Number for which to get the absolute value
57+
58+
"""
59+
super().__init__(value)
60+
61+
62+
class ceil(Function):
63+
"""Returns the nearest integer of equal or greater value to n
64+
65+
See: https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_saql.meta/bi_dev_guide_saql/bi_saql_functions_math_ceil.htm
66+
"""
67+
68+
def __init__(self, value: Scalar) -> None:
69+
"""Initializer
70+
71+
Args:
72+
value: Number for which to get ceiling
73+
74+
"""
75+
super().__init__(value)
76+
77+
78+
class floor(Function):
79+
"""Returns the nearest integer of equal or lesser value to n
80+
81+
See: https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_saql.meta/bi_dev_guide_saql/bi_saql_functions_math_floor.htm
82+
"""
83+
84+
def __init__(self, value: Scalar) -> None:
85+
"""Initializer
86+
87+
Args:
88+
value: Number for which to get the floor
89+
90+
"""
91+
super().__init__(value)
92+
93+
94+
class power(Function):
95+
"""Returns m raised to the nth power
96+
97+
See: https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_saql.meta/bi_dev_guide_saql/bi_saql_functions_math_power.htm
98+
"""
99+
100+
def __init__(self, m: Scalar, n: int) -> None:
101+
"""Initializer
102+
103+
Args:
104+
m: Number to raise to the exponent
105+
n: Exponent
106+
107+
"""
108+
super().__init__(m, n)
109+
110+
111+
class round_(Function):
112+
"""Returns the value of n rounded to m decimal places
113+
114+
See: https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_saql.meta/bi_dev_guide_saql/bi_saql_functions_math_round.htm
115+
"""
116+
117+
_name = "round"
118+
119+
def __init__(self, n: Scalar, m: int) -> None:
120+
"""Initializer
121+
122+
Args:
123+
n: Number to round
124+
m: Number of decimal places
125+
126+
"""
127+
super().__init__(n, m)
128+
129+
130+
class trunc(Function):
131+
"""Returns the value of the numeric expression n truncated to m decimal places
132+
133+
See: https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_saql.meta/bi_dev_guide_saql/bi_saql_functions_math_trunc.htm
134+
"""
135+
136+
def __init__(self, n: Scalar, m: int) -> None:
137+
"""Initializer
138+
139+
Args:
140+
n: Number to truncate
141+
m: Number of decimal places
142+
143+
"""
144+
super().__init__(n, m)

pysaql/scalar.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
operator.is_not: "is not",
2323
operator.le: "<=",
2424
operator.lt: "<",
25+
operator.mod: "%",
2526
operator.mul: "*",
2627
operator.ne: "!=",
2728
operator.neg: "-",

tests/unit/test_function.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""Contains unit tests for the function module"""
2+
3+
4+
import pysaql.function as fn
5+
from pysaql.scalar import field
6+
7+
8+
def test_coalesce():
9+
"""Should coalesce values"""
10+
assert (
11+
str(fn.coalesce(field("name"), field("other"), "empty").alias("NAME"))
12+
== """coalesce('name', 'other', "empty") as 'NAME'"""
13+
)
14+
15+
16+
def test_abs():
17+
"""Should render abs function"""
18+
assert str(fn.abs_(field("num")).alias("NAME")) == """abs('num') as 'NAME'"""
19+
20+
21+
def test_ceil():
22+
"""Should render ceil function"""
23+
assert str(fn.ceil(field("num")).alias("NAME")) == """ceil('num') as 'NAME'"""
24+
25+
26+
def test_floor():
27+
"""Should render floor function"""
28+
assert str(fn.floor(field("num")).alias("NAME")) == """floor('num') as 'NAME'"""
29+
30+
31+
def test_power():
32+
"""Should render power function"""
33+
assert (
34+
str(fn.power(field("num"), 12).alias("NAME"))
35+
== """power('num', 12) as 'NAME'"""
36+
)
37+
38+
39+
def test_round():
40+
"""Should render round function"""
41+
assert (
42+
str(fn.round_(field("num"), 0).alias("NAME")) == """round('num', 0) as 'NAME'"""
43+
)
44+
45+
46+
def test_trunc():
47+
"""Should render trunc function"""
48+
assert (
49+
str(fn.trunc(field("num"), 0).alias("NAME")) == """trunc('num', 0) as 'NAME'"""
50+
)

0 commit comments

Comments
 (0)