def test_unary_minus2(self): x = "y = -1 + -(-xx)" parsed = parse_expression(x) self.assertEqual(str(parsed), "(y = ((-1) + (-(-xx))))") result = parsed.evaluate({"xx": 1}) self.assertEqual(result["y"], 0)
def test_has_cs_series_left(self): x = 'A has_cs "hi"' parsed = parse_expression(x) self.assertEqual(str(parsed), '(A has_cs "hi")') result = parsed.evaluate( {"A": pd.Series(["hi", "hit", "thi", "hi there", "HI"])}) self.assertListEqual(list(result), [True, False, False, True, False])
def test_contains_ignores_case(self): x = "y = A contains \"hello\"" parsed = parse_expression(x) self.assertEqual(str(parsed), "(y = (A contains \"hello\"))") result = parsed.evaluate({"A": "Hello there"}) self.assertEqual(result["y"], True)
def test_notcontains_cs(self): x = "y = A !contains \"hello\"" parsed = parse_expression(x) self.assertEqual(str(parsed), "(y = (A !contains \"hello\"))") result = parsed.evaluate({"A": "Hello there"}) self.assertEqual(result["y"], False)
def test_eval_square_brackets_key_exception(self): x = 'A["k1"]' parsed = parse_expression(x) self.assertEqual(str(parsed), 'A["k1"]') result = parsed.evaluate( {"A": todynamic(pd.Series(['{"k1":"v1"}', '{"k2" : "v2"}']))}) self.assertListEqual(list(result), ["v1", None])
def test_timespan_literal(self): x = "y = C + 1d" parsed = parse_expression(x) self.assertEqual(str(parsed), "(y = (C + 1d))") result = parsed.evaluate({"C": pd.to_datetime("2020-01-02")}) self.assertEqual(result["y"], pd.to_datetime("2020-01-03"))
def test_contains_ignores_nan(self): x = "A contains \"h\"" parsed = parse_expression(x) self.assertEqual(str(parsed), "(A contains \"h\")") A = pd.Series(["hi", np.nan, "b", "", "H"]) result = parsed.evaluate({"A": A}) self.assertListEqual(list(result), [True, False, False, False, True])
def test_parse_method_multiple_args(self): x = "2 * xx(1, 2, 3, 4)" parsed = parse_expression(x) def xx(a, b, c, d): return a + b + c + d self.assertEqual(str(parsed), "(2 * xx(1, 2, 3, 4))") self.assertEqual(20, parsed.evaluate({"xx": xx}))
def test_parse_method_no_args(self): x = "2 * xx()" parsed = parse_expression(x) self.assertEqual(str(parsed), "(2 * xx())") def f(): return 7 self.assertEqual(14, parsed.evaluate({"xx": f}))
def test_unary_minus_comma(self): x = "y = xx(A, -B)" parsed = parse_expression(x) self.assertEqual(str(parsed), "(y = xx(A, (-B)))") def xx(a, b): return a + b result = parsed.evaluate({"xx": xx, "A": 1, "B": 2}) self.assertEqual(result["y"], -1)
def test_string_literal2(self): x = "y = xx(\"hello there\")" parsed = parse_expression(x) self.assertEqual(str(parsed), "(y = xx(\"hello there\"))") def xx(s): return s + "_suffix" result = parsed.evaluate({"xx": xx}) self.assertEqual(result["y"], "hello there_suffix")
def test_eval_square_brackets_dynamic_two_series(self): x = 'A[keys]' parsed = parse_expression(x) self.assertEqual(str(parsed), 'A[keys]') result = parsed.evaluate({ "A": todynamic(pd.Series(['{"k1":"v1"}', '{"k2" : "v2"}'])), "keys": pd.Series(['k1', 'k2']), }) self.assertListEqual(list(result), ["v1", "v2"])
def test_parse_parentheses(self): x = "a + (y / (b - c) + q)*w + (4/2 - 1) " parsed = parse_expression(x) #self.assertEqual(str(parsed), "((a + (((y / (b - c)) + q) * w)) + ((4 / 2) - 1))") self.assertEqual( 4.2, parsed.evaluate({ "a": 1, "y": 1, "b": 7, "c": 6, "q": 1, "w": 1.1 }))
def test_parse_methods_sub_method(self): x = "1 + z(a(), b(3))" parsed = parse_expression(x) self.assertEqual(str(parsed), "(1 + z(a(), b(3)))") def z(a, b): return a + b def a(): return 3 def b(i): return 2 * i self.assertEqual(10, parsed.evaluate({"z": z, "a": a, "b": b}))
def test_between_series_datetime(self): x = 'A between (datetime("2020-01-01") .. datetime("2020-02-01"))' parsed = parse_expression(x) self.assertEqual( str(parsed), '(A between (datetime(2020-01-01) .. datetime(2020-02-01)))') vars = MultiDict([ method_map, { "A": pd.Series([ pd.to_datetime("2019-01-10"), pd.to_datetime("2020-01-10"), pd.to_datetime("2020-02-10") ]) } ]) result = parsed.evaluate(vars) self.assertListEqual(list(result), [False, True, False])
def test_parse_methods3(self): x = "iff(W > 0, B, C)" parsed = parse_expression(x) self.assertEqual(str(parsed), "iff((W > 0), B, C)") def iff(a, b, c): if a: return b else: return c self.assertEqual(2, parsed.evaluate({ "W": 1, "B": 2, "C": 3, "iff": iff }))
def test_parse_parentheses_le(self): x = "1 <= (6 - 4) " parsed = parse_expression(x) self.assertEqual(str(parsed), "(1 <= (6 - 4))") self.assertEqual(True, parsed.evaluate(None))
def test_parse_parentheses_gt(self): x = "1 > (6 - 4) " parsed = parse_expression(x) self.assertEqual(str(parsed), "(1 > (6 - 4))") self.assertEqual(False, parsed.evaluate(None))
def test_parse_parentheses_not_equal(self): x = "1*3!=9/3 " parsed = parse_expression(x) self.assertEqual(str(parsed), "((1 * 3) != (9 / 3))") self.assertEqual(False, parsed.evaluate(None))
def test_dot_left_to_right(): x = "y = A.b.c" parsed = parse_expression(x) assert str(parsed) == "(y = ((A.b).c))"
def test_dot_with_math(): x = "y = 1 + A.b * 2" parsed = parse_expression(x) assert str(parsed) == "(y = (1 + ((A.b) * 2)))"
def test_parse_square_brackets_with_parentheses(self): x = "a = (x[y(2) + (4 - 1)] - 1)" parsed = parse_expression(x) self.assertEqual(str(parsed), "(a = (x[(y(2) + (4 - 1))] - 1))")
def test_star(): x = "any(*)" parsed = parse_expression(x) assert str(parsed) == "any(*)"
def test_string_literal(self): x = "y = \"hello \"" parsed = parse_expression(x) self.assertEqual(str(parsed), "(y = \"hello \")") result = parsed.evaluate(None) self.assertEqual(result["y"], "hello ")
def test_parse_expression3(self): x = "1.0 + xx + yy*(a + b) + zz(3, w) + (1 >= 2)" parsed = parse_expression(x) print(x) print(parsed)
def test_parse_square_brackets(self): x = "x[4 ]" parsed = parse_expression(x) self.assertEqual(str(parsed), "x[4]")
def test_parse_square_brackets_assignment(self): x = "a = x[4 ]" parsed = parse_expression(x) self.assertEqual(str(parsed), "(a = x[4])")
def test_parse_parentheses_equal(self): x = "1 + 3 ==8/2 " parsed = parse_expression(x) self.assertEqual(str(parsed), "((1 + 3) == (8 / 2))") self.assertEqual(True, parsed.evaluate(None))
def test_parse_square_brackets_negative_index(self): x = "x[-2]" parsed = parse_expression(x) self.assertEqual(str(parsed), "x[(-2)]") self.assertEqual(1, parsed.evaluate({"x": [1, 2]}))
def test_dot(): x = "y = A.b" parsed = parse_expression(x) assert str(parsed) == "(y = (A.b))"