Exemple #1
0
    def test_traverse_lines(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict11 = {'Alice': {'Grade': 4.0}}
        value_dict12 = {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.0}}
        value_dict21 = {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}, 'CS': {'Rank': 2, 'Grade': 3.9}}}
        value_dict22 = {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}, 'CS': {'Rank': 2, 'Grade': 3.8}},
                        'Bob': {'Math': {'Rank': 2, 'Grade': 3.0}, 'CS': {'Rank': 1, 'Grade': 3.9}}}

        value_lines11 = [{'Name': 'Alice', 'Grade': 4.0}]
        value_lines12 = [{'Name': 'Alice', 'Grade': 4.0}, {'Name': 'Bob', 'Grade': 3.0}]
        value_lines21 = [{'Name': 'Alice', 'Subject': 'Math', 'Rank': 1, 'Grade': 4.0},
                         {'Name': 'Alice', 'Subject': 'CS', 'Rank': 2, 'Grade': 3.9}]
        value_lines22 = [{'Name': 'Alice', 'Subject': 'Math', 'Rank': 1, 'Grade': 4.0},
                         {'Name': 'Alice', 'Subject': 'CS', 'Rank': 2, 'Grade': 3.8},
                         {'Name': 'Bob', 'Subject': 'Math', 'Rank': 2, 'Grade': 3.0},
                         {'Name': 'Bob', 'Subject': 'CS', 'Rank': 1, 'Grade': 3.9}]

        self.assertEqual(value_dict11, Hierarchy.traverse_lines(hierarchy1, value_lines11))
        self.assertEqual(value_dict12, Hierarchy.traverse_lines(hierarchy1, value_lines12))
        self.assertEqual(value_dict21, Hierarchy.traverse_lines(hierarchy2, value_lines21))
        self.assertEqual(value_dict22, Hierarchy.traverse_lines(hierarchy2, value_lines22))
Exemple #2
0
    def test_apply_post_map(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank

        grade.post_map_f = lambda _, x: x - 1.0
        rank.post_map_f = lambda _, x: x + 1

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict1 = {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.0}}
        value_dict2 = {
            'Alice': {
                'Math': {
                    'Rank': 1,
                    'Grade': 4.0
                }
            },
            'Bob': {
                'CS': {
                    'Rank': 2,
                    'Grade': 3.0
                }
            }
        }

        Hierarchy.apply_post_map(hierarchy1, value_dict1, {})
        Hierarchy.apply_post_map(hierarchy2, value_dict2, {})

        self.assertEqual(value_dict1, {
            'Alice': {
                'Grade': 3.0
            },
            'Bob': {
                'Grade': 2.0
            }
        })
        self.assertEqual(
            value_dict2, {
                'Alice': {
                    'Math': {
                        'Rank': 2,
                        'Grade': 3.0
                    }
                },
                'Bob': {
                    'CS': {
                        'Rank': 3,
                        'Grade': 2.0
                    }
                }
            })
Exemple #3
0
    def __init__(self, hierarchy_spec, value_line):
        """Initialize the writer.

        :param hierarchy_spec: a hierarchy specification (described in Hierarchy.py) describing the input dictionary.
        :param value_line ([GeneralValue]): an ordered value object list specifying each line of output.
        """
        Hierarchy.check(hierarchy_spec)
        for value in value_line:
            if not isinstance(value, GeneralValue):
                raise ValueError("Value is not a value object")

        self.hierarchy_spec = hierarchy_spec
        self.value_line = value_line
Exemple #4
0
    def __init__(self, hierarchy_spec, value_line):
        """Initialize the writer.

        :param hierarchy_spec: a hierarchy specification (described in Hierarchy.py) describing the input dictionary.
        :param value_line ([GeneralValue]): an ordered value object list specifying each line of output.
        """
        Hierarchy.check(hierarchy_spec)
        for value in value_line:
            if not isinstance(value, GeneralValue):
                raise ValueError("Value is not a value object")

        self.hierarchy_spec = hierarchy_spec
        self.value_line = value_line
