<commit_before>from unittest import TestCase, main

import numpy as np
import pandas as pd
import pandas.util.testing as pdt

from break4w.continous import Continous, _check_limits

class ContinousTest(TestCase):

    def setUp(self):
        self.map_ = pd.DataFrame([['1', '2', '2', '4'],
                                  ['TBD', 'True', 'True', 'False'],
                                  ['Striker', 'D-man', 'D-man', 'Goalie']],
                                 index=['years_on_team',
                                        'team_captain', 'position'],
                                 columns=['Bitty', 'Ransom', 'Holster',
                                          'Johnson'],
                                 ).T
        self.name = 'years_on_team'
        self.description = ("How many years the player has been on SMH during "
                            "Bitty's frog year")
        self.dtype = int
        self.units = 'years'

        self.c = Continous(self.name,
                           self.description,
                           units=self.units,
                           dtype=self.dtype,
                           limits=[1, None],
                           outliers=[None, 5],
                           )

    def test_init_default(self):
        test = Continous(
            name=self.name,
            description=self.description,
            units=self.units
            )
        self.assertEqual(test.units, self.units)
        self.assertEqual('Continous', test.type)
        self.assertEqual(test.dtype, float)
        self.assertEqual(test.bound_lower, None)
        self.assertEqual(test.bound_upper, None)
        self.assertEqual(test.outlier_lower, None)
        self.assertEqual(test.outlier_upper, None)
        self.assertEqual(test.sig_figs, None)

    def test_init(self):
        self.assertEqual(self.c.dtype, self.dtype)
        self.assertEqual(self.c.bound_lower, 1)
        self.assertEqual(self.c.bound_upper, None)
        self.assertEqual(self.c.outlier_lower, None)
        self.assertEqual(self.c.outlier_upper, 5)

    def test_dictionary_update_outliers(self):
        self.assertEqual(self.c.outlier_lower, None)
        self.assertEqual(self.c.outlier_upper, 5)
        self.c.dictionary_update_outliers([2, 7])
        self.assertEqual(self.c.outlier_lower, 2)
        self.assertEqual(self.c.outlier_upper, 7)

        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'update outlier values')
        self.assertEqual(log_['transform_type'], 'update dictionary')
        self.assertEqual(log_['transformation'], 'Outlier values have been '
                         'updated: None > 2 and 5 > 7.')

    def test_analysis_drop_outliers_none(self):
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([None, None])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        log_ = self.c.log[2]
        self.assertEqual(log_['command'], 'drop outliers')
        self.assertEqual(log_['transform_type'], 'drop')
        self.assertEqual(log_['transformation'], 'No values dropped')

    def test_analysis_drop_outliers_left(self):
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([2, None])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([np.nan, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.assertEqual(self.c.log[2]['transformation'], 'values less than 2')

    def test_analysis_drop_outliers_right(self):
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series(['1', '2', '2', '4'],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([None, 3])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, np.nan],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.assertEqual(self.c.log[2]['transformation'],
                         'values greater than 3')

    def test_analysis_drop_outliers_both(self):
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series(['1', '2', '2', '4'],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([2, 3])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([np.nan, 2, 2, np.nan],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.assertEqual(self.c.log[2]['transformation'],
                         'values outside [2, 3]')

    def test_analysis_remap_dtype_pass(self):
        self.c.analysis_remap_dtype(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'transformation')
        self.assertEqual(log_['transform_type'], 'cast data type')
        self.assertEqual(log_['transformation'], 'convert to int')

    def test_analysis_remap_dtype_error(self):
        self.map_.loc['Bitty', 'years_on_team'] = 'Freshman'
        with self.assertRaises(TypeError):
            self.c.analysis_remap_dtype(self.map_)
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'transformation')
        self.assertEqual(log_['transform_type'], 'cast data type')
        self.assertEqual(log_['transformation'], 'could not convert to int')

    def test_analysis_set_sig_figs_error(self):
        with self.assertRaises(ValueError):
            self.c.analysis_set_sig_figs(self.map_)
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'round significant figures')
        self.assertEqual(log_['transform_type'], 'correct')
        self.assertEqual(log_['transformation'], 'Rounding must be defined!')

    def test_analysis_set_sig_figs(self):
        self.c.sig_figs = 0.1
        self.c.analysis_remap_dtype(self.map_)
        self.c.analysis_set_sig_figs(self.map_)

        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )

        self.assertEqual(self.c.bound_lower, 1.0)
        self.assertEqual(self.c.bound_upper, None)
        self.assertEqual(self.c.outlier_lower, None)
        self.assertEqual(self.c.outlier_upper, 5.0)

        log_ = self.c.log[1]
        self.assertEqual(log_['command'], 'round significant figures')
        self.assertEqual(log_['transform_type'], 'correct')
        self.assertEqual(log_['transformation'],
                         'Rounded the data to the nearest 0.1.')

    def test_validate_fail_dtype(self):
        self.c.name = 'position'
        with self.assertRaises(TypeError):
            self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 1)
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'validate')
        self.assertEqual(log_['transform_type'], 'error')
        self.assertEqual(log_['transformation'],
                         'the data cannot be cast to int')

    def test_validate_no_lim_no_blank_no_ambigious_pass(self):
        self.c.bound_upper = None
        self.c.bound_lower = None
        self.c.blanks = None
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log0 = self.c.log[0]
        self.assertEqual(log0['command'], 'validate')
        self.assertEqual(log0['transform_type'], 'pass')
        self.assertEqual(log0['transformation'],
                         'the data can be cast to int')

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'there were no limits specified')

    def test_validate_lower_pass_blank_list_ambigious_list(self):
        self.c.blanks = ['missing']
        self.c.ambiguous = ['test']
        self.map_.loc['Ransom', 'years_on_team'] = 'missing'
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log0 = self.c.log[0]
        self.assertEqual(log0['command'], 'validate')
        self.assertEqual(log0['transform_type'], 'pass')
        self.assertEqual(log0['transformation'],
                         'the data can be cast to int')

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'The values were greater than or equal to 1 years.')
x
    def test_validate_greater_pass_blank_str_ambigious_str(self):
        self.c.blanks = 'missing'
        self.c.ambiguous = 'missing'
        self.c.test = 'test'
        self.c.bound_upper = 5
        self.c.bound_lower = None
        self.map_.loc['Ransom', 'years_on_team'] = 'missing'
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log0 = self.c.log[0]
        self.assertEqual(log0['command'], 'validate')
        self.assertEqual(log0['transform_type'], 'pass')
        self.assertEqual(log0['transformation'],
                         'the data can be cast to int')

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'The values were less than or equal to 5 years.')

    def test_validate_both_lim(self):
        self.c.bound_upper = 5
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'The values were between 1 and 5 years.')

    def test_validate_lower_error(self):
        self.c.bound_lower = 2
        with self.assertRaises(ValueError):
            self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'error')
        self.assertEqual(log1['transformation'],
                         'There are values less than 2 years.')

    def test_validate_upper_error(self):
        self.c.bound_upper = 3
        with self.assertRaises(ValueError):
            self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'error')
        self.assertEqual(log1['transformation'],
                         'There are values greater than 3 years.')

    def test_validate_both_error(self):
        self.c.bound_lower = 2
        self.c.bound_upper = 3
        with self.assertRaises(ValueError):
            self.c.validate(self.map_)

        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'error')
        self.assertEqual(log1['transformation'],
                         'There are values less than 2 and greater than'
                         ' 3 years.')

    def test_check_limits_none(self):
        limits = None
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, None)
        self.assertEqual(upper, None)

    def test_check_limits_left_none(self):
        limits = [None, 5]
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, None)
        self.assertEqual(upper, 5)

    def test_check_limits_right_none(self):
        limits = [-3, None]
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, -3)
        self.assertEqual(upper, None)

    def test_check_limits_all_pass(self):
        limits = [-3, 5]
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, -3)
        self.assertEqual(upper, 5)

    def test_check_limits_all_error(self):
        limits = [8, 5]
        with self.assertRaises(ValueError):
            _check_limits(limits, 'limits')

    def test_to_dict(self):
        known = {'name': self.name,
                 'description': self.description,
                 'units': self.units,
                 'dtype': self.dtype,
                 'limits': [1, None],
                 'outliers': [None, 5],
                 'clean_name': 'Years On Team'
                 }
        type_, test = self.c.to_dict()
x        self.assertEqual(test, known)
        self.assertEqual('continous', type_)

if __name__ == '__main__':
    main()
<commit_msg>fixes test continous<commit_after>from unittest import TestCase, main

import numpy as np
import pandas as pd
import pandas.util.testing as pdt

from break4w.continous import Continous, _check_limits

