Пример #1
0
    def test_missing(self):
        """
        Takes an array of data keys to search for (same format as var).
        Returns an array of any keys that are missing from the data object,
        or an empty array.
        """
        self.assertEqual(
            jsonLogic({"missing": ["a", "b"]}, {
                "a": "apple",
                "c": "carrot"
            }), ["b"])

        self.assertEqual(
            jsonLogic({"missing": ["a", "b"]}, {
                "a": "apple",
                "b": "banana"
            }), [])

        # Note, in JsonLogic, empty arrays are falsy. So you can use missing
        # with if like:
        self.assertEqual(
            jsonLogic(
                {
                    "if": [{
                        "missing": ["a", "b"]
                    }, "Not enough fruit", "OK to proceed"]
                }, {
                    "a": "apple",
                    "b": "banana"
                }), "OK to proceed")
Пример #2
0
 def test_strict_equality_ignores_numeric_type_differences(self):
     self.assertIs(jsonLogic({'===': [1, 1]}), True)
     self.assertIs(jsonLogic({'===': [1.23, 1.23]}), True)
     self.assertIs(jsonLogic({'===': [1, 1.0]}), True)
     self.assertIs(
         jsonLogic({'===': [10000000000000000000, 10000000000000000000.0]}),
         True)
Пример #3
0
    def test_ternary_operator_does_not_evaluate_depth_first(self):
        # False consequent of '?:' operation condition should not run
        consequents = []

        def push_then(arg):
            consequents.append(arg)
            return arg

        def push_else(arg):
            consequents.append(arg)
            return arg

        add_operation('push_then', push_then)
        add_operation('push_else', push_else)

        jsonLogic({
            '?:': [True, {
                'push_then': ["first"]
            }, {
                'push_else': ["second"]
            }]
        })
        self.assertSequenceEqual(consequents, ["first"])

        del (consequents[:])

        jsonLogic({
            '?:': [False, {
                'push_then': ["first"]
            }, {
                'push_else': ["second"]
            }]
        })
        self.assertSequenceEqual(consequents, ["second"])
Пример #4
0
def calculate_price(registration, campers):
    '''
    Parameters
    ----------
    registration: camphoric.models.Registration
    campers: [camphoric.models.Camper]

    In order to calculate the price without writing to the database,
    campers are passed as a separate array.

    Returns
    -------
    dict:
        keys: registration level components, camper level components and total.
        values: subtotals of respective components and the total.
    '''
    results = defaultdict(int)
    event = registration.event

    data = {"registration": registration.attributes, "pricing": event.pricing}
    for reg_component, logic in event.registration_pricing_logic.items():
        results[reg_component] = jsonLogic(logic, data)

    for camper in campers:
        camper_data = {
            "registration": registration.attributes,
            "pricing": event.pricing,
            "camper": camper.attributes
        }
        for camper_component, logic in event.camper_pricing_logic.items():
            results[camper_component] += jsonLogic(logic, camper_data)

    results['total'] = sum(results.values())

    return dict(results)
Пример #5
0
 def test_if_can_return_non_logic_dictionaries(self):
     logic = {
         'if': [{
             '==': [{
                 'var': 'a'
             }, 1]
         }, {
             'test': 1,
             'data': 'if'
         }, {
             '==': [{
                 'var': 'a'
             }, 2]
         }, {
             'test': 2,
             'data': 'else if'
         }, {
             'test': 3,
             'data': 'else'
         }]
     }
     self.assertEqual(jsonLogic(logic, {'a': 1}), {'test': 1, 'data': 'if'})
     self.assertEqual(jsonLogic(logic, {'a': 2}), {
         'test': 2,
         'data': 'else if'
     })
     self.assertEqual(jsonLogic(logic, {'a': 3}), {
         'test': 3,
         'data': 'else'
     })
Пример #6
0
 def test_rm_operation_restores_overridden_operation(self):
     self.assertEqual(jsonLogic({'+': [2, 3]}), 5)
     add_operation('+', lambda *args: "Ha-ha!")
     try:
         self.assertEqual(jsonLogic({'+': [2, 3]}), "Ha-ha!")
     finally:
         rm_operation('+')
         self.assertEqual(jsonLogic({'+': [2, 3]}), 5)
         self.assertNotEqual(jsonLogic({'+': [2, 3]}), "Ha-ha!")