Exemple #5
0
    def test_merge(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank.state_value()

        grade.reduce_f = max
        rank.reduce_f = min
        grade.post_map_f = lambda _, x: x - 1.0
        rank.post_map_f = lambda _, x: x + 1
        grade.post_reduce_f = min
        rank.post_reduce_f = max

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict11 = {'Alice': {'Grade': 4.0}}
        value_dict12 = {'Alice': {'Grade': 3.0}}
        value_dict13 = {'Bob': {'Grade': 3.5}}
        value_dict20 = {'Alice': {'Math': {'Rank': 2, 'Grade': 3.0}}}
        value_dict21 = {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}}}
        value_dict22 = {'Alice': {'CS': {'Rank': 2, 'Grade': 3.9}}}
        value_dict23 = {'Bob': {'Math': {'Rank': 2, 'Grade': 3.0}}}

        self.assertEqual(Hierarchy.merge(hierarchy1, value_dict11, value_dict12),
                         {'Alice': {'Grade': 4.0}})
        self.assertEqual(Hierarchy.merge(hierarchy1, value_dict11, value_dict12, True),
                         {'Alice': {'Grade': 2.0}})
        self.assertEqual(Hierarchy.merge(hierarchy1, value_dict11, value_dict13),
                         {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.5}})
        self.assertEqual(Hierarchy.merge(hierarchy1, value_dict11, value_dict13, True),
                         {'Alice': {'Grade': 3.0}, 'Bob': {'Grade': 2.5}})

        self.assertEqual(Hierarchy.merge(hierarchy2, value_dict20, value_dict21),
                         {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}}})
        self.assertEqual(Hierarchy.merge(hierarchy2, value_dict20, value_dict21, True),
                         {'Alice': {'Math': {'Rank': 3, 'Grade': 2.0}}})
        self.assertEqual(Hierarchy.merge(hierarchy2, value_dict21, value_dict22),
                         {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0},
                                    'CS': {'Rank': 2, 'Grade': 3.9}}})
        self.assertEqual(Hierarchy.merge(hierarchy2, value_dict21, value_dict22, True),
                         {'Alice': {'Math': {'Rank': 2, 'Grade': 3.0},
                                    'CS': {'Rank': 3, 'Grade': 2.9}}})
        self.assertEqual(Hierarchy.merge(hierarchy2, value_dict21, value_dict23),
                         {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}},
                          'Bob': {'Math': {'Rank': 2, 'Grade': 3.0}}})
        self.assertEqual(Hierarchy.merge(hierarchy2, value_dict21, value_dict23, True),
                         {'Alice': {'Math': {'Rank': 2, 'Grade': 3.0}},
                          'Bob': {'Math': {'Rank': 3, 'Grade': 2.0}}})
Exemple #6
0
    def __init__(self, hierarchy_spec, state=State({}), filter_f=lambda _, x: True):
        """Initialize the reader.

        :param hierarchy_spec: a (or a list of) hierarchy specification (described in Hierarchy.py).
        :param state (State): the state involved in reading.
        :param filter_f (State * Line -> bool): the predicate for filtering lines with access to state.
        """
        Hierarchy.check(hierarchy_spec)
        if not isinstance(state, State):
            raise ValueError("State is a State object")

        self.hierarchy_spec = hierarchy_spec
        self.state = state
        self.filter_f = filter_f
        self.__init_state = deepcopy(self.state)
Exemple #7
0
    def __init__(self,
                 hierarchy_spec,
                 state=State({}),
                 filter_f=lambda _, x: True):
        """Initialize the reader.

        :param hierarchy_spec: a (or a list of) hierarchy specification (described in Hierarchy.py).
        :param state (State): the state involved in reading.
        :param filter_f (State * Line -> bool): the predicate for filtering lines with access to state.
        """
        Hierarchy.check(hierarchy_spec)
        if not isinstance(state, State):
            raise ValueError("State is a State object")

        self.hierarchy_spec = hierarchy_spec
        self.state = state
        self.filter_f = filter_f
        self.__init_state = deepcopy(self.state)
Exemple #8
0
    def read_lines(self, value_lines, apply_post_map=False, carry_state=False):
        """Store the data in a list of lines with respect to the hierarchy specification of values

        :param value_lines ([dict]): a list of (name => value) dictionary
        :param apply_post_map (bool): whether apply post_map or not
        :param carry_state: whether mutate the input state
        :return (dict): the result dictionary and the final state.
        """
        # if not carry state, copy the state object such that the input state is not mutated.
        if not carry_state:
            current_state = deepcopy(self.state)
        else:
            current_state = self.state

        value_hierarchy = Hierarchy.traverse_lines(self.hierarchy_spec, value_lines, current_state, self.filter_f)

        # apply post_map_f in each value if apply_post_map is true
        if apply_post_map:
            Hierarchy.apply_post_map(self.hierarchy_spec, value_hierarchy, current_state)

        return value_hierarchy, current_state
Exemple #9
0
    def write(self, out_file, value_hierarchy, mode='w', sort_by=None, reverse=False):
        """Write a file according to value line specification.

        :param out_file (OutputFile): the file to write.
        :param value_hierarchy (dict): a value hierarchy (dictionary) for writing to the file.
        :param mode (str): writing mode ("w", "w+", ...)
        :param sort_by (str): the name of a value to sort by.
        :param reverse: sort in reverse order or not.
        """

        # flatten the value hierarchy (dictionary)
        value_lines = Hierarchy.flatten(self.hierarchy_spec, value_hierarchy)
        self.write_lines(out_file, value_lines, mode, sort_by, reverse)