class ContinousTest(TestCase):

    def setUp(self):
        self.map_ = pd.DataFrame([['1', '2', '2', '4'],
                                  ['TBD', 'True', 'True', 'False'],
                                  ['Striker', 'D-man', 'D-man', 'Goalie']],
                                 index=['years_on_team',
                                        'team_captain', 'position'],
                                 columns=['Bitty', 'Ransom', 'Holster',
                                          'Johnson'],
                                 ).T
        self.name = 'years_on_team'
        self.description = ("How many years the player has been on SMH during "
                            "Bitty's frog year")
        self.dtype = int
        self.units = 'years'

        self.c = Continous(self.name,
                           self.description,
                           units=self.units,
                           dtype=self.dtype,
                           limits=[1, None],
                           outliers=[None, 5],
                           )

    def test_init_default(self):
        test = Continous(
            name=self.name,
            description=self.description,
            units=self.units
            )
        self.assertEqual(test.units, self.units)
        self.assertEqual('Continous', test.type)
        self.assertEqual(test.dtype, float)
        self.assertEqual(test.bound_lower, None)
        self.assertEqual(test.bound_upper, None)
        self.assertEqual(test.outlier_lower, None)
        self.assertEqual(test.outlier_upper, None)
        self.assertEqual(test.sig_figs, None)

    def test_init(self):
        self.assertEqual(self.c.dtype, self.dtype)
        self.assertEqual(self.c.bound_lower, 1)
        self.assertEqual(self.c.bound_upper, None)
        self.assertEqual(self.c.outlier_lower, None)
        self.assertEqual(self.c.outlier_upper, 5)

    def test_dictionary_update_outliers(self):
        self.assertEqual(self.c.outlier_lower, None)
        self.assertEqual(self.c.outlier_upper, 5)
        self.c.dictionary_update_outliers([2, 7])
        self.assertEqual(self.c.outlier_lower, 2)
        self.assertEqual(self.c.outlier_upper, 7)

        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'update outlier values')
        self.assertEqual(log_['transform_type'], 'update dictionary')
        self.assertEqual(log_['transformation'], 'Outlier values have been '
                         'updated: None > 2 and 5 > 7.')

    def test_analysis_drop_outliers_none(self):
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([None, None])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        log_ = self.c.log[2]
        self.assertEqual(log_['command'], 'drop outliers')
        self.assertEqual(log_['transform_type'], 'drop')
        self.assertEqual(log_['transformation'], 'No values dropped')

    def test_analysis_drop_outliers_left(self):
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([2, None])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([np.nan, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.assertEqual(self.c.log[2]['transformation'], 'values less than 2')

    def test_analysis_drop_outliers_right(self):
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series(['1', '2', '2', '4'],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([None, 3])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, np.nan],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.assertEqual(self.c.log[2]['transformation'],
                         'values greater than 3')

    def test_analysis_drop_outliers_both(self):
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series(['1', '2', '2', '4'],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.c.analysis_remap_dtype(self.map_)
        self.c.dictionary_update_outliers([2, 3])
        self.c.analysis_drop_outliers(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([np.nan, 2, 2, np.nan],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        self.assertEqual(self.c.log[2]['transformation'],
                         'values outside [2, 3]')

    def test_analysis_remap_dtype_pass(self):
        self.c.analysis_remap_dtype(self.map_)
        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'transformation')
        self.assertEqual(log_['transform_type'], 'cast data type')
        self.assertEqual(log_['transformation'], 'convert to int')

    def test_analysis_remap_dtype_error(self):
        self.map_.loc['Bitty', 'years_on_team'] = 'Freshman'
        with self.assertRaises(TypeError):
            self.c.analysis_remap_dtype(self.map_)
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'transformation')
        self.assertEqual(log_['transform_type'], 'cast data type')
        self.assertEqual(log_['transformation'], 'could not convert to int')

    def test_analysis_set_sig_figs_error(self):
        with self.assertRaises(ValueError):
            self.c.analysis_set_sig_figs(self.map_)
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'round significant figures')
        self.assertEqual(log_['transform_type'], 'correct')
        self.assertEqual(log_['transformation'], 'Rounding must be defined!')

    def test_analysis_set_sig_figs(self):
        self.c.sig_figs = 0.1
        self.c.analysis_remap_dtype(self.map_)
        self.c.analysis_set_sig_figs(self.map_)

        pdt.assert_series_equal(
            self.map_['years_on_team'],
            pd.Series([1, 2, 2, 4],
                      index=['Bitty', 'Ransom', 'Holster', 'Johnson'],
                      name='years_on_team')
            )

        self.assertEqual(self.c.bound_lower, 1.0)
        self.assertEqual(self.c.bound_upper, None)
        self.assertEqual(self.c.outlier_lower, None)
        self.assertEqual(self.c.outlier_upper, 5.0)

        log_ = self.c.log[1]
        self.assertEqual(log_['command'], 'round significant figures')
        self.assertEqual(log_['transform_type'], 'correct')
        self.assertEqual(log_['transformation'],
                         'Rounded the data to the nearest 0.1.')

    def test_validate_fail_dtype(self):
        self.c.name = 'position'
        with self.assertRaises(TypeError):
            self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 1)
        log_ = self.c.log[0]
        self.assertEqual(log_['command'], 'validate')
        self.assertEqual(log_['transform_type'], 'error')
        self.assertEqual(log_['transformation'],
                         'the data cannot be cast to int')

    def test_validate_no_lim_no_blank_no_ambigious_pass(self):
        self.c.bound_upper = None
        self.c.bound_lower = None
        self.c.blanks = None
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log0 = self.c.log[0]
        self.assertEqual(log0['command'], 'validate')
        self.assertEqual(log0['transform_type'], 'pass')
        self.assertEqual(log0['transformation'],
                         'the data can be cast to int')

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'there were no limits specified')

    def test_validate_lower_pass_blank_list_ambigious_list(self):
        self.c.blanks = ['missing']
        self.c.ambiguous = ['test']
        self.map_.loc['Ransom', 'years_on_team'] = 'missing'
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log0 = self.c.log[0]
        self.assertEqual(log0['command'], 'validate')
        self.assertEqual(log0['transform_type'], 'pass')
        self.assertEqual(log0['transformation'],
                         'the data can be cast to int')

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'The values were greater than or equal to 1 years.')

    def test_validate_greater_pass_blank_str_ambigious_str(self):
        self.c.blanks = 'missing'
        self.c.ambiguous = 'missing'
        self.c.test = 'test'
        self.c.bound_upper = 5
        self.c.bound_lower = None
        self.map_.loc['Ransom', 'years_on_team'] = 'missing'
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log0 = self.c.log[0]
        self.assertEqual(log0['command'], 'validate')
        self.assertEqual(log0['transform_type'], 'pass')
        self.assertEqual(log0['transformation'],
                         'the data can be cast to int')

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'The values were less than or equal to 5 years.')

    def test_validate_both_lim(self):
        self.c.bound_upper = 5
        self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'pass')
        self.assertEqual(log1['transformation'],
                         'The values were between 1 and 5 years.')

    def test_validate_lower_error(self):
        self.c.bound_lower = 2
        with self.assertRaises(ValueError):
            self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'error')
        self.assertEqual(log1['transformation'],
                         'There are values less than 2 years.')

    def test_validate_upper_error(self):
        self.c.bound_upper = 3
        with self.assertRaises(ValueError):
            self.c.validate(self.map_)
        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'error')
        self.assertEqual(log1['transformation'],
                         'There are values greater than 3 years.')

    def test_validate_both_error(self):
        self.c.bound_lower = 2
        self.c.bound_upper = 3
        with self.assertRaises(ValueError):
            self.c.validate(self.map_)

        self.assertEqual(len(self.c.log), 2)

        log1 = self.c.log[1]
        self.assertEqual(log1['command'], 'validate')
        self.assertEqual(log1['transform_type'], 'error')
        self.assertEqual(log1['transformation'],
                         'There are values less than 2 and greater than'
                         ' 3 years.')

    def test_check_limits_none(self):
        limits = None
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, None)
        self.assertEqual(upper, None)

    def test_check_limits_left_none(self):
        limits = [None, 5]
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, None)
        self.assertEqual(upper, 5)

    def test_check_limits_right_none(self):
        limits = [-3, None]
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, -3)
        self.assertEqual(upper, None)

    def test_check_limits_all_pass(self):
        limits = [-3, 5]
        lower, upper = _check_limits(limits, 'limits')
        self.assertEqual(lower, -3)
        self.assertEqual(upper, 5)

    def test_check_limits_all_error(self):
        limits = [8, 5]
        with self.assertRaises(ValueError):
            _check_limits(limits, 'limits')

    def test_to_dict(self):
        known = {'name': self.name,
                 'description': self.description,
                 'units': self.units,
                 'dtype': self.dtype,
                 'limits': [1, None],
                 'outliers': [None, 5],
                 'clean_name': 'Years On Team'
                 }
        type_, test = self.c.to_dict()
        self.assertEqual(test, known)
        self.assertEqual('continous', type_)

    def test_to_series(self):
        self.c.missing = {"lacross"}
        self.c.frogs = ['foxtrot', 'whiskey', 'tango']
        known = pd.Series({'name': self.name,
                           'description': self.description,
                           'units': self.units,
                           'dtype': 'int',
                           'type': 'Continous',
                           'extremes': '1 | None',
                           'ambiguous': 'None | 5',
                           'missing': 'lacross',
                           'frogs': 'foxtrot | whiskey | tango',
                           'clean_name': 'Years On Team'})

        test = self.c._to_series()
        pdt.assert_series_equal(known, test)

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
#
# Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# $Id$

import os, re, sys, glob
from subprocess import Popen, PIPE

Import('env')

def call(cmd, silent=True):
    stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
    if not stderr:
        return stdin.strip()
    elif not silent:
        print stderr

def run_2to3(*args,**kwargs):
    call('2to3 -w %s' % os.path.dirname(kwargs['target'][0].path))

def is_py3():
    return 'True' in os.popen('''%s -c "import sys as s;s.stdout.write(str(s.version_info[0] == 3))"''' % env['PYTHON']).read().strip()

prefix = env['PREFIX']
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik')

libraries = ['mapnik','png']

if env['JPEG']:
    libraries.append('jpeg')

if env['BOOST_PYTHON_LIB']:
    libraries.append(env['BOOST_PYTHON_LIB'])
