Beispiel #1
0
 def setup_stack_Example_Data_A(self, name=None, fk=None, xk=None, yk=None, views=None, weights=None):
     if name is None:
         name = "Example Data (A)"
     if fk is None:
         fk = ['no_filter']
     if xk is None:
         xk = self.minimum
     if yk is None:
         yk = ['@'] + self.minimum
     if views is None:
         views = ['default']
     if not isinstance(weights, list):
         weights = [weights]
             
     stack = Stack(name=name)
     stack.add_data(
         data_key=stack.name, 
         meta=self.example_data_A_meta, 
         data=self.example_data_A_data
     )
     
     for weight in weights:
         stack.add_link(
             data_keys=stack.name,
             filters=fk,
             x=xk, 
             y=yk, 
             views=QuantipyViews(views),
             weights=weight
         )
     
     return stack    
Beispiel #2
0
    def setup_stack_Example_Data_A(self,
                                   fk=None,
                                   xk=None,
                                   yk=None,
                                   views=None,
                                   weights=None):
        if fk is None:
            fk = 'no_filter'
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default', 'cbase', 'counts', 'c%']
        if not isinstance(weights, list):
            weights = [weights]

        self.stack = Stack(name="Example Data (A)")
        self.stack.add_data(data_key=self.stack.name,
                            meta=self.example_data_A_meta,
                            data=self.example_data_A_data)

        for weight in weights:
            self.stack.add_link(data_keys=self.stack.name,
                                filters=fk,
                                x=xk,
                                y=yk,
                                views=QuantipyViews(views),
                                weights=weight)
    def get_stack_Example_Data_A(self, name=None, fk=None, xk=None, yk=None, views=None, weights=None):
        if name is None:
            name = 'Example Data (A)'
        if fk is None:
            fk = ['no_filter']
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default', 'counts']
        if weights is None:
            weights = self.weights

        stack = Stack(name=name)
        stack.add_data(
            data_key=stack.name, 
            meta=self.example_data_A_meta, 
            data=self.example_data_A_data
        )

        for weight in weights:
            stack.add_link(
                data_keys=stack.name,
                filters=fk,
                x=xk,
                y=yk,
                views=QuantipyViews(views),
                weights=weights
            )

        return stack    
Beispiel #4
0
 def setUp(self):
     self.path = './tests/'
     #         self.path = ''
     self.filepath = '%sengine_B_data.csv' % (self.path)
     self.metapath = '%sengine_B_meta.json' % (self.path)
     self.stack = Stack("StackName")
     self.stack.seperator = ','
     self.stack.decoding = "UTF-8"
     self.data = pd.DataFrame.from_csv(self.filepath)
     self.meta = load_json(self.metapath)
     self.stack.add_data(data_key="Jan", meta=self.meta, data=self.data)
     #         self.x_names=['age', 'cost_breakfast', 'age_group', 'endtime', 'name', 'q4'],
     self.x_names = ['age', 'cost_breakfast', 'age_group', 'q4']
     #         self._types = ['int', 'float', 'single', 'date', 'string', 'delimited set']
     self.x_types = ['int', 'float', 'single', 'delimited set']
     self.y_names = ['profile_gender']
Beispiel #5
0
    def get_stack_Example_Data_A(self,
                                 name=None,
                                 fk=None,
                                 xk=None,
                                 yk=None,
                                 views=None,
                                 weights=None):
        if name is None:
            name = 'Example Data (A)'
        if fk is None:
            fk = ['no_filter']
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default', 'counts']
        if weights is None:
            weights = self.weights

        stack = Stack(name=name)
        stack.add_data(data_key=stack.name,
                       meta=self.example_data_A_meta,
                       data=self.example_data_A_data)

        for weight in weights:
            stack.add_link(data_keys=stack.name,
                           filters=fk,
                           x=xk,
                           y=yk,
                           views=QuantipyViews(views),
                           weights=weights)

        return stack
    def setUp(self):
        self.path = './tests/'
#         self.path = ''
        self.filepath = '%sengine_B_data.csv' % (self.path)
        self.metapath = '%sengine_B_meta.json' % (self.path)
        self.stack = Stack("StackName")
        self.stack.seperator = ','
        self.stack.decoding = "UTF-8"
        self.data = pd.DataFrame.from_csv(self.filepath)
        self.meta = load_json(self.metapath)
        self.stack.add_data(data_key="Jan", meta=self.meta, data=self.data)
#         self.x_names=['age', 'cost_breakfast', 'age_group', 'endtime', 'name', 'q4'],
        self.x_names = ['age', 'cost_breakfast', 'age_group', 'q4']
#         self._types = ['int', 'float', 'single', 'date', 'string', 'delimited set']
        self.x_types = ['int', 'float', 'single', 'delimited set']
        self.y_names = ['profile_gender']
Beispiel #7
0
class TestChainObject(unittest.TestCase):
    def setUp(self):
        self.path = './tests/'
        self.path_chain = './temp.chain'.format(self.path)
        #         self.path = ''
        project_name = 'Example Data (A)'

        # Load Example Data (A) data and meta into self
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (self.path, name_data)
        self.example_data_A_data = pd.DataFrame.from_csv(path_data)
        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (self.path, name_meta)
        self.example_data_A_meta = load_json(path_meta)

        # The minimum list of variables required to populate a stack with all single*delimited set variations
        self.minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']

        self.setup_stack_Example_Data_A()

        self.setup_chains_Example_Data_A()

    def test_save_chain(self):

        self.setup_chains_Example_Data_A()

        for chain in self.chains:

            # Create a dictionary with the attribute structure of the chain
            chain_attributes = chain.__dict__
            chain_described = chain.describe()

            # Save and then load a copy of the chain
            chain.save(path=self.path_chain)
            loaded_chain = Chain.load(self.path_chain)

            # Ensure that we are not comparing the same variable (in memory)
            self.assertNotEqual(id(chain), id(loaded_chain))

            # Create a dictionary with the attribute structure of the chain
            loaded_chain_attributes = loaded_chain.__dict__
            loaded_chain_described = loaded_chain.describe()

            # Confirm that the chains contain the same views
            sort_order = ['data', 'filter', 'x', 'y', 'view']
            actual = chain_described.sort(sort_order).values.tolist()
            expected = loaded_chain_described.sort(sort_order).values.tolist()
            self.assertSequenceEqual(actual, expected)

            # Make sure that this is working by altering the loaded_stack_attributes
            # and comparing the result. (It should fail)

            # Change a 'value' in the dict
            loaded_chain_attributes['name'] = 'SomeOtherName'
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)

            # reset the value
            loaded_chain_attributes['name'] = chain_attributes['name']
            self.assertEqual(chain_attributes, loaded_chain_attributes)

            # Change a 'key' in the dict
            del loaded_chain_attributes['name']
            loaded_chain_attributes['new_name'] = chain_attributes['name']
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)

            # reset the value
            del loaded_chain_attributes['new_name']
            loaded_chain_attributes['name'] = chain_attributes['name']
            self.assertEqual(chain_attributes, loaded_chain_attributes)

            # Remove a key/value pair
            del loaded_chain_attributes['name']
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)

            # Cleanup
            if os.path.exists('./tests/{0}.chain'.format(chain.name)):
                os.remove('./tests/{0}.chain'.format(chain.name))

    def test_auto_orientation(self):

        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        views = ['cbase', 'counts', 'c%']

        # If multiple x and y keys are given without orient_on
        # x-orientation chains are assumed.
        chain = self.stack.get_chain(name='y',
                                     data_keys=self.stack.name,
                                     filters=fk,
                                     x=xk,
                                     y=yk,
                                     views=views)
        self.assertTrue(chain.orientation == 'x')

    def test_lazy_name(self):

        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        views = ['cbase', 'counts', 'c%']

        # get chain but do not name - y orientation
        chain_y = self.stack.get_chain(data_keys=self.stack.name,
                                       filters=fk,
                                       x=xk,
                                       y=yk[0],
                                       views=views)

        # get chain but do not name - x orientation
        chain_x = self.stack.get_chain(data_keys=self.stack.name,
                                       filters=fk,
                                       x=xk[0],
                                       y=yk,
                                       views=views)

        # check lazy_name is working as it should be
        self.assertEqual(chain_y.name,
                         '[email protected]_1.cbase.counts.c%')
        self.assertEqual(chain_x.name,
                         '[email protected]_1.cbase.counts.c%')

    def test_dervie_attributes(self):

        # check chain attributes
        self.assertEqual(self.chains[0].name, '@')
        self.assertEqual(self.chains[0].orientation, 'y')
        self.assertEqual(self.chains[0].source_name, '@')
        self.assertEqual(self.chains[0].len_of_axis, 5)
        self.assertEqual(self.chains[0].content_of_axis,
                         ['q2b', 'Wave', 'q2', 'q3', 'q5_1'])
        self.assertEqual(self.chains[0].views,
                         ['x|f|x:|||cbase', 'x|f|:|||counts', 'x|f|:|y||c%'])
        self.assertEqual(self.chains[0].data_key, 'Example Data (A)')
        self.assertEqual(self.chains[0].filter, 'no_filter')
        self.assertEqual(self.chains[0].source_type, None)

        self.assertEqual(self.chains[-1].name, 'q5_1')
        self.assertEqual(self.chains[-1].orientation, 'x')
        self.assertEqual(self.chains[-1].source_name, 'q5_1')
        self.assertEqual(self.chains[-1].len_of_axis, 6)
        self.assertEqual(self.chains[-1].content_of_axis,
                         ['@', 'q2b', 'Wave', 'q2', 'q3', 'q5_1'])
        self.assertEqual(self.chains[-1].views,
                         ['x|f|x:|||cbase', 'x|f|:|||counts', 'x|f|:|y||c%'])
        self.assertEqual(self.chains[-1].data_key, 'Example Data (A)')
        self.assertEqual(self.chains[-1].filter, 'no_filter')
        self.assertEqual(self.chains[-1].source_type, None)

    def test_describe(self):

        fk = 'no_filter'

        for chain in self.chains:

            chain_described = chain.describe()

            #test describe() returns a dataframe
            self.assertIsInstance(chain_described, pd.DataFrame)

            #test descibe() returns the expected dataframe - *no args*
            if chain.orientation == 'y':
                keys = chain[self.stack.name][fk].keys()
                views = chain[self.stack.name][fk][keys[0]][
                    chain.source_name].keys()
                data = [self.stack.name] * (len(keys) * len(views))
                filters = [fk] * (len(keys) * len(views))
                x = []
                for key in keys:
                    x.extend([key] * len(views))
                y = [chain.source_name] * (len(keys) * len(views))
                view = [v for v in views] * len(keys)
                ones = [1] * (len(keys) * len(views))
                df = pd.DataFrame({
                    'data': data,
                    'filter': filters,
                    'x': x,
                    'y': y,
                    'view': view,
                    '#': ones
                })
                df = df[chain_described.columns.tolist()]
                assert_frame_equal(chain_described, df)
            elif chain.orientation == 'x':

                keys = chain[self.stack.name][fk][chain.source_name].keys()
                views = chain[self.stack.name][fk][chain.source_name][
                    keys[0]].keys()
                data = [self.stack.name] * (len(keys) * len(views))
                filters = [fk] * (len(keys) * len(views))
                y = []
                for key in keys:
                    y.extend([key] * len(views))
                x = [chain.source_name] * (len(keys) * len(views))
                view = [v for v in views] * len(keys)
                ones = [1] * (len(keys) * len(views))
                df = pd.DataFrame({
                    'data': data,
                    'filter': filters,
                    'x': x,
                    'y': y,
                    'view': view,
                    '#': ones
                })
                df = df[chain_described.columns.tolist()]
                assert_frame_equal(chain_described, df)

    @classmethod
    def tearDownClass(self):
        self.stack = Stack("StackName")
        filepath = './tests/' + self.stack.name + '.stack'
        if os.path.exists(filepath):
            os.remove(filepath)

    def is_empty(self, any_structure):
        if any_structure:
            #print('Structure is not empty.')
            return False
        else:
            #print('Structure is empty.')
            return True

    def create_key_stack(self, branch_pos="data"):
        """ Creates a dictionary that has the structure of the keys in the Stack
            It is used to loop through the stack without affecting it.
        """
        key_stack = {}
        for data_key in self.stack:
            key_stack[data_key] = {}
            for the_filter in self.stack[data_key][branch_pos]:
                key_stack[data_key][the_filter] = {}
                for x in self.stack[data_key][branch_pos][the_filter]:
                    key_stack[data_key][the_filter][x] = []
                    for y in self.stack[data_key][branch_pos][the_filter][x]:
                        link = self.stack[data_key][branch_pos][the_filter][x][
                            y]
                        if not isinstance(link, Link):
                            continue
                        key_stack[data_key][the_filter][x].append(y)
        return key_stack

    def setup_stack_Example_Data_A(self,
                                   fk=None,
                                   xk=None,
                                   yk=None,
                                   views=None,
                                   weights=None):
        if fk is None:
            fk = 'no_filter'
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default', 'cbase', 'counts', 'c%']
        if not isinstance(weights, list):
            weights = [weights]

        self.stack = Stack(name="Example Data (A)")
        self.stack.add_data(data_key=self.stack.name,
                            meta=self.example_data_A_meta,
                            data=self.example_data_A_data)

        for weight in weights:
            self.stack.add_link(data_keys=self.stack.name,
                                filters=fk,
                                x=xk,
                                y=yk,
                                views=QuantipyViews(views),
                                weights=weight)

    def setup_chains_Example_Data_A(self,
                                    fk=None,
                                    xk=None,
                                    yk=None,
                                    views=None,
                                    orient_on=None):

        if fk is None:
            fk = 'no_filter'
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['x|f|x:|||cbase', 'x|f|:|||counts', 'x|f|:|y||c%']

        self.chains = []

        for y in yk:
            self.chains.append(
                self.stack.get_chain(name=y,
                                     data_keys=self.stack.name,
                                     filters='no_filter',
                                     x=xk,
                                     y=y,
                                     views=views))

        for x in xk:
            self.chains.append(
                self.stack.get_chain(name=x,
                                     data_keys=self.stack.name,
                                     filters='no_filter',
                                     x=x,
                                     y=yk,
                                     views=views))