Exemple #10
0
    def test_apply_post_map(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank

        grade.post_map_f = lambda _, x: x - 1.0
        rank.post_map_f = lambda _, x: x + 1

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict1 = {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.0}}
        value_dict2 = {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}},
                       'Bob': {'CS': {'Rank': 2, 'Grade': 3.0}}}

        Hierarchy.apply_post_map(hierarchy1, value_dict1, {})
        Hierarchy.apply_post_map(hierarchy2, value_dict2, {})

        self.assertEqual(value_dict1, {'Alice': {'Grade': 3.0}, 'Bob': {'Grade': 2.0}})
        self.assertEqual(value_dict2, {'Alice': {'Math': {'Rank': 2, 'Grade': 3.0}},
                                       'Bob': {'CS': {'Rank': 3, 'Grade': 2.0}}})
Exemple #11
0
    def read_lines(self, value_lines, apply_post_map=False, carry_state=False):
        """Store the data in a list of lines with respect to the hierarchy specification of values

        :param value_lines ([dict]): a list of (name => value) dictionary
        :param apply_post_map (bool): whether apply post_map or not
        :param carry_state: whether mutate the input state
        :return (dict): the result dictionary and the final state.
        """
        # if not carry state, copy the state object such that the input state is not mutated.
        if not carry_state:
            current_state = deepcopy(self.state)
        else:
            current_state = self.state

        value_hierarchy = Hierarchy.traverse_lines(self.hierarchy_spec,
                                                   value_lines, current_state,
                                                   self.filter_f)

        # apply post_map_f in each value if apply_post_map is true
        if apply_post_map:
            Hierarchy.apply_post_map(self.hierarchy_spec, value_hierarchy,
                                     current_state)

        return value_hierarchy, current_state
Exemple #12
0
    def test_flatten(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank.state_value()

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict11 = {'Alice': {'Grade': 4.0}}
        value_dict12 = {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.0}}
        value_dict21 = {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}, 'CS': {'Rank': 2, 'Grade': 3.9}}}
        value_dict22 = {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}, 'CS': {'Rank': 2, 'Grade': 3.8}},
                        'Bob': {'Math': {'Rank': 2, 'Grade': 3.0}, 'CS': {'Rank': 1, 'Grade': 3.9}}}

        def key(v):
            return v['Grade']

        value_lines11 = Hierarchy.flatten(hierarchy1, value_dict11)
        self.assertEqual(value_lines11, [{'Name': 'Alice', 'Grade': 4.0}])

        value_lines12 = Hierarchy.flatten(hierarchy1, value_dict12)
        self.assertEqual(sorted(value_lines12, key=key),
                         sorted([{'Name': 'Alice', 'Grade': 4.0}, {'Name': 'Bob', 'Grade': 3.0}], key=key))

        value_lines21 = Hierarchy.flatten(hierarchy2, value_dict21)
        self.assertEqual(sorted(value_lines21, key=key),
                         sorted([{'Name': 'Alice', 'Subject': 'Math', 'Rank': 1, 'Grade': 4.0},
                                 {'Name': 'Alice', 'Subject': 'CS', 'Rank': 2, 'Grade': 3.9}], key=key))

        value_lines22 = Hierarchy.flatten(hierarchy2, value_dict22)
        self.assertEqual(sorted(value_lines22, key=key),
                         sorted([{'Name': 'Alice', 'Subject': 'Math', 'Rank': 1, 'Grade': 4.0},
                                 {'Name': 'Alice', 'Subject': 'CS', 'Rank': 2, 'Grade': 3.8},
                                 {'Name': 'Bob', 'Subject': 'Math', 'Rank': 2, 'Grade': 3.0},
                                 {'Name': 'Bob', 'Subject': 'CS', 'Rank': 1, 'Grade': 3.9}], key=key))
Exemple #13
0
    def write(self,
              out_file,
              value_hierarchy,
              mode='w',
              sort_by=None,
              reverse=False):
        """Write a file according to value line specification.

        :param out_file (OutputFile): the file to write.
        :param value_hierarchy (dict): a value hierarchy (dictionary) for writing to the file.
        :param mode (str): writing mode ("w", "w+", ...)
        :param sort_by (str): the name of a value to sort by.
        :param reverse: sort in reverse order or not.
        """

        # flatten the value hierarchy (dictionary)
        value_lines = Hierarchy.flatten(self.hierarchy_spec, value_hierarchy)
        self.write_lines(out_file, value_lines, mode, sort_by, reverse)
