<commit_before># Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
#   contributors may be used to endorse or promote products derived from
#   this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""Unit tests for the nbhood.RecursiveFilter plugin."""

import unittest
from iris.cube import Cube
from iris.tests import IrisTest
from iris.coords import DimCoord
from cf_units import Unit
import numpy as np
from improver.nbhood.recursive_filter import RecursiveFilter
from improver.nbhood.square_kernel import SquareNeighbourhood

class Test__repr__(IrisTest):

    """Test the repr method."""

    def test_basic(self):
        """Test that the __repr__ returns the expected string."""
        alpha_x = None
        alpha_y = None
        iterations = None
        edge_width = 1
        result = str(RecursiveFilter(alpha_x, alpha_y, iterations, edge_width))
        msg = ('<RecursiveFilter: alpha_x: {}, alpha_y: {}, iterations: {},'
               ' edge_width: {}'.format(alpha_x, alpha_y,
                                        iterations, edge_width))
        self.assertEqual(result, msg)

class Test_RecursiveFilter(IrisTest):

    """Test class for the RecursiveFilter tests, setting up cubes."""

    def setUp(self):
        """Create test cubes."""

        self.alpha_x = 0.5
        self.alpha_y = 0.5
        self.iterations = 1

        # Generate data cube with dimensions 5 x 5
        data = np.zeros((1, 5, 5))
        data[0][0][2] = 0.1
        data[0][1][2] = 0.25
        data[0][2][2] = 0.5
        data[0][3][2] = 0.25
        data[0][4][2] = 0.1
        data[0][2][0] = 0.1
        data[0][2][1] = 0.25
        data[0][2][3] = 0.25
        data[0][2][4] = 0.1

        cube = Cube(data, standard_name="precipitation_amount",
                    units="kg m^-2 s^-1")
        cube.add_dim_coord(DimCoord(np.linspace(-45.0, 45.0, 5), 'latitude',
                                    units='degrees'), 1)
        cube.add_dim_coord(DimCoord(np.linspace(120, 180, 5), 'longitude',
                                    units='degrees'), 2)
        time_origin = "hours since 1970-01-01 00:00:00"
        calendar = "gregorian"
        tunit = Unit(time_origin, calendar)
        cube.add_dim_coord(DimCoord([402192.5],
                                    "time", units=tunit), 0)
        self.cube = cube

        # Generate alphas_cube with dimensions 5 x 5
        alphas_data1 = np.ones((5, 5)) * 0.5
        alphas_cube1 = Cube(alphas_data1)
        alphas_cube1.add_dim_coord(DimCoord(np.linspace(-45.0, 45.0, 5),
                                            'latitude', units='degrees'), 0)
        alphas_cube1.add_dim_coord(DimCoord(np.linspace(120, 180, 5),
                                            'longitude', units='degrees'), 1)
        self.alphas_cube1 = alphas_cube1

        # Generate alphas_cube with dimensions 6 x 6
        alphas_data2 = np.ones((6, 6)) * 0.5
        alphas_cube2 = Cube(alphas_data2)
        alphas_cube2.add_dim_coord(DimCoord(np.linspace(-45.0, 45.0, 6),
                                            'latitude', units='degrees'), 0)
        alphas_cube2.add_dim_coord(DimCoord(np.linspace(120, 180, 6),
                                            'longitude', units='degrees'), 1)
        self.alphas_cube2 = alphas_cube2

class Test__init__(Test_RecursiveFilter):

    """Test plugin initialisation."""

    def test_alpha_x_gt_unity(self):
        """Test when an alpha_x value > unity is given (invalid)."""
        alpha_x = 1.1
        msg = "Invalid alpha_x: must be >= 0 and < 1: 1.1"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=alpha_x, alpha_y=None,
                            iterations=None, edge_width=1)

    def test_alpha_x_lt_zero(self):
        """Test when an alpha_x value < zero is given (invalid)."""
        alpha_x = -0.5
        msg = "Invalid alpha_x: must be >= 0 and < 1: -0.5"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=alpha_x, alpha_y=None,
                            iterations=None, edge_width=1)

    def test_alpha_y_gt_unity(self):
        """Test when an alpha_y value > unity is given (invalid)."""
        alpha_y = 1.1
        msg = "Invalid alpha_y: must be >= 0 and < 1: 1.1"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=None, alpha_y=alpha_y,
                            iterations=None, edge_width=1)

    def test_alpha_y_lt_zero(self):
        """Test when an alpha_y value < zero is given (invalid)."""
        alpha_y = -0.5
        msg = "Invalid alpha_y: must be >= 0 and < 1: -0.5"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=None, alpha_y=alpha_y,
                            iterations=None, edge_width=1)

    def test_iterations(self):
        """Test when iterations value less than unity is given (invalid)."""
        iterations = 0
        msg = "Invalid number of iterations: must be >= 1: 0"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=None, alpha_y=None,
                            iterations=iterations, edge_width=1)

class Test_set_alphas(Test_RecursiveFilter):

    """Test the set_alphas function"""

    def test_alpha_x_used_result(self):
        """Test that the returned alphas array has the expected result
           when alphas_cube=None."""
        result = RecursiveFilter().set_alphas(self.cube, self.alpha_x, None)
        expected_result = 0.5
        self.assertIsInstance(result.data, np.ndarray)
        self.assertEqual(result.data[0][2], expected_result)
        # Check shape: Array should be padded with 4 extra rows/columns
        expected_shape = (9, 9)
        self.assertEqual(result.shape, expected_shape)

    def test_alphas_cube_used_result(self):
        """Test that the returned alphas array has the expected result
           when alphas_cube is not None."""
        result = RecursiveFilter().set_alphas(self.cube[0, :], None,
                                              self.alphas_cube1)
        expected_result = 0.5
        self.assertIsInstance(result.data, np.ndarray)
        self.assertEqual(result.data[0][2], expected_result)
        # Check shape: Array should be padded with 4 extra rows/columns
        expected_shape = (9, 9)
        self.assertEqual(result.shape, expected_shape)

    def test_mismatched_dimensions_alphas_cube_data_cube(self):
        """Test that an error is raised if the alphas_cube is of a different
        shape to the data cube."""
        msg = "Dimensions of alphas array do not match dimensions "
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter().set_alphas(self.cube, None, self.alphas_cube2)

    def test_alphas_cube_and_alpha_not_set(self):
        """Test error is raised when both alphas_cube and alpha are set
           to None (invalid)."""
        alpha = None
        alphas_cube = None
        msg = "A value for alpha must be set if alphas_cube is "
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter().set_alphas(self.cube, alpha, alphas_cube)

    def test_alphas_cube_and_alpha_both_set(self):
        """Test error is raised when both alphas_cube and alpha are set."""
        alpha = 0.5
        alphas_cube = self.alphas_cube1
        msg = "A cube of alpha values and a single float value for"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter().set_alphas(self.cube, alpha, alphas_cube)

class Test_recurse_forward_x(Test_RecursiveFilter):

    """Test the recurse_forward_x method"""

    def test_basic_method(self):
        """Test that the returned recurse_forward_x array has the expected
           type and result."""
        result = RecursiveFilter().recurse_forward_x(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.196875
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[4][2], expected_result)

class Test_recurse_backwards_x(Test_RecursiveFilter):

    """Test the recurse_backwards_x method"""

    def test_basic_method(self):
        """Test that the returned recurse_backwards_x array has the expected
           type and result."""
        result = RecursiveFilter().recurse_backwards_x(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.196875
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[0][2], expected_result)

class Test_recurse_forward_y(Test_RecursiveFilter):

    """Test the recurse_forward_y method"""

    def test_basic_method(self):
        """Test that the returned recurse_forward_y array has the expected
           type and result."""
        result = RecursiveFilter().recurse_forward_y(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.0125
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[0][4], expected_result)

class Test_recurse_backwards_y(Test_RecursiveFilter):

    """Test the recurse_backwards_y method"""

    def test_basic_method(self):
        """Test that the returned recurse_backwards_y array has the expected
           type and result."""
        result = RecursiveFilter().recurse_backwards_y(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.0125
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[0][0], expected_result)

class Test_run_recursion(Test_RecursiveFilter):

    """Test the run_recursion method"""

    def test_return_type(self):
        """Test that the run_recursion method returns an iris.cube.Cube."""
        edge_width = 1
        alphas_x = RecursiveFilter().set_alphas(self.cube, self.alpha_x, None)
        alphas_y = RecursiveFilter().set_alphas(self.cube, self.alpha_y, None)
        padded_cube = SquareNeighbourhood().pad_cube_with_halo(
            self.cube, edge_width, edge_width)
        result = RecursiveFilter().run_recursion(
            padded_cube, alphas_x, alphas_y, self.iterations)
        self.assertIsInstance(result, Cube)

    def test_expected_result(self):
        """Test that the run_recursion method returns the expected value."""
        edge_width = 1
        alphas_x = RecursiveFilter().set_alphas(self.cube, self.alpha_x, None)
        alphas_y = RecursiveFilter().set_alphas(self.cube, self.alpha_y, None)
        padded_cube = SquareNeighbourhood().pad_cube_with_halo(
            self.cube, edge_width, edge_width)
        result = RecursiveFilter().run_recursion(
            padded_cube, alphas_x, alphas_y, self.iterations)
        expected_result = 0.13382206
        self.assertAlmostEqual(result.data[4][4], expected_result)

class Test_process(Test_RecursiveFilter):

    """Test the process method. """

    # Test output from plugin returns expected values
    def test_return_type(self):
        """Test that the RecursiveFilter plugin returns an iris.cube.Cube."""
        plugin = RecursiveFilter(alpha_x=self.alpha_x, alpha_y=self.alpha_y,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=None, alphas_y=None)
        self.assertIsInstance(result, Cube)

    def test_alpha_floats(self):
        """Test that the RecursiveFilter plugin returns the correct data
        when using float alpha values."""
        plugin = RecursiveFilter(alpha_x=self.alpha_x, alpha_y=self.alpha_y,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=None, alphas_y=None)
        expected = 0.13382206
        self.assertAlmostEqual(result.data[0][2][2], expected)

    def test_alpha_cubes(self):
        """Test that the RecursiveFilter plugin returns the correct data
        when using alpha cubes."""
        plugin = RecursiveFilter(alpha_x=None, alpha_y=None,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=self.alphas_cube1,
                                alphas_y=self.alphas_cube1)
        expected = 0.13382206
        self.assertAlmostEqual(result.data[0][2][2], expected)

    def test_dimensions_of_output_array_is_as_expected(self):
        """Test that the RecursiveFilter plugin returns a data array with
           the correct dimensions"""
        plugin = RecursiveFilter(alpha_x=self.alpha_x, alpha_y=self.alpha_y,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=None, alphas_y=None)
        # Output data array should have same dimensions as input data array
        expected_shape = (1, 5, 5)
        self.assertEqual(result.data.shape, expected_shape)
        self.assertEqual(result.data.shape, expected_shape)

if __name__ == '__main__':
    unittest.main()