Пример #7
0
def main():
    # Temp. in Fahrenheit [Normal = 98.6 - 100.4]
    rule1 = {"<=": [{"var": "temp"}, 98.6]}

    rule2 = {
        "and": [{
            ">": [{
                "var": "temp"
            }, 98.6]
        }, {
            "<=": [{
                "var": "temp"
            }, 100.4]
        }]
    }

    # data = { "temp" : 50 }
    # data = { "temp" : 99 }
    # data = { "temp" : 500 }

    rule3 = {
        "and": [{
            ">": [{
                "var": "bp"
            }, 120]
        }, {
            ">": [{
                "var": "oxygen"
            }, 100]
        }, {
            ">": [{
                "var": "temp"
            }, 100.4]
        }]
    }

    data = sys.argv[1]

    try:
        data = json.loads(data)
    except Exception as e:
        print 'Error occured:', e

    data_temp = {"temp": float(data["temp"])}

    if jsonLogic(rule1, data_temp) == True:
        print 'Service Requested:'
        print "heat_up"
    elif jsonLogic(rule2, data_temp) == True:
        print 'Service Requested:'
        print "cool_down"
    elif jsonLogic(rule3, data) == True:
        print 'Next Workflow to execute:'
        print '_bp'
    else:
        print 'Next Workflow to execute:'
        print "_triplet"
Пример #8
0
 def test_or(self):
     """
     'or' can be used for simple boolean tests, with 1 or more arguments.
     """
     self.assertTrue(jsonLogic({"or": [True, False]}))
     # At a more sophisticated level, or returns the first truthy argument,
     # or the last argument.
     self.assertTrue(jsonLogic({"or": [False, True]}))
     self.assertEqual(jsonLogic({"or": [False, "apple"]}), "apple")
     self.assertEqual(jsonLogic({"or": [False, None, "apple"]}), "apple")
Пример #9
0
 def test_cmp(self):
     """Arithmetic comparison functions."""
     # Greater than:
     self.assertTrue(jsonLogic({">": [2, 1]}))
     # Greater than or equal to:
     self.assertTrue(jsonLogic({">=": [1, 1]}))
     # Less than:
     self.assertTrue(jsonLogic({"<": [1, 2]}))
     # Less than or equal to:
     self.assertTrue(jsonLogic({"<=": [1, 1]}))
Пример #10
0
 def test_and(self):
     """
     'and' can be used for simple boolean tests, with 1 or more arguments.
     """
     self.assertTrue(jsonLogic({"and": [True, True]}))
     self.assertFalse(jsonLogic({"and": [True, True, True, False]}))
     # At a more sophisticated level, and returns the first falsy argument,
     # or the last argument.
     self.assertFalse(jsonLogic({"and": [True, "apple", False]}))
     self.assertEqual(jsonLogic({"and": [True, "apple", 3.14]}), 3.14)
Пример #11
0
 def test_cat(self):
     """
     Concatenate all the supplied arguments. Note that this is not
     a join or implode operation, there is no "glue" string.
     """
     self.assertEqual(jsonLogic({"cat": ["I love", " pie"]}), "I love pie")
     self.assertEqual(
         jsonLogic({"cat": ["I love ", {
             "var": "filling"
         }, " pie"]}, {
             "filling": "apple",
             "temp": 110
         }), "I love apple pie")
Пример #12
0
    def test_add_operation_with_simple_method(self):
        def add_to_five(*args):
            return sum((5, ) + args)

        self.assertRaisesRegex(ValueError, "Unrecognized operation", jsonLogic,
                               {'add_to_five': [3]})
        add_operation('add_to_five', add_to_five)
        try:
            self.assertEqual(jsonLogic({'add_to_five': 1}), 6)
            self.assertEqual(jsonLogic({'add_to_five': [3]}), 8)
            self.assertEqual(jsonLogic({'add_to_five': [3, 2]}), 10)
        finally:
            rm_operation('add_to_five')