Beispiel #8
0
 def tearDownClass(self):
     self.stack = Stack("StackName")
     filepath ='./tests/'+self.stack.name+'.stack'
     if os.path.exists(filepath):
         os.remove(filepath)
Beispiel #9
0
class TestLinkObject(unittest.TestCase):

# stack.add_link(x='q1', y=y, views=mean_views.subset('m1to6'), weights=weight)

    def setUp(self):        
        self.path = './tests/'
#         self.path = ''
        project_name = 'Example Data (A)'
        
        # Load Example Data (A) data and meta into self
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (self.path, name_data)
        self.example_data_A_data = pd.DataFrame.from_csv(path_data)        
        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (self.path, name_meta)
        self.example_data_A_meta = load_json(path_meta)
        
        # The minimum list of variables required to populate a stack with all single*delimited set variations
        self.minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']
        
        self.setup_stack_Example_Data_A()
        
    def test_link_is_a_subclassed_dict(self):        
        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        
        for x in xk:
            for y in yk:
                link = self.stack[dk][fk][x][y]
                self.assertIsInstance(link, dict)
                self.assertIsInstance(link, Link)
    
    def test_link_behaves_like_a_dict(self):
        
        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        
        key = "some_key_name"
        value = "some_value"
        
        for x in xk:
            for y in yk:
                link = self.stack[dk][fk][x][y]
                link[key] = value
                self.assertIn(
                    key,
                    link.keys(), 
                    msg="Link should have key {data_key}, but has {link_keys}".format(
                        data_key=key, 
                        link_keys=link.keys()
                    )
                )   
    
    def test_get_meta(self):
        
        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        
        #test returned meta against stack meta
        for x in xk:
            for y in yk:
                link = self.stack[dk][fk][x][y]
                self.assertEqual(link.get_meta(), self.stack[dk].meta)
    
    def test_get_data(self):
        
        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        
        stack_data = self.stack[dk][fk].data
        
        #test returned data against stack data
        for x in xk:
            for y in yk:
                link_data = self.stack[dk][fk][x][y].get_data()                
                self.assertTrue(link_data is stack_data)
        
    @classmethod
    def tearDownClass(self):
        self.stack = Stack("StackName")
        filepath ='./tests/'+self.stack.name+'.stack'
        if os.path.exists(filepath):
            os.remove(filepath)

    def is_empty(self, any_structure):
        if any_structure:
            #print('Structure is not empty.')
            return False
        else:
            #print('Structure is empty.')
            return True

    def create_key_stack(self, branch_pos="data"):
        """ Creates a dictionary that has the structure of the keys in the Stack
            It is used to loop through the stack without affecting it.
        """
        key_stack = {}
        for data_key in self.stack:
            key_stack[data_key] = {}
            for the_filter in self.stack[data_key][branch_pos]:
                key_stack[data_key][the_filter] = {}
                for x in self.stack[data_key][branch_pos][the_filter]:
                    key_stack[data_key][the_filter][x] = []
                    for y in self.stack[data_key][branch_pos][the_filter][x]:
                        link = self.stack[data_key][branch_pos][the_filter][x][y]
                        if not isinstance(link, Link):
                            continue
                        key_stack[data_key][the_filter][x].append(y)
        return key_stack

    def setup_stack_Example_Data_A(self, fk=None, xk=None, yk=None, views=None, weights=None):
        if fk is None:
            fk = [
                'no_filter',
                'Wave == 1'
            ]
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default']
        if not isinstance(weights, list):
            weights = [weights]
         
        self.stack = Stack(name="Example Data (A)")
        self.stack.add_data(
            data_key=self.stack.name, 
            meta=self.example_data_A_meta, 
            data=self.example_data_A_data
        )
        
        for weight in weights:
            self.stack.add_link(
                data_keys=self.stack.name,
                filters=fk,
                x=xk, 
                y=yk, 
                views=QuantipyViews(views),
                weights=weight
            )            
def get_stack(self, meta, data, xks, yks, views, weights):

    stack = Stack('test')
    stack.add_data('test', data, meta)
    stack.add_link(x=xks, y=yks, views=views, weights=weights)

    # Add two basic net
    net_views = ViewMapper(
        template={
            'method': QuantipyViews().frequency,
            'kwargs': {
                'iterators': {
                    'rel_to': [None, 'y']
                }
            }
        })
    net_views.add_method(name='Net 1-3',
                         kwargs={
                             'logic': [1, 2, 3],
                             'axis': 'x',
                             'text': {
                                 'en-GB': '1-3'
                             }
                         })
    net_views.add_method(name='Net 4-6',
                         kwargs={
                             'logic': [4, 5, 6],
                             'axis': 'x',
                             'text': {
                                 'en-GB': '4-6'
                             }
                         })
    stack.add_link(x=xks, y=yks, views=net_views, weights=weights)

    # Add block net
    net_views.add_method(name='Block net',
                         kwargs={
                             'logic': [{
                                 'bn1': [1, 2]
                             }, {
                                 'bn2': [2, 3]
                             }, {
                                 'bn3': [1, 3]
                             }],
                             'axis':
                             'x'
                         })
    stack.add_link(x=xks,
                   y=yks,
                   views=net_views.subset(['Block net']),
                   weights=weights)

    # Add NPS
    ## TO DO

    # Add standard deviation
    desc_views = ViewMapper(
        template={
            'method': QuantipyViews().descriptives,
            'kwargs': {
                'axis': 'x',
                'iterators': {
                    'stats': ['mean', 'median', 'stddev']
                }
            }
        })

    desc_views.add_method(name='descriptives')
    stack.add_link(x=xks, y=yks, views=desc_views, weights=weights)

    # Add tests
    test_views = ViewMapper(
        template={
            'method': QuantipyViews().coltests,
            'kwargs': {
                'mimic': 'askia',
                'iterators': {
                    'metric': ['props', 'means'],
                    'level': ['low', 'mid', 'high']
                }
            }
        })
    test_views.add_method('askia tests')
    stack.add_link(x=xks, y=yks, views=test_views, weights=weights)

    return stack
Beispiel #11
0
class TestChainObject(unittest.TestCase):

    def setUp(self):        
        self.path = './tests/'