<commit_msg>pep8 fix<commit_after># Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
#   contributors may be used to endorse or promote products derived from
#   this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""Unit tests for the nbhood.RecursiveFilter plugin."""

import unittest
from iris.cube import Cube
from iris.tests import IrisTest
from iris.coords import DimCoord
from cf_units import Unit
import numpy as np
from improver.nbhood.recursive_filter import RecursiveFilter
from improver.nbhood.square_kernel import SquareNeighbourhood

class Test__repr__(IrisTest):

    """Test the repr method."""

    def test_basic(self):
        """Test that the __repr__ returns the expected string."""
        alpha_x = None
        alpha_y = None
        iterations = None
        edge_width = 1
        result = str(RecursiveFilter(alpha_x, alpha_y, iterations, edge_width))
        msg = ('<RecursiveFilter: alpha_x: {}, alpha_y: {}, iterations: {},'
               ' edge_width: {}'.format(alpha_x, alpha_y,
                                        iterations, edge_width))
        self.assertEqual(result, msg)

class Test_RecursiveFilter(IrisTest):

    """Test class for the RecursiveFilter tests, setting up cubes."""

    def setUp(self):
        """Create test cubes."""

        self.alpha_x = 0.5
        self.alpha_y = 0.5
        self.iterations = 1

        # Generate data cube with dimensions 5 x 5
        data = np.zeros((1, 5, 5))
        data[0][0][2] = 0.1
        data[0][1][2] = 0.25
        data[0][2][2] = 0.5
        data[0][3][2] = 0.25
        data[0][4][2] = 0.1
        data[0][2][0] = 0.1
        data[0][2][1] = 0.25
        data[0][2][3] = 0.25
        data[0][2][4] = 0.1

        cube = Cube(data, standard_name="precipitation_amount",
                    units="kg m^-2 s^-1")
        cube.add_dim_coord(DimCoord(np.linspace(-45.0, 45.0, 5), 'latitude',
                                    units='degrees'), 1)
        cube.add_dim_coord(DimCoord(np.linspace(120, 180, 5), 'longitude',
                                    units='degrees'), 2)
        time_origin = "hours since 1970-01-01 00:00:00"
        calendar = "gregorian"
        tunit = Unit(time_origin, calendar)
        cube.add_dim_coord(DimCoord([402192.5],
                                    "time", units=tunit), 0)
        self.cube = cube

        # Generate alphas_cube with dimensions 5 x 5
        alphas_data1 = np.ones((5, 5)) * 0.5
        alphas_cube1 = Cube(alphas_data1)
        alphas_cube1.add_dim_coord(DimCoord(np.linspace(-45.0, 45.0, 5),
                                            'latitude', units='degrees'), 0)
        alphas_cube1.add_dim_coord(DimCoord(np.linspace(120, 180, 5),
                                            'longitude', units='degrees'), 1)
        self.alphas_cube1 = alphas_cube1

        # Generate alphas_cube with dimensions 6 x 6
        alphas_data2 = np.ones((6, 6)) * 0.5
        alphas_cube2 = Cube(alphas_data2)
        alphas_cube2.add_dim_coord(DimCoord(np.linspace(-45.0, 45.0, 6),
                                            'latitude', units='degrees'), 0)
        alphas_cube2.add_dim_coord(DimCoord(np.linspace(120, 180, 6),
                                            'longitude', units='degrees'), 1)
        self.alphas_cube2 = alphas_cube2

class Test__init__(Test_RecursiveFilter):

    """Test plugin initialisation."""

    def test_alpha_x_gt_unity(self):
        """Test when an alpha_x value > unity is given (invalid)."""
        alpha_x = 1.1
        msg = "Invalid alpha_x: must be >= 0 and < 1: 1.1"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=alpha_x, alpha_y=None,
                            iterations=None, edge_width=1)

    def test_alpha_x_lt_zero(self):
        """Test when an alpha_x value < zero is given (invalid)."""
        alpha_x = -0.5
        msg = "Invalid alpha_x: must be >= 0 and < 1: -0.5"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=alpha_x, alpha_y=None,
                            iterations=None, edge_width=1)

    def test_alpha_y_gt_unity(self):
        """Test when an alpha_y value > unity is given (invalid)."""
        alpha_y = 1.1
        msg = "Invalid alpha_y: must be >= 0 and < 1: 1.1"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=None, alpha_y=alpha_y,
                            iterations=None, edge_width=1)

    def test_alpha_y_lt_zero(self):
        """Test when an alpha_y value < zero is given (invalid)."""
        alpha_y = -0.5
        msg = "Invalid alpha_y: must be >= 0 and < 1: -0.5"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=None, alpha_y=alpha_y,
                            iterations=None, edge_width=1)

    def test_iterations(self):
        """Test when iterations value less than unity is given (invalid)."""
        iterations = 0
        msg = "Invalid number of iterations: must be >= 1: 0"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter(alpha_x=None, alpha_y=None,
                            iterations=iterations, edge_width=1)

class Test_set_alphas(Test_RecursiveFilter):

    """Test the set_alphas function"""

    def test_alpha_x_used_result(self):
        """Test that the returned alphas array has the expected result
           when alphas_cube=None."""
        result = RecursiveFilter().set_alphas(self.cube, self.alpha_x, None)
        expected_result = 0.5
        self.assertIsInstance(result.data, np.ndarray)
        self.assertEqual(result.data[0][2], expected_result)
        # Check shape: Array should be padded with 4 extra rows/columns
        expected_shape = (9, 9)
        self.assertEqual(result.shape, expected_shape)

    def test_alphas_cube_used_result(self):
        """Test that the returned alphas array has the expected result
           when alphas_cube is not None."""
        result = RecursiveFilter().set_alphas(self.cube[0, :], None,
                                              self.alphas_cube1)
        expected_result = 0.5
        self.assertIsInstance(result.data, np.ndarray)
        self.assertEqual(result.data[0][2], expected_result)
        # Check shape: Array should be padded with 4 extra rows/columns
        expected_shape = (9, 9)
        self.assertEqual(result.shape, expected_shape)

    def test_mismatched_dimensions_alphas_cube_data_cube(self):
        """Test that an error is raised if the alphas_cube is of a different
        shape to the data cube."""
        msg = "Dimensions of alphas array do not match dimensions "
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter().set_alphas(self.cube, None, self.alphas_cube2)

    def test_alphas_cube_and_alpha_not_set(self):
        """Test error is raised when both alphas_cube and alpha are set
           to None (invalid)."""
        alpha = None
        alphas_cube = None
        msg = "A value for alpha must be set if alphas_cube is "
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter().set_alphas(self.cube, alpha, alphas_cube)

    def test_alphas_cube_and_alpha_both_set(self):
        """Test error is raised when both alphas_cube and alpha are set."""
        alpha = 0.5
        alphas_cube = self.alphas_cube1
        msg = "A cube of alpha values and a single float value for"
        with self.assertRaisesRegexp(ValueError, msg):
            RecursiveFilter().set_alphas(self.cube, alpha, alphas_cube)

class Test_recurse_forward_x(Test_RecursiveFilter):

    """Test the recurse_forward_x method"""

    def test_basic_method(self):
        """Test that the returned recurse_forward_x array has the expected
           type and result."""
        result = RecursiveFilter().recurse_forward_x(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.196875
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[4][2], expected_result)

class Test_recurse_backwards_x(Test_RecursiveFilter):

    """Test the recurse_backwards_x method"""

    def test_basic_method(self):
        """Test that the returned recurse_backwards_x array has the expected
           type and result."""
        result = RecursiveFilter().recurse_backwards_x(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.196875
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[0][2], expected_result)

class Test_recurse_forward_y(Test_RecursiveFilter):

    """Test the recurse_forward_y method"""

    def test_basic_method(self):
        """Test that the returned recurse_forward_y array has the expected
           type and result."""
        result = RecursiveFilter().recurse_forward_y(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.0125
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[0][4], expected_result)

class Test_recurse_backwards_y(Test_RecursiveFilter):

    """Test the recurse_backwards_y method"""

    def test_basic_method(self):
        """Test that the returned recurse_backwards_y array has the expected
           type and result."""
        result = RecursiveFilter().recurse_backwards_y(
            self.cube.data[0, :], self.alphas_cube1.data)
        expected_result = 0.0125
        self.assertIsInstance(result, np.ndarray)
        self.assertAlmostEqual(result[0][0], expected_result)

class Test_run_recursion(Test_RecursiveFilter):

    """Test the run_recursion method"""

    def test_return_type(self):
        """Test that the run_recursion method returns an iris.cube.Cube."""
        edge_width = 1
        alphas_x = RecursiveFilter().set_alphas(self.cube, self.alpha_x, None)
        alphas_y = RecursiveFilter().set_alphas(self.cube, self.alpha_y, None)
        padded_cube = SquareNeighbourhood().pad_cube_with_halo(
            self.cube, edge_width, edge_width)
        result = RecursiveFilter().run_recursion(
            padded_cube, alphas_x, alphas_y, self.iterations)
        self.assertIsInstance(result, Cube)

    def test_expected_result(self):
        """Test that the run_recursion method returns the expected value."""
        edge_width = 1
        alphas_x = RecursiveFilter().set_alphas(self.cube, self.alpha_x, None)
        alphas_y = RecursiveFilter().set_alphas(self.cube, self.alpha_y, None)
        padded_cube = SquareNeighbourhood().pad_cube_with_halo(
            self.cube, edge_width, edge_width)
        result = RecursiveFilter().run_recursion(
            padded_cube, alphas_x, alphas_y, self.iterations)
        expected_result = 0.13382206
        self.assertAlmostEqual(result.data[4][4], expected_result)

class Test_process(Test_RecursiveFilter):

    """Test the process method. """

    # Test output from plugin returns expected values
    def test_return_type(self):
        """Test that the RecursiveFilter plugin returns an iris.cube.Cube."""
        plugin = RecursiveFilter(alpha_x=self.alpha_x, alpha_y=self.alpha_y,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=None, alphas_y=None)
        self.assertIsInstance(result, Cube)

    def test_alpha_floats(self):
        """Test that the RecursiveFilter plugin returns the correct data
        when using float alpha values."""
        plugin = RecursiveFilter(alpha_x=self.alpha_x, alpha_y=self.alpha_y,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=None, alphas_y=None)
        expected = 0.13382206
        self.assertAlmostEqual(result.data[0][2][2], expected)

    def test_alpha_cubes(self):
        """Test that the RecursiveFilter plugin returns the correct data
        when using alpha cubes."""
        plugin = RecursiveFilter(alpha_x=None, alpha_y=None,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=self.alphas_cube1,
                                alphas_y=self.alphas_cube1)
        expected = 0.13382206
        self.assertAlmostEqual(result.data[0][2][2], expected)

    def test_dimensions_of_output_array_is_as_expected(self):
        """Test that the RecursiveFilter plugin returns a data array with
           the correct dimensions"""
        plugin = RecursiveFilter(alpha_x=self.alpha_x, alpha_y=self.alpha_y,
                                 iterations=self.iterations)
        result = plugin.process(self.cube, alphas_x=None, alphas_y=None)
        # Output data array should have same dimensions as input data array
        expected_shape = (1, 5, 5)
        self.assertEqual(result.data.shape, expected_shape)
        self.assertEqual(result.data.shape, expected_shape)

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