Пример #13
0
    def test_or_operator_does_not_evaluate_depth_first(self):
        # 'or' operator should stop at first truthy value
        evaluated_elements = []

        def push(arg):
            evaluated_elements.append(arg)
            return arg

        add_operation('push', push)

        jsonLogic({'or': [{'push': [False]}, {'push': [False]}]})
        self.assertSequenceEqual(evaluated_elements, [False, False])

        del (evaluated_elements[:])

        jsonLogic({'or': [{'push': [False]}, {'push': [True]}]})
        self.assertSequenceEqual(evaluated_elements, [False, True])

        del (evaluated_elements[:])

        jsonLogic({'or': [{'push': [True]}, {'push': [False]}]})
        self.assertSequenceEqual(evaluated_elements, [True])

        del (evaluated_elements[:])

        jsonLogic({'or': [{'push': [True]}, {'push': [True]}]})
        self.assertSequenceEqual(evaluated_elements, [True])
Пример #14
0
 def test_method_operation_with_method_without_arguments(self):
     todays_date = datetime.date.today()
     logic = {'method': [{'var': 'today'}, 'isoformat']}
     data = {'today': todays_date}
     returned_value = jsonLogic(logic, data)
     self.assertIsInstance(returned_value, six.string_types)
     self.assertEqual(returned_value, todays_date.isoformat())
Пример #15
0
    def validate_logic(self, errors, data_row, rec_idx, date_conversion_errors,
                       id_field, client_eps):
        """
        1. Checks the date format and converts dates into integer ('ordinal's) for easy comparison.
        2. Checks MDS business logic defined in MDS_RULES.py (and imported in the global 'rule_definitions').
            For example EPISODEs OVERLAP.(See 'ACT MDS Data Collection Guide' document for suggested logic checks)

        3. If there errors in the date formats, all the logic checks (for the passed-in data row),
            that involve the malformed dates are excluded.
           The errors from these validations are added to the 'errors' array that is passed in.

        4. client_eps : This is an (on-going) accumulated list of the start and end dates of the
            passed-in client's episodes. This allows us to calculate episode overlaps with the current data row.
        """

        temp_rd =  self.rule_definitions
        temp_rules = self.rules
        dce_fields = []
        if any(date_conversion_errors):
            dce_fields = [dce['field'] for dce in date_conversion_errors]
            temp_rd = remove_vrules(dce_fields)
            temp_rules = [rd['rule'] for rd in temp_rd]
        
        result = (jsonLogic(r, data_row) for r in temp_rules)
        
        logic_errors = compile_logic_errors(result, temp_rd, data_row,
                                             rec_idx, id_field, date_conversion_errors) 
        if rec_idx not in errors:
            errors[rec_idx] = logic_errors
        elif logic_errors:
            errors[rec_idx].extend(logic_errors)
        
        prep_and_check_overlap(data_row, client_eps, errors, rec_idx, dce_fields)
Пример #16
0
 def test_method_operation_with_property(self):
     todays_date = datetime.date.today()
     logic = {'method': [{'var': 'today'}, 'month']}
     data = {'today': todays_date}
     returned_value = jsonLogic(logic, data)
     self.assertIsInstance(returned_value, int)
     self.assertEqual(returned_value, todays_date.month)
Пример #17
0
 def test_type(self):
     """
     Checks type of first value to the string representation of the second value.
     """
     self.assertEqual(
         jsonLogic({"type": ["This is a string and should be None", None]}),
         True)
Пример #18
0
 def test_array_of_logic_entries_can_return_non_logic_dictionaries(self):
     logic = [{'+': [1, 2]}, {'test': 1, 'data': 'if'}]
     self.assertSequenceEqual(jsonLogic(logic),
                              [3, {
                                  'test': 1,
                                  'data': 'if'
                              }])
Пример #19
0
 def test_add_operation_with_packages(self):
     self.assertRaisesRegex(ValueError, "Unrecognized operation.*datetime",
                            jsonLogic, {'datetime.datetime.now': []})
     add_operation('datetime', datetime)
     try:
         # .now()
         start = datetime.datetime.now()
         returned_value = jsonLogic({'datetime.datetime.now': []})
         self.assertIsInstance(returned_value, datetime.datetime)
         self.assertTrue(start <= returned_value <= datetime.datetime.now())
         # .date()
         returned_value = jsonLogic({'datetime.date': [2018, 1, 1]})
         self.assertIsInstance(returned_value, datetime.date)
         self.assertEqual(returned_value, datetime.date(2018, 1, 1))
     finally:
         rm_operation('datetime')