else:
    if is_py3():
        libraries.append('boost_python3%s' % env['BOOST_APPEND'])
    else:
        libraries.append('boost_python%s' % env['BOOST_APPEND'])

if env['PLATFORM'] == 'Darwin':
    libraries.append(env['ICU_LIB_NAME'])
    libraries.append('boost_regex%s' % env['BOOST_APPEND'])
    if env['THREADING'] == 'multi':
        libraries.append('boost_thread%s' % env['BOOST_APPEND'])

    ##### Python linking on OS X is tricky ###
    # Confounding problems are:
    # 1) likelyhood of multiple python installs of the same major.minor version
    #  because apple supplies python built-in and many users may have installed
    #  further versions using macports
    # 2) boost python directly links to a python version
    # 3) the below will directly link _mapnik.so to a python version
    # 4) _mapnik.so must link to the same python lib as boost_python.dylib otherwise
    # python will Abort with a Version Mismatch error.
    # See http://trac.mapnik.org/ticket/453 for the seeds of a better approach
    # for now we offer control over method of direct linking...
    # The default below is to link against the python dylib in the form of
    #/path/to/Python.framework/Python instead of -lpython

    # http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/ld.1.html

    if env['PYTHON_DYNAMIC_LOOKUP']:
        python_link_flag = '-undefined dynamic_lookup'
    elif env['FRAMEWORK_PYTHON']:
        if env['FRAMEWORK_SEARCH_PATH']:
            # if the user has supplied a custom root path to search for
            # a given Python framework, then use that to direct the linker
            python_link_flag = '-F%s -framework Python -Z' % env['FRAMEWORK_SEARCH_PATH']
        else:
            # otherwise be as explicit as possible for linking to the same Framework
            # as the executable we are building with (or is pointed to by the PYTHON variable)
            # otherwise we may accidentally link against either:
            # /System/Library/Frameworks/Python.framework/Python/Versions/
            # or
            # /Library/Frameworks/Python.framework/Python/Versions/
            # See: http://trac.mapnik.org/ticket/380
            link_prefix = env['PYTHON_SYS_PREFIX']
            if '.framework' in link_prefix:
                python_link_flag = '-F%s -framework Python -Z' % os.path.dirname(link_prefix.split('.')[0])
            elif '/System' in link_prefix:
                python_link_flag = '-F/System/Library/Frameworks/ -framework Python -Z'
            else:
                # should we fall back to -lpython here?
                python_link_flag = '-F/ -framework Python'

    # if we are not linking to a framework then use the *nix standard approach
    else:
        # TODO - do we need to pass -L/?
        python_link_flag = '-lpython%s' % env['PYTHON_VERSION']
elif env['PLATFORM'] == 'SunOS':
    # make sure to explicitly link mapnik.so against
    # libmapnik in its installed location
    python_link_flag = '-R%s' % env['MAPNIK_LIB_BASE']
else:
    # all other platforms we don't directly link python
    python_link_flag = ''

if env['CUSTOM_LDFLAGS']:
    linkflags = '%s %s' % (env['CUSTOM_LDFLAGS'], python_link_flag)
else:
    linkflags = python_link_flag

paths = '''
"""Configuration paths of Mapnik fonts and input plugins (auto-generated by SCons)."""

import os

mapniklibpath = '%s'
'''

paths += "inputpluginspath = os.path.normpath(mapniklibpath + '/input')\n"

if env['SYSTEM_FONTS']:
    paths += "fontscollectionpath = os.path.normpath('%s')" % env['SYSTEM_FONTS']
else:
    paths += "fontscollectionpath = os.path.normpath(mapniklibpath + '/fonts')"

if not os.path.exists('mapnik'):
    os.mkdir('mapnik')
file('mapnik/paths.py','w').write(paths % (env['MAPNIK_LIB_DIR']))

# force open perms temporarily so that `sudo scons install`
# does not later break simple non-install non-sudo rebuild
try:
    os.chmod('mapnik/paths.py',0666)
except: pass

# install the core mapnik python files, including '__init__.py'
if 'install' in COMMAND_LINE_TARGETS:
    init_files = glob.glob('mapnik/*.py')
    if 'mapnik/paths.py' in init_files:
        init_files.remove('mapnik/paths.py')
    init_module = env.Install(target_path, init_files)
    env.Alias(target='install', source=init_module)
    # install mapnik2 module which redirects to mapnik and issues DeprecatedWarning
    path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
    init_mapnik2 = env.Install(path, 'mapnik2/__init__.py')
    env.Alias(target='install', source=init_mapnik2)

# fix perms and install the custom generated 'paths.py'
if 'install' in COMMAND_LINE_TARGETS:
    targetp = os.path.join(target_path,'paths.py')
    env.Alias("install", targetp)
    # use env.Command rather than env.Install
    # to enable setting proper perms on `paths.py`
    env.Command( targetp, 'mapnik/paths.py',
        [
        Copy("$TARGET","$SOURCE"),
        Chmod("$TARGET", 0644),
        ])

# install the shared object beside the module directory
sources = glob.glob('*.cpp')

py_env = env.Clone()
py_env.Append(CPPPATH = env['PYTHON_INCLUDES'])

if env['HAS_CAIRO']:
    py_env.Append(CPPPATH = env['CAIROMM_CPPPATHS'])
    py_env.Append(CXXFLAGS = '-DHAVE_CAIRO')
    if env['PLATFORM'] == 'Darwin':
        py_env.Append(LIBS=env['CAIROMM_LINKFLAGS'])

if env['HAS_PYCAIRO']:
    py_env.ParseConfig('pkg-config --cflags pycairo')
    py_env.Append(CXXFLAGS = '-DHAVE_PYCAIRO')

_mapnik = py_env.LoadableModule('mapnik/_mapnik', sources, LIBS=libraries, LDMODULEPREFIX='', LDMODULESUFFIX='.so',LINKFLAGS=linkflags)

Depends(_mapnik, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))

if env['PLATFORM'] == 'SunOS' and env['PYTHON_IS_64BIT']:
    # http://mail.python.org/pipermail/python-dev/2006-August/068528.html
    cxx_module_path = os.path.join(target_path,'64')
else:
    cxx_module_path = target_path

if 'uninstall' not in COMMAND_LINE_TARGETS:
    pymapniklib = env.Install(cxx_module_path,_mapnik)
    py_env.Alias(target='install',source=pymapniklib)
    if 'install' in COMMAND_LINE_TARGETS:
        if is_py3():
            env.AddPostAction(pymapniklib, run_2to3)

env['create_uninstall_target'](env, target_path)

<commit_msg>python: also include uninstall target for deprecated module name<commit_after>#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
#
# Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# $Id$

import os, re, sys, glob
from subprocess import Popen, PIPE

Import('env')

def call(cmd, silent=True):
    stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
    if not stderr:
        return stdin.strip()
    elif not silent:
        print stderr

def run_2to3(*args,**kwargs):
    call('2to3 -w %s' % os.path.dirname(kwargs['target'][0].path))

def is_py3():
    return 'True' in os.popen('''%s -c "import sys as s;s.stdout.write(str(s.version_info[0] == 3))"''' % env['PYTHON']).read().strip()

prefix = env['PREFIX']
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik')
target_path_deprecated = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')

libraries = ['mapnik','png']

if env['JPEG']:
    libraries.append('jpeg')

if env['BOOST_PYTHON_LIB']:
    libraries.append(env['BOOST_PYTHON_LIB'])
else:
    if is_py3():
        libraries.append('boost_python3%s' % env['BOOST_APPEND'])
    else:
        libraries.append('boost_python%s' % env['BOOST_APPEND'])

if env['PLATFORM'] == 'Darwin':
    libraries.append(env['ICU_LIB_NAME'])
    libraries.append('boost_regex%s' % env['BOOST_APPEND'])
    if env['THREADING'] == 'multi':
        libraries.append('boost_thread%s' % env['BOOST_APPEND'])

    ##### Python linking on OS X is tricky ###
    # Confounding problems are:
    # 1) likelyhood of multiple python installs of the same major.minor version
    #  because apple supplies python built-in and many users may have installed
    #  further versions using macports
    # 2) boost python directly links to a python version
    # 3) the below will directly link _mapnik.so to a python version
    # 4) _mapnik.so must link to the same python lib as boost_python.dylib otherwise
    # python will Abort with a Version Mismatch error.
    # See http://trac.mapnik.org/ticket/453 for the seeds of a better approach
    # for now we offer control over method of direct linking...
    # The default below is to link against the python dylib in the form of
    #/path/to/Python.framework/Python instead of -lpython

    # http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/ld.1.html

    if env['PYTHON_DYNAMIC_LOOKUP']:
        python_link_flag = '-undefined dynamic_lookup'
    elif env['FRAMEWORK_PYTHON']:
        if env['FRAMEWORK_SEARCH_PATH']:
            # if the user has supplied a custom root path to search for
            # a given Python framework, then use that to direct the linker
            python_link_flag = '-F%s -framework Python -Z' % env['FRAMEWORK_SEARCH_PATH']
        else:
            # otherwise be as explicit as possible for linking to the same Framework
            # as the executable we are building with (or is pointed to by the PYTHON variable)
            # otherwise we may accidentally link against either:
            # /System/Library/Frameworks/Python.framework/Python/Versions/
            # or
            # /Library/Frameworks/Python.framework/Python/Versions/
            # See: http://trac.mapnik.org/ticket/380
            link_prefix = env['PYTHON_SYS_PREFIX']
            if '.framework' in link_prefix:
                python_link_flag = '-F%s -framework Python -Z' % os.path.dirname(link_prefix.split('.')[0])
            elif '/System' in link_prefix:
                python_link_flag = '-F/System/Library/Frameworks/ -framework Python -Z'
            else:
                # should we fall back to -lpython here?
                python_link_flag = '-F/ -framework Python'

    # if we are not linking to a framework then use the *nix standard approach
    else:
        # TODO - do we need to pass -L/?
        python_link_flag = '-lpython%s' % env['PYTHON_VERSION']