<commit_before>"""
We deal (mostly) with remote hosts. To avoid special casing each different
commands (e.g. using `yum` as opposed to `apt`) we can make a one time call to
that remote host and set all the special cases for running commands depending
on the type of distribution/version we are dealing with.
"""
import logging
from ceph_deploy import exc
from ceph_deploy.util import versions
from ceph_deploy.hosts import debian, centos, fedora, suse, remotes, rhel
from ceph_deploy.connection import get_connection

logger = logging.getLogger()

def get(hostname,
        username=None,
        fallback=None,
        detect_sudo=True,
        use_rhceph=False):
    """
    Retrieve the module that matches the distribution of a ``hostname``. This
    function will connect to that host and retrieve the distribution
    information, then return the appropriate module and slap a few attributes
    to that module defining the information it found from the hostname.

    For example, if host ``node1.example.com`` is an Ubuntu server, the
    ``debian`` module would be returned and the following would be set::

        module.name = 'ubuntu'
        module.release = '12.04'
        module.codename = 'precise'

    :param hostname: A hostname that is reachable/resolvable over the network
    :param fallback: Optional fallback to use if no supported distro is found
    :param use_rhceph: Whether or not to install RH Ceph on a RHEL machine or
                       the community distro.  Changes what host module is
                       returned for RHEL.
    """
    conn = get_connection(
        hostname,
        username=username,
        logger=logging.getLogger(hostname),
        detect_sudo=detect_sudo
    )
    try:
        conn.import_module(remotes)
    except IOError as error:
        if 'already closed' in getattr(error, 'message', ''):
            raise RuntimeError('remote connection got closed, ensure ``requiretty`` is disabled for %s' % hostname)
    distro_name, release, codename = conn.remote_module.platform_information()
    if not codename or not _get_distro(distro_name):
        raise exc.UnsupportedPlatform(
            distro=distro_name,
            codename=codename,
            release=release)

    machine_type = conn.remote_module.machine_type()
    module = _get_distro(distro_name, use_rhceph=use_rhceph)
    module.name = distro_name
    module.normalized_name = _normalized_distro_name(distro_name)
    module.normalized_release = _normalized_release(release)
    module.distro = module.normalized_name
    module.is_el = module.normalized_name in ['redhat', 'centos', 'fedora', 'scientific']
    module.is_rpm = module.normalized_name in ['redhat', 'centos',
                                               'fedora', 'scientific', 'suse']
    module.is_deb = not module.is_rpm
    module.release = release
    module.codename = codename
    module.conn = conn
    module.machine_type = machine_type
    module.init = module.choose_init(module)
    module.packager = module.get_packager(module)
    return module

def _get_distro(distro, fallback=None, use_rhceph=False):
    if not distro:
        return

    distro = _normalized_distro_name(distro)
    distributions = {
        'debian': debian,
        'ubuntu': debian,
        'centos': centos,
        'scientific': centos,
        'redhat': centos,
        'fedora': fedora,
        'suse': suse,
        }

    if distro == 'redhat' and use_rhceph:
        return rhel
    else:
        return distributions.get(distro) or _get_distro(fallback)

def _normalized_distro_name(distro):
    distro = distro.lower()
    if distro.startswith(('redhat', 'red hat')):
        return 'redhat'
    elif distro.startswith(('scientific', 'scientific linux')):
        return 'scientific'
    elif distro.startswith(('suse', 'opensuse')):
        return 'suse'
    elif distro.startswith('centos'):
        return 'centos'
    elif distro.startswith('linuxmint'):
        return 'ubuntu'
    return distro

def _normalized_release(release):
    """
    A normalizer function to make sense of distro
    release versions.

    Returns an object with: major, minor, patch, and garbage

    These attributes can be accessed as ints with prefixed "int"
    attribute names, for example:

        normalized_version.int_major
    """
    # TODO: at some point deprecate this function so that we just
    # use this class directly (and update every test that calls it
    return versions.NormalizedVersion(release)
<commit_msg>[RM-11115] allow a list of callbacks when creating a connection<commit_after>"""
We deal (mostly) with remote hosts. To avoid special casing each different
commands (e.g. using `yum` as opposed to `apt`) we can make a one time call to
that remote host and set all the special cases for running commands depending
on the type of distribution/version we are dealing with.
"""
import logging
from ceph_deploy import exc
from ceph_deploy.util import versions
from ceph_deploy.hosts import debian, centos, fedora, suse, remotes, rhel
from ceph_deploy.connection import get_connection

logger = logging.getLogger()

def get(hostname,
        username=None,
        fallback=None,
        detect_sudo=True,
        use_rhceph=False,
        callbacks=None):
    """
    Retrieve the module that matches the distribution of a ``hostname``. This
    function will connect to that host and retrieve the distribution
    information, then return the appropriate module and slap a few attributes
    to that module defining the information it found from the hostname.

    For example, if host ``node1.example.com`` is an Ubuntu server, the
    ``debian`` module would be returned and the following would be set::

        module.name = 'ubuntu'
        module.release = '12.04'
        module.codename = 'precise'

    :param hostname: A hostname that is reachable/resolvable over the network
    :param fallback: Optional fallback to use if no supported distro is found
    :param use_rhceph: Whether or not to install RH Ceph on a RHEL machine or
                       the community distro.  Changes what host module is
                       returned for RHEL.
    :params callbacks: A list of callables that accept one argument (the actual
                       module that contains the connection) that will be
                       called, in order at the end of the instantiation of the
                       module.
    """
    conn = get_connection(
        hostname,
        username=username,
        logger=logging.getLogger(hostname),
        detect_sudo=detect_sudo
    )
    try:
        conn.import_module(remotes)
    except IOError as error:
        if 'already closed' in getattr(error, 'message', ''):
            raise RuntimeError('remote connection got closed, ensure ``requiretty`` is disabled for %s' % hostname)
    distro_name, release, codename = conn.remote_module.platform_information()
    if not codename or not _get_distro(distro_name):
        raise exc.UnsupportedPlatform(
            distro=distro_name,
            codename=codename,
            release=release)

    machine_type = conn.remote_module.machine_type()
    module = _get_distro(distro_name, use_rhceph=use_rhceph)
    module.name = distro_name
    module.normalized_name = _normalized_distro_name(distro_name)
    module.normalized_release = _normalized_release(release)
    module.distro = module.normalized_name
    module.is_el = module.normalized_name in ['redhat', 'centos', 'fedora', 'scientific']
    module.is_rpm = module.normalized_name in ['redhat', 'centos',
                                               'fedora', 'scientific', 'suse']
    module.is_deb = not module.is_rpm
    module.release = release
    module.codename = codename
    module.conn = conn
    module.machine_type = machine_type
    module.init = module.choose_init(module)
    module.packager = module.get_packager(module)
    # execute each callback if any
    if callbacks:
        for c in callbacks:
            c(module)
    return module

def _get_distro(distro, fallback=None, use_rhceph=False):
    if not distro:
        return

    distro = _normalized_distro_name(distro)
    distributions = {
        'debian': debian,
        'ubuntu': debian,
        'centos': centos,
        'scientific': centos,
        'redhat': centos,
        'fedora': fedora,
        'suse': suse,
        }

    if distro == 'redhat' and use_rhceph:
        return rhel
    else:
        return distributions.get(distro) or _get_distro(fallback)

def _normalized_distro_name(distro):
    distro = distro.lower()
    if distro.startswith(('redhat', 'red hat')):
        return 'redhat'
    elif distro.startswith(('scientific', 'scientific linux')):
        return 'scientific'
    elif distro.startswith(('suse', 'opensuse')):
        return 'suse'
    elif distro.startswith('centos'):
        return 'centos'
    elif distro.startswith('linuxmint'):
        return 'ubuntu'
    return distro

def _normalized_release(release):
    """
    A normalizer function to make sense of distro
    release versions.

    Returns an object with: major, minor, patch, and garbage

    These attributes can be accessed as ints with prefixed "int"
    attribute names, for example:

        normalized_version.int_major
    """
    # TODO: at some point deprecate this function so that we just
    # use this class directly (and update every test that calls it
    return versions.NormalizedVersion(release)
<|endoftext|>


<commit_before># cerbero - a multi-platform build system for Open Source software
# Copyright (C) 2012 Andoni Morales Alastruey <ylatuya@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 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
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import os
import shutil

from cerbero.commands import Command, register_command
from cerbero.build.cookbook import CookBook
from cerbero.errors import FatalError
from cerbero.utils import _, N_, ArgparseArgument, shell, messages as m
from cerbero.build.recipe import BuildSteps

class Uninstall(Command):
    doc = N_('Uninstall a single recipe\'s status')
    name = 'uninstall'

    def __init__(self):
        Command.__init__(self,
                         [ArgparseArgument('recipe', nargs='*',
                                           help=_('Name of the recipes to uninstall')),
                          ArgparseArgument('--deps', action='store_true', default=False,
                                           help=_('Uninstall all its dependencies recursively')),
                          ])

    def run(self, config, args):
        cookbook = CookBook(config)
        recipe_names = []
        if args.deps:
            m.message('Uninstalling the following recipes along with all their dependencies: {}'
                      .format(' '.join(args.recipe)))
            for recipe in args.recipe:
                recipe_names += [r.name for r in cookbook.list_recipe_deps(recipe)]
        else:
            m.message('Uninstalling the following recipes without their dependencies: {}'
                      .format(' '.join(args.recipe)))
            recipe_names = args.recipe

        for recipe_name in recipe_names:
            recipe = cookbook.get_recipe(recipe_name)

            if recipe_name not in cookbook.status:
                m.message('Recipe {} is not installed'.format(recipe_name))
                continue

            # As a first step, we attempt using the uninstall target,
            # that may or not be present
            try:
                recipe.uninstall()
            except Exception as ex:
                m.warning('{}: failed running uninstall. This is expected if the recipe '
                          'was installed using fridge: {}'.format(recipe.name, ex))

            # As a fallback, in case the uninstall target does not exist,
            # or in case it misses some of the installed files, call the
            # `clean_installed_files` method which will remove them
            recipe.clean_installed_files()
            cookbook.clean_recipe_status(recipe_name)

            # Lastly, remove the build directory
            build_dir = os.path.join(config.sources, recipe.package_name)
            if os.path.isdir(build_dir):
                shutil.rmtree(build_dir)

        m.message('Recipes uninstalled: {}'.format(' '.join(recipe_names)))

register_command(Uninstall)
<commit_msg>Remove also local sources when uninstalling<commit_after># cerbero - a multi-platform build system for Open Source software
# Copyright (C) 2012 Andoni Morales Alastruey <ylatuya@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 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
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import os
import shutil

