<commit_before># coding=utf-8
"""Base class for Ladybug Data Collections."""

from __future__ import division

from .header import Header

from collections import Iterable
from string import ascii_lowercase
import math
import sys
if (sys.version_info >= (3, 0)):
    xrange = range


class BaseCollection(object):
    """Base class for all Data Collections."""

    __slots__ = ('_header', '_values', '_datetimes')

    def __init__(self, header, values, datetimes):
        """Initialize base collection.

        Args:
            header: A Ladybug Header object.
            values: A list of values.
            datetimes: A list of Ladybug DateTime objects that aligns with
                the list of values.
        """
        assert isinstance(header, Header), \
            'header must be a Ladybug Header object. Got {}'.format(type(header))
        assert isinstance(datetimes, Iterable) \
            and not isinstance(datetimes, (str, dict)), \
            'datetimes should be a list or tuple. Got {}'.format(type(datetimes))
        datetimes = list(datetimes)

        self._header = header
        self._datetimes = datetimes
        self.values = values

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

        Args:
            {
                "header": A Ladybug Header,
                "values": An array of values,
                "datetimes": An array of datetimes
            }
        """
        assert 'header' in data, 'Required keyword "header" is missing!'
        assert 'values' in data, 'Required keyword "values" is missing!'
        assert 'datetimes' in data, 'Required keyword "datetimes" is missing!'
        return cls(Header.from_json(data['header']), data['values'], data['datetimes'])

    @property
    def header(self):
        """Return the header for this collection."""
        return self._header

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

    @property
    def values(self):
        """Return the Data Collection's list of numerical values."""
        return tuple(self._values)

    @values.setter
    def values(self, values):
        assert isinstance(values, Iterable) and not isinstance(values, (str, dict)), \
            'values should be a list or tuple. Got {}'.format(type(values))
        values = list(values)
        assert len(values) == len(self.datetimes), \
            'Length of values list must match length of datetimes list. {} != {}'.format(
                len(values), len(self.datetimes))
        self._values = values

    @property
    def bounds(self):
        """Return a tuple as (min, max)."""
        return (min(self._values), max(self._values))

    @property
    def min(self):
        """Return the min of the Data Collection values."""
        return min(self._values)

    @property
    def max(self):
        """Return the max of the Data Collection values."""
        return max(self._values)

    @property
    def average(self):
        """Return the average of the Data Collection values."""
        return sum(self._values) / len(self._values)

    @property
    def median(self):
        """Return the median of the Data Collection values."""
        return self._percentile(self._values, 50)

    @property
    def total(self):
        """Return the total of the Data Collection values."""
        return sum(self._values)

    def convert_to_unit(self, unit):
        """Convert the Data Collection to the input unit."""
        self._values = self._header.data_type.to_unit(
            self._values, unit, self._header.unit)
        self._header._unit = unit

    def convert_to_ip(self):
        """Convert the Data Collection to IP units."""
        self._values, self._header._unit = self._header.data_type.to_ip(
                self._values, self._header.unit)

    def convert_to_si(self):
        """Convert the Data Collection to SI units."""
        self._values, self._header._unit = self._header.data_type.to_si(
                self._values, self._header.unit)

    def to_unit(self, unit):
        """Return a Data Collection in the input unit."""
        new_data_c = self.duplicate()
        new_data_c.convert_to_unit(unit)
        return new_data_c

    def to_ip(self):
        """Return a Data Collection in IP units."""
        new_data_c = self.duplicate()
        new_data_c.convert_to_ip()
        return new_data_c

    def to_si(self):
        """Return a Data Collection in SI units."""
        new_data_c = self.duplicate()
        new_data_c.convert_to_si()
        return new_data_c

    def get_highest_values(self, count):
        """Get a list of the the x highest values of the Data Collection and their indices.

        Args:
            count: Integer representing the number of highest values to account for.

        Returns:
            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.
        """
        count = int(count)
        assert count <= len(self._values), \
            'count must be smaller than or equal to values length. {} > {}.'.format(
                count, len(self._values))
        assert count > 0, \
            'count must be greater than 0. Got {}.'.format(count)
        highest_values = sorted(self._values, reverse=True)[0:count]
        highest_values_index = sorted(list(xrange(len(self._values))),
                                      key=lambda k: self._values[k],
                                      reverse=True)[0:count]
        return highest_values, highest_values_index

    def get_lowest_values(self, count):
        """Get a list of the the x lowest values of the Data Collection and their indices.

        Args:
            count: Integer representing the number of lowest values to account for.

        Returns:
            highest_values: The n lowest values in data list, ordered from
                lowest to lowest.
            lowest_values_index: Indicies of the n lowest values in data
                list, ordered from lowest to lowest.
        """
        count = int(count)
        assert count <= len(self._values), \
            'count must be <= to Data Collection len. {} > {}.'.format(
                count, len(self._values))
        assert count > 0, \
            'count must be greater than 0. Got {}.'.format(count)
        lowest_values = sorted(self._values)[0:count]
        lowest_values_index = sorted(list(xrange(len(self._values))),<commit_msg>Embellishing Docstring of highest and lowest values<commit_after># coding=utf-8
"""Base class for Ladybug Data Collections."""

from __future__ import division

from .header import Header

from collections import Iterable
from string import ascii_lowercase
import math
import sys
if (sys.version_info >= (3, 0)):
    xrange = range


class BaseCollection(object):
    """Base class for all Data Collections."""

    __slots__ = ('_header', '_values', '_datetimes')

    def __init__(self, header, values, datetimes):
        """Initialize base collection.

        Args:
            header: A Ladybug Header object.
            values: A list of values.
            datetimes: A list of Ladybug DateTime objects that aligns with
                the list of values.
        """
        assert isinstance(header, Header), \
            'header must be a Ladybug Header object. Got {}'.format(type(header))
        assert isinstance(datetimes, Iterable) \
            and not isinstance(datetimes, (str, dict)), \
            'datetimes should be a list or tuple. Got {}'.format(type(datetimes))
        datetimes = list(datetimes)

        self._header = header
        self._datetimes = datetimes
        self.values = values

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

        Args:
            {
                "header": A Ladybug Header,
                "values": An array of values,
                "datetimes": An array of datetimes
            }
        """
        assert 'header' in data, 'Required keyword "header" is missing!'
        assert 'values' in data, 'Required keyword "values" is missing!'
        assert 'datetimes' in data, 'Required keyword "datetimes" is missing!'
        return cls(Header.from_json(data['header']), data['values'], data['datetimes'])

    @property
    def header(self):
        """Return the header for this collection."""
        return self._header

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

    @property
    def values(self):
        """Return the Data Collection's list of numerical values."""
        return tuple(self._values)

    @values.setter
    def values(self, values):
        assert isinstance(values, Iterable) and not isinstance(values, (str, dict)), \
            'values should be a list or tuple. Got {}'.format(type(values))
        values = list(values)
        assert len(values) == len(self.datetimes), \
            'Length of values list must match length of datetimes list. {} != {}'.format(
                len(values), len(self.datetimes))
        self._values = values

    @property
    def bounds(self):
        """Return a tuple as (min, max)."""
        return (min(self._values), max(self._values))

    @property
    def min(self):
        """Return the min of the Data Collection values."""
        return min(self._values)

    @property
    def max(self):
        """Return the max of the Data Collection values."""
        return max(self._values)

    @property
    def average(self):
        """Return the average of the Data Collection values."""
        return sum(self._values) / len(self._values)

    @property
    def median(self):
        """Return the median of the Data Collection values."""
        return self._percentile(self._values, 50)

    @property
    def total(self):
        """Return the total of the Data Collection values."""
        return sum(self._values)

    def convert_to_unit(self, unit):
        """Convert the Data Collection to the input unit."""
        self._values = self._header.data_type.to_unit(
            self._values, unit, self._header.unit)
        self._header._unit = unit

    def convert_to_ip(self):
        """Convert the Data Collection to IP units."""
        self._values, self._header._unit = self._header.data_type.to_ip(
                self._values, self._header.unit)

    def convert_to_si(self):
        """Convert the Data Collection to SI units."""
        self._values, self._header._unit = self._header.data_type.to_si(
                self._values, self._header.unit)

    def to_unit(self, unit):
        """Return a Data Collection in the input unit."""
        new_data_c = self.duplicate()
        new_data_c.convert_to_unit(unit)
        return new_data_c

    def to_ip(self):
        """Return a Data Collection in IP units."""
        new_data_c = self.duplicate()
        new_data_c.convert_to_ip()
        return new_data_c

    def to_si(self):
        """Return a Data Collection in SI units."""
        new_data_c = self.duplicate()
        new_data_c.convert_to_si()
        return new_data_c

    def get_highest_values(self, count):
        """Get a list of the the x highest values of the Data Collection and their indices.

        This is useful for situations where one needs to know the times of
        the year when the largest values of a data collection occur.  For example,
        there is a European dayight code that requires an analysis for the hours
        of the year with the greatest exterior illuminance level.  This method
        can be used to help build a shcedule for such a study.

        Args:
            count: Integer representing the number of highest values to account for.

        Returns:
            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.
        """
        count = int(count)
        assert count <= len(self._values), \
            'count must be smaller than or equal to values length. {} > {}.'.format(
                count, len(self._values))
        assert count > 0, \
            'count must be greater than 0. Got {}.'.format(count)
        highest_values = sorted(self._values, reverse=True)[0:count]
        highest_values_index = sorted(list(xrange(len(self._values))),
                                      key=lambda k: self._values[k],
                                      reverse=True)[0:count]
        return highest_values, highest_values_index

    def get_lowest_values(self, count):
        """Get a list of the the x lowest values of the Data Collection and their indices.

        This is useful for situations where one needs to know the times of
        the year when the smallest values of a data collection occur.

        Args:
            count: Integer representing the number of lowest values to account for.

        Returns:
            highest_values: The n lowest values in data list, ordered from
                lowest to lowest.
            lowest_values_index: Indicies of the n lowest values in data
                list, ordered from lowest to lowest.
        """
        count = int(count)
        assert count <= len(self._values), \
            'count must be <= to Data Collection len. {} > {}.'.format(
                count, len(self._values))
        assert count > 0, \
            'count must be greater than 0. Got {}.'.format(count)
        lowest_values = sorted(self._values)[0:count]
        lowest_values_index = sorted(list(xrange(len(self._values))),
{'fraction_non_alphanumeric': 0.09673492768151225, 'fraction_numerical': 0.0017184591149935558, 'mean_word_length': 2.2085917757868136, 'pattern_counts': {'":': 6, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6790398', 'n_tokens_mistral': 3720, 'n_tokens_neox': 3578, 'n_words': 1313}