elif env['PLATFORM'] == 'SunOS':
    # make sure to explicitly link mapnik.so against
    # libmapnik in its installed location
    python_link_flag = '-R%s' % env['MAPNIK_LIB_BASE']
else:
    # all other platforms we don't directly link python
    python_link_flag = ''

if env['CUSTOM_LDFLAGS']:
    linkflags = '%s %s' % (env['CUSTOM_LDFLAGS'], python_link_flag)
else:
    linkflags = python_link_flag

paths = '''
"""Configuration paths of Mapnik fonts and input plugins (auto-generated by SCons)."""

import os

mapniklibpath = '%s'
'''

paths += "inputpluginspath = os.path.normpath(mapniklibpath + '/input')\n"

if env['SYSTEM_FONTS']:
    paths += "fontscollectionpath = os.path.normpath('%s')" % env['SYSTEM_FONTS']
else:
    paths += "fontscollectionpath = os.path.normpath(mapniklibpath + '/fonts')"

if not os.path.exists('mapnik'):
    os.mkdir('mapnik')
file('mapnik/paths.py','w').write(paths % (env['MAPNIK_LIB_DIR']))

# force open perms temporarily so that `sudo scons install`
# does not later break simple non-install non-sudo rebuild
try:
    os.chmod('mapnik/paths.py',0666)
except: pass

# install the core mapnik python files, including '__init__.py'
if 'install' in COMMAND_LINE_TARGETS:
    init_files = glob.glob('mapnik/*.py')
    if 'mapnik/paths.py' in init_files:
        init_files.remove('mapnik/paths.py')
    init_module = env.Install(target_path, init_files)
    env.Alias(target='install', source=init_module)
    # install mapnik2 module which redirects to mapnik and issues DeprecatedWarning
    init_mapnik2 = env.Install(target_path_deprecated, 'mapnik2/__init__.py')
    env.Alias(target='install', source=init_mapnik2)

# fix perms and install the custom generated 'paths.py'
if 'install' in COMMAND_LINE_TARGETS:
    targetp = os.path.join(target_path,'paths.py')
    env.Alias("install", targetp)
    # use env.Command rather than env.Install
    # to enable setting proper perms on `paths.py`
    env.Command( targetp, 'mapnik/paths.py',
        [
        Copy("$TARGET","$SOURCE"),
        Chmod("$TARGET", 0644),
        ])

# install the shared object beside the module directory
sources = glob.glob('*.cpp')

py_env = env.Clone()
py_env.Append(CPPPATH = env['PYTHON_INCLUDES'])

if env['HAS_CAIRO']:
    py_env.Append(CPPPATH = env['CAIROMM_CPPPATHS'])
    py_env.Append(CXXFLAGS = '-DHAVE_CAIRO')
    if env['PLATFORM'] == 'Darwin':
        py_env.Append(LIBS=env['CAIROMM_LINKFLAGS'])

if env['HAS_PYCAIRO']:
    py_env.ParseConfig('pkg-config --cflags pycairo')
    py_env.Append(CXXFLAGS = '-DHAVE_PYCAIRO')

_mapnik = py_env.LoadableModule('mapnik/_mapnik', sources, LIBS=libraries, LDMODULEPREFIX='', LDMODULESUFFIX='.so',LINKFLAGS=linkflags)

Depends(_mapnik, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))

if env['PLATFORM'] == 'SunOS' and env['PYTHON_IS_64BIT']:
    # http://mail.python.org/pipermail/python-dev/2006-August/068528.html
    cxx_module_path = os.path.join(target_path,'64')
else:
    cxx_module_path = target_path

if 'uninstall' not in COMMAND_LINE_TARGETS:
    pymapniklib = env.Install(cxx_module_path,_mapnik)
    py_env.Alias(target='install',source=pymapniklib)
    if 'install' in COMMAND_LINE_TARGETS:
        if is_py3():
            env.AddPostAction(pymapniklib, run_2to3)

env['create_uninstall_target'](env, target_path)
env['create_uninstall_target'](env, target_path_deprecated)

<|endoftext|>


<commit_before># Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This script is used to synthesize generated parts of this library."""

import synthtool as s
from synthtool import gcp

common = gcp.CommonTemplates()

default_version = "v3"

for library in s.get_staging_dirs(default_version):
    # Resolve sphinx warning `Inline substitution_reference start-string without end-string`
    # Remove tables from docstring. Requested change upstream in cl/377766167 due to https://google.aip.dev/192#formatting.
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/folders/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/folders.py"
        ],
        "-------------------------[|]----------------------------------------",
        "-------------------------\|----------------------------------------"
    )
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/organizations/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/organizations.py"
        ],
        "------------------[|]--------------------------------------------",
        "------------------\|--------------------------------------------"
    )
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/projects/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/projects.py"
        ],
        "-------------------------[|]----------------------------------------------",
        "-------------------------\|----------------------------------------------"
    )
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/projects/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/projects.py"
        ],
        "------------------[|]-----------------------------------------------------",
        "------------------\|-----------------------------------------------------"
    )

    # Work around gapic generator bug https://github.com/googleapis/gapic-generator-python/issues/902
    s.replace(library / f"google/cloud/resourcemanager_{library.name}/types/folders.py",
                r""".
    Attributes:""",
                r""".\n
    Attributes:""",
    )

    s.move(library, excludes=["setup.py", "README.rst", "docs/index.rst"])

s.remove_staging_dirs()

# ----------------------------------------------------------------------------
# Add templated files
# ----------------------------------------------------------------------------
templated_files = common.py_library(cov_level=98, microgenerator=True)
python.py_samples(skip_readmes=True)
s.move(templated_files)

s.shell.run(["nox", "-s", "blacken"], hide_output=False)
<commit_msg>chore: add missing import in owlbot.py (#100)<commit_after># Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This script is used to synthesize generated parts of this library."""

import synthtool as s
from synthtool import gcp
from synthtool.languages import python

common = gcp.CommonTemplates()

default_version = "v3"

for library in s.get_staging_dirs(default_version):
    # Resolve sphinx warning `Inline substitution_reference start-string without end-string`
    # Remove tables from docstring. Requested change upstream in cl/377766167 due to https://google.aip.dev/192#formatting.
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/folders/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/folders.py"
        ],
        "-------------------------[|]----------------------------------------",
        "-------------------------\|----------------------------------------"
    )
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/organizations/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/organizations.py"
        ],
        "------------------[|]--------------------------------------------",
        "------------------\|--------------------------------------------"
    )
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/projects/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/projects.py"
        ],
        "-------------------------[|]----------------------------------------------",
        "-------------------------\|----------------------------------------------"
    )
    s.replace(
        [
            library / f"google/cloud/resourcemanager_{library.name}/services/projects/*client.py",
            library / f"google/cloud/resourcemanager_{library.name}/types/projects.py"
        ],
        "------------------[|]-----------------------------------------------------",
        "------------------\|-----------------------------------------------------"
    )

    # Work around gapic generator bug https://github.com/googleapis/gapic-generator-python/issues/902
    s.replace(library / f"google/cloud/resourcemanager_{library.name}/types/folders.py",
                r""".
    Attributes:""",
                r""".\n
    Attributes:""",
    )

    s.move(library, excludes=["setup.py", "README.rst", "docs/index.rst"])

s.remove_staging_dirs()

# ----------------------------------------------------------------------------
# Add templated files
# ----------------------------------------------------------------------------
templated_files = common.py_library(cov_level=98, microgenerator=True)
python.py_samples(skip_readmes=True)
s.move(templated_files)

s.shell.run(["nox", "-s", "blacken"], hide_output=False)
<|endoftext|>


<commit_before>"""example_project URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('example_app.urls', namespace='example_app')),
]
<commit_msg>modifying project urls with budget app<commit_after>"""example_project URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('example_app.urls', namespace='budget_app')),
]
<|endoftext|>


<commit_before><commit_msg>Update task.py<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
import glob
import os
import platform
import shutil

from distutils import log
from distutils import dir_util
from distutils.command.build_clib import build_clib
from distutils.command.sdist import sdist
from distutils.core import setup

VERSION = '3.0'
SYSTEM = platform.system().lower()

class LazyList(list):
    """A list which re-evaluates each time.

    This is used to provide late binding for setup() below.
    """
    def __init__(self, callback):
        super(LazyList, self).__init__()
        self.callback = callback

    def __iter__(self):
        return iter(self.callback())

def get_sources():
    """Returns a list of C source files that should be compiled to
    create the library.
    """
    result = []
    for root, _, files in os.walk("./src/"):
        for name in files:
            if name.endswith(".c"):
                result.append(os.path.join(root, name))

    return result

class custom_sdist(sdist):
    """Reshuffle files for distribution."""

    def run(self):
        self.copy_sources()
        return sdist.run(self)

    def copy_sources(self):
        """Copy the C sources into the source directory.

        This rearranges the source files under the python distribution
        directory.
        """
        result = []

        try:
            dir_util.remove_tree("src/")
        except:
            pass
        dir_util.copy_tree("../../arch", "src/arch/")
        dir_util.copy_tree("../../include", "src/include/")
        dir_util.copy_tree("../../msvc/headers", "src/msvc/headers/")

        result.extend(glob.glob("../../*.[ch]"))

        for filename in result:
            outpath = os.path.join("./src/", os.path.basename(filename))
            print "%s -> %s" % (filename, outpath)
            shutil.copy(filename, outpath)