from cerbero.commands import Command, register_command
from cerbero.build.cookbook import CookBook
from cerbero.errors import FatalError
from cerbero.utils import _, N_, ArgparseArgument, shell, messages as m
from cerbero.build.recipe import BuildSteps

class Uninstall(Command):
    doc = N_('Uninstall a single recipe\'s status')
    name = 'uninstall'

    def __init__(self):
        Command.__init__(self,
                         [ArgparseArgument('recipe', nargs='*',
                                           help=_('Name of the recipes to uninstall')),
                          ArgparseArgument('--deps', action='store_true', default=False,
                                           help=_('Uninstall all its dependencies recursively')),
                          ])

    def run(self, config, args):
        cookbook = CookBook(config)
        recipe_names = []
        if args.deps:
            m.message('Uninstalling the following recipes along with all their dependencies: {}'
                      .format(' '.join(args.recipe)))
            for recipe in args.recipe:
                recipe_names += [r.name for r in cookbook.list_recipe_deps(recipe)]
        else:
            m.message('Uninstalling the following recipes without their dependencies: {}'
                      .format(' '.join(args.recipe)))
            recipe_names = args.recipe

        for recipe_name in recipe_names:
            recipe = cookbook.get_recipe(recipe_name)

            if recipe_name not in cookbook.status:
                m.message('Recipe {} is not installed'.format(recipe_name))
                continue

            # As a first step, we attempt using the uninstall target,
            # that may or not be present
            try:
                recipe.uninstall()
            except Exception as ex:
                m.warning('{}: failed running uninstall. This is expected if the recipe '
                          'was installed using fridge: {}'.format(recipe.name, ex))

            # As a fallback, in case the uninstall target does not exist,
            # or in case it misses some of the installed files, call the
            # `clean_installed_files` method which will remove them
            recipe.clean_installed_files()
            cookbook.clean_recipe_status(recipe_name)

            # Lastly, remove the build and local sources directory
            self._remove_sources_dir(os.path.join(config.sources, recipe.package_name))
            self._remove_sources_dir(os.path.join(config.local_sources, recipe.package_name))

        m.message('Recipes uninstalled: {}'.format(' '.join(recipe_names)))

    def _remove_sources_dir(self, dir):
        if os.path.isdir(dir):
            m.message('Removing sources directory {}'.format(dir))
            shutil.rmtree(dir)

register_command(Uninstall)
<|endoftext|>


<commit_before># Utility functions that provide basic operations on colors given as
# color codes.

from functools import reduce
from numbers import Number
import re

_HEX_RE = re.compile(r'\A#?[0-9a-f]{3}([0-9a-f]{3})?\Z', re.IGNORECASE)

def hex_to_rgb(hex_code):
    """Converts a hex color code string to a RGB value

    :param hex_code: Hex color code such as "#ffff00"
    :type hex_code: str
    :return: RGB value represented as a tuple of integers
    :rtype: (int, int, int)
    """
    hex_part = _remove_head_sharp(hex_code)

    if len(hex_part) == 3:
        return tuple(int(c, 16) * 17 for c in hex_part)
    elif len(hex_part) == 6:
        primaries = (hex_part[i:(i+2)] for i in (0, 2, 4))
        return tuple(int(c, 16) for c in primaries)

    return None

def rgb_to_hex(rgb):
    return '#{:02x}{:02x}{:02x}'.format(*rgb)

def normalize_hex(code, prefix=True):
    if len(code) < 6:
        hex_part = _remove_head_sharp(code)
        code = ''.join(c * 2 for c in hex_part)

    lowered = code.lower()

    if prefix == lowered.startswith('#'):
        return lowered

    return '#' + lowered if prefix else lowered[1:]

# https://www.w3.org/TR/css3-color/#hsl-color

def hsl_to_rgb(hsl):
    h, s, l = (c / u for (c, u) in zip(hsl, (360.0, 100.0, 100.0)))

    m2 = l * (s + 1) if l <= 0.5 else l + s - l * s
    m1 = l * 2 - m2

    adjusted_h = (h + 1 / 3.0, h, h - 1 / 3.0)
    return tuple(round(_hue_to_rgb(m1, m2, ah) * 255) for ah in adjusted_h)

def _hue_to_rgb(m1, m2, h):
    if h < 0:
        h += 1
    if h > 1:
        h -= 1
    if h * 6 < 1:
        return m1 + (m2 - m1) * h * 6
    if h * 2 < 1:
        return m2
    if h * 3 < 2:
        return m1 + (m2 - m1) * (2 / 3.0 - h) * 6
    return m1

def _remove_head_sharp(hex_code):
    if hex_code.startswith('#'):
        return hex_code[1:]

    return hex_code

def hsl_to_hex(hsl):
    return rgb_to_hex(hsl_to_rgb(hsl))

# References:
# Agoston, Max K. (2005).
# "Computer Graphics and Geometric Modeling: Implementation and Algorithms".
# London: Springer
#
# https://accessibility.kde.org/hsl-adjusted.php#hue

def rgb_to_hsl(rgb):
    return (_rgb_to_hue(rgb),
            _rgb_to_saturation(rgb) * 100,
            _rgb_to_lightness(rgb) * 100)

def _rgb_to_lightness(rgb):
    return (max(rgb) + min(rgb)) / 510.0

def _rgb_to_saturation(rgb):
    min_c = min(rgb)
    max_c = max(rgb)

    if min_c == max_c:
        return 0

    d = float(max_c - min_c)

    if _rgb_to_lightness(rgb) <= 0.5:
        return d / (max_c + min_c)
    else:
        return d / (510 - max_c - min_c)

def _rgb_to_hue(rgb):
    min_c = min(rgb)
    max_c = max(rgb)

    if min_c == max_c:
        return 0

    d = float(max_c - min_c)

    mi = reduce(lambda m, c: m if rgb[m] > c[1] else c[0], enumerate(rgb), 0)
    h = mi * 120 + (rgb[(mi + 1) % 3] - rgb[(mi + 2) % 3]) * 60 / d

    return h + 360 if h < 0 else h

def hex_to_hsl(hex_code):
    return rgb_to_hsl(hex_to_rgb(hex_code))

def is_valid_rgb(rgb):
    return len(rgb) == 3 and all(_valid_rgb_component(c) for c in rgb)

def _valid_rgb_component(component):
    return isinstance(component, int) and component >= 0 and component <= 255

def is_valid_hsl(hsl):
    if len(hsl) != 3:
        return False

    for (i, u) in enumerate((360, 100, 100)):
        c = hsl[i]

        if not isinstance(c, Number) or c < 0 or c > u:
            return False

    return True

def is_valid_hex(hex_code):
    return _HEX_RE.match(hex_code) is not None

def is_same_hex_color(hex1, hex2):
    return normalize_hex(hex1) == normalize_hex(hex2)

def is_uppercase(string):
    return string == string.upper()
<commit_msg>add docstring to utils.rgb_to_hex()<commit_after># Utility functions that provide basic operations on colors given as
# color codes.

from functools import reduce
from numbers import Number
import re

_HEX_RE = re.compile(r'\A#?[0-9a-f]{3}([0-9a-f]{3})?\Z', re.IGNORECASE)

def hex_to_rgb(hex_code):
    """Converts a hex color code string to a RGB value

    :param hex_code: Hex color code such as "#ffff00"
    :type hex_code: str
    :return: RGB value represented as a tuple of integers
    :rtype: (int, int, int)
    """
    hex_part = _remove_head_sharp(hex_code)

    if len(hex_part) == 3:
        return tuple(int(c, 16) * 17 for c in hex_part)
    elif len(hex_part) == 6:
        primaries = (hex_part[i:(i+2)] for i in (0, 2, 4))
        return tuple(int(c, 16) for c in primaries)

    return None

def rgb_to_hex(rgb):
    """Converts a RGB value to a hex color code

    :param rgb: RGB value represented as a tuple of integers
    :type rgb: (int, int, int)
    :return: Hex color code such as "#ffff00"
    :rtype: str
    """
    return '#{:02x}{:02x}{:02x}'.format(*rgb)

def normalize_hex(code, prefix=True):
    if len(code) < 6:
        hex_part = _remove_head_sharp(code)
        code = ''.join(c * 2 for c in hex_part)

    lowered = code.lower()

    if prefix == lowered.startswith('#'):
        return lowered

    return '#' + lowered if prefix else lowered[1:]

# https://www.w3.org/TR/css3-color/#hsl-color

def hsl_to_rgb(hsl):
    h, s, l = (c / u for (c, u) in zip(hsl, (360.0, 100.0, 100.0)))

    m2 = l * (s + 1) if l <= 0.5 else l + s - l * s
    m1 = l * 2 - m2

    adjusted_h = (h + 1 / 3.0, h, h - 1 / 3.0)
    return tuple(round(_hue_to_rgb(m1, m2, ah) * 255) for ah in adjusted_h)

def _hue_to_rgb(m1, m2, h):
    if h < 0:
        h += 1
    if h > 1:
        h -= 1
    if h * 6 < 1:
        return m1 + (m2 - m1) * h * 6
    if h * 2 < 1:
        return m2
    if h * 3 < 2:
        return m1 + (m2 - m1) * (2 / 3.0 - h) * 6
    return m1

def _remove_head_sharp(hex_code):
    if hex_code.startswith('#'):
        return hex_code[1:]

    return hex_code

def hsl_to_hex(hsl):
    return rgb_to_hex(hsl_to_rgb(hsl))

# References:
# Agoston, Max K. (2005).
# "Computer Graphics and Geometric Modeling: Implementation and Algorithms".
# London: Springer
#
# https://accessibility.kde.org/hsl-adjusted.php#hue

def rgb_to_hsl(rgb):
    return (_rgb_to_hue(rgb),
            _rgb_to_saturation(rgb) * 100,
            _rgb_to_lightness(rgb) * 100)

def _rgb_to_lightness(rgb):
    return (max(rgb) + min(rgb)) / 510.0

def _rgb_to_saturation(rgb):
    min_c = min(rgb)
    max_c = max(rgb)

    if min_c == max_c:
        return 0

    d = float(max_c - min_c)

    if _rgb_to_lightness(rgb) <= 0.5:
        return d / (max_c + min_c)
    else:
        return d / (510 - max_c - min_c)

def _rgb_to_hue(rgb):
    min_c = min(rgb)
    max_c = max(rgb)

    if min_c == max_c:
        return 0

    d = float(max_c - min_c)

    mi = reduce(lambda m, c: m if rgb[m] > c[1] else c[0], enumerate(rgb), 0)
    h = mi * 120 + (rgb[(mi + 1) % 3] - rgb[(mi + 2) % 3]) * 60 / d

    return h + 360 if h < 0 else h

def hex_to_hsl(hex_code):
    return rgb_to_hsl(hex_to_rgb(hex_code))

def is_valid_rgb(rgb):
    return len(rgb) == 3 and all(_valid_rgb_component(c) for c in rgb)

def _valid_rgb_component(component):
    return isinstance(component, int) and component >= 0 and component <= 255

