def test_creation_table_with_type(self): vb = SymbolTableBuilder() vb.register(six.text_type, self.FakeVariable) vb.register(int, self.FakeVariableSub) st = vb("root", {"name": six.text_type, "age": 15}) assert_equal( st, SymbolTable('root', ( Bind("name", self.FakeVariable), Bind("age", self.FakeVariableSub), )))
def create_grammar(self): root_table = SymbolTable( "root", map(lambda f: Bind(f['name'], GeometryProperty(f['name'])), self.fields)) tokens = { 'not': "not", 'eq': "==", 'ne': "!=", 'belongs_to': "in", 'is_subset': "are included in" } grammar = Grammar(**tokens) self.parse_manager = EvaluableParseManager(root_table, grammar)
def create_grammar(self): root_table = SymbolTable("Shop_root", map( lambda f: Bind(f['name'], GeometryProperty(f['name'])), self.fields ) ) tokens = { 'not': 'not', 'eq': '==', 'ne': '!=', 'belongs_to': 'in', 'is_subset': 'are included in', 'or': "or", 'and': 'and' } grammar = Grammar(**tokens) self.parse_manager = EvaluableParseManager(root_table, grammar)
def __call__(self, name, sample): """ create a SymbolTalbe from the sample data :param string name: the name of the symbolTable :param dict sample: the sample of data :return: the SymbolTable :rtype: SymbolTable """ from booleano.parser import Bind, SymbolTable # isort:skip binds = [] for k, v in sample.items(): var_type = v if isinstance(v, six.class_types) else type(v) var = self.find_for_type(var_type) binds.append(Bind(k, var(k if self.use_key else v))) return SymbolTable(name, binds)
class TestEvaluableParseManager(object): """ Tests for the :class:`EvaluableParseManager` with caching disabled. """ # A symbol table to be used across the tests: symbol_table = SymbolTable( "root", ( Bind("boolean", BoolVar(), es="booleano"), Bind("message", String("Hello world"), es="mensaje"), Bind("foo", PermissiveFunction, es="fulano"), ), SymbolTable("traffic", ( Bind("traffic_light", TrafficLightVar(), es=u"semáforo"), Bind("pedestrians_crossing_road", PedestriansCrossingRoad(), es="peatones_cruzando_calle"), Bind("drivers_awaiting_green", DriversAwaitingGreenLightVar(), es="conductores_esperando_verde"), Bind("traffic_violation", TrafficViolationFunc, es=u"infracción"), ), es=u"tráfico"), ) def test_parsing_with_no_localized_grammars(self): mgr = EvaluableParseManager(self.symbol_table, Grammar()) parse_tree1 = mgr.parse('message == "2009-07-13"') parse_tree2 = mgr.parse('message == "2009-07-13"', None) expected_tree = EvaluableParseTree( Equal(String("Hello world"), String("2009-07-13"))) eq_(parse_tree1, parse_tree2) eq_(parse_tree1, expected_tree) def test_parsing_with_localized_grammars(self): castilian_grammar = Grammar(decimal_separator=",", thousands_separator=".") mgr = EvaluableParseManager(self.symbol_table, Grammar(), es=castilian_grammar) parse_tree = mgr.parse(u"tráfico:peatones_cruzando_calle <= 3,00", "es") expected_tree = EvaluableParseTree( LessEqual(PedestriansCrossingRoad(), Number(3.0))) eq_(parse_tree, expected_tree) def test_parsing_with_undefined_grammar_but_available_translations(self): """ When an expression is written in an unsupported grammar, a parser based on the generic grammar must be created and used. The respective translated bindings must be used if available. """ log_handler = LoggingHandlerFixture() mgr = EvaluableParseManager(self.symbol_table, Grammar()) # Castilian grammar is not supported: parse_tree = mgr.parse(u"tráfico:peatones_cruzando_calle <= 3.0", "es") expected_tree = EvaluableParseTree( LessEqual(PedestriansCrossingRoad(), Number(3))) eq_(parse_tree, expected_tree) # Checking the log: info = "Generated parser for unknown grammar %s" % repr(u'es') ok_(info in log_handler.handler.messages['info']) log_handler.undo() def test_parsing_with_undefined_grammar_and_no_translated_bindings(self): """ When an expression is written in an unsupported grammar, a parser based on the generic grammar must be created and used. If there are no translated bindings, the default names must be used. """ log_handler = LoggingHandlerFixture() mgr = EvaluableParseManager(self.symbol_table, Grammar()) # French grammar is not supported: parse_tree = mgr.parse("traffic:pedestrians_crossing_road <= 3.0", "fr") expected_tree = EvaluableParseTree( LessEqual(PedestriansCrossingRoad(), Number(3))) eq_(parse_tree, expected_tree) # Checking the log: info = "Generated parser for unknown grammar %s" % repr('fr') ok_(info in log_handler.handler.messages['info']) log_handler.undo() def test_parsing_with_defined_grammar_but_no_available_translations(self): """ When an expression is written in an supported grammar but there are no translated bindings, the default names must be used along with the custom grammar. """ french_grammar = Grammar(decimal_separator=",", thousands_separator=".") mgr = EvaluableParseManager(self.symbol_table, Grammar(), fr=french_grammar) # French grammar is not supported: parse_tree = mgr.parse("traffic:pedestrians_crossing_road <= 3,0", "fr") expected_tree = EvaluableParseTree( LessEqual(PedestriansCrossingRoad(), Number(3))) eq_(parse_tree, expected_tree) def test_adding_grammar(self): """It should be possible to add grammars after instantiation.""" castilian_grammar = Grammar(decimal_separator=",", thousands_separator=".") mgr = EvaluableParseManager(self.symbol_table, Grammar()) mgr.add_parser("es", castilian_grammar) parse_tree = mgr.parse(u'tráfico:peatones_cruzando_calle <= 3,00', "es") expected_tree = EvaluableParseTree( LessEqual(PedestriansCrossingRoad(), Number(3.0))) eq_(parse_tree, expected_tree) def test_adding_existing_grammar(self): """There can't be duplicate/overlapped parsers.""" mgr = EvaluableParseManager(self.symbol_table, Grammar(), es=Grammar()) assert_raises(GrammarError, mgr.add_parser, "es", Grammar()) def test_evaluating_expressions(self): """Managers should be able to evaluate the expressions too.""" mgr = EvaluableParseManager(self.symbol_table, Grammar()) context = {'pedestrians_crossroad': (u"gustavo", u"carla")} evaluation1 = mgr.evaluate("traffic:pedestrians_crossing_road <= 3", None, context) evaluation2 = mgr.evaluate( u'"carla" ∈ traffic:pedestrians_crossing_road', None, context) evaluation3 = mgr.evaluate("traffic:pedestrians_crossing_road > 2", None, context) ok_(evaluation1) ok_(evaluation2) assert_false(evaluation3)
buy_conditions = m.group(reg.groupindex["buy_cond"]) sell_conditions = m.group(reg.groupindex["sell_cond"]) else: buy_conditions = args.buy_conditions[0] sell_conditions = args.sell_conditions[0] import stockVars stock_symbol_var = stockVars.StockSymbol() today_var = stockVars.DateToday() root_table = SymbolTable("root", [ Bind("stock", stock_symbol_var), Bind("date", today_var), ], SymbolTable("stock", [ Bind("symbol", stock_symbol_var), Bind("open_price", stockVars.StockOpenPrice()), Bind("close_price", stockVars.StockClosePrice()), Bind("price", stockVars.StockPrice()), Bind("increase_rank", stockVars.StockIncreaseRank()), Bind("decrease_rank", stockVars.StockDecreaseRank()), Bind("change_percent", stockVars.StockPercChange()), Bind("owned", stockVars.StockOwned()), Bind("buy_price", stockVars.StockBuyPrice()), ], SymbolTable("decrease_rank", []),
class TestNativeVariableEvaluableParseManager(object): """ Tests for the :class:`EvaluableParseManager` with caching disabled. """ # A symbol table to be used across the tests: symbol_table = SymbolTable( "root", ( Bind("myint", NumberVariable("myint")), Bind("mybool", BooleanVariable("mybool")), Bind("mystring", StringVariable("mystring")), Bind("mydate", DateVariable("mydate")), Bind("mydate2", DateVariable("mydate2")), Bind("mydatetime", DateTimeVariable("mydatetime")), Bind("mydatetime2", DateTimeVariable("mydatetime2")), Bind("myset", SetVariable("myset")), Bind("myintbis", NumberVariable("myint")), ), SymbolTable( "sub", (Bind("myint", NumberVariable("sub.myint")), ), ), SymbolTable("const", ( Bind("hello", String("hello")), Bind("li", String("li")), ))) mgr = EvaluableParseManager( symbol_table, Grammar(belongs_to='in', is_subset='is subset of')) def test_variable_values_myint(self): ok_(self.mgr.parse('myint > 0')({'myint': 1})) ok_(not self.mgr.parse('myint > 0')({'myint': 0})) ok_(self.mgr.parse('myint == 1')({'myint': 1})) ok_(not self.mgr.parse('myint == 1')({'myint': 0})) ok_(self.mgr.parse('myint < 1')({'myint': 0})) ok_(not self.mgr.parse('myint < 0')({'myint': 2})) def test_variable_values_mybool(self): ok_(self.mgr.parse('mybool')({'mybool': True})) ok_(not self.mgr.parse('mybool')({'mybool': False})) ok_(self.mgr.parse('mybool > 0')({'mybool': True})) ok_(not self.mgr.parse('mybool > 0')({'mybool': False})) ok_(self.mgr.parse('mybool == 1')({'mybool': True})) ok_(not self.mgr.parse('mybool == 1')({'mybool': False})) ok_(self.mgr.parse('mybool < 1')({'mybool': False})) ok_(not self.mgr.parse('mybool < 0')({'mybool': True})) def test_variable_values_mystring(self): mystring = {'mystring': "hello"} # equiality ok_(self.mgr.parse('mystring == "hello"')(mystring)) ok_(not self.mgr.parse('mystring != "hello"')(mystring)) ok_(self.mgr.parse('mystring != "hell"')(mystring)) ok_(not self.mgr.parse('mystring == "hell"')(mystring)) # inequality ok_(self.mgr.parse('mystring > "hella"')(mystring)) ok_(self.mgr.parse('mystring < "hellz"')(mystring)) ok_(self.mgr.parse('mystring < "hellz"')(mystring)) ok_(self.mgr.parse('mystring <= "hello"')(mystring)) ok_(self.mgr.parse('mystring >= "hello"')(mystring)) # inequality reversed ok_(self.mgr.parse('"hella" < mystring')(mystring)) ok_(self.mgr.parse('"hellz" > mystring')(mystring)) ok_(self.mgr.parse('"hellz" > mystring')(mystring)) ok_(self.mgr.parse('"hello" >= mystring')(mystring)) ok_(self.mgr.parse('"hello" >= mystring')(mystring)) # bool ok_(self.mgr.parse('mystring')(mystring)) ok_(not self.mgr.parse('~ mystring')(mystring)) ok_(not self.mgr.parse('mystring')({'mystring': ''})) ok_(self.mgr.parse('~ mystring')({'mystring': ''})) # membership ok_(self.mgr.parse('mystring is subset of "zhelloy"')(mystring)) ok_(not self.mgr.parse('mystring is subset of "zhellai"')(mystring)) ok_(not self.mgr.parse('mystring is subset of "hello"')(mystring)) ok_(self.mgr.parse('mystring in "ahelloa"')(mystring)) ok_(self.mgr.parse('mystring in "hello"')(mystring)) ok_(not self.mgr.parse('mystring in "hola"')(mystring)) # inversed membership ok_(self.mgr.parse('"he" in mystring')(mystring)) ok_(self.mgr.parse('"lo" in mystring')(mystring)) ok_(not self.mgr.parse('"li" in mystring')(mystring)) ok_(self.mgr.parse('"he" is subset of mystring')(mystring)) ok_(self.mgr.parse('"lo" is subset of mystring')(mystring)) ok_(not self.mgr.parse('"li" is subset of mystring')(mystring)) ok_(not self.mgr.parse(' "hello" is subset of mystring')(mystring)) # test to string ok_(not self.mgr.parse('const:hello is subset of mystring')(mystring)) ok_(not self.mgr.parse('const:li in mystring')(mystring)) def test_variable_str(self): eq_("%s" % NativeVariable('coucou'), 'Scop variable for coucou [NativeVariable]') eq_("%s" % BooleanVariable('name'), 'Scop variable for name [BooleanVariable]') eq_("%s" % NumberVariable('age'), 'Scop variable for age [NumberVariable]') def test_variable_values_date(self): mydate = { 'mydate': datetime.date(2017, 1, 15), 'mydate2': datetime.date(2017, 1, 17), } ok_(self.mgr.parse('mydate')(mydate)) ok_(self.mgr.parse('mydate < "2017-01-18"')(mydate)) ok_(self.mgr.parse('mydate < "18-01-2017"')(mydate)) ok_(not self.mgr.parse('mydate < "12-01-2017"')(mydate)) ok_(self.mgr.parse('mydate > "12-01-2017"')(mydate)) ok_(self.mgr.parse('mydate == "15-01-2017"')(mydate)) ok_(not self.mgr.parse('mydate == 1')(mydate)) ok_(not self.mgr.parse('mydate == "13-01-2017"')(mydate)) ok_(self.mgr.parse('mydate < mydate2')(mydate)) ok_(not self.mgr.parse('mydate > mydate2')(mydate)) ok_(not self.mgr.parse('mydate == mydate2')(mydate)) def test_variable_values_datetime(self): mydatetime = { 'mydatetime': datetime.datetime(2017, 1, 15, 12, 25), 'mydatetime2': datetime.datetime(2017, 1, 17, 12, 23), } ok_(self.mgr.parse('mydatetime')(mydatetime)) ok_(self.mgr.parse('mydatetime < "2017-01-15 12:25:02"')(mydatetime)) ok_(self.mgr.parse('mydatetime > "2017-01-15 12:24:52"')(mydatetime)) ok_(self.mgr.parse('mydatetime < "2017-01-15 13:00:00"')(mydatetime)) ok_(self.mgr.parse('mydatetime < "18-01-2017 12:25:02"')(mydatetime)) ok_(self.mgr.parse('mydatetime < "18-01-2017 12:25:02"')(mydatetime)) ok_(not self.mgr.parse('mydatetime < "12-01-2017 12:25:02"') (mydatetime)) ok_(self.mgr.parse('mydatetime > "12-01-2017 12:25:02"')(mydatetime)) ok_(self.mgr.parse('mydatetime == "15-01-2017 12:25:00"')(mydatetime)) ok_(not self.mgr.parse('mydatetime == 1')(mydatetime)) ok_(not self.mgr.parse('mydatetime == "13-01-2017 12:25:02"') (mydatetime)) ok_(self.mgr.parse('mydatetime < mydatetime2')(mydatetime)) ok_(not self.mgr.parse('mydatetime > mydatetime2')(mydatetime)) ok_(not self.mgr.parse('mydatetime == mydatetime2')(mydatetime)) def test_variable_values_set(self): myset = { "myset": {1, 2, 3}, } ok_(self.mgr.parse("1 is subset of myset ")(myset)) ok_(self.mgr.parse("{1, 2} is subset of myset ")(myset)) ok_(not self.mgr.parse("{1, 2, 3} is subset of myset ")(myset)) ok_(self.mgr.parse("1 in myset ")(myset)) ok_(self.mgr.parse("{1, 2} in myset ")(myset)) ok_(self.mgr.parse("{1, 2, 3} in myset ")(myset)) def test_variable_values_namespaced(self): myints = {"myint": 1, "sub.myint": 4} ok_(self.mgr.parse('sub:myint > 3')(myints)) ok_(self.mgr.parse('sub:myint < 5')(myints)) ok_(self.mgr.parse('sub:myint == 4')(myints)) ok_(self.mgr.parse('sub:myint > myint')(myints)) ok_(not self.mgr.parse('sub:myint < myint')(myints)) ok_(not self.mgr.parse('sub:myint == myint')(myints)) def test_format_date(self): dt = DateVariable("mydate", '%d %m %y') assert_raises(ValueError, dt._from_native_string, "2001-03-04") eq_(dt._from_native_string("04 03 01"), datetime.date(2001, 3, 4)) def test_multi_formats(self): dt = DateVariable("mydate", ['%d %m %Y', '%Y %m %d']) assert_raises(ValueError, dt._from_native_string, "2001-03-04") assert_raises(ValueError, dt._from_native_string, "04-03-2001") eq_(dt._from_native_string("04 03 2001"), datetime.date(2001, 3, 4)) eq_(dt._from_native_string("2001 03 04"), datetime.date(2001, 3, 4))
def equals(self, value, context): return context.average_rating == value def greater_than(self, value, context): return context.average_rating > value def less_than(self, value, context): return context.average_rating < value # Defining the scope: symbols = SymbolTable("global", ( Bind("movie", MovieId(), nl="film", es=u"película"), ), SymbolTable("movie", ( Bind("id", MovieId(), nl="id", es="id"), Bind("title", MovieTitle(), nl="titel", es=u"título"), Bind("year", MovieYear(), nl="jaar", es=u"año"), Bind("average_rating", MovieAverageRating(), nl="gemiddelde_rating", es=u"puntuación_promedio") ), nl="film", es=u"película" ), )