class custom_build_clib(build_clib):
    """Customized build_clib command."""

    def run(self):
        log.info('running custom_build_clib')
        build_clib.run(self)

    def finalize_options(self):
        # We want build-clib to default to build-lib as defined by the "build"
        # command.  This is so the compiled library will be put in the right
        # place along side the python code.
        self.set_undefined_options('build',
                                   ('build_lib', 'build_clib'),
                                   ('build_temp', 'build_temp'),
                                   ('compiler', 'compiler'),
                                   ('debug', 'debug'),
                                   ('force', 'force'))

        build_clib.finalize_options(self)

    def build_libraries(self, libraries):
        for (lib_name, build_info) in libraries:
            sources = self.get_source_files()
            sources = list(sources)

            log.info("building '%s' library", lib_name)

            # First, compile the source code to object files in the
            # library directory.
            macros = build_info.get('macros')
            include_dirs = build_info.get('include_dirs')
            objects = self.compiler.compile(
                sources,
                output_dir=self.build_temp,
                macros=macros,
                include_dirs=include_dirs,
                extra_postargs=build_info.get('extra_compile_args', []),
                debug=self.debug)

            # Then link the object files and put the result in the
            # package build directory.
            package = build_info.get('package', '')
            self.compiler.link_shared_lib(
                objects, lib_name,
                output_dir=os.path.join(self.build_clib, package),
                extra_preargs=build_info.get('extra_link_args', []),
                debug=self.debug,)

def get_compile_args():
    result = []
    for flag in ['CAPSTONE_X86_ATT_DISABLE_NO', 'CAPSTONE_DIET_NO',
                 'CAPSTONE_X86_REDUCE_NO', 'CAPSTONE_HAS_ARM',
                 'CAPSTONE_HAS_ARM64', 'CAPSTONE_HAS_MIPS',
                 'CAPSTONE_HAS_POWERPC', 'CAPSTONE_HAS_SPARC',
                 'CAPSTONE_HAS_SYSZ', 'CAPSTONE_HAS_X86',
                 'CAPSTONE_HAS_XCORE', 'CAPSTONE_USE_SYS_DYN_MEM',
                 "CAPSTONE_SHARED"]:

        if "windows" in SYSTEM:
            result.append("/D")
        else:
            result.append("-D")
        result.append(flag)

    if "windows" in SYSTEM:
        result += ['/GL', '/Ox', '/Ob1', '/Oy',
                   '/nologo', '/c', '/TC']

    elif "darwin" in SYSTEM:
        result += ['-arch', 'i386', '-arch', 'x86_64', '-O2',
                   '-Wall', '-fPIC']

    else:
        result += ['-fPIC', '-O2', '-Wall']

    return result

def get_link_args():
    result = []
    if "windows" in SYSTEM:
        result = [
            '/MANIFEST',
            '/LTCG',
        ]

    return result

setup(
    provides=['capstone'],
    packages=['capstone'],
    name='capstone',
    version=VERSION,
    author='Nguyen Anh Quynh',
    author_email='aquynh@gmail.com',
    description='Capstone disassembly engine',
    url='http://www.capstone-engine.org',
    classifiers=[
        'License :: OSI Approved :: BSD License',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 3',
    ],
    requires=['ctypes'],
    cmdclass=dict(
        build_clib=custom_build_clib,
        sdist=custom_sdist,
    ),

    libraries=[(
        'capstone', dict(
            package='capstone',
            sources=LazyList(get_sources),
            include_dirs=['./src/include/'],
            extra_compile_args=get_compile_args(),
            extra_link_args=get_link_args(),
        ),
    )],
)
<commit_msg>python: add some missing source files of sdist (setup.py)<commit_after>#!/usr/bin/env python
import glob
import os
import platform
import shutil

from distutils import log
from distutils import dir_util
from distutils.command.build_clib import build_clib
from distutils.command.sdist import sdist
from distutils.core import setup

VERSION = '3.0'
SYSTEM = platform.system().lower()

class LazyList(list):
    """A list which re-evaluates each time.

    This is used to provide late binding for setup() below.
    """
    def __init__(self, callback):
        super(LazyList, self).__init__()
        self.callback = callback

    def __iter__(self):
        return iter(self.callback())

def get_sources():
    """Returns a list of C source files that should be compiled to
    create the library.
    """
    result = []
    for root, _, files in os.walk("./src/"):
        for name in files:
            if name.endswith(".c") or name.endswith(".h") or \
                name.endswith(".inc") or root == "./src/":
                result.append(os.path.join(root, name))

    return result

class custom_sdist(sdist):
    """Reshuffle files for distribution."""

    def run(self):
        self.copy_sources()
        return sdist.run(self)

    def copy_sources(self):
        """Copy the C sources into the source directory.

        This rearranges the source files under the python distribution
        directory.
        """
        result = []

        try:
            dir_util.remove_tree("src/")
        except:
            pass
        dir_util.copy_tree("../../arch", "src/arch/")
        dir_util.copy_tree("../../include", "src/include/")
        dir_util.copy_tree("../../msvc/headers", "src/msvc/headers/")

        result.extend(glob.glob("../../*.[ch]"))
        result.extend(glob.glob("../../*.mk"))
        result.extend(glob.glob("../../Makefile"))
        result.extend(glob.glob("../../LICENSE*"))
        result.extend(glob.glob("../../README"))
        result.extend(glob.glob("../../*.TXT"))
        result.extend(glob.glob("../../RELEASE_NOTES"))

        for filename in result:
            outpath = os.path.join("./src/", os.path.basename(filename))
            print "%s -> %s" % (filename, outpath)
            shutil.copy(filename, outpath)

class custom_build_clib(build_clib):
    """Customized build_clib command."""

    def run(self):
        log.info('running custom_build_clib')
        build_clib.run(self)

    def finalize_options(self):
        # We want build-clib to default to build-lib as defined by the "build"
        # command.  This is so the compiled library will be put in the right
        # place along side the python code.
        self.set_undefined_options('build',
                                   ('build_lib', 'build_clib'),
                                   ('build_temp', 'build_temp'),
                                   ('compiler', 'compiler'),
                                   ('debug', 'debug'),
                                   ('force', 'force'))

        build_clib.finalize_options(self)

    def build_libraries(self, libraries):
        for (lib_name, build_info) in libraries:
            sources = self.get_source_files()
            sources = list(sources)

            log.info("building '%s' library", lib_name)

            # First, compile the source code to object files in the
            # library directory.
            macros = build_info.get('macros')
            include_dirs = build_info.get('include_dirs')
            objects = self.compiler.compile(
                sources,
                output_dir=self.build_temp,
                macros=macros,
                include_dirs=include_dirs,
                extra_postargs=build_info.get('extra_compile_args', []),
                debug=self.debug)

            # Then link the object files and put the result in the
            # package build directory.
            package = build_info.get('package', '')
            self.compiler.link_shared_lib(
                objects, lib_name,
                output_dir=os.path.join(self.build_clib, package),
                extra_preargs=build_info.get('extra_link_args', []),
                debug=self.debug,)

def get_compile_args():
    result = []
    for flag in ['CAPSTONE_X86_ATT_DISABLE_NO', 'CAPSTONE_DIET_NO',
                 'CAPSTONE_X86_REDUCE_NO', 'CAPSTONE_HAS_ARM',
                 'CAPSTONE_HAS_ARM64', 'CAPSTONE_HAS_MIPS',
                 'CAPSTONE_HAS_POWERPC', 'CAPSTONE_HAS_SPARC',
                 'CAPSTONE_HAS_SYSZ', 'CAPSTONE_HAS_X86',
                 'CAPSTONE_HAS_XCORE', 'CAPSTONE_USE_SYS_DYN_MEM',
                 "CAPSTONE_SHARED"]:

        if "windows" in SYSTEM:
            result.append("/D")
        else:
            result.append("-D")
        result.append(flag)

    if "windows" in SYSTEM:
        result += ['/GL', '/Ox', '/Ob1', '/Oy',
                   '/nologo', '/c', '/TC']

    elif "darwin" in SYSTEM:
        result += ['-arch', 'i386', '-arch', 'x86_64', '-O2',
                   '-Wall', '-fPIC']

    else:
        result += ['-fPIC', '-O2', '-Wall']

    return result

def get_link_args():
    result = []
    if "windows" in SYSTEM:
        result = [
            '/MANIFEST',
            '/LTCG',
        ]

    return result