def is_valid_hsl(hsl):
    if len(hsl) != 3:
        return False

    for (i, u) in enumerate((360, 100, 100)):
        c = hsl[i]

        if not isinstance(c, Number) or c < 0 or c > u:
            return False

    return True

def is_valid_hex(hex_code):
    return _HEX_RE.match(hex_code) is not None

def is_same_hex_color(hex1, hex2):
    return normalize_hex(hex1) == normalize_hex(hex2)

def is_uppercase(string):
    return string == string.upper()
<|endoftext|>


<commit_before>import itertools

### Fill in each function below. Each function should be a one-liner.

def sort_rows(mat):
    '''
    INPUT: 2 dimensional list of integers (matrix)
    OUTPUT: 2 dimensional list of integers (matrix)

    Use list comprehension to modify each row of the matrix to be sorted.

    Example:
    >>> M = [[4, 5, 2, 8], [3, 9, 6, 7]]
    >>> sort_rows(M)
    >>> M
    [[2, 4, 5, 8], [3, 6, 7, 9]]
    '''
    pass

def average_rows1(mat):
    '''
    INPUT: 2 dimensional list of integers (matrix)
    OUTPUT: list of floats

    Use list comprehension to take the average of each row in the matrix and
    return it as a list.

    Example:
    >>> average_rows1([[4, 5, 2, 8], [3, 9, 6, 7]])
    [4.75, 6.25]
    '''
    pass

def average_rows2(mat):
    '''
    INPUT: 2 dimensional list of integers (matrix)
    OUTPUT: list of floats

    Use map to take the average of each row in the matrix and
    return it as a list.
    '''
    pass

def word_lengths1(phrase):
    '''
    INPUT: string
    OUTPUT: list of integers

    Use list comprehension to find the length of each word in the phrase
    (broken by spaces) and return the values in a list.

    Example:
    >>> word_lengths1("Welcome to Zipfian Academy!")
    [7, 2, 7, 8]
    '''
    pass

def word_lengths2(phrase):
    '''
    INPUT: string
    OUTPUT: list of integers

    Use map to find the length of each word in the phrase
    (broken by spaces) and return the values in a list.
    '''
    pass

def even_odd1(L):
    '''
    INPUT: list of integers
    OUTPUT: list of strings

    Use list comprehension to return a list of the same length with the strings
    "even" or "odd" depending on whether the element in L is even or odd.

    Example:
    >>> even_odd([6, 4, 1, 3, 8, 5])
    ['even', 'even', 'odd', 'odd', 'even', 'odd']
    '''
    pass

def even_odd2(L):
    '''
    INPUT: list of integers
    OUTPUT: list of strings

    Use map to return a list of the same length with the strings
    "even" or "odd" depending on whether the element in L is even or odd.
    '''
    pass

def shift_on_character(string, char):
    '''
    INPUT: string, string
    OUTPUT: string

    Find the first occurence of the character char and return the string witth
    everything before char moved to the end of the string. If char doesn't
    appear, return the same string.

    This function may use more than one line.

    Example:
    >>> shift_on_character("zipfian", "f")
    'fianzip'
    '''
    pass

def is_palindrome(string):
    '''
    INPUT: string
    OUTPUT: boolean

    Return whether the given string is the same forwards and backwards.

    Example:
    >>> is_palindrome("rats live on no evil star")
    True
    '''
    pass

def alternate(L):
    '''
    INPUT: list
    OUTPUT: list

    Use list slicing to return a list containing all the odd indexed elements
    followed by all the even indexed elements.

    Example:
    >>> alternate(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
    ['b', 'd', 'f', 'a', 'c', 'e', 'g']
    '''
    pass

def shuffle(L):
    '''
    INPUT: list
    OUTPUT: list

    Return the result of a "perfect" shuffle. You may assume that L has even
    length. You should return the result of splitting L in half and alternating
    taking an element from each.

    Example:
    >>> shuffle([1, 2, 3, 4, 5, 6])
    [1, 4, 2, 5, 3, 6]
    '''
    pass

def filter_words(word_list, letter):
    '''
    INPUT: list of words, string
    OUTPUT: list of words

    Use filter to return the words from word_list which start with letter.

    Example:
    >>> filter_words(["salumeria", "dandelion", "yamo", "doc loi", "rosamunde",
                      "beretta", "ike's", "delfina"], "d")
    ['dandelion', 'doc loi', 'delfina']
    '''
    pass

def factors(num):
    '''
    INPUT: integer
    OUTPUT: list of integers

    Use filter to return all of the factors of num.
    '''
    pass

def acronym(phrase):
    '''
    INPUT: string
    OUTPUT: string

    Given a phrase, return the associated acronym by breaking on spaces and
    concatenating the first letters of each word together capitalized.

    Example:
    >>> acronym("zipfian academy")
    'ZA'

    Hint: You can do this on one line using list comprehension and the join
    method. Python has a builtin string method to uppercase strings.
    '''
    pass

def sort_by_ratio(L):
    '''
    INPUT: list of 2-tuples of integers
    OUTPUT: None

    Sort the list L by the ratio of the elements in the 2-tuples.
    For example, (1, 3) < (2, 4) since 1/3 < 2/4.
    Use the key parameter in the sort method.

    Example:
    >>> L = [(2, 4), (8, 5), (1, 3), (9, 4), (3, 5)]
    >>> sort_by_ratio(L)
    >>> L
    [(1, 3), (2, 4), (3, 5), (8, 5), (9, 4)]
    '''
    pass

def count_match_index(L):
    '''
    INTPUT: list of integers
    OUTPUT: integer

    Use enumerate and other skills from above to return the count of the number
    of items in the list whose value equals its index.

    Example:
    >>> count_match_index([0, 2, 2, 3, 6, 5])
    4
    '''
    pass

def only_sorted(L):
    '''
    INPUT: list of list of integers
    OUTPUT: list of list of integers

    Use filter to return only the lists from L that are in sorted order.
    Hint: the all function may come in handy.

    Example:
    >>> only_sorted([[3, 4, 5], [4, 3, 5], [5, 6, 3], [5, 6, 7]])
    [[3, 4, 5], [5, 6, 7]]
    '''
    pass

def concatenate(L1, L2, connector=""):
    '''
    INPUT: list of strings, list of strings
    OUTPUT: list of strings

    L1 and L2 have the same length. Use zip and other skills from above to
    return a list of the same length where each value is the two strings from
    L1 and L2 concatenated together with connector between them.

    Example:
    >>> concatenate(["A", "B"], ["b", "b"])
    ['Ab', 'Bb']
    >>> concatenate(["San Francisco", "New York", "Las Vegas", "Los Angeles"], \
                    ["California", "New York", "Nevada", "California"], ", ")
    ['San Francisco, California', 'New York, New York', 'Las Vegas, Nevada',
    'Los Angeles, California']
    '''
    pass

def transpose(mat):
    '''
    INPUT: 2 dimensional list of integers
    OUTPUT: 2 dimensional list of integers

    Return the transpose of the matrix. You may assume that the matrix is not
    empty. You can do this using a double for loop in a list comprehension.
    There is also a solution using zip.
    '''
    pass

def invert_list(L):
    '''
    INPUT: list
    OUTPUT: dictionary

    Use enumerate and other skills from above to return a dictionary which has
    the values of the list as keys and the index as the value. You may assume
    that a value will only appear once in the given list.

    Example:
    >>> invert_list(['a', 'b', 'c', 'd'])
    {'a': 0, 'c': 2, 'b': 1, 'd': 3}
    '''
    pass

def digits_to_num(digits):
    '''
    INPUT: list of integers
    OUTPUT: integer

    Use reduce to take a list of digits and return the number that they
    correspond to. Do not convert the integers to strings.

    Example:
    >>> digits_to_num([5, 0, 3, 8])
    5038
    '''
    pass

def intersection_of_sets(list_of_sets):
    '''
    INPUT: list of sets
    OUTPUT: set

    Use reduce to take the intersection of a list of sets.
    Hint: the & operator takes the intersection of two sets.

    Example:
    >>> intersection_of_sets([{1, 2, 3}, {2, 3, 4}, {2, 5}])
    set([2])
    '''
    pass

def combinations(alphabet, n):
    '''
    INPUT: string, integer
    OUTPUT: list of strings

    Use itertools.combinations to return all the combinations of letters in
    alphabet with length at most n.

    Example:
    >>> combinations('abc', 2)
    ['a', 'b', 'c', 'ab', 'ac', 'bc']
    '''
    pass

def permutations_in_dict(string, words):
    '''
    INPUT: string, set
    OUTPUT: list of strings

    Use itertools.permutations to return all the permutations of the string
    and return only the ones which are members of set words.

    Example:
    >>> permutations_in_dict('act', {'cat', 'rat', 'dog', 'act'})
    ['act', 'cat']
    '''
    pass
<commit_msg>Half solutions to 1<commit_after>import itertools

### Fill in each function below. Each function should be a one-liner.

def sort_rows(mat):
    '''
    INPUT: 2 dimensional list of integers (matrix)
    OUTPUT: 2 dimensional list of integers (matrix)
    Use list comprehension to modify each row of the matrix to be sorted.
    Example:
    >>> M = [[4, 5, 2, 8], [3, 9, 6, 7]]
    >>> sort_rows(M)
    >>> M
    [[2, 4, 5, 8], [3, 6, 7, 9]]
    '''
    mat = [sorted(mat[0]),sorted(mat[1])];
    pass

def average_rows1(mat):
    '''
    INPUT: 2 dimensional list of integers (matrix)
    OUTPUT: list of floats
    Use list comprehension to take the average of each row in the matrix and
    return it as a list.
    Example:
    >>> average_rows1([[4, 5, 2, 8], [3, 9, 6, 7]])
    [4.75, 6.25]
    '''
    return [float(sum(mat[0]))/float(len(mat[0])),float(sum(mat[1]))/float(len(mat[0]))];
    pass

def average_rows2(mat):
    '''
    INPUT: 2 dimensional list of integers (matrix)
    OUTPUT: list of floats
    Use map to take the average of each row in the matrix and
    return it as a list.
    '''
    def avg(x): return float(sum(x))/float(len(x));
    return map(avg,mat);
    pass

def word_lengths1(phrase):
    '''
    INPUT: string
    OUTPUT: list of integers
    Use list comprehension to find the length of each word in the phrase
    (broken by spaces) and return the values in a list.
    Example:
    >>> word_lengths1("Welcome to Zipfian Academy!")
    [7, 2, 7, 8]
    '''
    return [len(x) for x in phrase.split()]
    pass

def word_lengths2(phrase):
    '''
    INPUT: string
    OUTPUT: list of integers
    Use map to find the length of each word in the phrase
    (broken by spaces) and return the values in a list.
    '''
    return map(len,phrase.split());
    pass