#         self.path = ''
        project_name = 'Example Data (A)'
        
        # Load Example Data (A) data and meta into self
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (self.path, name_data)
        self.example_data_A_data = pd.DataFrame.from_csv(path_data)        
        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (self.path, name_meta)
        self.example_data_A_meta = load_json(path_meta)
        
        # The minimum list of variables required to populate a stack with all single*delimited set variations
        self.minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']
        
        self.setup_stack_Example_Data_A()
        
        self.setup_chains_Example_Data_A()
        
    def test_save_chain(self):
        
        self.setup_chains_Example_Data_A()
        
        for chain in self.chains:
        
            chain.save(path=self.path)
     
            loaded_chain = Chain.load('%s%s.chain' % (self.path, chain.name))
     
            # Create a dictionary with the attribute structure of the chain
            chain_attributes = test_helper.create_attribute_dict(chain)
     
            # Create a dictionary with the attribute structure of the chain
            loaded_chain_attributes = test_helper.create_attribute_dict(loaded_chain)
     
            # Ensure that we are not comparing the same variable (in memory)
            self.assertNotEqual(id(chain), id(loaded_chain))
     
            # Make sure that this is working by altering the loaded_stack_attributes
            # and comparing the result. (It should fail)
     
            # Change a 'value' in the dict
            loaded_chain_attributes['__dict__']['name'] = 'SomeOtherName'
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)
     
            # reset the value
            loaded_chain_attributes['__dict__']['name'] = chain_attributes['__dict__']['name']
            self.assertEqual(chain_attributes, loaded_chain_attributes)
     
            # Change a 'key' in the dict
            del loaded_chain_attributes['__dict__']['name']
            loaded_chain_attributes['__dict__']['new_name'] = chain_attributes['__dict__']['name']
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)
     
            # reset the value
            del loaded_chain_attributes['__dict__']['new_name']
            loaded_chain_attributes['__dict__']['name'] = chain_attributes['__dict__']['name']
            self.assertEqual(chain_attributes, loaded_chain_attributes)
     
            # Remove a key/value pair
            del loaded_chain_attributes['__dict__']['name']
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)
     
            # Cleanup
            if os.path.exists('./tests/{0}.chain'.format(chain.name)):
                os.remove('./tests/{0}.chain'.format(chain.name))
    
    def test_validate_x_y_combination(self):
        
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        views = ['cbase', 'counts', 'c%']
                  
        # check the correct error message is returned, irrespective of orientation...
        
        # error #1
        expected_message = "If the number of keys for both x and y are greater than 1, whether or not you have specified the x and y values, orient_on must be either 'x' or 'y'."
        with self.assertRaises(ValueError) as error_message:
            _ = self.stack.get_chain(
                name='y', 
                data_keys=self.stack.name, 
                filters=fk, 
                x=xk, 
                y=yk, 
                views=views,
                post_process=True
            )
        self.assertEqual(error_message.exception[0], expected_message)

    def test_lazy_name(self):
        
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        views = ['cbase', 'counts', 'c%']
    
        # get chain but do not name - y orientation
        chain_y = self.stack.get_chain(
                    data_keys=self.stack.name, 
                    filters=fk, 
                    x=xk, 
                    y=yk[0],  
                    views=views, 
                    post_process=False
                )
        
        # get chain but do not name - x orientation
        chain_x = self.stack.get_chain(
                    data_keys=self.stack.name,
                    filters=fk,  
                    x=xk[0], 
                    y=yk,  
                    views=views, 
                    post_process=False
                )
  
        # check lazy_name is working as it should be
        self.assertEqual(chain_y.name, '[email protected]_1.cbase.counts.c%')   
        self.assertEqual(chain_x.name, '[email protected]_1.cbase.counts.c%')         

    def test_dervie_attributes(self):
                
        # check chain attributes 
        self.assertEqual(self.chains[0].name, '@')
        self.assertEqual(self.chains[0].orientation, 'y')
        self.assertEqual(self.chains[0].source_name, '@')
        self.assertEqual(self.chains[0].len_of_axis, 5)
        self.assertEqual(self.chains[0].content_of_axis, ['q2b', 'Wave', 'q2', 'q3', 'q5_1'])
        self.assertEqual(self.chains[0].views, ['x|frequency|x:y|||cbase', 'x|frequency||||counts', 'x|frequency||y||c%'])
        self.assertEqual(self.chains[0].data_key, 'Example Data (A)')
        self.assertEqual(self.chains[0].filter, 'no_filter')
        self.assertEqual(self.chains[0].source_type, None)

        self.assertEqual(self.chains[-1].name, 'q5_1')
        self.assertEqual(self.chains[-1].orientation, 'x')
        self.assertEqual(self.chains[-1].source_name, 'q5_1')
        self.assertEqual(self.chains[-1].len_of_axis, 6)
        self.assertEqual(self.chains[-1].content_of_axis, ['@', 'q2b', 'Wave', 'q2', 'q3', 'q5_1'])
        self.assertEqual(self.chains[-1].views, ['x|frequency|x:y|||cbase', 'x|frequency||||counts', 'x|frequency||y||c%'])
        self.assertEqual(self.chains[-1].data_key, 'Example Data (A)')
        self.assertEqual(self.chains[-1].filter, 'no_filter')
        self.assertEqual(self.chains[-1].source_type, None)
    
    def test_post_process_shapes(self):
        
        # check chain attributes after post_processing 
        self.assertEqual(self.chains[0].x_new_order,  [[], [], [], [], [], [], [], [], [], [], [], [], [], [], []])
        self.assertEqual(self.chains[0].x_hidden_codes, [[], [], [], [], [], [], [], [], [], [], [], [], [], [], []])
        self.assertEqual(self.chains[0].y_new_order, None)
        self.assertEqual(self.chains[0].y_hidden_codes, None)        
        self.assertEqual(self.chains[0].props_tests, [])
        self.assertEqual(self.chains[0].props_tests_levels, [])
        self.assertEqual(self.chains[0].has_props_tests, False)
        self.assertEqual(self.chains[0].means_tests, [])
        self.assertEqual(self.chains[0].means_tests_levels, [])
        self.assertEqual(self.chains[0].has_means_tests, False)
        self.assertEqual(self.chains[0].view_sizes, [[(1, 1), (3, 1), (3, 1)], [(1, 1), (5, 1), (5, 1)], [(1, 1), (8, 1), (8, 1)], [(1, 1), (9, 1), (9, 1)], [(1, 1), (7, 1), (7, 1)]])
        self.assertEqual(self.chains[0].view_lengths, [[1, 3, 3], [1, 5, 5], [1, 8, 8], [1, 9, 9], [1, 7, 7]])
        self.assertEqual(self.chains[0].source_length, 1)
        
        self.assertEqual(self.chains[-1].x_new_order,  [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []])
        self.assertEqual(self.chains[-1].x_hidden_codes, [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []])
        self.assertEqual(self.chains[-1].y_new_order, None)
        self.assertEqual(self.chains[-1].y_hidden_codes, None)        
        self.assertEqual(self.chains[-1].props_tests, [])
        self.assertEqual(self.chains[-1].props_tests_levels, [])
        self.assertEqual(self.chains[-1].has_props_tests, False)
        self.assertEqual(self.chains[-1].means_tests, [])
        self.assertEqual(self.chains[-1].means_tests_levels, [])
        self.assertEqual(self.chains[-1].has_means_tests, False)
        self.assertEqual(self.chains[-1].view_sizes, [[(1, 1), (7, 1), (7, 1)], [(1, 3), (7, 3), (7, 3)], [(1, 5), (7, 5), (7, 5)], [(1, 8), (7, 8), (7, 8)], [(1, 9), (7, 9), (7, 9)], [(1, 7), (7, 7), (7, 7)]])
        self.assertEqual(self.chains[-1].view_lengths, [[1, 7, 7], [1, 7, 7], [1, 7, 7], [1, 7, 7], [1, 7, 7], [1, 7, 7]])
        self.assertEqual(self.chains[-1].source_length, 9)
    
    def test_describe(self):
        
        fk = 'no_filter'
        
        for chain in self.chains:
            
            chain_described = chain.describe()
            
            #test describe() returns a dataframe
            self.assertIsInstance(chain_described, pd.DataFrame)
            
            #test descibe() returns the expected dataframe - *no args* 
            if chain.orientation == 'y':
                keys = chain[self.stack.name][fk].keys()
                views = chain[self.stack.name][fk][keys[0]][chain.source_name].keys()
                data = [self.stack.name]*(len(keys)*len(views))
                filters = [fk]*(len(keys)*len(views))
                x = []
                for key in keys:
                    x.extend([key]*len(views))
                y = [chain.source_name]*(len(keys)*len(views))
                view = [v for v in views]*len(keys)
                ones = [1]*(len(keys)*len(views))
                df = pd.DataFrame({'data': data, 
                                   'filter': filters, 
                                   'x': x, 
                                   'y': y, 
                                   'view': view, 
                                   '#': ones})
                df = df[chain_described.columns.tolist()]
                assert_frame_equal(chain_described, df)
            elif chain.orientation == 'x':
                
                keys = chain[self.stack.name][fk][chain.source_name].keys()
                views = chain[self.stack.name][fk][chain.source_name][keys[0]].keys()
                data = [self.stack.name]*(len(keys)*len(views))
                filters = [fk]*(len(keys)*len(views))
                y = []
                for key in keys:
                    y.extend([key]*len(views))
                x = [chain.source_name]*(len(keys)*len(views))
                view = [v for v in views]*len(keys)
                ones = [1]*(len(keys)*len(views))
                df = pd.DataFrame({'data': data, 
                                   'filter': filters, 
                                   'x': x, 
                                   'y': y, 
                                   'view': view, 
                                   '#': ones})
                df = df[chain_described.columns.tolist()]
                assert_frame_equal(chain_described, df)
    
    @classmethod
    def tearDownClass(self):
        self.stack = Stack("StackName")
        filepath ='./tests/'+self.stack.name+'.stack'
        if os.path.exists(filepath):
            os.remove(filepath)

    def is_empty(self, any_structure):
        if any_structure:
            #print('Structure is not empty.')
            return False
        else:
            #print('Structure is empty.')
            return True

    def create_key_stack(self, branch_pos="data"):
        """ Creates a dictionary that has the structure of the keys in the Stack
            It is used to loop through the stack without affecting it.
        """
        key_stack = {}
        for data_key in self.stack:
            key_stack[data_key] = {}
            for the_filter in self.stack[data_key][branch_pos]:
                key_stack[data_key][the_filter] = {}
                for x in self.stack[data_key][branch_pos][the_filter]:
                    key_stack[data_key][the_filter][x] = []
                    for y in self.stack[data_key][branch_pos][the_filter][x]:
                        link = self.stack[data_key][branch_pos][the_filter][x][y]
                        if not isinstance(link, Link):
                            continue
                        key_stack[data_key][the_filter][x].append(y)
        return key_stack

    def setup_stack_Example_Data_A(self, fk=None, xk=None, yk=None, views=None, weights=None):
        if fk is None:
            fk = 'no_filter'
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default', 'cbase', 'counts', 'c%'] 
        if not isinstance(weights, list):
            weights = [weights]
         
        self.stack = Stack(name="Example Data (A)")
        self.stack.add_data(
            data_key=self.stack.name, 
            meta=self.example_data_A_meta, 
            data=self.example_data_A_data
        )
        
        for weight in weights:
            self.stack.add_link(
                data_keys=self.stack.name,
                filters=fk,
                x=xk, 
                y=yk, 
                views=QuantipyViews(views),
                weights=weight
            )     
        
    def setup_chains_Example_Data_A(self, fk=None, xk=None, yk=None, views=None, orient_on=None):
                    
        if fk is None:
            fk = 'no_filter'
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = [
                'x|frequency|x:y|||cbase',
                'x|frequency||||counts',
                'x|frequency||y||c%'
            ] 
        
        self.chains = []
        
        for y in yk:
            self.chains.append(
                self.stack.get_chain(
                    name=y, 
                    data_keys=self.stack.name, 
                    filters='no_filter', 
                    x=xk, 
                    y=y, 
                    views=views,
                    post_process=True
                )
            )
            
        for x in xk:
            self.chains.append(
                self.stack.get_chain(
                    name=x, 
                    data_keys=self.stack.name, 
                    filters='no_filter', 
                    x=x, 
                    y=yk, 
                    views=views,
                    post_process=True
                )
            )