Exemple #14
0
    def test_traverse_lines(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict11 = {'Alice': {'Grade': 4.0}}
        value_dict12 = {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.0}}
        value_dict21 = {
            'Alice': {
                'Math': {
                    'Rank': 1,
                    'Grade': 4.0
                },
                'CS': {
                    'Rank': 2,
                    'Grade': 3.9
                }
            }
        }
        value_dict22 = {
            'Alice': {
                'Math': {
                    'Rank': 1,
                    'Grade': 4.0
                },
                'CS': {
                    'Rank': 2,
                    'Grade': 3.8
                }
            },
            'Bob': {
                'Math': {
                    'Rank': 2,
                    'Grade': 3.0
                },
                'CS': {
                    'Rank': 1,
                    'Grade': 3.9
                }
            }
        }

        value_lines11 = [{'Name': 'Alice', 'Grade': 4.0}]
        value_lines12 = [{
            'Name': 'Alice',
            'Grade': 4.0
        }, {
            'Name': 'Bob',
            'Grade': 3.0
        }]
        value_lines21 = [{
            'Name': 'Alice',
            'Subject': 'Math',
            'Rank': 1,
            'Grade': 4.0
        }, {
            'Name': 'Alice',
            'Subject': 'CS',
            'Rank': 2,
            'Grade': 3.9
        }]
        value_lines22 = [{
            'Name': 'Alice',
            'Subject': 'Math',
            'Rank': 1,
            'Grade': 4.0
        }, {
            'Name': 'Alice',
            'Subject': 'CS',
            'Rank': 2,
            'Grade': 3.8
        }, {
            'Name': 'Bob',
            'Subject': 'Math',
            'Rank': 2,
            'Grade': 3.0
        }, {
            'Name': 'Bob',
            'Subject': 'CS',
            'Rank': 1,
            'Grade': 3.9
        }]

        self.assertEqual(value_dict11,
                         Hierarchy.traverse_lines(hierarchy1, value_lines11))
        self.assertEqual(value_dict12,
                         Hierarchy.traverse_lines(hierarchy1, value_lines12))
        self.assertEqual(value_dict21,
                         Hierarchy.traverse_lines(hierarchy2, value_lines21))
        self.assertEqual(value_dict22,
                         Hierarchy.traverse_lines(hierarchy2, value_lines22))
Exemple #15
0
    def test_flatten(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank.state_value()

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict11 = {'Alice': {'Grade': 4.0}}
        value_dict12 = {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.0}}
        value_dict21 = {
            'Alice': {
                'Math': {
                    'Rank': 1,
                    'Grade': 4.0
                },
                'CS': {
                    'Rank': 2,
                    'Grade': 3.9
                }
            }
        }
        value_dict22 = {
            'Alice': {
                'Math': {
                    'Rank': 1,
                    'Grade': 4.0
                },
                'CS': {
                    'Rank': 2,
                    'Grade': 3.8
                }
            },
            'Bob': {
                'Math': {
                    'Rank': 2,
                    'Grade': 3.0
                },
                'CS': {
                    'Rank': 1,
                    'Grade': 3.9
                }
            }
        }

        def key(v):
            return v['Grade']

        value_lines11 = Hierarchy.flatten(hierarchy1, value_dict11)
        self.assertEqual(value_lines11, [{'Name': 'Alice', 'Grade': 4.0}])

        value_lines12 = Hierarchy.flatten(hierarchy1, value_dict12)
        self.assertEqual(
            sorted(value_lines12, key=key),
            sorted([{
                'Name': 'Alice',
                'Grade': 4.0
            }, {
                'Name': 'Bob',
                'Grade': 3.0
            }],
                   key=key))

        value_lines21 = Hierarchy.flatten(hierarchy2, value_dict21)
        self.assertEqual(
            sorted(value_lines21, key=key),
            sorted([{
                'Name': 'Alice',
                'Subject': 'Math',
                'Rank': 1,
                'Grade': 4.0
            }, {
                'Name': 'Alice',
                'Subject': 'CS',
                'Rank': 2,
                'Grade': 3.9
            }],
                   key=key))

        value_lines22 = Hierarchy.flatten(hierarchy2, value_dict22)
        self.assertEqual(
            sorted(value_lines22, key=key),
            sorted([{
                'Name': 'Alice',
                'Subject': 'Math',
                'Rank': 1,
                'Grade': 4.0
            }, {
                'Name': 'Alice',
                'Subject': 'CS',
                'Rank': 2,
                'Grade': 3.8
            }, {
                'Name': 'Bob',
                'Subject': 'Math',
                'Rank': 2,
                'Grade': 3.0
            }, {
                'Name': 'Bob',
                'Subject': 'CS',
                'Rank': 1,
                'Grade': 3.9
            }],
                   key=key))