Пример #20
0
    def conditionally_visible(self):
        """
        If conditional visibility applies, evaluate to see if it is visible.
        Note that the component can also be hidden, which is a separate concept.
        """
        try:
            cond = self.raw['conditional']
            if cond.get('json'):
                # Optional package
                try:
                    from json_logic import jsonLogic
                    context = {'data': self._all_data}
                    try:
                        context['row'] = self.component_owner.row
                    except AttributeError:
                        pass  # only datagrid rows have a "row" attribute
                    return jsonLogic(cond['json'], context)
                except ImportError:
                    logger = logging.getLogger(__name__)
                    logger.warn(f'Could not load json logic extension; will not evaluate visibility of {self.__class__.__name__} {self.id} ("{self.key}")')
                    return True

            elif cond.get('when'):
                triggering_component = self.component_owner.input_components[cond['when']]
                triggering_value = cond['eq']
                if triggering_component.value == triggering_value:
                    return cond['show']
                else:
                    return not cond['show']
        except KeyError:
            # Unknown component or no 'when', 'eq' or 'show' property
            pass

        # By default, it's visible
        return True
Пример #21
0
def main():
    # Considering Systolic Pressure only
    rule1 = {"<=": [{"var": "bp"}, 90]}

    rule2 = {"and": [{">": [{"var": "bp"}, 90]}, {"<=": [{"var": "bp"}, 120]}]}

    # data = { "bp" : 40 }
    # data = { "bp" : 100 }

    rule3 = {
        "and": [{
            ">": [{
                "var": "bp"
            }, 120]
        }, {
            ">": [{
                "var": "oxygen"
            }, 100]
        }, {
            ">": [{
                "var": "temp"
            }, 100.4]
        }]
    }
    # data = '{ "bp" : 99, "temp" : 5000, "xyz":455}'

    data = sys.argv[1]

    try:
        data = json.loads(data)
    except Exception as e:
        print 'Error occured:', e

    data_bp = {"bp": float(data["bp"])}

    if jsonLogic(rule1, data_bp) == True:
        print 'Service Requested:'
        print "take_high_medicine"
    elif jsonLogic(rule2, data_bp) == True:
        print 'Service Requested:'
        print "take_low_medicine"
    elif jsonLogic(rule3, data) == True:
        print 'Next Workflow to execute:'
        print '_temp'
    else:
        print 'Next Workflow to execute:'
        print "_triplet"
Пример #22
0
 def rule_triggers_event(rule, data, resources):
     if rule["resource"] not in resources:
         return False
     else:
         return rule["active"] and \
                resources[rule["resource"]]["guard"] and \
                rule["generates"] == "events" and \
                jsonLogic(rule["rule"], data)
Пример #23
0
 def test_arithmetic(self):
     """Arithmetic operators."""
     self.assertEqual(jsonLogic({"+": [1, 1]}), 2)
     self.assertEqual(jsonLogic({"*": [2, 3]}), 6)
     self.assertEqual(jsonLogic({"-": [3, 2]}), 1)
     self.assertEqual(jsonLogic({"/": [2, 4]}), .5)
     self.assertEqual(jsonLogic({"+": [1, 1]}), 2)
     # Because addition and multiplication are associative,
     # they happily take as many args as you want:
     self.assertEqual(jsonLogic({"+": [1, 1, 1, 1, 1]}), 5)
     self.assertEqual(jsonLogic({"*": [2, 2, 2, 2, 2]}), 32)
     # Passing just one argument to - returns its arithmetic
     # negative (additive inverse).
     self.assertEqual(jsonLogic({"-": [2]}), -2)
     self.assertEqual(jsonLogic({"-": [-2]}), 2)
     # Passing just one argument to + casts it to a number.
     self.assertEqual(jsonLogic({"+": "0"}), 0)
Пример #24
0
 def test_rm_operation_removes_custom_operation(self):
     add_operation('custom', lambda: "Ha-ha!")
     try:
         self.assertEqual(jsonLogic({'custom': []}), "Ha-ha!")
     finally:
         rm_operation('custom')
     self.assertRaisesRegex(ValueError, "Unrecognized operation", jsonLogic,
                            {'custom': []})
Пример #25
0
def determine_score(rules, data):
    score = 0
    if rules and isinstance(rules, List):
        for rule_obj in rules:
            rule = rule_obj.get(CONSTANTS.RULE_KEY)
            points = rule_obj.get(CONSTANTS.POINTS_KEY)
            if jsonLogic(rule, data):
                score = score + points
    return score