def even_odd1(L):
    '''
    INPUT: list of integers
    OUTPUT: list of strings

    Use list comprehension to return a list of the same length with the strings
    "even" or "odd" depending on whether the element in L is even or odd.

    Example:
    >>> even_odd([6, 4, 1, 3, 8, 5])
    ['even', 'even', 'odd', 'odd', 'even', 'odd']
    '''
    return ['even' if x % 2 == 0 else 'odd' for x in L]
    pass

def even_odd2(L):
    '''
    INPUT: list of integers
    OUTPUT: list of strings

    Use map to return a list of the same length with the strings
    "even" or "odd" depending on whether the element in L is even or odd.
    '''
    pass

def shift_on_character(string, char):
    '''
    INPUT: string, string
    OUTPUT: string

    Find the first occurence of the character char and return the string witth
    everything before char moved to the end of the string. If char doesn't
    appear, return the same string.

    This function may use more than one line.

    Example:
    >>> shift_on_character("zipfian", "f")
    'fianzip'
    '''
    if char not in string:
        return string;
    else:
        start_num = string.index(char)
        return string[start_num:]+string[:start_num];
    pass

def is_palindrome(string):
    '''
    INPUT: string
    OUTPUT: boolean

    Return whether the given string is the same forwards and backwards.

    Example:
    >>> is_palindrome("rats live on no evil star")
    True
    '''
    return string == string[::-1]
    pass

def alternate(L):
    '''
    INPUT: list
    OUTPUT: list

    Use list slicing to return a list containing all the odd indexed elements
    followed by all the even indexed elements.

    Example:
    >>> alternate(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
    ['b', 'd', 'f', 'a', 'c', 'e', 'g']
    '''
    return L[1::2]
    pass

def shuffle(L):
    '''
    INPUT: list
    OUTPUT: list

    Return the result of a "perfect" shuffle. You may assume that L has even
    length. You should return the result of splitting L in half and alternating
    taking an element from each.

    Example:
    >>> shuffle([1, 2, 3, 4, 5, 6])
    [1, 4, 2, 5, 3, 6]
    '''
    shuffled = []
    for i in range(len(L)/2):
        shuffled.append(L[i])
        shuffled.append(L[i+len(L)/2])
    return shuffled
    return [x]
    pass

def filter_words(word_list, letter):
    '''
    INPUT: list of words, string
    OUTPUT: list of words
    Use filter to return the words from word_list which start with letter.
    Example:
    >>> filter_words(["salumeria", "dandelion", "yamo", "doc loi", "rosamunde",
                      "beretta", "ike's", "delfina"], "d")
    ['dandelion', 'doc loi', 'delfina']
    '''
    return [x for x in word_list if x[0]==letter]
    pass

def factors(num):
    '''
    INPUT: integer
    OUTPUT: list of integers
    Use filter to return all of the factors of num.
    '''
    return [x for x in range(1,num) if num % x == 0]
    pass

def acronym(phrase):
    '''
    INPUT: string
    OUTPUT: string
    Given a phrase, return the associated acronym by breaking on spaces and
    concatenating the first letters of each word together capitalized.
    Example:
    >>> acronym("zipfian academy")
    'ZA'
    Hint: You can do this on one line using list comprehension and the join
    method. Python has a builtin string method to uppercase strings.
    '''
    return ''.join([x[0].upper() for x in phrase.split()])
    pass

def sort_by_ratio(L):
    '''
    INPUT: list of 2-tuples of integers
    OUTPUT: None

    Sort the list L by the ratio of the elements in the 2-tuples.
    For example, (1, 3) < (2, 4) since 1/3 < 2/4.
    Use the key parameter in the sort method.

    Example:
    >>> L = [(2, 4), (8, 5), (1, 3), (9, 4), (3, 5)]
    >>> sort_by_ratio(L)
    >>> L
    [(1, 3), (2, 4), (3, 5), (8, 5), (9, 4)]
    '''

    return sorted(L,key = lambda ratio: ratio[0]/ratio[1])
    pass

def count_match_index(L):
    '''
    INTPUT: list of integers
    OUTPUT: integer

    Use enumerate and other skills from above to return the count of the number
    of items in the list whose value equals its index.

    Example:
    >>> count_match_index([0, 2, 2, 3, 6, 5])
    4
    '''
    return len([x for x in list(enumerate(L)) if x[0]==x[1]])
    pass

def only_sorted(L):
    '''
    INPUT: list of list of integers
    OUTPUT: list of list of integers

    Use filter to return only the lists from L that are in sorted order.
    Hint: the all function may come in handy.

    Example:
    >>> only_sorted([[3, 4, 5], [4, 3, 5], [5, 6, 3], [5, 6, 7]])
    [[3, 4, 5], [5, 6, 7]]
    '''

    pass

def concatenate(L1, L2, connector=""):
    '''
    INPUT: list of strings, list of strings
    OUTPUT: list of strings

    L1 and L2 have the same length. Use zip and other skills from above to
    return a list of the same length where each value is the two strings from
    L1 and L2 concatenated together with connector between them.

    Example:
    >>> concatenate(["A", "B"], ["b", "b"])
    ['Ab', 'Bb']
    >>> concatenate(["San Francisco", "New York", "Las Vegas", "Los Angeles"], \
                    ["California", "New York", "Nevada", "California"], ", ")
    ['San Francisco, California', 'New York, New York', 'Las Vegas, Nevada',
    'Los Angeles, California']
    '''
    pass

def transpose(mat):
    '''
    INPUT: 2 dimensional list of integers
    OUTPUT: 2 dimensional list of integers

    Return the transpose of the matrix. You may assume that the matrix is not
    empty. You can do this using a double for loop in a list comprehension.
    There is also a solution using zip.
    '''
    pass

def invert_list(L):
    '''
    INPUT: list
    OUTPUT: dictionary

    Use enumerate and other skills from above to return a dictionary which has
    the values of the list as keys and the index as the value. You may assume
    that a value will only appear once in the given list.

    Example:
    >>> invert_list(['a', 'b', 'c', 'd'])
    {'a': 0, 'c': 2, 'b': 1, 'd': 3}
    '''
    pass

def digits_to_num(digits):
    '''
    INPUT: list of integers
    OUTPUT: integer

    Use reduce to take a list of digits and return the number that they
    correspond to. Do not convert the integers to strings.

    Example:
    >>> digits_to_num([5, 0, 3, 8])
    5038
    '''
    pass

def intersection_of_sets(list_of_sets):
    '''
    INPUT: list of sets
    OUTPUT: set

    Use reduce to take the intersection of a list of sets.
    Hint: the & operator takes the intersection of two sets.

    Example:
    >>> intersection_of_sets([{1, 2, 3}, {2, 3, 4}, {2, 5}])
    set([2])
    '''
    pass

def combinations(alphabet, n):
    '''
    INPUT: string, integer
    OUTPUT: list of strings

    Use itertools.combinations to return all the combinations of letters in
    alphabet with length at most n.

    Example:
    >>> combinations('abc', 2)
    ['a', 'b', 'c', 'ab', 'ac', 'bc']
    '''
    pass

def permutations_in_dict(string, words):
    '''
    INPUT: string, set
    OUTPUT: list of strings

    Use itertools.permutations to return all the permutations of the string
    and return only the ones which are members of set words.

    Example:
    >>> permutations_in_dict('act', {'cat', 'rat', 'dog', 'act'})
    ['act', 'cat']
    '''
    pass<|endoftext|>


<commit_before># fmt: off
__title__ = "spacy"
__version__ = "3.0.0.dev8"
__release__ = True
__download_url__ = "https://github.com/explosion/spacy-models/releases/download"
__compatibility__ = "https://raw.githubusercontent.com/explosion/spacy-models/master/compatibility.json"
__shortcuts__ = "https://raw.githubusercontent.com/explosion/spacy-models/master/shortcuts-v2.json"
<commit_msg>Set version to v3.0.0.dev9<commit_after># fmt: off
__title__ = "spacy"
__version__ = "3.0.0.dev9"
__release__ = True
__download_url__ = "https://github.com/explosion/spacy-models/releases/download"
__compatibility__ = "https://raw.githubusercontent.com/explosion/spacy-models/master/compatibility.json"
__shortcuts__ = "https://raw.githubusercontent.com/explosion/spacy-models/master/shortcuts-v2.json"
<|endoftext|>


<commit_before>from enerdata.profiles.profile import *
from enerdata.contracts.tariff import T20DHA
from enerdata.metering.measure import *

with description("A coeficient"):
    with before.all:
        start = TIMEZONE.localize(datetime(2014, 1, 1))
        end = TIMEZONE.localize(datetime(2015, 1, 1))
        cofs = []
        day = start
        while day < end:
            day += timedelta(hours=1)
            cofs.append((TIMEZONE.normalize(day), {'A': 0, 'B': 0}))
        self.cofs = cofs

    with it("must read and sum the hours of the file"):
        # TODO: Move this test to integration test with REE
        cofs = REEProfile.get(2014, 10)
        # We have one hour more in October
        assert len(cofs) == (31 * 24) + 1
        # The first second hour in the 26th of October is DST
        assert cofs[(24 * 25) + 1][0].dst() == timedelta(seconds=3600)
        # The second second hour in the 26th of October is not DST
        assert cofs[(24 * 25) + 2][0].dst() == timedelta(0)
        assert REEProfile._CACHE['201410'] == cofs

    with it("must return the sum of coefs for each period"):
        c = Coefficients(self.cofs)
        t = T20DHA()
        t.cof = 'A'
        assert c.get_coefs_by_tariff(t, date(2014, 1, 1), date(2014, 1, 31)) == {'P1': 0, 'P2': 0}

    with it('should insert coeficients if empty'):
        c = Coefficients()
        assert len(c.coefs) == 0
        c.insert_coefs(self.cofs)
        assert len(c.coefs) == (365 * 24)

    with it('should replace the coeficients'):
        c = Coefficients(self.cofs)
        assert len(c.coefs) == (365 * 24)
        c.insert_coefs(self.cofs)
        assert len(c.coefs) == (365 * 24)

    with it('should append the coefficients'):
        c = Coefficients()
        c.insert_coefs(self.cofs)
        start = TIMEZONE.localize(datetime(2015, 1, 1))
        end = TIMEZONE.localize(datetime(2015, 2, 1))
        cofs = []
        day = start
        while day < end:
            cofs.append((TIMEZONE.normalize(day + timedelta(hours=1)), {'A': 0, 'B': 0}))
            day += timedelta(hours=1)
        c.insert_coefs(cofs)
        assert c.coefs[0][0] == TIMEZONE.localize(datetime(2014, 1, 1, 1))
        assert c.coefs[-1][0] == TIMEZONE.localize(datetime(2015, 2, 1))
        assert len(c.coefs) == ((365 * 24) + (31 * 24))

    with it('should return the range of dates'):
        c = Coefficients(self.cofs)
        cofs = c.get_range(date(2014, 10, 26), date(2014, 10, 26))
        assert len(cofs) == 25
        assert cofs[1][0] == TIMEZONE.localize(datetime(2014, 10, 26, 2), is_dst=True)
        assert cofs[2][0] == TIMEZONE.localize(datetime(2014, 10, 26, 2), is_dst=False)

        cofs = c.get_range(date(2014, 3, 30), date(2014, 3, 30))
        assert len(cofs) == 23
        assert cofs[1][0] == TIMEZONE.normalize(TIMEZONE.localize(datetime(2014, 3, 30, 2)))