Exemple #16
0
    def test_traverse(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank.state_value()

        grade.map_f = lambda _, x: float(x)
        grade.reduce_f = max
        rank.map_f = lambda _, x: int(x)
        rank.reduce_f = min

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        line11 = {'Name': 'Alice', 'Subject': 'Math', 'Grade': '3.0'}
        line12 = {'Name': 'Alice', 'Subject': 'Math', 'Grade': '4.0'}
        line13 = {'Name': 'Alice', 'Subject': 'CS', 'Grade': '3.5'}
        line21 = {'Name': 'Bob', 'Subject': 'CS', 'Grade': '3.5'}
        line22 = {'Name': 'Bob', 'Subject': 'CS', 'Grade': '3.0'}
        line23 = {'Name': 'Bob', 'Subject': 'Math', 'Grade': '4.0'}

        value_dict1 = {}
        Hierarchy.traverse(hierarchy1, line11, {'Rank': '3'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 3.0}})
        Hierarchy.traverse(hierarchy1, line12, {'Rank': '1'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 4.0}})
        Hierarchy.traverse(hierarchy1, line13, {'Rank': '2'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 4.0}})
        Hierarchy.traverse(hierarchy1, line21, {'Rank': '2'}, value_dict1)
        self.assertEqual(value_dict1, {
            'Alice': {
                'Grade': 4.0
            },
            'Bob': {
                'Grade': 3.5
            }
        })
        Hierarchy.traverse(hierarchy1, line22, {'Rank': '3'}, value_dict1)
        self.assertEqual(value_dict1, {
            'Alice': {
                'Grade': 4.0
            },
            'Bob': {
                'Grade': 3.5
            }
        })
        Hierarchy.traverse(hierarchy1, line23, {'Rank': '1'}, value_dict1)
        self.assertEqual(value_dict1, {
            'Alice': {
                'Grade': 4.0
            },
            'Bob': {
                'Grade': 4.0
            }
        })

        value_dict2 = {}
        Hierarchy.traverse(hierarchy2, line11, {'Rank': '3'}, value_dict2)
        self.assertEqual(value_dict2,
                         {'Alice': {
                             'Math': {
                                 'Grade': 3.0,
                                 'Rank': 3
                             }
                         }})
        Hierarchy.traverse(hierarchy2, line12, {'Rank': '1'}, value_dict2)
        self.assertEqual(value_dict2,
                         {'Alice': {
                             'Math': {
                                 'Grade': 4.0,
                                 'Rank': 1
                             }
                         }})
        Hierarchy.traverse(hierarchy2, line13, {'Rank': '2'}, value_dict2)
        self.assertEqual(
            value_dict2, {
                'Alice': {
                    'Math': {
                        'Grade': 4.0,
                        'Rank': 1
                    },
                    'CS': {
                        'Grade': 3.5,
                        'Rank': 2
                    }
                }
            })
        Hierarchy.traverse(hierarchy2, line21, {'Rank': '2'}, value_dict2)
        self.assertEqual(
            value_dict2, {
                'Alice': {
                    'Math': {
                        'Grade': 4.0,
                        'Rank': 1
                    },
                    'CS': {
                        'Grade': 3.5,
                        'Rank': 2
                    }
                },
                'Bob': {
                    'CS': {
                        'Grade': 3.5,
                        'Rank': 2
                    }
                }
            })
        Hierarchy.traverse(hierarchy2, line22, {'Rank': '3'}, value_dict2)
        self.assertEqual(
            value_dict2, {
                'Alice': {
                    'Math': {
                        'Grade': 4.0,
                        'Rank': 1
                    },
                    'CS': {
                        'Grade': 3.5,
                        'Rank': 2
                    }
                },
                'Bob': {
                    'CS': {
                        'Grade': 3.5,
                        'Rank': 2
                    }
                }
            })
        Hierarchy.traverse(hierarchy2, line23, {'Rank': '1'}, value_dict2)
        self.assertEqual(
            value_dict2, {
                'Alice': {
                    'Math': {
                        'Grade': 4.0,
                        'Rank': 1
                    },
                    'CS': {
                        'Grade': 3.5,
                        'Rank': 2
                    }
                },
                'Bob': {
                    'CS': {
                        'Grade': 3.5,
                        'Rank': 2
                    },
                    'Math': {
                        'Grade': 4.0,
                        'Rank': 1
                    }
                }
            })
