<commit_before>"""Ladybug data collection."""
from .header import Header
from .datatype import DataPoint

from collections import OrderedDict

try:
    from itertools import izip as zip
except ImportError:
    # python 3
    xrange = range


class DataCollection(object):
    """A list of data with a header."""

    __slots__ = ('_header', '_data')

    def __init__(self, data=None, header=None):
        """Init class."""
        self.header = header

        if not data:
            data = []
        elif not hasattr(data, '__iter__'):
            assert hasattr(data, 'isDataPoint'), \
                'Expected DataPoint got {}'.format(type(data))
            data = [data]

        for d in data:
            assert hasattr(d, 'isDataPoint'), \
                'Expected DataPoint got {}'.format(type(d))

        self._data = list(data)

    @classmethod
    def from_json(cls, data):
        """Create a data collection from a dictionary.

        Args:
            {
                "data": [], //An array of Ladybug data points,
                "header": {} // A Ladybug header
            }
        """
        if 'data' not in data:
            input_data = []
        else:
            input_data = [DataPoint.from_json(d) for d in data['data']]

        if 'header' not in data:
            data['header'] = {}

        return cls(input_data, Header.from_json(data['header']))

    @classmethod
    def from_list(cls, lst, location=None, data_type=None, unit=None,
                  analysis_period=None):
        """Create a data collection from a list.

        lst items can be DataPoint or other values.

        Args:
            lst: A list of data.
            location: location data as a ladybug Location or location string
                (Default: unknown).
            data_type: Type of data (e.g. Temperature) (Default: unknown).
            unit: data_type unit (Default: unknown).
            analysis_period: A Ladybug analysis period (Defualt: None)
        """
        header = Header(location, data_type, unit, analysis_period)
        if analysis_period:
            return cls.from_data_and_datetimes(lst, analysis_period.datetimes, header)
        else:
            data = tuple(DataPoint.from_data(d) for d in lst)
            return cls(data, header)

    @classmethod
    def from_data_and_datetimes(cls, data, datetimes, header=None):
        """Create a list from data and dateteimes."""
        _d = tuple(DataPoint(v, d) for v, d in zip(data, datetimes))
        return cls(_d, header)

    @classmethod
    def from_data_and_analysis_period(cls, data, analysis_period, header=None):
        """Create a list from data and analysis period."""
        return cls.from_data_and_datetimes(data, analysis_period.datetimes, header)

    @property
    def header(self):
        """Get or set header."""
        return self._header

    @header.setter
    def header(self, h):
        self._header = None if not h else Header.from_header(h)

    def append(self, d):
        """Append a single item to the list."""
        assert hasattr(d, 'isDataPoint'), \
            'Expected DataPoint got {}'.format(type(d))
        self._data.append(d)

    def extend(self, new_data):
        """Extend a number of items to the end of items."""
        for d in new_data:
            assert hasattr(d, 'isDataPoint'), \
                'Expected DataPoint got {}'.format(type(d))
        self._data.extend(new_data)

    def insert(self, i, d):
        """Insert an item at a given position."""
        assert hasattr(d, 'isDataPoint'), \
            'Expected DataPoint got {}'.format(type(d))
        assert isinstance(i, int), \
            'Expected Integer got {}'.format(type(i))
        self._data.insert(i, d)

    def pop(self, i=-1):
        """Remove the item at the given position in the data collection, and return it.

        If no index is specified, a.pop() removes and returns the last
        item in the list.
        """
        assert isinstance(i, int), \
            'Expected Integer got {}'.format(type(i))
        assert i < len(self._data), \
            'Item({}) is larger than the length of the data collection({})' \
            .format(i, len(self._data))
        return self._data.pop(i)

    @property
    def datetimes(self):
        """Return datetimes for this collection as a tuple."""
        return tuple(value.datetime for value in self)

    @property
    def values(self):
        """Return the list of values."""
        return self._data

    def duplicate(self):
        """Duplicate current data list."""
        return DataCollection(self.values, self.header)

    @staticmethod
    def average(data):
        """Return average value for a list of ladybug data."""
        values = (value.value for value in data)
        return sum(values) / len(data)

    def get_highest_values(self, count):
        """Find highest values in a list of DataPoints
        
        Args:
            data: A list of DataPoint to be processed
            count: Number of highest values to account for
            
        Return:
            highest_values: The n highest values in data list, ordered from
                highest to lowest
            highest_values_index: Indicies of the n highest values in data 
                list, ordered from highest to lowest
        """
        dataPoints = self._data
        
        values = [obj._value for obj in dataPoints]
        
        lenght_values = len(values)
        
        count = int(count)
        
        assert count <= lenght_values, \
            'Count must be equal to or smaller than list of data lenght'
            
        assert count > 0, \
            'Count must be higher than zero'
        
        highest_values = sorted(values, reverse = True)[0:count]
        
        highest_values_index = sorted(range(lenght_values), 
                                      key = lambda k: values[k],
                                      reverse = True)[0:count]
        
        return highest_values, highest_values_index

    @staticmethod
    def group_data_by_month(data, month_range=xrange(1, 13)):
        """Return a dictionary of values where values are grouped for each month.
<commit_msg>Post workshop changes<commit_after>"""Ladybug data collection."""
from .header import Header
from .datatype import DataPoint

from collections import OrderedDict

try:
    from itertools import izip as zip
except ImportError:
    # python 3
    xrange = range


class DataCollection(object):
    """A list of data with a header."""

    __slots__ = ('_header', '_data')

    def __init__(self, data=None, header=None):
        """Init class."""
        self.header = header

        if not data:
            data = []
        elif not hasattr(data, '__iter__'):
            assert hasattr(data, 'isDataPoint'), \
                'Expected DataPoint got {}'.format(type(data))
            data = [data]

        for d in data:
            assert hasattr(d, 'isDataPoint'), \
                'Expected DataPoint got {}'.format(type(d))

        self._data = list(data)

    @classmethod
    def from_json(cls, data):
        """Create a data collection from a dictionary.

        Args:
            {
                "data": [], //An array of Ladybug data points,
                "header": {} // A Ladybug header
            }
        """
        if 'data' not in data:
            input_data = []
        else:
            input_data = [DataPoint.from_json(d) for d in data['data']]

        if 'header' not in data:
            data['header'] = {}

        return cls(input_data, Header.from_json(data['header']))

    @classmethod
    def from_list(cls, lst, location=None, data_type=None, unit=None,
                  analysis_period=None):
        """Create a data collection from a list.

        lst items can be DataPoint or other values.

        Args:
            lst: A list of data.
            location: location data as a ladybug Location or location string
                (Default: unknown).
            data_type: Type of data (e.g. Temperature) (Default: unknown).
            unit: data_type unit (Default: unknown).
            analysis_period: A Ladybug analysis period (Defualt: None)
        """
        header = Header(location, data_type, unit, analysis_period)
        if analysis_period:
            return cls.from_data_and_datetimes(lst, analysis_period.datetimes, header)
        else:
            data = tuple(DataPoint.from_data(d) for d in lst)
            return cls(data, header)

    @classmethod
    def from_data_and_datetimes(cls, data, datetimes, header=None):
        """Create a list from data and dateteimes."""
        _d = tuple(DataPoint(v, d) for v, d in zip(data, datetimes))
        return cls(_d, header)

    @classmethod
    def from_data_and_analysis_period(cls, data, analysis_period, header=None):
        """Create a list from data and analysis period."""
        return cls.from_data_and_datetimes(data, analysis_period.datetimes, header)

    @property
    def header(self):
        """Get or set header."""
        return self._header

    @header.setter
    def header(self, h):
        self._header = None if not h else Header.from_header(h)

    def append(self, d):
        """Append a single item to the list."""
        assert hasattr(d, 'isDataPoint'), \
            'Expected DataPoint got {}'.format(type(d))
        self._data.append(d)

    def extend(self, new_data):
        """Extend a number of items to the end of items."""
        for d in new_data:
            assert hasattr(d, 'isDataPoint'), \
                'Expected DataPoint got {}'.format(type(d))
        self._data.extend(new_data)

    def insert(self, i, d):
        """Insert an item at a given position."""
        assert hasattr(d, 'isDataPoint'), \
            'Expected DataPoint got {}'.format(type(d))
        assert isinstance(i, int), \
            'Expected Integer got {}'.format(type(i))
        self._data.insert(i, d)

    def pop(self, i=-1):
        """Remove the item at the given position in the data collection, and return it.

        If no index is specified, a.pop() removes and returns the last
        item in the list.
        """
        assert isinstance(i, int), \
            'Expected Integer got {}'.format(type(i))
        assert i < len(self._data), \
            'Item({}) is larger than the length of the data collection({})' \
            .format(i, len(self._data))
        return self._data.pop(i)

    @property
    def datetimes(self):
        """Return datetimes for this collection as a tuple."""
        return tuple(value.datetime for value in self)

    @property
    def values(self):
        """Return the list of values."""
        return self._data

    def duplicate(self):
        """Duplicate current data list."""
        return DataCollection(self.values, self.header)

    @staticmethod
    def average(data):
        """Return average value for a list of ladybug data."""
        values = (value.value for value in data)
        return sum(values) / len(data)

    def get_highest_values(self, count):
        """Find highest values in a list of DataPoints
        
        Args:
            data: A list of DataPoint to be processed
            count: Number of highest values to account for
            
        Return:
            highest_values: The n highest values in data list, ordered from
                highest to lowest
            highest_values_index: Indicies of the n highest values in data 
                list, ordered from highest to lowest
        """
        data_points = self._data
        
        values = [obj._value for obj in data_points]
        
        lenght_values = len(values)
        
        count = int(count)
        
        assert count <= lenght_values, \
            'Count must be equal to or smaller than list of data lenght'
            
        assert count > 0, \
            'Count must be higher than zero'
        
        highest_values = sorted(values, reverse = True)[0:count]
        
        highest_values_index = sorted(range(lenght_values), 
                                      key = lambda k: values[k],
                                      reverse = True)[0:count]
        
        return highest_values, highest_values_index

    @staticmethod
    def group_data_by_month(data, month_range=xrange(1, 13)):
        """Return a dictionary of values where values are grouped for each month.

{'fraction_non_alphanumeric': 0.09931122857600512, 'fraction_numerical': 0.0012814352074323242, 'mean_word_length': 1.978058669210589, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1042444', 'n_tokens_mistral': 3445, 'n_tokens_neox': 3328, 'n_words': 1154}