with description("When profiling"):

    with it('the total energy must be the sum of the profiled energy'):
        c = Coefficients(REEProfile.get(2014, 10))
        profiler = Profiler(c)
        measures = [
            EnergyMeasure(
                date(2014, 9, 30),
                TariffPeriod('P1', 'te'), 307, consumption=145
            ),
            EnergyMeasure(
                date(2014, 9, 30),
                TariffPeriod('P2', 'te'), 108, consumption=10
            ),
            EnergyMeasure(
                date(2014, 10, 31),
                TariffPeriod('P1', 'te'), 540, consumption=233
            ),
            EnergyMeasure(
                date(2014, 10, 31),
                TariffPeriod('P2', 'te'), 150, consumption=42
            )
        ]
        t = T20DHA()
        t.cof = 'A'
        prof = list(profiler.profile(t, measures))
        assert len(prof) == (31 * 24) + 1
        consum = sum([i[1]['aprox'] for i in prof])
        assert consum == 233 + 42
<commit_msg>Add the test for dragging per period<commit_after>from enerdata.profiles.profile import *
from enerdata.contracts.tariff import T20DHA, T30A
from enerdata.metering.measure import *

with description("A coeficient"):
    with before.all:
        start = TIMEZONE.localize(datetime(2014, 1, 1))
        end = TIMEZONE.localize(datetime(2015, 1, 1))
        cofs = []
        day = start
        while day < end:
            day += timedelta(hours=1)
            cofs.append((TIMEZONE.normalize(day), {'A': 0, 'B': 0}))
        self.cofs = cofs

    with it("must read and sum the hours of the file"):
        # TODO: Move this test to integration test with REE
        cofs = REEProfile.get(2014, 10)
        # We have one hour more in October
        assert len(cofs) == (31 * 24) + 1
        # The first second hour in the 26th of October is DST
        assert cofs[(24 * 25) + 1][0].dst() == timedelta(seconds=3600)
        # The second second hour in the 26th of October is not DST
        assert cofs[(24 * 25) + 2][0].dst() == timedelta(0)
        assert REEProfile._CACHE['201410'] == cofs

    with it("must return the sum of coefs for each period"):
        c = Coefficients(self.cofs)
        t = T20DHA()
        t.cof = 'A'
        assert c.get_coefs_by_tariff(t, date(2014, 1, 1), date(2014, 1, 31)) == {'P1': 0, 'P2': 0}

    with it('should insert coeficients if empty'):
        c = Coefficients()
        assert len(c.coefs) == 0
        c.insert_coefs(self.cofs)
        assert len(c.coefs) == (365 * 24)

    with it('should replace the coeficients'):
        c = Coefficients(self.cofs)
        assert len(c.coefs) == (365 * 24)
        c.insert_coefs(self.cofs)
        assert len(c.coefs) == (365 * 24)

    with it('should append the coefficients'):
        c = Coefficients()
        c.insert_coefs(self.cofs)
        start = TIMEZONE.localize(datetime(2015, 1, 1))
        end = TIMEZONE.localize(datetime(2015, 2, 1))
        cofs = []
        day = start
        while day < end:
            cofs.append((TIMEZONE.normalize(day + timedelta(hours=1)), {'A': 0, 'B': 0}))
            day += timedelta(hours=1)
        c.insert_coefs(cofs)
        assert c.coefs[0][0] == TIMEZONE.localize(datetime(2014, 1, 1, 1))
        assert c.coefs[-1][0] == TIMEZONE.localize(datetime(2015, 2, 1))
        assert len(c.coefs) == ((365 * 24) + (31 * 24))

    with it('should return the range of dates'):
        c = Coefficients(self.cofs)
        cofs = c.get_range(date(2014, 10, 26), date(2014, 10, 26))
        assert len(cofs) == 25
        assert cofs[1][0] == TIMEZONE.localize(datetime(2014, 10, 26, 2), is_dst=True)
        assert cofs[2][0] == TIMEZONE.localize(datetime(2014, 10, 26, 2), is_dst=False)

        cofs = c.get_range(date(2014, 3, 30), date(2014, 3, 30))
        assert len(cofs) == 23
        assert cofs[1][0] == TIMEZONE.normalize(TIMEZONE.localize(datetime(2014, 3, 30, 2)))

with description("When profiling"):

    with it('the total energy must be the sum of the profiled energy'):
        c = Coefficients(REEProfile.get(2014, 10))
        profiler = Profiler(c)
        measures = [
            EnergyMeasure(
                date(2014, 9, 30),
                TariffPeriod('P1', 'te'), 307, consumption=145
            ),
            EnergyMeasure(
                date(2014, 9, 30),
                TariffPeriod('P2', 'te'), 108, consumption=10
            ),
            EnergyMeasure(
                date(2014, 10, 31),
                TariffPeriod('P1', 'te'), 540, consumption=233
            ),
            EnergyMeasure(
                date(2014, 10, 31),
                TariffPeriod('P2', 'te'), 150, consumption=42
            )
        ]
        t = T20DHA()
        t.cof = 'A'
        prof = list(profiler.profile(t, measures))
        assert len(prof) == (31 * 24) + 1
        consum = sum([i[1]['aprox'] for i in prof])
        assert consum == 233 + 42

    with it('should be the same per period if drag per period is used'):
        c = Coefficients()
        c.insert_coefs(REEProfile.get(2015, 2))
        c.insert_coefs(REEProfile.get(2015, 3))
        profiler = Profiler(c)
        measures = [
            EnergyMeasure(
                date(2015, 2, 17),
                TariffPeriod('P1', 'te'), 0, consumption=0
            ),
            EnergyMeasure(
                date(2015, 2, 17),
                TariffPeriod('P2', 'te'), 0, consumption=0
            ),
            EnergyMeasure(
                date(2015, 2, 17),
                TariffPeriod('P3', 'te'), 0, consumption=0
            ),
            EnergyMeasure(
                date(2015, 2, 17),
                TariffPeriod('P4', 'te'), 0, consumption=0
            ),
            EnergyMeasure(
                date(2015, 2, 17),
                TariffPeriod('P5', 'te'), 0, consumption=0
            ),
            EnergyMeasure(
                date(2015, 2, 17),
                TariffPeriod('P6', 'te'), 0, consumption=0
            ),
            EnergyMeasure(
                date(2015, 3, 18),
                TariffPeriod('P1', 'te'), 0, consumption=282
            ),
            EnergyMeasure(
                date(2015, 3, 18),
                TariffPeriod('P2', 'te'), 0, consumption=156
            ),
            EnergyMeasure(
                date(2015, 3, 18),
                TariffPeriod('P3', 'te'), 0, consumption=325
            ),
            EnergyMeasure(
                date(2015, 3, 18),
                TariffPeriod('P4', 'te'), 0, consumption=56
            ),
            EnergyMeasure(
                date(2015, 3, 18),
                TariffPeriod('P5', 'te'), 0, consumption=643
            ),
            EnergyMeasure(
                date(2015, 3, 18),
                TariffPeriod('P6', 'te'), 0, consumption=32
            )
        ]
        t = T30A()
        t.cof = 'C'
        prof = list(profiler.profile(t, measures, drag_method='period'))
        cons = {}
        for p in prof:
            period = p[1]['period']
            cons.setdefault(period, 0)
            cons[period] += p[1]['aprox']

        assert cons['P1'] == 282
        assert cons['P2'] == 156
        assert cons['P3'] == 325
        assert cons['P4'] == 56
        assert cons['P5'] == 643
        assert cons['P6'] == 32
<|endoftext|>


<commit_before>from machine import Machine
from control import KRPosControl as Control

class SentenceParser:
    """This class will create machines from analyzed and chunked text"""

    def parse(self, sentence):
        """
        input sentence is a list of tokens and chunk in the following format:
            [(token1_tag1, token1_tag2, token1_tagX, ...),
             ([(tokeninchunk1_tag1, tokeninchunk1_tagX,...),
               ...
              ], case_of_chunk),
             (token_out_of_chunk_again_tagX,...),
             ...
            ]
        output is a list of machines
        """
        machines = []
        for token_or_chunk in sentence:
            # chunk or token?
            if type(token_or_chunk[0]) == list:
                # chunk
                chunk, _ = token_or_chunk
                machines.append([Machine(analysis.split("/")[0], Control(analysis))
                                 for _, analysis in chunk])
            else:
                # token
                token = token_or_chunk[0]
                _, analysis = token
                machines.append([Machine(analysis.split("/")[0], Control(analysis))])
        return machines

if __name__ == "__main__":
    pass

<commit_msg>modified:   sentence_parser.py token bug fix<commit_after>from machine import Machine
from control import KRPosControl as Control

class SentenceParser:
    """This class will create machines from analyzed and chunked text"""

    def parse(self, sentence):
        """
        input sentence is a list of tokens and chunk in the following format:
            [(token1_tag1, token1_tag2, token1_tagX, ...),
             ([(tokeninchunk1_tag1, tokeninchunk1_tagX,...),
               ...
              ], case_of_chunk),
             (token_out_of_chunk_again_tagX,...),
             ...
            ]
        output is a list of machines
        """
        machines = []
        for token_or_chunk in sentence:
            # chunk or token?
            if type(token_or_chunk[0]) == list:
                # chunk
                chunk, _ = token_or_chunk
                machines.append([Machine(analysis.split("/")[0], Control(analysis))
                                 for _, analysis in chunk])
            else:
                # token
                token = token_or_chunk#[0]
                _, analysis = token
                machines.append([Machine(analysis.split("/")[0], Control(analysis))])
        return machines

if __name__ == "__main__":
    pass

<|endoftext|>


<commit_before>import xml.etree.ElementTree as ElementTree

import requests

from CommandTemplate import CommandTemplate
import GlobalStore
import SharedFunctions