Exemple #17
0
    def test_check(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank
        s_name = self.name.state_value()
        s_subject = self.subject.state_value()
        s_grade = self.grade.state_value()
        s_rank = self.rank.state_value()

        Hierarchy.check({name: [grade]})
        Hierarchy.check({name: [grade, subject]})
        Hierarchy.check({name: [grade, subject, rank]})
        Hierarchy.check({name: {subject: [grade, rank]}})
        Hierarchy.check({name: {subject: {grade: [rank]}}})
        Hierarchy.check({s_name: [s_grade]})
        Hierarchy.check({s_name: [s_grade, s_subject]})
        Hierarchy.check({s_name: [s_grade, s_subject, s_rank]})
        Hierarchy.check({s_name: {s_subject: [s_grade, s_rank]}})
        Hierarchy.check({s_name: {s_subject: {s_grade: [s_rank]}}})

        with self.assertRaises(Exception):
            Hierarchy.check(name)
        with self.assertRaises(Exception):
            Hierarchy.check({name: grade})
        with self.assertRaises(Exception):
            Hierarchy.check({name: {subject: [grade], rank: [grade]}})
        with self.assertRaises(Exception):
            Hierarchy.check([{name: grade}])
        with self.assertRaises(Exception):
            Hierarchy.check(s_name)
        with self.assertRaises(Exception):
            Hierarchy.check({s_name: s_grade})
        with self.assertRaises(Exception):
            Hierarchy.check(
                {s_name: {
                    s_subject: [s_grade],
                    s_rank: [s_grade]
                }})
        with self.assertRaises(Exception):
            Hierarchy.check([{s_name: s_grade}])
Exemple #18
0
    def test_merge(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank.state_value()

        grade.reduce_f = max
        rank.reduce_f = min
        grade.post_map_f = lambda _, x: x - 1.0
        rank.post_map_f = lambda _, x: x + 1
        grade.post_reduce_f = min
        rank.post_reduce_f = max

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        value_dict11 = {'Alice': {'Grade': 4.0}}
        value_dict12 = {'Alice': {'Grade': 3.0}}
        value_dict13 = {'Bob': {'Grade': 3.5}}
        value_dict20 = {'Alice': {'Math': {'Rank': 2, 'Grade': 3.0}}}
        value_dict21 = {'Alice': {'Math': {'Rank': 1, 'Grade': 4.0}}}
        value_dict22 = {'Alice': {'CS': {'Rank': 2, 'Grade': 3.9}}}
        value_dict23 = {'Bob': {'Math': {'Rank': 2, 'Grade': 3.0}}}

        self.assertEqual(
            Hierarchy.merge(hierarchy1, value_dict11, value_dict12),
            {'Alice': {
                'Grade': 4.0
            }})
        self.assertEqual(
            Hierarchy.merge(hierarchy1, value_dict11, value_dict12, True),
            {'Alice': {
                'Grade': 2.0
            }})
        self.assertEqual(
            Hierarchy.merge(hierarchy1, value_dict11, value_dict13), {
                'Alice': {
                    'Grade': 4.0
                },
                'Bob': {
                    'Grade': 3.5
                }
            })
        self.assertEqual(
            Hierarchy.merge(hierarchy1, value_dict11, value_dict13, True), {
                'Alice': {
                    'Grade': 3.0
                },
                'Bob': {
                    'Grade': 2.5
                }
            })

        self.assertEqual(
            Hierarchy.merge(hierarchy2, value_dict20, value_dict21),
            {'Alice': {
                'Math': {
                    'Rank': 1,
                    'Grade': 4.0
                }
            }})
        self.assertEqual(
            Hierarchy.merge(hierarchy2, value_dict20, value_dict21, True),
            {'Alice': {
                'Math': {
                    'Rank': 3,
                    'Grade': 2.0
                }
            }})
        self.assertEqual(
            Hierarchy.merge(hierarchy2, value_dict21, value_dict22), {
                'Alice': {
                    'Math': {
                        'Rank': 1,
                        'Grade': 4.0
                    },
                    'CS': {
                        'Rank': 2,
                        'Grade': 3.9
                    }
                }
            })
        self.assertEqual(
            Hierarchy.merge(hierarchy2, value_dict21, value_dict22, True), {
                'Alice': {
                    'Math': {
                        'Rank': 2,
                        'Grade': 3.0
                    },
                    'CS': {
                        'Rank': 3,
                        'Grade': 2.9
                    }
                }
            })
        self.assertEqual(
            Hierarchy.merge(hierarchy2, value_dict21, value_dict23), {
                'Alice': {
                    'Math': {
                        'Rank': 1,
                        'Grade': 4.0
                    }
                },
                'Bob': {
                    'Math': {
                        'Rank': 2,
                        'Grade': 3.0
                    }
                }
            })
        self.assertEqual(
            Hierarchy.merge(hierarchy2, value_dict21, value_dict23, True), {
                'Alice': {
                    'Math': {
                        'Rank': 2,
                        'Grade': 3.0
                    }
                },
                'Bob': {
                    'Math': {
                        'Rank': 3,
                        'Grade': 2.0
                    }
                }
            })
Exemple #19
0
    def read(self, data_file, mode='r', apply_post_map=False, carry_state=False):
        """Read a file to store the data with respect to the hierarchy specification of values.

        :param data_file (DataFile): the file to read.
        :param mode (str): reading mode ('r', 'r+', ...).
        :param apply_post_map (bool): whether apply post_map for each value or not.
        :param carry_state (bool): whether keep the mutated state or not.
        :return (dict, State): the result dictionary and the final state.
        """
        if not isinstance(data_file, DataFile):
            raise ValueError("Data file is not a DataFile object.")

        lineno = 0
        value_hierarchy = {}

        # if not carry state, copy the state object such that the input state is not mutated.
        if not carry_state:
            current_state = deepcopy(self.state)
        else:
            current_state = self.state

        filter_f = self.filter_f
        hierarchy_spec = self.hierarchy_spec

        file_name = data_file.file_name
        line = data_file.line
        header_lineno = data_file.header_lineno

        store_line = line.store
        set_line_header = line.set_header

        release = current_state.release
        update = current_state.update
        lock = current_state.lock

        traverse = Hierarchy.traverse

        def update_state(line):
            release()
            update(line)
            lock()

        with open(file_name, mode) as file:

            for data_line in file:
                try:
                    # read a line
                    store_line(data_line[:-1])

                    # set header if header line number matches
                    if header_lineno == lineno:
                        set_line_header()
                        lineno += 1
                        continue

                    # update state
                    # current_state.release()
                    # current_state.update(line)
                    # current_state.lock()
                    update_state(line)

                    # filter out a line if predicate returns false
                    if not filter_f(current_state, line):
                        lineno += 1
                        continue

                    # traverse a line with respect to hierarchy
                    traverse(hierarchy_spec, line, current_state, value_hierarchy)

                except (KeyError, ValueError):
                    print("Error occurred when reading line %s of %s" % (str(lineno+1), file_name))
                    raise

                lineno += 1

        # apply post_map_f in each value if apply_post_map is true
        if apply_post_map:
            Hierarchy.apply_post_map(hierarchy_spec, value_hierarchy, current_state)

        return value_hierarchy, current_state
Exemple #20
0
    def read(self,
             data_file,
             mode='r',
             apply_post_map=False,
             carry_state=False):
        """Read a file to store the data with respect to the hierarchy specification of values.

        :param data_file (DataFile): the file to read.
        :param mode (str): reading mode ('r', 'r+', ...).
        :param apply_post_map (bool): whether apply post_map for each value or not.
        :param carry_state (bool): whether keep the mutated state or not.
        :return (dict, State): the result dictionary and the final state.
        """
        if not isinstance(data_file, DataFile):
            raise ValueError("Data file is not a DataFile object.")

        lineno = 0
        value_hierarchy = {}

        # if not carry state, copy the state object such that the input state is not mutated.
        if not carry_state:
            current_state = deepcopy(self.state)
        else:
            current_state = self.state

        filter_f = self.filter_f
        hierarchy_spec = self.hierarchy_spec

        file_name = data_file.file_name
        line = data_file.line
        header_lineno = data_file.header_lineno

        store_line = line.store
        set_line_header = line.set_header

        release = current_state.release
        update = current_state.update
        lock = current_state.lock

        traverse = Hierarchy.traverse

        def update_state(line):
            release()
            update(line)
            lock()

        with open(file_name, mode) as file:

            for data_line in file:
                try:
                    # read a line
                    store_line(data_line[:-1])

                    # set header if header line number matches
                    if header_lineno == lineno:
                        set_line_header()
                        lineno += 1
                        continue

                    # update state
                    # current_state.release()
                    # current_state.update(line)
                    # current_state.lock()
                    update_state(line)

                    # filter out a line if predicate returns false
                    if not filter_f(current_state, line):
                        lineno += 1
                        continue

                    # traverse a line with respect to hierarchy
                    traverse(hierarchy_spec, line, current_state,
                             value_hierarchy)

                except (KeyError, ValueError):
                    print("Error occurred when reading line %s of %s" %
                          (str(lineno + 1), file_name))
                    raise

                lineno += 1

        # apply post_map_f in each value if apply_post_map is true
        if apply_post_map:
            Hierarchy.apply_post_map(hierarchy_spec, value_hierarchy,
                                     current_state)

        return value_hierarchy, current_state
Exemple #21
0
    def test_traverse(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank.state_value()

        grade.map_f = lambda _, x: float(x)
        grade.reduce_f = max
        rank.map_f = lambda _, x: int(x)
        rank.reduce_f = min

        hierarchy1 = {name: [grade]}
        hierarchy2 = {name: {subject: [rank, grade]}}

        line11 = {'Name': 'Alice', 'Subject': 'Math',  'Grade': '3.0'}
        line12 = {'Name': 'Alice', 'Subject': 'Math',  'Grade': '4.0'}
        line13 = {'Name': 'Alice', 'Subject': 'CS', 'Grade': '3.5'}
        line21 = {'Name': 'Bob', 'Subject': 'CS',  'Grade': '3.5'}
        line22 = {'Name': 'Bob', 'Subject': 'CS', 'Grade': '3.0'}
        line23 = {'Name': 'Bob', 'Subject': 'Math', 'Grade': '4.0'}

        value_dict1 = {}
        Hierarchy.traverse(hierarchy1, line11, {'Rank': '3'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 3.0}})
        Hierarchy.traverse(hierarchy1, line12, {'Rank': '1'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 4.0}})
        Hierarchy.traverse(hierarchy1, line13, {'Rank': '2'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 4.0}})
        Hierarchy.traverse(hierarchy1, line21, {'Rank': '2'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.5}})
        Hierarchy.traverse(hierarchy1, line22, {'Rank': '3'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 3.5}})
        Hierarchy.traverse(hierarchy1, line23, {'Rank': '1'}, value_dict1)
        self.assertEqual(value_dict1, {'Alice': {'Grade': 4.0}, 'Bob': {'Grade': 4.0}})

        value_dict2 = {}
        Hierarchy.traverse(hierarchy2, line11, {'Rank': '3'}, value_dict2)
        self.assertEqual(value_dict2, {'Alice': {'Math': {'Grade': 3.0, 'Rank': 3}}})
        Hierarchy.traverse(hierarchy2, line12, {'Rank': '1'}, value_dict2)
        self.assertEqual(value_dict2, {'Alice': {'Math': {'Grade': 4.0, 'Rank': 1}}})
        Hierarchy.traverse(hierarchy2, line13, {'Rank': '2'}, value_dict2)
        self.assertEqual(value_dict2, {'Alice': {'Math': {'Grade': 4.0, 'Rank': 1},
                                                 'CS': {'Grade': 3.5, 'Rank': 2}}})
        Hierarchy.traverse(hierarchy2, line21, {'Rank': '2'}, value_dict2)
        self.assertEqual(value_dict2, {'Alice': {'Math': {'Grade': 4.0, 'Rank': 1},
                                                 'CS': {'Grade': 3.5, 'Rank': 2}},
                                       'Bob': {'CS': {'Grade': 3.5, 'Rank': 2}}})
        Hierarchy.traverse(hierarchy2, line22, {'Rank': '3'}, value_dict2)
        self.assertEqual(value_dict2, {'Alice': {'Math': {'Grade': 4.0, 'Rank': 1},
                                                 'CS': {'Grade': 3.5, 'Rank': 2}},
                                       'Bob': {'CS': {'Grade': 3.5, 'Rank': 2}}})
        Hierarchy.traverse(hierarchy2, line23, {'Rank': '1'}, value_dict2)
        self.assertEqual(value_dict2, {'Alice': {'Math': {'Grade': 4.0, 'Rank': 1},
                                                 'CS': {'Grade': 3.5, 'Rank': 2}},
                                       'Bob': {'CS': {'Grade': 3.5, 'Rank': 2},
                                               'Math': {'Grade': 4.0, 'Rank': 1}}})