Пример #26
0
def property_filter_literal(candidate, simple_filter):
    '''
    Given a single candidate entity ("uri", list_labels) and a filter where the value is a literal, it gives a tuple
    (true/false, score) where true/false depends on if the filter is respected and score is the product between
    similarity (or distance) and weight of the filter
    '''
    #value = simple_filter.get_value()
    #threshold = simple_filter.get_threshold()
    results = find_property(candidate, simple_filter.get_property())
    list_literal = []
    list_uri = []
    results_uri = []
    list_literal_2 = []
    for result in results["results"]["bindings"]:
        if result["object"]["type"] == 'literal':
            list_literal.append(result["object"]["value"])
        elif result["object"]["type"] == 'uri':
            #list_uri.append(result["object"]["value"])
            x = find_property(result["object"]["value"],
                              "http://www.w3.org/2000/01/rdf-schema#label")
            y = find_property(result["object"]["value"],
                              "http://xmlns.com/foaf/0.1/name")
            for j in x["results"]["bindings"]:
                list_literal_2.append(j["object"]["value"])
            for k in y["results"]["bindings"]:
                list_literal_2.append(k["object"]["value"])
            '''results_uri.append(x)  # rdfs:label
            results_uri.append(y)  # foaf:name'''
    #print("list literal:", list_literal)
    #print("list uri:", list_uri)
    #filter_literal =  {"some" : [list_literal, {"<=" : [{"edit_distance" : [{"var" : ""}, value]}, threshold]}]}
    #print("filter literal:", jsonLogic(filter_literal))
    '''for y in results_uri:
        for j in y["results"]["bindings"]:
            list_literal_2.append(j["object"]["value"])'''
    #print("list literal 2:", list_literal_2)
    list_total = list_literal + list_literal_2
    #print("list total:", list_total)
    '''#filter_uri =  {"some" : [list_literal_2, {"<=" : [{"edit_distance" : [{"var" : ""}, value]}, threshold]}]}
    filter = {"some" : [list_total, {"<=": [{"edit_distance": [{"var": ""}, value]}, threshold]}]}
    list_editdistance = jsonLogic({"map" : [list_total, {"edit_distance": [{"var": ""}, value]}]})
    print("list editdistace:", list_editdistance)
    min_editdistance = jsonLogic({"min" : list_editdistance})
    print("editdistance min:", jsonLogic(min_editdistance))
    #print("filter uri:", jsonLogic(filter_uri))
    print("filter total:", jsonLogic(filter))
    print("score:", min_editdistance * simple_filter.get_weight())'''
    if (len(list_total) != 0):
        filter_and_score = similarity_filter(simple_filter, list_total)
        #print("filter and score[0]", filter_and_score[0])
        #print("jsonlogic", jsonLogic(filter_and_score[0]))
        #print("result", (jsonLogic(filter_and_score[0]), filter_and_score[1] * simple_filter.get_weight()))
        return (jsonLogic(filter_and_score[0]),
                filter_and_score[1] * simple_filter.get_weight())
    else:
        return ("No matches", None)
Пример #27
0
 def test_operations_value_modifications_do_not_impact_fuctionality(self):
     global operations
     old_operations = operations
     try:
         operations['+'] = lambda *args: "Ha-ha!"
         result = jsonLogic({'+': [1, 2]})
         self.assertNotEqual(result, "Ha-ha!")
         self.assertEqual(result, 3)
     finally:
         operations = old_operations  # Restore exposed operations list
Пример #28
0
def filter_candidates(candidate_list, total_filter):
    '''
    Given the list of candidate entities for a single value and the filter that aggregates all the filters, it returns
    only the candidate entities which satisfy total_filter
    '''
    new_candidate_list = []
    for x in candidate_list:
        if jsonLogic(total_filter):
            new_candidate_list.append(x)
    return new_candidate_list
Пример #29
0
 def test_array(self):
     self.assertEqual(
         jsonLogic([{
             "var": "a"
         }, {
             "var": "b"
         }], {
             "a": 1,
             "b": 2
         }), [1, 2])
Пример #30
0
 def test_depth_first_rule_still_applies_to_custom_operators(self):
     add_operation('sum_up', lambda *args: sum(args))
     try:
         self.assertEqual(
             jsonLogic({'sum_up': [{
                 '-': [5, 3]
             }, {
                 '*': [2, 3]
             }]}), 8)
     finally:
         rm_operation('sum_up')