class Command(CommandTemplate):
	triggers = ['define', 'dictionary', 'dict', 'word']
	helptext = "Looks up the definition of the provided word"

	def execute(self, message):
		"""
		:type message: IrcMessage.IrcMessage
		"""

		#First check if we have the required data
		if 'dictionarylookup' not in GlobalStore.commandhandler.apikeys:
			self.logError("[Dictionary] No API key for DictionaryLookup found!")
			return message.reply("Sorry, I don't seem to have the key required to be able to use this module. Inform my owner, they'll fix it!")
		if message.messagePartsLength == 0:
			return message.reply("Look up which word? I'm not just going to pick a random one")

		searchQuery = message.message.lower()
		#Retrieve the definition
		apireply = requests.get('http://www.dictionaryapi.com/api/v1/references/collegiate/xml/{}?key={}'.format(searchQuery, GlobalStore.commandhandler.apikeys['dictionarylookup']))
		xmltext = apireply.text.encode('utf8')
		#<fw> tags are useless and mess everything up. They're links to other definitions on the site, but in here they just confuse the XML parser
		#There's also a few fields only used to indicate a certain layout. Remove those too
		for field in ('fw', 'd_link', 'i_link', 'dx_ety', 'dx_def', 'it', 'bold', 'bit'):
			xmltext = xmltext.replace('<{}>'.format(field), '').replace('</{}>'.format(field), '')
		xmldata = ElementTree.fromstring(xmltext)

		maxMessageLength = 290

		#Check if we have actual results or if the user made a typo or something. If there is one or more 'suggestion' entry, it's not an existing word
		if xmldata.find('suggestion') is not None:
			replytext = "That term doesn't seem to exist. Did you perhaps mean: "
			#List all the suggestions, at least until we run out of room
			for suggestionNode in xmldata.findall('suggestion'):
				suggestion = suggestionNode.text
				if len(replytext) + len(suggestion) < maxMessageLength:
					replytext += suggestion + '; '
			replytext = replytext[:-2]  #Remove the last semicolon
			return message.reply(replytext)

		#Check if there are any definitions
		if xmldata.find('entry') is None:
			return message.reply("No definition found for '{}', sorry".format(message.message))

		#Definition(s) found. List as many as we can
		entriesSkipped = 0
		definitionsSkipped = 0
		replytext = SharedFunctions.makeTextBold(message.message) + ':'
		for entry in xmldata.findall('entry'):
			#The API returns terms containing the search term too. If the entry isn't literally the search term, skip it
			entryword = entry.find('ew').text.lower()
			if entryword != searchQuery:
				continue
			#First check if the required fields exist
			if entry.find('fl') is None:
				#Maybe it suggests an alternative spelling?
				cognate = entry.find('cx')
				if cognate is None or cognate.find('cl') is None or cognate.find('ct') is None:
					continue
				replytext += " {} {}".format(cognate.find('cl').text, cognate.find('ct').text)
				continue
			#Prefix the type of word it is
			wordType = entry.find('fl').text
			if entriesSkipped > 0 and len(replytext) + len(wordType) >= maxMessageLength:
				entriesSkipped += 1
			else:
				replytext += '. [{}] '.format(wordType)
				#Now go through all the <def>initions, to get the actual definitions
				for definitionNode in entry.find('def').findall('dt'):
					definition = definitionNode.text.strip().strip(':').strip()  #Whether an item stars with a space and then a colon or vice versa is inconsistent
					if len(definition) == 0:
						continue
					if len(replytext) + len(definition) >= maxMessageLength:
						definitionsSkipped += 1
					else:
						replytext += definition + '; '
				#Check if it doesn't just end with the wordType indicator
				if replytext.endswith('] '):
					replytext = replytext[:replytext.rfind('[')].rstrip()
					entriesSkipped += 1  #Increment this because we didn't add anything from this entry
				else:
					replytext = replytext.rstrip('; ')  #Remove the trailing separator
		if entriesSkipped > 0 or definitionsSkipped > 0:
			replytext += " ({:,} skipped)".format(entriesSkipped + definitionsSkipped)

		message.reply(replytext)
<commit_msg>[DictLookup] Undo word type separator display change<commit_after>import xml.etree.ElementTree as ElementTree

import requests

from CommandTemplate import CommandTemplate
import GlobalStore
import SharedFunctions

class Command(CommandTemplate):
	triggers = ['define', 'dictionary', 'dict', 'word']
	helptext = "Looks up the definition of the provided word"

	def execute(self, message):
		"""
		:type message: IrcMessage.IrcMessage
		"""

		#First check if we have the required data
		if 'dictionarylookup' not in GlobalStore.commandhandler.apikeys:
			self.logError("[Dictionary] No API key for DictionaryLookup found!")
			return message.reply("Sorry, I don't seem to have the key required to be able to use this module. Inform my owner, they'll fix it!")
		if message.messagePartsLength == 0:
			return message.reply("Look up which word? I'm not just going to pick a random one")

		searchQuery = message.message.lower()
		#Retrieve the definition
		apireply = requests.get('http://www.dictionaryapi.com/api/v1/references/collegiate/xml/{}?key={}'.format(searchQuery, GlobalStore.commandhandler.apikeys['dictionarylookup']))
		xmltext = apireply.text.encode('utf8')
		#<fw> tags are useless and mess everything up. They're links to other definitions on the site, but in here they just confuse the XML parser
		#There's also a few fields only used to indicate a certain layout. Remove those too
		for field in ('fw', 'd_link', 'i_link', 'dx_ety', 'dx_def', 'it', 'bold', 'bit'):
			xmltext = xmltext.replace('<{}>'.format(field), '').replace('</{}>'.format(field), '')
		xmldata = ElementTree.fromstring(xmltext)

		maxMessageLength = 290

		#Check if we have actual results or if the user made a typo or something. If there is one or more 'suggestion' entry, it's not an existing word
		if xmldata.find('suggestion') is not None:
			replytext = "That term doesn't seem to exist. Did you perhaps mean: "
			#List all the suggestions, at least until we run out of room
			for suggestionNode in xmldata.findall('suggestion'):
				suggestion = suggestionNode.text
				if len(replytext) + len(suggestion) < maxMessageLength:
					replytext += suggestion + '; '
			replytext = replytext[:-2]  #Remove the last semicolon
			return message.reply(replytext)

		#Check if there are any definitions
		if xmldata.find('entry') is None:
			return message.reply("No definition found for '{}', sorry".format(message.message))

		#Definition(s) found. List as many as we can
		entriesSkipped = 0
		definitionsSkipped = 0
		replytext = SharedFunctions.makeTextBold(message.message) + ':'
		for entry in xmldata.findall('entry'):
			#The API returns terms containing the search term too. If the entry isn't literally the search term, skip it
			entryword = entry.find('ew').text.lower()
			if entryword != searchQuery:
				continue
			#First check if the required fields exist
			if entry.find('fl') is None:
				#Maybe it suggests an alternative spelling?
				cognate = entry.find('cx')
				if cognate is None or cognate.find('cl') is None or cognate.find('ct') is None:
					continue
				replytext += " {} {}".format(cognate.find('cl').text, cognate.find('ct').text)
				continue
			#Prefix the type of word it is
			wordType = entry.find('fl').text
			if entriesSkipped > 0 and len(replytext) + len(wordType) >= maxMessageLength:
				entriesSkipped += 1
			else:
				replytext += ' [{}] '.format(wordType)
				#Now go through all the <def>initions, to get the actual definitions
				for definitionNode in entry.find('def').findall('dt'):
					definition = definitionNode.text.strip().strip(':').strip()  #Whether an item stars with a space and then a colon or vice versa is inconsistent
					if len(definition) == 0:
						continue
					if len(replytext) + len(definition) >= maxMessageLength:
						definitionsSkipped += 1
					else:
						replytext += definition + '; '
				#Check if it doesn't just end with the wordType indicator
				if replytext.endswith('] '):
					replytext = replytext[:replytext.rfind('[')].rstrip()
					entriesSkipped += 1  #Increment this because we didn't add anything from this entry
				else:
					replytext = replytext.rstrip('; ')  #Remove the trailing separator
		if entriesSkipped > 0 or definitionsSkipped > 0:
			replytext += " ({:,} skipped)".format(entriesSkipped + definitionsSkipped)

		message.reply(replytext)
<|endoftext|>


<commit_before># inspired from:
# https://python-packaging-user-guide.readthedocs.org/en/latest/single_source_version/
# https://github.com/pypa/warehouse/blob/master/warehouse/__about__.py

__title__ = 'spacy'
__version__ = '1.8.1'
__summary__ = 'Industrial-strength Natural Language Processing (NLP) with Python and Cython'
__uri__ = 'https://spacy.io'
__author__ = 'Matthew Honnibal'
__email__ = 'matt@explosion.ai'
__license__ = 'MIT'

__docs__ = 'https://spacy.io/docs/usage'
__download_url__ = 'https://github.com/explosion/spacy-models/releases/download'
__compatibility__ = 'https://raw.githubusercontent.com/explosion/spacy-models/master/compatibility.json'
__shortcuts__ = 'https://raw.githubusercontent.com/explosion/spacy-models/master/shortcuts.json'
<commit_msg>Increment version<commit_after># inspired from:
# https://python-packaging-user-guide.readthedocs.org/en/latest/single_source_version/
# https://github.com/pypa/warehouse/blob/master/warehouse/__about__.py

__title__ = 'spacy'
__version__ = '1.8.2'
__summary__ = 'Industrial-strength Natural Language Processing (NLP) with Python and Cython'
__uri__ = 'https://spacy.io'
__author__ = 'Matthew Honnibal'
__email__ = 'matt@explosion.ai'
__license__ = 'MIT'

__docs__ = 'https://spacy.io/docs/usage'
__download_url__ = 'https://github.com/explosion/spacy-models/releases/download'
__compatibility__ = 'https://raw.githubusercontent.com/explosion/spacy-models/master/compatibility.json'
__shortcuts__ = 'https://raw.githubusercontent.com/explosion/spacy-models/master/shortcuts.json'
<|endoftext|>


<commit_before>from util import preprocess as pp

class seq2seq_contrib:
    def __init__(self):
        #(vocab_size, embedding_dim, embedding , X, Y)
        ''' X is now an id array mapping to word embedding', Y is just the text of labels'''
        (self.vocab_size, self.embedding_dim, self.embedding , self.X, self.Y) = pp.read_from_csv()

<commit_msg>move code into src folder<commit_after>from util import preprocess as pp
import tensorflow as tf
from model import Seq2SeqModel
from tensorflow.contrib.rnn import LSTMCell, GRUCell

class seq2seq_contrib:
    def __init__(self):
        #(vocab_size, embedding_dim, embedding , X, Y)
        ''' X is now an id array mapping to word embedding', Y is just the text of labels'''
        (self.vocab_size, self.embedding_dim, self.embedding , self.X, self.Y) = pp.read_from_csv()
        self.hidden_units_encoder = 10 #number of hidden units

    def tf_session(self):
        with tf.session() as session:
            model =  Seq2SeqModel(
                        encoder_cell=LSTMCell(input_size=self.hidden_units_encoder),
                        decoder_cell=LSTMCell(input_size=self.hidden_units_encoder),
                        vocab_size=self.vocab_size,
                        attention=True,
                        bidirectional=True,
                        debug=False
            )

         # Word Embedding Initialiser
            W = tf.Variable(tf.constant(0.0, shape=[self.vocab_size, self.embedding_dim]),
                        trainable=False, name="W")
            embedding_placeholder = tf.placeholder(tf.float32, [self.vocab_size, self.embedding_dim])
            embedding_init = W.assign(embedding_placeholder)
            req_embedded = tf.nn.embedding_lookup(W, self.X)

            session.run(tf.global_variables_initializer())

            #global vars initialised

            # Call the session
            #session.run(embedding_init, feed_dict={embedding_placeholder: self.embedding})
            #vectors = req_embedded.eval()

<|endoftext|>