Beispiel #12
0
class TestChainObject(unittest.TestCase):
    def setUp(self):
        self.path = './tests/'
        #         self.path = ''
        project_name = 'Example Data (A)'

        # Load Example Data (A) data and meta into self
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (self.path, name_data)
        self.example_data_A_data = pd.DataFrame.from_csv(path_data)
        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (self.path, name_meta)
        self.example_data_A_meta = load_json(path_meta)

        # The minimum list of variables required to populate a stack with all single*delimited set variations
        self.minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']

        self.setup_stack_Example_Data_A()

        self.setup_chains_Example_Data_A()

    def test_save_chain(self):

        self.setup_chains_Example_Data_A()

        for chain in self.chains:

            chain.save(path=self.path)

            loaded_chain = Chain.load('%s%s.chain' % (self.path, chain.name))

            # Create a dictionary with the attribute structure of the chain
            chain_attributes = test_helper.create_attribute_dict(chain)

            # Create a dictionary with the attribute structure of the chain
            loaded_chain_attributes = test_helper.create_attribute_dict(
                loaded_chain)

            # Ensure that we are not comparing the same variable (in memory)
            self.assertNotEqual(id(chain), id(loaded_chain))

            # Make sure that this is working by altering the loaded_stack_attributes
            # and comparing the result. (It should fail)

            # Change a 'value' in the dict
            loaded_chain_attributes['__dict__']['name'] = 'SomeOtherName'
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)

            # reset the value
            loaded_chain_attributes['__dict__']['name'] = chain_attributes[
                '__dict__']['name']
            self.assertEqual(chain_attributes, loaded_chain_attributes)

            # Change a 'key' in the dict
            del loaded_chain_attributes['__dict__']['name']
            loaded_chain_attributes['__dict__']['new_name'] = chain_attributes[
                '__dict__']['name']
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)

            # reset the value
            del loaded_chain_attributes['__dict__']['new_name']
            loaded_chain_attributes['__dict__']['name'] = chain_attributes[
                '__dict__']['name']
            self.assertEqual(chain_attributes, loaded_chain_attributes)

            # Remove a key/value pair
            del loaded_chain_attributes['__dict__']['name']
            with self.assertRaises(AssertionError):
                self.assertEqual(chain_attributes, loaded_chain_attributes)

            # Cleanup
            if os.path.exists('./tests/{0}.chain'.format(chain.name)):
                os.remove('./tests/{0}.chain'.format(chain.name))

    def test_validate_x_y_combination(self):

        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        views = ['cbase', 'counts', 'c%']

        # check the correct error message is returned, irrespective of orientation...

        # error #1
        expected_message = "If the number of keys for both x and y are greater than 1, whether or not you have specified the x and y values, orient_on must be either 'x' or 'y'."
        with self.assertRaises(ValueError) as error_message:
            _ = self.stack.get_chain(name='y',
                                     data_keys=self.stack.name,
                                     filters=fk,
                                     x=xk,
                                     y=yk,
                                     views=views,
                                     post_process=True)
        self.assertEqual(error_message.exception[0], expected_message)

    def test_lazy_name(self):

        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum
        views = ['cbase', 'counts', 'c%']

        # get chain but do not name - y orientation
        chain_y = self.stack.get_chain(data_keys=self.stack.name,
                                       filters=fk,
                                       x=xk,
                                       y=yk[0],
                                       views=views,
                                       post_process=False)

        # get chain but do not name - x orientation
        chain_x = self.stack.get_chain(data_keys=self.stack.name,
                                       filters=fk,
                                       x=xk[0],
                                       y=yk,
                                       views=views,
                                       post_process=False)

        # check lazy_name is working as it should be
        self.assertEqual(chain_y.name,
                         '[email protected]_1.cbase.counts.c%')
        self.assertEqual(chain_x.name,
                         '[email protected]_1.cbase.counts.c%')

    def test_dervie_attributes(self):

        # check chain attributes
        self.assertEqual(self.chains[0].name, '@')
        self.assertEqual(self.chains[0].orientation, 'y')
        self.assertEqual(self.chains[0].source_name, '@')
        self.assertEqual(self.chains[0].len_of_axis, 5)
        self.assertEqual(self.chains[0].content_of_axis,
                         ['q2b', 'Wave', 'q2', 'q3', 'q5_1'])
        self.assertEqual(self.chains[0].views, [
            'x|frequency|x:y|||cbase', 'x|frequency||||counts',
            'x|frequency||y||c%'
        ])
        self.assertEqual(self.chains[0].data_key, 'Example Data (A)')
        self.assertEqual(self.chains[0].filter, 'no_filter')
        self.assertEqual(self.chains[0].source_type, None)

        self.assertEqual(self.chains[-1].name, 'q5_1')
        self.assertEqual(self.chains[-1].orientation, 'x')
        self.assertEqual(self.chains[-1].source_name, 'q5_1')
        self.assertEqual(self.chains[-1].len_of_axis, 6)
        self.assertEqual(self.chains[-1].content_of_axis,
                         ['@', 'q2b', 'Wave', 'q2', 'q3', 'q5_1'])
        self.assertEqual(self.chains[-1].views, [
            'x|frequency|x:y|||cbase', 'x|frequency||||counts',
            'x|frequency||y||c%'
        ])
        self.assertEqual(self.chains[-1].data_key, 'Example Data (A)')
        self.assertEqual(self.chains[-1].filter, 'no_filter')
        self.assertEqual(self.chains[-1].source_type, None)

    def test_post_process_shapes(self):

        # check chain attributes after post_processing
        self.assertEqual(
            self.chains[0].x_new_order,
            [[], [], [], [], [], [], [], [], [], [], [], [], [], [], []])
        self.assertEqual(
            self.chains[0].x_hidden_codes,
            [[], [], [], [], [], [], [], [], [], [], [], [], [], [], []])
        self.assertEqual(self.chains[0].y_new_order, None)
        self.assertEqual(self.chains[0].y_hidden_codes, None)
        self.assertEqual(self.chains[0].props_tests, [])
        self.assertEqual(self.chains[0].props_tests_levels, [])
        self.assertEqual(self.chains[0].has_props_tests, False)
        self.assertEqual(self.chains[0].means_tests, [])
        self.assertEqual(self.chains[0].means_tests_levels, [])
        self.assertEqual(self.chains[0].has_means_tests, False)
        self.assertEqual(
            self.chains[0].view_sizes,
            [[(1, 1), (3, 1),
              (3, 1)], [(1, 1), (5, 1),
                        (5, 1)], [(1, 1), (8, 1),
                                  (8, 1)], [(1, 1), (9, 1),
                                            (9, 1)], [(1, 1), (7, 1), (7, 1)]])
        self.assertEqual(
            self.chains[0].view_lengths,
            [[1, 3, 3], [1, 5, 5], [1, 8, 8], [1, 9, 9], [1, 7, 7]])
        self.assertEqual(self.chains[0].source_length, 1)

        self.assertEqual(self.chains[-1].x_new_order,
                         [[], [], [], [], [], [], [], [], [], [], [], [], [],
                          [], [], [], [], []])
        self.assertEqual(self.chains[-1].x_hidden_codes,
                         [[], [], [], [], [], [], [], [], [], [], [], [], [],
                          [], [], [], [], []])
        self.assertEqual(self.chains[-1].y_new_order, None)
        self.assertEqual(self.chains[-1].y_hidden_codes, None)
        self.assertEqual(self.chains[-1].props_tests, [])
        self.assertEqual(self.chains[-1].props_tests_levels, [])
        self.assertEqual(self.chains[-1].has_props_tests, False)
        self.assertEqual(self.chains[-1].means_tests, [])
        self.assertEqual(self.chains[-1].means_tests_levels, [])
        self.assertEqual(self.chains[-1].has_means_tests, False)
        self.assertEqual(self.chains[-1].view_sizes,
                         [[(1, 1), (7, 1), (7, 1)], [(1, 3), (7, 3), (7, 3)],
                          [(1, 5), (7, 5),
                           (7, 5)], [(1, 8), (7, 8),
                                     (7, 8)], [(1, 9), (7, 9),
                                               (7, 9)], [(1, 7), (7, 7),
                                                         (7, 7)]])
        self.assertEqual(
            self.chains[-1].view_lengths,
            [[1, 7, 7], [1, 7, 7], [1, 7, 7], [1, 7, 7], [1, 7, 7], [1, 7, 7]])
        self.assertEqual(self.chains[-1].source_length, 9)

    def test_describe(self):

        fk = 'no_filter'

        for chain in self.chains:

            chain_described = chain.describe()

            #test describe() returns a dataframe
            self.assertIsInstance(chain_described, pd.DataFrame)

            #test descibe() returns the expected dataframe - *no args*
            if chain.orientation == 'y':
                keys = chain[self.stack.name][fk].keys()
                views = chain[self.stack.name][fk][keys[0]][
                    chain.source_name].keys()
                data = [self.stack.name] * (len(keys) * len(views))
                filters = [fk] * (len(keys) * len(views))
                x = []
                for key in keys:
                    x.extend([key] * len(views))
                y = [chain.source_name] * (len(keys) * len(views))
                view = [v for v in views] * len(keys)
                ones = [1] * (len(keys) * len(views))
                df = pd.DataFrame({
                    'data': data,
                    'filter': filters,
                    'x': x,
                    'y': y,
                    'view': view,
                    '#': ones
                })
                df = df[chain_described.columns.tolist()]
                assert_frame_equal(chain_described, df)
            elif chain.orientation == 'x':

                keys = chain[self.stack.name][fk][chain.source_name].keys()
                views = chain[self.stack.name][fk][chain.source_name][
                    keys[0]].keys()
                data = [self.stack.name] * (len(keys) * len(views))
                filters = [fk] * (len(keys) * len(views))
                y = []
                for key in keys:
                    y.extend([key] * len(views))
                x = [chain.source_name] * (len(keys) * len(views))
                view = [v for v in views] * len(keys)
                ones = [1] * (len(keys) * len(views))
                df = pd.DataFrame({
                    'data': data,
                    'filter': filters,
                    'x': x,
                    'y': y,
                    'view': view,
                    '#': ones
                })
                df = df[chain_described.columns.tolist()]
                assert_frame_equal(chain_described, df)

    @classmethod
    def tearDownClass(self):
        self.stack = Stack("StackName")
        filepath = './tests/' + self.stack.name + '.stack'
        if os.path.exists(filepath):
            os.remove(filepath)

    def is_empty(self, any_structure):
        if any_structure:
            #print('Structure is not empty.')
            return False
        else:
            #print('Structure is empty.')
            return True

    def create_key_stack(self, branch_pos="data"):
        """ Creates a dictionary that has the structure of the keys in the Stack
            It is used to loop through the stack without affecting it.
        """
        key_stack = {}
        for data_key in self.stack:
            key_stack[data_key] = {}
            for the_filter in self.stack[data_key][branch_pos]:
                key_stack[data_key][the_filter] = {}
                for x in self.stack[data_key][branch_pos][the_filter]:
                    key_stack[data_key][the_filter][x] = []
                    for y in self.stack[data_key][branch_pos][the_filter][x]:
                        link = self.stack[data_key][branch_pos][the_filter][x][
                            y]
                        if not isinstance(link, Link):
                            continue
                        key_stack[data_key][the_filter][x].append(y)
        return key_stack

    def setup_stack_Example_Data_A(self,
                                   fk=None,
                                   xk=None,
                                   yk=None,
                                   views=None,
                                   weights=None):
        if fk is None:
            fk = 'no_filter'
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default', 'cbase', 'counts', 'c%']
        if not isinstance(weights, list):
            weights = [weights]

        self.stack = Stack(name="Example Data (A)")
        self.stack.add_data(data_key=self.stack.name,
                            meta=self.example_data_A_meta,
                            data=self.example_data_A_data)

        for weight in weights:
            self.stack.add_link(data_keys=self.stack.name,
                                filters=fk,
                                x=xk,
                                y=yk,
                                views=QuantipyViews(views),
                                weights=weight)

    def setup_chains_Example_Data_A(self,
                                    fk=None,
                                    xk=None,
                                    yk=None,
                                    views=None,
                                    orient_on=None):

        if fk is None:
            fk = 'no_filter'
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = [
                'x|frequency|x:y|||cbase', 'x|frequency||||counts',
                'x|frequency||y||c%'
            ]

        self.chains = []

        for y in yk:
            self.chains.append(
                self.stack.get_chain(name=y,
                                     data_keys=self.stack.name,
                                     filters='no_filter',
                                     x=xk,
                                     y=y,
                                     views=views,
                                     post_process=True))

        for x in xk:
            self.chains.append(
                self.stack.get_chain(name=x,
                                     data_keys=self.stack.name,
                                     filters='no_filter',
                                     x=x,
                                     y=yk,
                                     views=views,
                                     post_process=True))
    def test_iterations_object(self):
        
        # Set up path to example files
        path_tests = self.path
        project_name = 'Example Data (A)'

        # Load Example Data (A) data and meta
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (path_tests, name_data)
        example_data_A_data = pd.DataFrame.from_csv(path_data)
        
        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (path_tests, name_meta)
        example_data_A_meta = load_json(path_meta)
 
        # Variables by type for Example Data A
        eda_int = ['record_number', 'unique_id', 'age', 'birth_day', 'birth_month']
        eda_float = ['weight', 'weight_a', 'weight_b']
        eda_single = ['gender', 'locality', 'ethnicity', 'religion', 'q1']
        eda_delimited_set = ['q2', 'q3', 'q8', 'q9']
        eda_string = ['q8a', 'q9a']
        eda_date = ['start_time', 'end_time']
        eda_time = ['duration']
        eda_array = ['q5', 'q6', 'q7']       
        eda_minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']
        
        # Create basic stack
        stack = Stack(name=project_name)
        stack.add_data(project_name, example_data_A_data, example_data_A_meta)
        stack.add_link(
            data_keys=project_name,
            filters=['no_filter'],
            x=eda_minimum,
            y=['@'],
            views=QuantipyViews(['default', 'cbase', 'counts', 'c%']),
            weights=[None, 'weight_a', 'weight_b']
        )
    
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that weighted an unweighted versions of all basic views
        # were created
        self.assertIn('x|default|x:y|||default', views_present)
        self.assertIn('x|default|x:y||weight_a|default', views_present)
        self.assertIn('x|default|x:y||weight_b|default', views_present)
        
        self.assertIn('x|frequency|x:y|||cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_a|cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_b|cbase', views_present)
        
        self.assertIn('x|frequency||y||c%', views_present)
        self.assertIn('x|frequency||y|weight_a|c%', views_present)
        self.assertIn('x|frequency||y|weight_b|c%', views_present)
        
        self.assertIn('x|frequency||||counts', views_present)
        self.assertIn('x|frequency|||weight_a|counts', views_present)
        self.assertIn('x|frequency|||weight_b|counts', views_present)

        # Create a ViewMapper using the iterator object in a template
        xnets = ViewMapper(
            template={
                'method': QuantipyViews().frequency,
                'kwargs': {
                    'axis': 'x',
                    'groups': ['Nets'],
                    'iterators': {
                        'rel_to': [None, 'y'],
                        'weights': [None, 'weight_a']
                    }
                }
            })
        
        # Add a method to the xnets ViewMapper, then use it to generate additional
        # views which include N/c% and unweighted/weighted
        xnets.add_method(name='ever', kwargs={'text': 'Ever', 'logic': [1, 2]})
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever']))
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever', views_present)
        
        # Add another method to the xnets ViewMapper, but then override the weights
        # in the iterator object using the stack.add_link(weights) parameter
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever']), weights='weight_b')
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever', views_present)
        
        # Add two methods and apply them at the same time, make sure all expected iterations 
        # of both were created
        xnets.add_method(name='ever (multi test)', kwargs={'text': 'Ever', 'logic': [1, 2]})
        xnets.add_method(name='never (multi test)', kwargs={'text': 'Never', 'logic': [2, 3]})
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever (multi test)', 'never (multi test)']))
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|||never (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y||never (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_a|never (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_a|never (multi test)', views_present)
        
        # Add two methods and apply them at the same time, make sure all expected iterations 
        # of both were created, in this case that the weights arg for stack.add_link() overrides
        # what the iterator object is asking for
        xnets.add_method(name='ever (weights test)', kwargs={'text': 'Ever', 'logic': [1, 2]})
        xnets.add_method(name='never (weights test)', kwargs={'text': 'Never', 'logic': [2, 3]})
        stack.add_link(
            x='q2b', y=['@'], 
            views=xnets.subset(['ever (weights test)', 'never (weights test)']), 
            weights=['weight_b']
        )
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertNotIn('x|frequency|x[(1,2)]:y|||ever (weights test)', views_present)
        self.assertNotIn('x|frequency|x[(1,2)]:y|y||ever (weights test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever (weights test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever (weights test)', views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|||never (weights test)', views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|y||never (weights test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_b|never (weights test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_b|never (weights test)', views_present)
class TestViewObject(unittest.TestCase):

    def setUp(self):
        self.path = './tests/'
#         self.path = ''
        self.filepath = '%sengine_B_data.csv' % (self.path)
        self.metapath = '%sengine_B_meta.json' % (self.path)
        self.stack = Stack("StackName")
        self.stack.seperator = ','
        self.stack.decoding = "UTF-8"
        self.data = pd.DataFrame.from_csv(self.filepath)
        self.meta = load_json(self.metapath)
        self.stack.add_data(data_key="Jan", meta=self.meta, data=self.data)
#         self.x_names=['age', 'cost_breakfast', 'age_group', 'endtime', 'name', 'q4'],
        self.x_names = ['age', 'cost_breakfast', 'age_group', 'q4']
#         self._types = ['int', 'float', 'single', 'date', 'string', 'delimited set']
        self.x_types = ['int', 'float', 'single', 'delimited set']
        self.y_names = ['profile_gender']
        
    def test_add_method(self):
            views = ViewMapper()
    
            #At first there should not be method 'plus' in views
            self.assertRaises(KeyError, lambda: views['plus'])
            self.assertNotIn('plus', views.keys())
            
            #Plus method added:
            views.add_method('plus', lambda x: 2)
            
            #Checked for the existance of the plus method
            self.assertIsNotNone(views['plus']['method'])
            self.assertIsNotNone(views['plus']['kwargs'])
            self.assertIn('plus', views.keys())
    
            #Check to see wether a method is overridden properly
            views.add_method('plus', 'me')
            
            #The method should have changed from lambda x:2 to me
            self.assertEqual(views['plus']['method'], 'me')
            
#             Check to see wether a method is overridden properly
            views.add_method('minus', 'x', {'key': 'value'})
            self.assertEqual(views['minus']['method'], 'x')
            
    def test__custom_methods(self):
        views = ViewMapper()
        
        views.add_method('minus_x', 'x', {'key': 'value'})
        views.add_method('minus_y', 'y')
        views.add_method('minus_z', 'z')
        
        for view in ['minus_x', 'minus_y', 'minus_z']:
            self.assertIn(view, views._custom_methods())
            
        for view in ['X', 'Y', 'Z']:
            self.assertNotIn(view, views._custom_methods())
        
    def test__get_method_types(self):
        
        #not checked - time & string - need to implemented 
        #examples: time   - "endtime"
        #          string - "name"
        
        views = QuantipyViews(['default'])
        
        self.stack.add_link(data_keys="Jan",
                            x=self.x_names, 
                            y=self.y_names, 
                            views=views)
        
        for x_type, x_name in zip(self.x_types, self.x_names):
            link = self.stack['Jan']['no_filter'][x_name]['profile_gender']    
            self.assertEqual(x_type, views._get_method_types(link)[0])

    def test__apply_to(self):
        
        #not checked - time & string - need to implemented 
        #examples: time   - "endtime"
        #          string - "name"
        
        views = QuantipyViews(['cbase', 'counts', 'mean'])
        
        # This matches the view method names to their resulting view key
        # based on the new view notation
        notation = {
            'default': 'x|default|x:y|||default',
            'cbase': 'x|frequency|x:y|||cbase',
            'counts': 'x|frequency||||counts',
            'mean': 'x|mean|x:y|||mean'
        }
        
        x_names = ['profile_gender', 'age_group', 'q4']
        y_names = x_names
        
        self.stack.add_link(data_keys="Jan",
                            x=x_names, 
                            y=y_names)
        
        for a_x in self.stack['Jan']['no_filter'].keys():
            for a_y in self.stack['Jan']['no_filter'][a_x].keys():
                link = self.stack['Jan']['no_filter'][a_x][a_y]
                if not link.y == "@":
                    views._apply_to(link)

        for view in views.keys():
            for a_x in self.stack['Jan']['no_filter'].keys():
                for a_y in self.stack['Jan']['no_filter'][a_x].keys():
                    if views[view]['method'] == 'descriptives':
                        if a_x == 'q4':
                            self.assertNotIn(notation[view], self.stack['Jan']['no_filter'][a_x][a_y].keys())
                        else:                        
                            self.assertIn(notation[view], self.stack['Jan']['no_filter'][a_x][a_y].keys())
                    else:
                        self.assertIn(notation[view], self.stack['Jan']['no_filter'][a_x][a_y].keys())

    def test_get_view_iterations(self):
        
        views = QuantipyViews(['default'])
        iterators = {'A': [1, 2], 'B': [3, 4, 5], 'C': [6, 7, 8, 9]}
        iterations = views.__get_view_iterations__(iterators)
        
        # Test that iterations has the anticipated number of items
        # It should be the multiplication of the len of all of 
        # iterators lists, in this case 2x3x4=24
        self.assertEqual(len(iterations), 24)
        
        self.assertEqual(iterations[0], {'A': 1, 'B': 3, 'C': 6})
        self.assertEqual(iterations[1], {'A': 1, 'B': 4, 'C': 6})
        self.assertEqual(iterations[2], {'A': 1, 'B': 5, 'C': 6})
        self.assertEqual(iterations[3], {'A': 1, 'B': 3, 'C': 7})
        self.assertEqual(iterations[4], {'A': 1, 'B': 4, 'C': 7})
        self.assertEqual(iterations[5], {'A': 1, 'B': 5, 'C': 7})
        self.assertEqual(iterations[6], {'A': 1, 'B': 3, 'C': 8})
        self.assertEqual(iterations[7], {'A': 1, 'B': 4, 'C': 8})
        self.assertEqual(iterations[8], {'A': 1, 'B': 5, 'C': 8})
        self.assertEqual(iterations[9], {'A': 1, 'B': 3, 'C': 9})
        self.assertEqual(iterations[10], {'A': 1, 'B': 4, 'C': 9})
        self.assertEqual(iterations[11], {'A': 1, 'B': 5, 'C': 9})
        self.assertEqual(iterations[12], {'A': 2, 'B': 3, 'C': 6})
        self.assertEqual(iterations[13], {'A': 2, 'B': 4, 'C': 6})
        self.assertEqual(iterations[14], {'A': 2, 'B': 5, 'C': 6})
        self.assertEqual(iterations[15], {'A': 2, 'B': 3, 'C': 7})
        self.assertEqual(iterations[16], {'A': 2, 'B': 4, 'C': 7})
        self.assertEqual(iterations[17], {'A': 2, 'B': 5, 'C': 7})
        self.assertEqual(iterations[18], {'A': 2, 'B': 3, 'C': 8})
        self.assertEqual(iterations[19], {'A': 2, 'B': 4, 'C': 8})
        self.assertEqual(iterations[20], {'A': 2, 'B': 5, 'C': 8})
        self.assertEqual(iterations[21], {'A': 2, 'B': 3, 'C': 9})
        self.assertEqual(iterations[22], {'A': 2, 'B': 4, 'C': 9})
        self.assertEqual(iterations[23], {'A': 2, 'B': 5, 'C': 9})

    def test_iterations_object(self):
        
        # Set up path to example files
        path_tests = self.path
        project_name = 'Example Data (A)'

        # Load Example Data (A) data and meta
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (path_tests, name_data)
        example_data_A_data = pd.DataFrame.from_csv(path_data)
        
        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (path_tests, name_meta)
        example_data_A_meta = load_json(path_meta)
 
        # Variables by type for Example Data A
        eda_int = ['record_number', 'unique_id', 'age', 'birth_day', 'birth_month']
        eda_float = ['weight', 'weight_a', 'weight_b']
        eda_single = ['gender', 'locality', 'ethnicity', 'religion', 'q1']
        eda_delimited_set = ['q2', 'q3', 'q8', 'q9']
        eda_string = ['q8a', 'q9a']
        eda_date = ['start_time', 'end_time']
        eda_time = ['duration']
        eda_array = ['q5', 'q6', 'q7']       
        eda_minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']
        
        # Create basic stack
        stack = Stack(name=project_name)
        stack.add_data(project_name, example_data_A_data, example_data_A_meta)
        stack.add_link(
            data_keys=project_name,
            filters=['no_filter'],
            x=eda_minimum,
            y=['@'],
            views=QuantipyViews(['default', 'cbase', 'counts', 'c%']),
            weights=[None, 'weight_a', 'weight_b']
        )
    
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that weighted an unweighted versions of all basic views
        # were created
        self.assertIn('x|default|x:y|||default', views_present)
        self.assertIn('x|default|x:y||weight_a|default', views_present)
        self.assertIn('x|default|x:y||weight_b|default', views_present)
        
        self.assertIn('x|frequency|x:y|||cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_a|cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_b|cbase', views_present)
        
        self.assertIn('x|frequency||y||c%', views_present)
        self.assertIn('x|frequency||y|weight_a|c%', views_present)
        self.assertIn('x|frequency||y|weight_b|c%', views_present)
        
        self.assertIn('x|frequency||||counts', views_present)
        self.assertIn('x|frequency|||weight_a|counts', views_present)
        self.assertIn('x|frequency|||weight_b|counts', views_present)

        # Create a ViewMapper using the iterator object in a template
        xnets = ViewMapper(
            template={
                'method': QuantipyViews().frequency,
                'kwargs': {
                    'axis': 'x',
                    'groups': ['Nets'],
                    'iterators': {
                        'rel_to': [None, 'y'],
                        'weights': [None, 'weight_a']
                    }
                }
            })
        
        # Add a method to the xnets ViewMapper, then use it to generate additional
        # views which include N/c% and unweighted/weighted
        xnets.add_method(name='ever', kwargs={'text': 'Ever', 'logic': [1, 2]})
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever']))
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever', views_present)
        
        # Add another method to the xnets ViewMapper, but then override the weights
        # in the iterator object using the stack.add_link(weights) parameter
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever']), weights='weight_b')
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever', views_present)
        
        # Add two methods and apply them at the same time, make sure all expected iterations 
        # of both were created
        xnets.add_method(name='ever (multi test)', kwargs={'text': 'Ever', 'logic': [1, 2]})
        xnets.add_method(name='never (multi test)', kwargs={'text': 'Never', 'logic': [2, 3]})
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever (multi test)', 'never (multi test)']))
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|||never (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y||never (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_a|never (multi test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_a|never (multi test)', views_present)
        
        # Add two methods and apply them at the same time, make sure all expected iterations 
        # of both were created, in this case that the weights arg for stack.add_link() overrides
        # what the iterator object is asking for
        xnets.add_method(name='ever (weights test)', kwargs={'text': 'Ever', 'logic': [1, 2]})
        xnets.add_method(name='never (weights test)', kwargs={'text': 'Never', 'logic': [2, 3]})
        stack.add_link(
            x='q2b', y=['@'], 
            views=xnets.subset(['ever (weights test)', 'never (weights test)']), 
            weights=['weight_b']
        )
        
        # Get list of views created
        views_present = stack.describe(index=['view'])
        
        # Test that the expected views were all created
        self.assertNotIn('x|frequency|x[(1,2)]:y|||ever (weights test)', views_present)
        self.assertNotIn('x|frequency|x[(1,2)]:y|y||ever (weights test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever (weights test)', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever (weights test)', views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|||never (weights test)', views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|y||never (weights test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_b|never (weights test)', views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_b|never (weights test)', views_present)
Beispiel #15
0
    def test_iterations_object(self):

        # Set up path to example files
        path_tests = self.path
        project_name = 'Example Data (A)'

        # Load Example Data (A) data and meta
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (path_tests, name_data)
        example_data_A_data = pd.DataFrame.from_csv(path_data)

        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (path_tests, name_meta)
        example_data_A_meta = load_json(path_meta)

        # Variables by type for Example Data A
        eda_int = [
            'record_number', 'unique_id', 'age', 'birth_day', 'birth_month'
        ]
        eda_float = ['weight', 'weight_a', 'weight_b']
        eda_single = ['gender', 'locality', 'ethnicity', 'religion', 'q1']
        eda_delimited_set = ['q2', 'q3', 'q8', 'q9']
        eda_string = ['q8a', 'q9a']
        eda_date = ['start_time', 'end_time']
        eda_time = ['duration']
        eda_array = ['q5', 'q6', 'q7']
        eda_minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']

        # Create basic stack
        stack = Stack(name=project_name)
        stack.add_data(project_name, example_data_A_data, example_data_A_meta)
        stack.add_link(data_keys=project_name,
                       filters=['no_filter'],
                       x=eda_minimum,
                       y=['@'],
                       views=QuantipyViews(
                           ['default', 'cbase', 'counts', 'c%']),
                       weights=[None, 'weight_a', 'weight_b'])

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that weighted an unweighted versions of all basic views
        # were created
        self.assertIn('x|default|x:y|||default', views_present)
        self.assertIn('x|default|x:y||weight_a|default', views_present)
        self.assertIn('x|default|x:y||weight_b|default', views_present)

        self.assertIn('x|frequency|x:y|||cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_a|cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_b|cbase', views_present)

        self.assertIn('x|frequency||y||c%', views_present)
        self.assertIn('x|frequency||y|weight_a|c%', views_present)
        self.assertIn('x|frequency||y|weight_b|c%', views_present)

        self.assertIn('x|frequency||||counts', views_present)
        self.assertIn('x|frequency|||weight_a|counts', views_present)
        self.assertIn('x|frequency|||weight_b|counts', views_present)

        # Create a ViewMapper using the iterator object in a template
        xnets = ViewMapper(
            template={
                'method': QuantipyViews().frequency,
                'kwargs': {
                    'axis': 'x',
                    'groups': ['Nets'],
                    'iterators': {
                        'rel_to': [None, 'y'],
                        'weights': [None, 'weight_a']
                    }
                }
            })

        # Add a method to the xnets ViewMapper, then use it to generate additional
        # views which include N/c% and unweighted/weighted
        xnets.add_method(name='ever', kwargs={'text': 'Ever', 'logic': [1, 2]})
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever']))

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever', views_present)

        # Add another method to the xnets ViewMapper, but then override the weights
        # in the iterator object using the stack.add_link(weights) parameter
        stack.add_link(x='q2b',
                       y=['@'],
                       views=xnets.subset(['ever']),
                       weights='weight_b')

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever', views_present)

        # Add two methods and apply them at the same time, make sure all expected iterations
        # of both were created
        xnets.add_method(name='ever (multi test)',
                         kwargs={
                             'text': 'Ever',
                             'logic': [1, 2]
                         })
        xnets.add_method(name='never (multi test)',
                         kwargs={
                             'text': 'Never',
                             'logic': [2, 3]
                         })
        stack.add_link(x='q2b',
                       y=['@'],
                       views=xnets.subset(
                           ['ever (multi test)', 'never (multi test)']))

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|||never (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y||never (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_a|never (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_a|never (multi test)',
                      views_present)

        # Add two methods and apply them at the same time, make sure all expected iterations
        # of both were created, in this case that the weights arg for stack.add_link() overrides
        # what the iterator object is asking for
        xnets.add_method(name='ever (weights test)',
                         kwargs={
                             'text': 'Ever',
                             'logic': [1, 2]
                         })
        xnets.add_method(name='never (weights test)',
                         kwargs={
                             'text': 'Never',
                             'logic': [2, 3]
                         })
        stack.add_link(x='q2b',
                       y=['@'],
                       views=xnets.subset(
                           ['ever (weights test)', 'never (weights test)']),
                       weights=['weight_b'])

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertNotIn('x|frequency|x[(1,2)]:y|||ever (weights test)',
                         views_present)
        self.assertNotIn('x|frequency|x[(1,2)]:y|y||ever (weights test)',
                         views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever (weights test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever (weights test)',
                      views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|||never (weights test)',
                         views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|y||never (weights test)',
                         views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_b|never (weights test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_b|never (weights test)',
                      views_present)
Beispiel #16
0
 def tearDownClass(self):
     self.stack = Stack("StackName")
     filepath = './tests/' + self.stack.name + '.stack'
     if os.path.exists(filepath):
         os.remove(filepath)
Beispiel #17
0
class TestLinkObject(unittest.TestCase):

    # stack.add_link(x='q1', y=y, views=mean_views.subset('m1to6'), weights=weight)

    def setUp(self):
        self.path = './tests/'
        #         self.path = ''
        project_name = 'Example Data (A)'

        # Load Example Data (A) data and meta into self
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (self.path, name_data)
        self.example_data_A_data = pd.read_csv(path_data)
        self.example_data_A_data = dataframe_fix_string_types(
            self.example_data_A_data)
        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (self.path, name_meta)
        self.example_data_A_meta = load_json(path_meta)

        # The minimum list of variables required to populate a stack with all single*delimited set variations
        self.minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']

        self.setup_stack_Example_Data_A()

    def test_link_is_a_subclassed_dict(self):
        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum

        for x in xk:
            for y in yk:
                link = self.stack[dk][fk][x][y]
                self.assertIsInstance(link, dict)
                self.assertIsInstance(link, Link)

    def test_link_behaves_like_a_dict(self):

        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum

        key = "some_key_name"
        value = "some_value"

        for x in xk:
            for y in yk:
                link = self.stack[dk][fk][x][y]
                link[key] = value
                self.assertIn(
                    key,
                    link.keys(),
                    msg="Link should have key {data_key}, but has {link_keys}".
                    format(data_key=key, link_keys=link.keys()))

    def test_get_meta(self):

        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum

        #test returned meta against stack meta
        for x in xk:
            for y in yk:
                link = self.stack[dk][fk][x][y]
                self.assertEqual(link.get_meta(), self.stack[dk].meta)

    def test_get_data(self):

        dk = self.stack.name
        fk = 'no_filter'
        xk = self.minimum
        yk = ['@'] + self.minimum

        stack_data = self.stack[dk][fk].data

        #test returned data against stack data
        for x in xk:
            for y in yk:
                link_data = self.stack[dk][fk][x][y].get_data()
                self.assertTrue(link_data is stack_data)

    @classmethod
    def tearDownClass(self):
        self.stack = Stack("StackName")
        filepath = './tests/' + self.stack.name + '.stack'
        if os.path.exists(filepath):
            os.remove(filepath)

    def is_empty(self, any_structure):
        if any_structure:
            #print('Structure is not empty.')
            return False
        else:
            #print('Structure is empty.')
            return True

    def create_key_stack(self, branch_pos="data"):
        """ Creates a dictionary that has the structure of the keys in the Stack
            It is used to loop through the stack without affecting it.
        """
        key_stack = {}
        for data_key in self.stack:
            key_stack[data_key] = {}
            for the_filter in self.stack[data_key][branch_pos]:
                key_stack[data_key][the_filter] = {}
                for x in self.stack[data_key][branch_pos][the_filter]:
                    key_stack[data_key][the_filter][x] = []
                    for y in self.stack[data_key][branch_pos][the_filter][x]:
                        link = self.stack[data_key][branch_pos][the_filter][x][
                            y]
                        if not isinstance(link, Link):
                            continue
                        key_stack[data_key][the_filter][x].append(y)
        return key_stack

    def setup_stack_Example_Data_A(self,
                                   fk=None,
                                   xk=None,
                                   yk=None,
                                   views=None,
                                   weights=None):
        if fk is None:
            fk = ['no_filter', 'Wave == 1']
        if xk is None:
            xk = self.minimum
        if yk is None:
            yk = ['@'] + self.minimum
        if views is None:
            views = ['default']
        if not isinstance(weights, list):
            weights = [weights]

        self.stack = Stack(name="Example Data (A)")
        self.stack.add_data(data_key=self.stack.name,
                            meta=self.example_data_A_meta,
                            data=self.example_data_A_data)

        for weight in weights:
            self.stack.add_link(data_keys=self.stack.name,
                                filters=fk,
                                x=xk,
                                y=yk,
                                views=QuantipyViews(views),
                                weights=weight)
Beispiel #18
0
class TestViewObject(unittest.TestCase):
    def setUp(self):
        self.path = './tests/'
        #         self.path = ''
        self.filepath = '%sengine_B_data.csv' % (self.path)
        self.metapath = '%sengine_B_meta.json' % (self.path)
        self.stack = Stack("StackName")
        self.stack.seperator = ','
        self.stack.decoding = "UTF-8"
        self.data = pd.DataFrame.from_csv(self.filepath)
        self.meta = load_json(self.metapath)
        self.stack.add_data(data_key="Jan", meta=self.meta, data=self.data)
        #         self.x_names=['age', 'cost_breakfast', 'age_group', 'endtime', 'name', 'q4'],
        self.x_names = ['age', 'cost_breakfast', 'age_group', 'q4']
        #         self._types = ['int', 'float', 'single', 'date', 'string', 'delimited set']
        self.x_types = ['int', 'float', 'single', 'delimited set']
        self.y_names = ['profile_gender']

    def test_add_method(self):
        views = ViewMapper()

        #At first there should not be method 'plus' in views
        self.assertRaises(KeyError, lambda: views['plus'])
        self.assertNotIn('plus', views.keys())

        #Plus method added:
        views.add_method('plus', lambda x: 2)

        #Checked for the existance of the plus method
        self.assertIsNotNone(views['plus']['method'])
        self.assertIsNotNone(views['plus']['kwargs'])
        self.assertIn('plus', views.keys())

        #Check to see wether a method is overridden properly
        views.add_method('plus', 'me')

        #The method should have changed from lambda x:2 to me
        self.assertEqual(views['plus']['method'], 'me')

        #             Check to see wether a method is overridden properly
        views.add_method('minus', 'x', {'key': 'value'})
        self.assertEqual(views['minus']['method'], 'x')

    def test__custom_methods(self):
        views = ViewMapper()

        views.add_method('minus_x', 'x', {'key': 'value'})
        views.add_method('minus_y', 'y')
        views.add_method('minus_z', 'z')

        for view in ['minus_x', 'minus_y', 'minus_z']:
            self.assertIn(view, views._custom_methods())

        for view in ['X', 'Y', 'Z']:
            self.assertNotIn(view, views._custom_methods())

    def test__get_method_types(self):

        #not checked - time & string - need to implemented
        #examples: time   - "endtime"
        #          string - "name"

        views = QuantipyViews(['default'])

        self.stack.add_link(data_keys="Jan",
                            x=self.x_names,
                            y=self.y_names,
                            views=views)

        for x_type, x_name in zip(self.x_types, self.x_names):
            link = self.stack['Jan']['no_filter'][x_name]['profile_gender']
            self.assertEqual(x_type, views._get_method_types(link)[0])

    def test__apply_to(self):

        #not checked - time & string - need to implemented
        #examples: time   - "endtime"
        #          string - "name"

        views = QuantipyViews(['cbase', 'counts', 'mean'])

        # This matches the view method names to their resulting view key
        # based on the new view notation
        notation = {
            'default': 'x|default|x:y|||default',
            'cbase': 'x|frequency|x:y|||cbase',
            'counts': 'x|frequency||||counts',
            'mean': 'x|mean|x:y|||mean'
        }

        x_names = ['profile_gender', 'age_group', 'q4']
        y_names = x_names

        self.stack.add_link(data_keys="Jan", x=x_names, y=y_names)

        for a_x in self.stack['Jan']['no_filter'].keys():
            for a_y in self.stack['Jan']['no_filter'][a_x].keys():
                link = self.stack['Jan']['no_filter'][a_x][a_y]
                if not link.y == "@":
                    views._apply_to(link)

        for view in views.keys():
            for a_x in self.stack['Jan']['no_filter'].keys():
                for a_y in self.stack['Jan']['no_filter'][a_x].keys():
                    if views[view]['method'] == 'descriptives':
                        if a_x == 'q4':
                            self.assertNotIn(
                                notation[view], self.stack['Jan']['no_filter']
                                [a_x][a_y].keys())
                        else:
                            self.assertIn(
                                notation[view], self.stack['Jan']['no_filter']
                                [a_x][a_y].keys())
                    else:
                        self.assertIn(
                            notation[view],
                            self.stack['Jan']['no_filter'][a_x][a_y].keys())

    def test_get_view_iterations(self):

        views = QuantipyViews(['default'])
        iterators = {'A': [1, 2], 'B': [3, 4, 5], 'C': [6, 7, 8, 9]}
        iterations = views.__get_view_iterations__(iterators)

        # Test that iterations has the anticipated number of items
        # It should be the multiplication of the len of all of
        # iterators lists, in this case 2x3x4=24
        self.assertEqual(len(iterations), 24)

        self.assertEqual(iterations[0], {'A': 1, 'B': 3, 'C': 6})
        self.assertEqual(iterations[1], {'A': 1, 'B': 4, 'C': 6})
        self.assertEqual(iterations[2], {'A': 1, 'B': 5, 'C': 6})
        self.assertEqual(iterations[3], {'A': 1, 'B': 3, 'C': 7})
        self.assertEqual(iterations[4], {'A': 1, 'B': 4, 'C': 7})
        self.assertEqual(iterations[5], {'A': 1, 'B': 5, 'C': 7})
        self.assertEqual(iterations[6], {'A': 1, 'B': 3, 'C': 8})
        self.assertEqual(iterations[7], {'A': 1, 'B': 4, 'C': 8})
        self.assertEqual(iterations[8], {'A': 1, 'B': 5, 'C': 8})
        self.assertEqual(iterations[9], {'A': 1, 'B': 3, 'C': 9})
        self.assertEqual(iterations[10], {'A': 1, 'B': 4, 'C': 9})
        self.assertEqual(iterations[11], {'A': 1, 'B': 5, 'C': 9})
        self.assertEqual(iterations[12], {'A': 2, 'B': 3, 'C': 6})
        self.assertEqual(iterations[13], {'A': 2, 'B': 4, 'C': 6})
        self.assertEqual(iterations[14], {'A': 2, 'B': 5, 'C': 6})
        self.assertEqual(iterations[15], {'A': 2, 'B': 3, 'C': 7})
        self.assertEqual(iterations[16], {'A': 2, 'B': 4, 'C': 7})
        self.assertEqual(iterations[17], {'A': 2, 'B': 5, 'C': 7})
        self.assertEqual(iterations[18], {'A': 2, 'B': 3, 'C': 8})
        self.assertEqual(iterations[19], {'A': 2, 'B': 4, 'C': 8})
        self.assertEqual(iterations[20], {'A': 2, 'B': 5, 'C': 8})
        self.assertEqual(iterations[21], {'A': 2, 'B': 3, 'C': 9})
        self.assertEqual(iterations[22], {'A': 2, 'B': 4, 'C': 9})
        self.assertEqual(iterations[23], {'A': 2, 'B': 5, 'C': 9})

    def test_iterations_object(self):

        # Set up path to example files
        path_tests = self.path
        project_name = 'Example Data (A)'

        # Load Example Data (A) data and meta
        name_data = '%s.csv' % (project_name)
        path_data = '%s%s' % (path_tests, name_data)
        example_data_A_data = pd.DataFrame.from_csv(path_data)

        name_meta = '%s.json' % (project_name)
        path_meta = '%s%s' % (path_tests, name_meta)
        example_data_A_meta = load_json(path_meta)

        # Variables by type for Example Data A
        eda_int = [
            'record_number', 'unique_id', 'age', 'birth_day', 'birth_month'
        ]
        eda_float = ['weight', 'weight_a', 'weight_b']
        eda_single = ['gender', 'locality', 'ethnicity', 'religion', 'q1']
        eda_delimited_set = ['q2', 'q3', 'q8', 'q9']
        eda_string = ['q8a', 'q9a']
        eda_date = ['start_time', 'end_time']
        eda_time = ['duration']
        eda_array = ['q5', 'q6', 'q7']
        eda_minimum = ['q2b', 'Wave', 'q2', 'q3', 'q5_1']

        # Create basic stack
        stack = Stack(name=project_name)
        stack.add_data(project_name, example_data_A_data, example_data_A_meta)
        stack.add_link(data_keys=project_name,
                       filters=['no_filter'],
                       x=eda_minimum,
                       y=['@'],
                       views=QuantipyViews(
                           ['default', 'cbase', 'counts', 'c%']),
                       weights=[None, 'weight_a', 'weight_b'])

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that weighted an unweighted versions of all basic views
        # were created
        self.assertIn('x|default|x:y|||default', views_present)
        self.assertIn('x|default|x:y||weight_a|default', views_present)
        self.assertIn('x|default|x:y||weight_b|default', views_present)

        self.assertIn('x|frequency|x:y|||cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_a|cbase', views_present)
        self.assertIn('x|frequency|x:y||weight_b|cbase', views_present)

        self.assertIn('x|frequency||y||c%', views_present)
        self.assertIn('x|frequency||y|weight_a|c%', views_present)
        self.assertIn('x|frequency||y|weight_b|c%', views_present)

        self.assertIn('x|frequency||||counts', views_present)
        self.assertIn('x|frequency|||weight_a|counts', views_present)
        self.assertIn('x|frequency|||weight_b|counts', views_present)

        # Create a ViewMapper using the iterator object in a template
        xnets = ViewMapper(
            template={
                'method': QuantipyViews().frequency,
                'kwargs': {
                    'axis': 'x',
                    'groups': ['Nets'],
                    'iterators': {
                        'rel_to': [None, 'y'],
                        'weights': [None, 'weight_a']
                    }
                }
            })

        # Add a method to the xnets ViewMapper, then use it to generate additional
        # views which include N/c% and unweighted/weighted
        xnets.add_method(name='ever', kwargs={'text': 'Ever', 'logic': [1, 2]})
        stack.add_link(x='q2b', y=['@'], views=xnets.subset(['ever']))

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever', views_present)

        # Add another method to the xnets ViewMapper, but then override the weights
        # in the iterator object using the stack.add_link(weights) parameter
        stack.add_link(x='q2b',
                       y=['@'],
                       views=xnets.subset(['ever']),
                       weights='weight_b')

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever', views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever', views_present)

        # Add two methods and apply them at the same time, make sure all expected iterations
        # of both were created
        xnets.add_method(name='ever (multi test)',
                         kwargs={
                             'text': 'Ever',
                             'logic': [1, 2]
                         })
        xnets.add_method(name='never (multi test)',
                         kwargs={
                             'text': 'Never',
                             'logic': [2, 3]
                         })
        stack.add_link(x='q2b',
                       y=['@'],
                       views=xnets.subset(
                           ['ever (multi test)', 'never (multi test)']))

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertIn('x|frequency|x[(1,2)]:y|||ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y||ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_a|ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_a|ever (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|||never (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y||never (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_a|never (multi test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_a|never (multi test)',
                      views_present)

        # Add two methods and apply them at the same time, make sure all expected iterations
        # of both were created, in this case that the weights arg for stack.add_link() overrides
        # what the iterator object is asking for
        xnets.add_method(name='ever (weights test)',
                         kwargs={
                             'text': 'Ever',
                             'logic': [1, 2]
                         })
        xnets.add_method(name='never (weights test)',
                         kwargs={
                             'text': 'Never',
                             'logic': [2, 3]
                         })
        stack.add_link(x='q2b',
                       y=['@'],
                       views=xnets.subset(
                           ['ever (weights test)', 'never (weights test)']),
                       weights=['weight_b'])

        # Get list of views created
        views_present = stack.describe(index=['view'])

        # Test that the expected views were all created
        self.assertNotIn('x|frequency|x[(1,2)]:y|||ever (weights test)',
                         views_present)
        self.assertNotIn('x|frequency|x[(1,2)]:y|y||ever (weights test)',
                         views_present)
        self.assertIn('x|frequency|x[(1,2)]:y||weight_b|ever (weights test)',
                      views_present)
        self.assertIn('x|frequency|x[(1,2)]:y|y|weight_b|ever (weights test)',
                      views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|||never (weights test)',
                         views_present)
        self.assertNotIn('x|frequency|x[(2,3)]:y|y||never (weights test)',
                         views_present)
        self.assertIn('x|frequency|x[(2,3)]:y||weight_b|never (weights test)',
                      views_present)
        self.assertIn('x|frequency|x[(2,3)]:y|y|weight_b|never (weights test)',
                      views_present)