setup(
    provides=['capstone'],
    packages=['capstone'],
    name='capstone',
    version=VERSION,
    author='Nguyen Anh Quynh',
    author_email='aquynh@gmail.com',
    description='Capstone disassembly engine',
    url='http://www.capstone-engine.org',
    classifiers=[
        'License :: OSI Approved :: BSD License',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 3',
    ],
    requires=['ctypes'],
    cmdclass=dict(
        build_clib=custom_build_clib,
        sdist=custom_sdist,
    ),

    libraries=[(
        'capstone', dict(
            package='capstone',
            sources=LazyList(get_sources),
            include_dirs=['./src/include/'],
            extra_compile_args=get_compile_args(),
            extra_link_args=get_link_args(),
        ),
    )],
)
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""Find owner of file/directory by git commit logs"""

from argparse import ArgumentParser
from collections import Counter
from datetime import datetime
from os import path
from subprocess import check_output, CalledProcessError

def path_type(val):
    """Check that val is an exisiting path"""
    if not path.exists(val):
        raise ValueError('{!r} does not exists'.format(val))
    return val

def dt2str(dt):
    """Convert datetime.timedelta to human readable format"""
    if dt.days:
        return '{}D'.format(dt.days)
    if dt.seconds > 3600:
        return '{}H'.format(dt.seconds // 3600)
    return '{}M'.format(dt.seconds // 60)

parser = ArgumentParser(description=__doc__)
parser.add_argument(
    'path', help='file/directory to check', type=path_type, default='.',
    nargs='?')
count = 3
parser.add_argument(
    '--count', help='how many people to show ({})'.format(count),
    type=int, default=count)

args = parser.parse_args()

try:
    out = check_output(['git', 'log', '--format=%aN -- %aD', args.path])
except CalledProcessError as err:
    raise SystemExit('error: {}'.format(err))

commits = Counter()
# Last people who touched the code
last = []

now = datetime.utcnow()
for line in out.decode().splitlines():
    name, time = line.strip().split(' -- ')
    if len(last) < args.count and name not in last:
        # 'Tue, 6 Jun 2017 22:13:36 -0400'
        time = datetime.strptime(time, '%a, %d %b %Y %H:%M:%S %z')
        time = (time - time.utcoffset()).replace(tzinfo=None)
        last.append('{} ({})'.format(name, dt2str(now-time)))
    commits[name] += 1

total = sum(commits.values())
most = []
for name, count in commits.most_common(args.count):
    perc = float(count) / total * 100
    most.append('{} ({:.1f}%)'.format(name, perc))

print('Most: {}'.format(', '.join(most)))
print('Last: {}'.format(', '.join(last)))
<commit_msg>comment and spell<commit_after>#!/usr/bin/env python
"""Find owner of file/directory by git commit logs"""

from argparse import ArgumentParser
from collections import Counter
from datetime import datetime
from os import path
from subprocess import check_output, CalledProcessError

def path_type(val):
    """Check that val is an existing path"""
    if not path.exists(val):
        raise ValueError('{!r} does not exists'.format(val))
    return val

def dt2str(dt):
    """Convert datetime.timedelta to human readable format"""
    if dt.days:
        return '{}D'.format(dt.days)
    if dt.seconds > 3600:
        return '{}H'.format(dt.seconds // 3600)
    return '{}M'.format(dt.seconds // 60)

parser = ArgumentParser(description=__doc__)
parser.add_argument(
    'path', help='file/directory to check', type=path_type, default='.',
    nargs='?')
count = 3
parser.add_argument(
    '--count', help='how many people to show ({})'.format(count),
    type=int, default=count)

args = parser.parse_args()

try:
    out = check_output(['git', 'log', '--format=%aN -- %aD', args.path])
except CalledProcessError as err:
    raise SystemExit('error: {}'.format(err))

commits = Counter()
# Last people who touched the code
last = []

now = datetime.utcnow()
for line in out.decode().splitlines():
    name, time = line.strip().split(' -- ')
    if len(last) < args.count and name not in last:
        # 'Tue, 6 Jun 2017 22:13:36 -0400'
        time = datetime.strptime(time, '%a, %d %b %Y %H:%M:%S %z')
        # Convert to naive datetime so we can subtract
        time = (time - time.utcoffset()).replace(tzinfo=None)
        last.append('{} ({})'.format(name, dt2str(now-time)))
    commits[name] += 1

total = sum(commits.values())
most = []
for name, count in commits.most_common(args.count):
    perc = float(count) / total * 100
    most.append('{} ({:.1f}%)'.format(name, perc))

print('Most: {}'.format(', '.join(most)))
print('Last: {}'.format(', '.join(last)))
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import rospkg
import rospy
import time

from python_qt_binding.QtCore import Qt, QMetaType, QDataStream, QVariant
from python_qt_binding import loadUi
from rqt_gui_py.plugin import Plugin
from python_qt_binding.QtWidgets import QWidget, QTreeWidget, QTreeWidgetItem,QListWidgetItem, QSlider, QGroupBox, QVBoxLayout, QLabel, QLineEdit, QListWidget, QAbstractItemView, QFileDialog
from python_qt_binding.QtGui import QDoubleValidator

from sensor_msgs.msg import JointState
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint

import os

from .animation_recording import Recorder

class DragDropList(QListWidget):
    """ QListWidget with an event that is called when a drag and drop action was performed."""

    def __init__(self, parent, ui):
        super(DragDropList, self).__init__(parent)

        self.ui = ui
        self.setAcceptDrops(True)

    def dropEvent(self, e):
        super(DragDropList, self).dropEvent(e)
        items = []
        for i in range(0, self.count()):
            items.append(self.item(i).text())
        print(items)
        self.ui.change_frame_order(items)

class RecordUI(Plugin):
    def __init__(self, context):
        super(RecordUI, self).__init__(context)

        self._widget = QWidget()
        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('bitbots_recordui_rqt'), 'resource', 'RecordUI.ui')
        loadUi(ui_file, self._widget, {})

        self._recorder = Recorder()
        self._sliders = {}
        self._textFields = {}
        self._motorSwitched = {}

        self._currentGoals = {}                 # this is the data about the current unsaved frame
        self._currentDuration = 1.0
        self._currentPause = 0.0
        self._currentName = "new frame"

        self._workingValues = {}                # this is the data about the frame that is displayed
        self._workingDuration = 1.0
        self._workingPause = 0.0
        self._workingName = self._currentName

        self._freeze = False
        self._saveDir = None

        #save current frame when switching to other frames for reference
        #working frame

        self._treeItems = {}
        self._motorCheckBody = QTreeWidgetItem(self._widget.motorTree)
        self._motorCheckLegs = QTreeWidgetItem(self._motorCheckBody)
        self._motorCheckArms = QTreeWidgetItem(self._motorCheckBody)
        self._motorCheckHead = QTreeWidgetItem(self._motorCheckBody)
        self._motorCheckLArm = QTreeWidgetItem(self._motorCheckArms)
        self._motorCheckRArm = QTreeWidgetItem(self._motorCheckArms)
        self._motorCheckLLeg = QTreeWidgetItem(self._motorCheckLegs)
        self._motorCheckRLeg = QTreeWidgetItem(self._motorCheckLegs)

        self.setObjectName('Record Animation')

        self._initial_joints = None

        self._widget.frameList = DragDropList(self._widget, self)
        self._widget.verticalLayout_2.insertWidget(0, self._widget.frameList)
        self._widget.frameList.setDragDropMode(QAbstractItemView.InternalMove)

        rospy.Subscriber("/joint_states", JointState, self.state_update, queue_size=100)
        self._joint_pub = rospy.Publisher("/motor_goals", JointTrajectory, queue_size=1)

        while not self._initial_joints:
            if not rospy.is_shutdown():
                time.sleep(0.5)
                print "wait"
            else:
                return

        self.initialize()

        context.add_widget(self._widget)

    def initialize(self):
        for i in range(0, len(self._initial_joints.name)):
            self._currentGoals[self._initial_joints.name[i]] = self._initial_joints.position[i]
            self._motorSwitched[self._initial_joints.name[i]] = True

        self.motor_controller()
        self.motor_switcher()
        self.button_connect()
        self.box_ticked()
        self.frame_list()
        self.update_frames()

    def state_update(self, joint_states):
        if not self._initial_joints:
            self._initial_joints = joint_states
            time.sleep(1)

        for i in range(0, len(joint_states.name)):
            if (not self._motorSwitched[joint_states.name[i]]) and (not self._freeze):
                self._currentGoals[joint_states.name[i]] = joint_states.position[i]
                print "update"

        self.set_sliders_and_text_fields()

    def motor_controller(self):
        """
        Sets up the GUI in the middle of the Screen to control the motors.
        Uses self._motorValues to determine which motors are present.
        """
        i = 0
        for k, v in self._currentGoals.items():
            group = QGroupBox()
            slider = QSlider(Qt.Horizontal)
            slider.setTickInterval(1)
            slider.setMinimum(-180)
            slider.setMaximum(180)
            slider.valueChanged.connect(self.slider_update)
            self._sliders[k] = slider

            textfield = QLineEdit()
            textfield.setText('0')
            textfield.textEdited.connect(self.textfield_update)
            textfield.setValidator(QDoubleValidator(-180.0, 180.0, 2))
            self._textFields[k] = textfield

            label = QLabel()
            label.setText(k)

            layout = QVBoxLayout()
            layout.addWidget(label)
            layout.addWidget(self._sliders[k])
            layout.addWidget(self._textFields[k])
            group.setLayout(layout)
            self._widget.motorControlLayout.addWidget(group, i / 5, i % 5)
            i = i+1

    def button_connect(self):
        """
        Connects the buttons in the top bar to the corresponding functions
        :return:
        """
        self._widget.buttonNew.clicked.connect(self.new)
        self._widget.buttonSave.clicked.connect(self.save)
        self._widget.buttonSaveAs.clicked.connect(self.save_as)
        self._widget.buttonOpen.clicked.connect(self.open)

        self._widget.buttonPlay.clicked.connect(self.play)
        self._widget.buttonGotoFrame.clicked.connect(self.goto_frame)
        self._widget.buttonRecord.clicked.connect(self.record)

        self._widget.buttonUndo.clicked.connect(self.undo)
        self._widget.buttonRedo.clicked.connect(self.redo)

    def new(self):
        self._recorder.clear()
        self.update_frames()

    def save(self):
        self.set_metadata()
        if not self._saveDir:
            self._saveDir = QFileDialog.getExistingDirectory()
        self._recorder.save_animation(self._saveDir, self._widget.lineAnimationName.text())

    def save_as(self):
        self._saveDir = QFileDialog.getExistingDirectory()
        self._recorder.save_animation(self._saveDir, self._widget.lineAnimationName.text())

    def set_metadata(self):
        self._recorder.set_meta_data(self._widget.lineAnimationName.text(),
                                     self._widget.lineVersion.text(),
                                     self._widget.lineAuthor.text(),
                                     self._widget.fieldDescription.toPlainText())

    def open(self):
        my_file = QFileDialog.getOpenFileName()[0]
        if my_file:
            self._recorder.load_animation(my_file)
        self.update_frames()

        metadata = self._recorder.get_meta_data()

        self._widget.lineAnimationName.setText(metadata[0])
        self._widget.lineAuthor.setText(metadata[2])
        self._widget.lineVersion.setText(metadata[1])
        self._widget.fieldDescription.setPlainText(metadata[3])

    def play(self):
        self._recorder.play()

    def goto_frame(self):
        raise NotImplementedError
        #todo publish joint trajecory message with stuff

    def record(self):
        self._recorder.record(self._currentGoals, self._widget.lineFrameName.text(), 1, 0) #todo time and pause
        self.update_frames()

    def undo(self):
        self._recorder.undo()
        self.update_frames()

    def redo(self):
        self._recorder.redo()
        self.update_frames()

    def frame_list(self):
        self._widget.frameList.itemClicked.connect(self.frame_select)

    def frame_select(self):
        selected_frame_name = self._widget.frameList.currentItem().text()
        selected_frame = None
        for v in self._recorder.get_animation_state():
            if v["name"] == selected_frame_name:
                selected_frame = v
                break

        self._freeze = not (selected_frame_name == "#CURRENT_FRAME")
        print "freeze is " + str(not (selected_frame_name == "#CURRENT_FRAME"))

        if selected_frame_name != "#CURRENT_FRAME":
            self._currentGoals = selected_frame["goals"]
            print "setting motor values"
            for k,v in self._currentGoals.items():
                print k + " set to " + str(v)
                print str(selected_frame["goals"][k])

        self.set_sliders_and_text_fields()

    def motor_switcher(self):
        self._widget.motorTree.setHeaderLabel("Stiff Motors")
        self._motorCheckBody.setText(0, "Body")
        self._motorCheckBody.setFlags(self._motorCheckBody.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckBody.setExpanded(True)
        self._motorCheckHead.setText(0, "Head")
        self._motorCheckHead.setFlags(self._motorCheckHead.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckHead.setExpanded(True)
        self._motorCheckArms.setText(0, "Arms")
        self._motorCheckArms.setFlags(self._motorCheckArms.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckArms.setExpanded(True)
        self._motorCheckLegs.setText(0, "Legs")
        self._motorCheckLegs.setFlags(self._motorCheckLegs.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckLegs.setExpanded(True)
        self._motorCheckLArm.setText(0, "Left Arm")
        self._motorCheckLArm.setFlags(self._motorCheckLArm.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckLArm.setExpanded(True)
        self._motorCheckRArm.setText(0, "Right Arm")
        self._motorCheckRArm.setFlags(self._motorCheckRArm.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckRArm.setExpanded(True)
        self._motorCheckLLeg.setText(0, "Left Leg")
        self._motorCheckLLeg.setFlags(self._motorCheckLLeg.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckLLeg.setExpanded(True)
        self._motorCheckRLeg.setText(0, "Right Leg")
        self._motorCheckRLeg.setFlags(self._motorCheckRLeg.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckRLeg.setExpanded(True)

        for k, v in self._currentGoals.items():
            parent = None
            if 'LHip' in k or 'LKnee' in k or 'LAnkle' in k:
                parent = self._motorCheckLLeg
            elif 'RHip' in k or 'RKnee' in k or 'RAnkle' in k:
                parent = self._motorCheckRLeg
            elif 'LShoulder' in k or 'LElbow' in k:
                parent = self._motorCheckLArm
            elif 'RShoulder' in k or 'RElbow' in k:
                parent = self._motorCheckRArm
            elif 'Head' in k:
                parent = self._motorCheckHead
            child = QTreeWidgetItem(parent)
            child.setText(0, k)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            child.setCheckState(0, Qt.Checked)
            self._treeItems[k] = child

        self._widget.motorTree.itemChanged.connect(self.box_ticked)

    def slider_update(self):
        for k, v in self._sliders.items():
            self._currentGoals[k] = float(v.value()) * 3.14 / 180.0
        self.set_sliders_and_text_fields()

    def set_sliders_and_text_fields(self):
        """
        Updates the text fields and sliders ins self._sliders and self._textfields to the values in self._motor_values
        :return:
        """
        for k, v in self._currentGoals.items():
            self._textFields[k].setText(str(int(v / 3.14 * 180)))
            self._sliders[k].setValue(int(v / 3.14 * 180))

    def textfield_update(self):
        for k, v in self._textFields.items():
            try:
                self._currentGoals[k] = float(v.text()) * 3.14 / 180.0
            except ValueError:
                continue
        self.set_sliders_and_text_fields()

    def box_ticked(self):
        msg = JointTrajectory()
        msg.header.stamp = rospy.Time.now()
        msg.joint_names = []
        msg.points = []
        msg.points.append(JointTrajectoryPoint())

        for k, v in self._treeItems.items():
            self._motorSwitched[k] = (v.checkState(0) == Qt.Checked)
            msg.joint_names.append(k)
            msg.points[0].positions.append(self._currentGoals[k])
            if self._motorSwitched[k]:
                msg.points[0].effort.append(1.0)
            else:
                msg.points[0].effort.append(0.0)
        self._joint_pub.publish(msg)
        print "published"

    def update_frames(self):
        """
        updates the list of frames present in the current animation
        :return:
        """
        current_state = self._recorder.get_animation_state()
        while self._widget.frameList.takeItem(0):
            continue

        for i in range(0, len(current_state)):
            item = QListWidgetItem()
            item.setText(current_state[i]["name"])
            self._widget.frameList.addItem(item)

        current = QListWidgetItem()
        current.setText("#CURRENT_FRAME")
        self._widget.frameList.setCurrentItem(current)

    def change_frame_order(self, new_order):
        """ Calls the recorder to update frame order and updates the gui"""
        self._recorder.change_frame_order(new_order)
        self.update_frames()<commit_msg>record ui<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import rospkg
import rospy
import time

from copy import deepcopy
from python_qt_binding.QtCore import Qt, QMetaType, QDataStream, QVariant
from python_qt_binding import loadUi
from rqt_gui_py.plugin import Plugin
from python_qt_binding.QtWidgets import QWidget, QTreeWidget, QTreeWidgetItem,QListWidgetItem, \
    QSlider, QGroupBox, QVBoxLayout, QLabel, QLineEdit, QListWidget, QAbstractItemView, QFileDialog, QDoubleSpinBox
from python_qt_binding.QtGui import QDoubleValidator

from sensor_msgs.msg import JointState
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint

import os

from .animation_recording import Recorder

class DragDropList(QListWidget):
    """ QListWidget with an event that is called when a drag and drop action was performed."""

    def __init__(self, parent, ui):
        super(DragDropList, self).__init__(parent)

        self.ui = ui
        self.setAcceptDrops(True)

    def dropEvent(self, e):
        super(DragDropList, self).dropEvent(e)
        items = []
        for i in range(0, self.count()):
            items.append(self.item(i).text())
        print(items)
        self.ui.change_frame_order(items)

class RecordUI(Plugin):
    def __init__(self, context):
        super(RecordUI, self).__init__(context)

        self._widget = QWidget()
        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('bitbots_recordui_rqt'), 'resource', 'RecordUI.ui')
        loadUi(ui_file, self._widget, {})

        self._recorder = Recorder()
        self._sliders = {}
        self._textFields = {}
        self._motorSwitched = {}

        self._currentGoals = {}                 # this is the data about the current unsaved frame
        self._currentDuration = 1.0
        self._currentPause = 0.0
        self._currentName = "new frame"

        self._workingValues = {}                # this is the data about the frame that is displayed
        self._workingDuration = 1.0
        self._workingPause = 0.0
        self._workingName = self._currentName

        self._freeze = False
        self._saveDir = None

        #save current frame when switching to other frames for reference
        #working frame

        self._treeItems = {}
        self._motorCheckBody = QTreeWidgetItem(self._widget.motorTree)
        self._motorCheckLegs = QTreeWidgetItem(self._motorCheckBody)
        self._motorCheckArms = QTreeWidgetItem(self._motorCheckBody)
        self._motorCheckHead = QTreeWidgetItem(self._motorCheckBody)
        self._motorCheckLArm = QTreeWidgetItem(self._motorCheckArms)
        self._motorCheckRArm = QTreeWidgetItem(self._motorCheckArms)
        self._motorCheckLLeg = QTreeWidgetItem(self._motorCheckLegs)
        self._motorCheckRLeg = QTreeWidgetItem(self._motorCheckLegs)

        self.setObjectName('Record Animation')

        self._initial_joints = None

        self._widget.frameList = DragDropList(self._widget, self)
        self._widget.verticalLayout_2.insertWidget(0, self._widget.frameList)
        self._widget.frameList.setDragDropMode(QAbstractItemView.InternalMove)

        rospy.Subscriber("/joint_states", JointState, self.state_update, queue_size=100)
        self._joint_pub = rospy.Publisher("/motor_goals", JointTrajectory, queue_size=1)

        while not self._initial_joints:
            if not rospy.is_shutdown():
                time.sleep(0.5)
                print "wait"
            else:
                return

        self.initialize()

        context.add_widget(self._widget)

    def initialize(self):
        for i in range(0, len(self._initial_joints.name)):
            self._currentGoals[self._initial_joints.name[i]] = self._initial_joints.position[i]
            self._motorSwitched[self._initial_joints.name[i]] = True

        self.motor_controller()
        self.motor_switcher()
        self.button_connect()
        self.box_ticked()
        self.frame_list()
        self.update_frames()

    def state_update(self, joint_states):
        if not self._initial_joints:
            self._initial_joints = joint_states
            time.sleep(1)

        for i in range(0, len(joint_states.name)):
            if (not self._motorSwitched[joint_states.name[i]]):
                self._workingValues[joint_states.name[i]] = joint_states.position[i]
                print "update"

        self.set_sliders_and_text_fields()

    def motor_controller(self):
        """
        Sets up the GUI in the middle of the Screen to control the motors.
        Uses self._motorValues to determine which motors are present.
        """
        i = 0
        for k, v in self._currentGoals.items():
            group = QGroupBox()
            slider = QSlider(Qt.Horizontal)
            slider.setTickInterval(1)
            slider.setMinimum(-180)
            slider.setMaximum(180)
            slider.valueChanged.connect(self.slider_update)
            self._sliders[k] = slider

            textfield = QLineEdit()
            textfield.setText('0')
            textfield.textEdited.connect(self.textfield_update)
            textfield.setValidator(QDoubleValidator(-180.0, 180.0, 2))
            self._textFields[k] = textfield

            label = QLabel()
            label.setText(k)

            layout = QVBoxLayout()
            layout.addWidget(label)
            layout.addWidget(self._sliders[k])
            layout.addWidget(self._textFields[k])
            group.setLayout(layout)
            self._widget.motorControlLayout.addWidget(group, i / 5, i % 5)
            i = i+1

    def button_connect(self):
        """
        Connects the buttons in the top bar to the corresponding functions
        :return:
        """
        self._widget.buttonNew.clicked.connect(self.new)
        self._widget.buttonSave.clicked.connect(self.save)
        self._widget.buttonSaveAs.clicked.connect(self.save_as)
        self._widget.buttonOpen.clicked.connect(self.open)

        self._widget.buttonPlay.clicked.connect(self.play)
        self._widget.buttonGotoFrame.clicked.connect(self.goto_frame)
        self._widget.buttonRecord.clicked.connect(self.record)

        self._widget.buttonUndo.clicked.connect(self.undo)
        self._widget.buttonRedo.clicked.connect(self.redo)

    def new(self):
        self._recorder.clear()
        self.update_frames()

    def save(self):
        self.set_metadata()
        if not self._saveDir:
            self._saveDir = QFileDialog.getExistingDirectory()
        self._recorder.save_animation(self._saveDir, self._widget.lineAnimationName.text())

    def save_as(self):
        self._saveDir = QFileDialog.getExistingDirectory()
        self._recorder.save_animation(self._saveDir, self._widget.lineAnimationName.text())

    def set_metadata(self):
        self._recorder.set_meta_data(self._widget.lineAnimationName.text(),
                                     self._widget.lineVersion.text(),
                                     self._widget.lineAuthor.text(),
                                     self._widget.fieldDescription.toPlainText())

    def open(self):
        my_file = QFileDialog.getOpenFileName()[0]
        if my_file:
            self._recorder.load_animation(my_file)
        self.update_frames()

        metadata = self._recorder.get_meta_data()

        self._widget.lineAnimationName.setText(metadata[0])
        self._widget.lineAuthor.setText(metadata[2])
        self._widget.lineVersion.setText(metadata[1])
        self._widget.fieldDescription.setPlainText(metadata[3])

    def play(self):
        self._recorder.play()

    def goto_frame(self):
        raise NotImplementedError
        #todo publish joint trajecory message with stuff

    def record(self):
        if self._widget.frameList.currentItem().text() == "#CURRENT_FRAME":
            self._recorder.record(self._workingValues,
                                  self._widget.lineFrameName.text(),
                                  self._widget.spinBoxDuration.value(),
                                  self._widget.spinBoxPause.value())
        else:
            current_row = self._widget.frameList.currentRow()
            self._recorder.record(self._workingValues,
                                  self._widget.lineFrameName.text(),
                                  self._widget.spinBoxDuration.value(),
                                  self._widget.spinBoxPause.value(),
                                  current_row,
                                  True)

        self.update_frames()

    def undo(self):
        self._recorder.undo()
        self.update_frames()

    def redo(self):
        self._recorder.redo()
        self.update_frames()

    def frame_list(self):
        self._widget.frameList.itemClicked.connect(self.frame_select)

    def frame_select(self):
        selected_frame_name = self._widget.frameList.currentItem().text()
        selected_frame = None

        for v in self._recorder.get_animation_state():
            if v["name"] == selected_frame_name:
                selected_frame = v
                break

        if selected_frame_name != "#CURRENT_FRAME":
            self._currentGoals = deepcopy(self._workingValues)
            self._workingValues = selected_frame["goals"]
        else:
            self._workingValues = deepcopy(self._currentGoals)

        self.set_sliders_and_text_fields()

    def motor_switcher(self):
        self._widget.motorTree.setHeaderLabel("Stiff Motors")
        self._motorCheckBody.setText(0, "Body")
        self._motorCheckBody.setFlags(self._motorCheckBody.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckBody.setExpanded(True)
        self._motorCheckHead.setText(0, "Head")
        self._motorCheckHead.setFlags(self._motorCheckHead.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckHead.setExpanded(True)
        self._motorCheckArms.setText(0, "Arms")
        self._motorCheckArms.setFlags(self._motorCheckArms.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckArms.setExpanded(True)
        self._motorCheckLegs.setText(0, "Legs")
        self._motorCheckLegs.setFlags(self._motorCheckLegs.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckLegs.setExpanded(True)
        self._motorCheckLArm.setText(0, "Left Arm")
        self._motorCheckLArm.setFlags(self._motorCheckLArm.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckLArm.setExpanded(True)
        self._motorCheckRArm.setText(0, "Right Arm")
        self._motorCheckRArm.setFlags(self._motorCheckRArm.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckRArm.setExpanded(True)
        self._motorCheckLLeg.setText(0, "Left Leg")
        self._motorCheckLLeg.setFlags(self._motorCheckLLeg.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckLLeg.setExpanded(True)
        self._motorCheckRLeg.setText(0, "Right Leg")
        self._motorCheckRLeg.setFlags(self._motorCheckRLeg.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self._motorCheckRLeg.setExpanded(True)

        for k, v in self._currentGoals.items():
            parent = None
            if 'LHip' in k or 'LKnee' in k or 'LAnkle' in k:
                parent = self._motorCheckLLeg
            elif 'RHip' in k or 'RKnee' in k or 'RAnkle' in k:
                parent = self._motorCheckRLeg
            elif 'LShoulder' in k or 'LElbow' in k:
                parent = self._motorCheckLArm
            elif 'RShoulder' in k or 'RElbow' in k:
                parent = self._motorCheckRArm
            elif 'Head' in k:
                parent = self._motorCheckHead
            child = QTreeWidgetItem(parent)
            child.setText(0, k)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            child.setCheckState(0, Qt.Checked)
            self._treeItems[k] = child

        self._widget.motorTree.itemChanged.connect(self.box_ticked)

    def slider_update(self):
        for k, v in self._sliders.items():
            self._workingValues[k] = float(v.value()) * 3.14 / 180.0
        self.set_sliders_and_text_fields()

    def set_sliders_and_text_fields(self):
        """
        Updates the text fields and sliders ins self._sliders and self._textfields to the values in self._workingValues
        :return:
        """
        for k, v in self._workingValues.items():
            self._textFields[k].setText(str(int(v / 3.14 * 180)))
            self._sliders[k].setValue(int(v / 3.14 * 180))

    def textfield_update(self):
        for k, v in self._textFields.items():
            try:
                self._workingValues[k] = float(v.text()) * 3.14 / 180.0
            except ValueError:
                continue
        self.set_sliders_and_text_fields()

    def box_ticked(self):
        msg = JointTrajectory()
        msg.header.stamp = rospy.Time.now()
        msg.joint_names = []
        msg.points = []
        msg.points.append(JointTrajectoryPoint())

        for k, v in self._treeItems.items():
            self._motorSwitched[k] = (v.checkState(0) == Qt.Checked)
            msg.joint_names.append(k)
            msg.points[0].positions.append(self._currentGoals[k])
            if self._motorSwitched[k]:
                msg.points[0].effort.append(1.0)
            else:
                msg.points[0].effort.append(0.0)
        self._joint_pub.publish(msg)
        print "published"

    def update_frames(self):
        """
        updates the list of frames present in the current animation
        :return:
        """
        current_state = self._recorder.get_animation_state()
        while self._widget.frameList.takeItem(0):
            continue

        for i in range(0, len(current_state)):
            item = QListWidgetItem()
            item.setText(current_state[i]["name"])
            self._widget.frameList.addItem(item)

        current = QListWidgetItem()
        current.setText("#CURRENT_FRAME")
        self._widget.frameList.addItem(current)
        self._widget.frameList.setCurrentItem(current)

    def change_frame_order(self, new_order):
        """ Calls the recorder to update frame order and updates the gui"""
        self._recorder.change_frame_order(new_order)
        self.update_frames()<|endoftext|>