Exemple #22
0
    def test_check(self):
        name = self.name
        subject = self.subject
        grade = self.grade
        rank = self.rank
        s_name = self.name.state_value()
        s_subject = self.subject.state_value()
        s_grade = self.grade.state_value()
        s_rank = self.rank.state_value()

        Hierarchy.check({name: [grade]})
        Hierarchy.check({name: [grade, subject]})
        Hierarchy.check({name: [grade, subject, rank]})
        Hierarchy.check({name: {subject: [grade, rank]}})
        Hierarchy.check({name: {subject: {grade: [rank]}}})
        Hierarchy.check({s_name: [s_grade]})
        Hierarchy.check({s_name: [s_grade, s_subject]})
        Hierarchy.check({s_name: [s_grade, s_subject, s_rank]})
        Hierarchy.check({s_name: {s_subject: [s_grade, s_rank]}})
        Hierarchy.check({s_name: {s_subject: {s_grade: [s_rank]}}})

        with self.assertRaises(Exception):
            Hierarchy.check(name)
        with self.assertRaises(Exception):
            Hierarchy.check({name: grade})
        with self.assertRaises(Exception):
            Hierarchy.check({name: {subject: [grade], rank: [grade]}})
        with self.assertRaises(Exception):
            Hierarchy.check([{name: grade}])
        with self.assertRaises(Exception):
            Hierarchy.check(s_name)
        with self.assertRaises(Exception):
            Hierarchy.check({s_name: s_grade})
        with self.assertRaises(Exception):
            Hierarchy.check({s_name: {s_subject: [s_grade], s_rank: [s_grade]}})
        with self.assertRaises(Exception):
            Hierarchy.check([{s_name: s_grade}])