def _get_history_data(instance, country_province, column_label):
    """
    History of all the available cases for the given data.
    If no change can be calculated value = 'na' is assigned
    :param instance: instance of the class
    :param country_province: str
    :param column_label: str
    :return: dict
    """
    _country_province_id = h.convert_label_to_id(country_province)
    result = dict()

    for _action in instance._actions_files:
        reader = instance.get_reader(_action)
        for row in reader:
            _country = h.convert_label_to_id(row.get(column_label))
            # if given country
            if _country_province_id == _country:
                # If country exists in dict
                if _country_province_id in result:
                    _previous_value = ''
                    # Update the existing dict and calculate change in value
                    result = _update_history(row, result, _country_province_id, _action, _previous_value)
                else:
                    # Only executed for the action = confirmed (for the first time)
                    # new data
                    result[_country_province_id] = dict()
                    result[_country_province_id]['label'] = row.get(column_label)
                    result[_country_province_id]['lat'] = row.get('Lat')
                    result[_country_province_id]['long'] = row.get('Long')
                    result[_country_province_id]['history'] = dict()
                    _previous_value = ''

                    for key in row:
                        try:
                            _item = str(parse(key))
                            _current_value = row.get(key)
                            _history = result[_country_province_id]['history']
                            _history[_item] = dict()
                            _history[_item][_action] = int(_current_value)
                            # Calculate the change in value
                            _history[_item]["change_{}".format(_action)] = h.calculate_change(
                                _current_value, _previous_value)

                            # Assign previous value to current to calculate the next change
                            _previous_value = _current_value
                        except Exception as e:
                            pass
    if result:
        return result
    else:
        raise errors.CountryNotFound("Given {} not found".format(column_label))
def get_all_records_by_provinces(instance):
    """
    Collect all the data if the province column is not null and get corresponding latitude and longitude data
    :param instance: class instance
    :return: dict
    """

    result = dict()

    for _action in instance._actions_files.keys():
        reader = instance.get_reader(_action)
        for row in reader:
            _province_label = row.get('Province/State')
            if _province_label:
                _province = h.convert_label_to_id(_province_label)
                _key = list(row.keys())[-1]
                _val = int(row.get(_key))
                # Aggregation
                if _province in result:
                    _province_data = result.get(_province)
                    if _action in _province_data:
                        _province_data[_action] += _val
                    else:
                        _province_data[_action] = _val
                else:
                    # Data model for the new record
                    result[_province] = dict()
                    result[_province][_action] = _val
                    result[_province]['label'] = _province_label
                    result[_province]['country'] = row.get('Country/Region')
                    result[_province]['lat'] = row.get('Lat')
                    result[_province]['long'] = row.get('Long')
                    result[_province]['last_updated'] = str(parse(_key))

    return result
def get_all_records_by_country(instance):
    """
    Collect all confirmed, recovered and deaths for all the countries
    :param instance: class instance
    :return: dict
    """
    result = dict()

    for _action in instance._actions_files.keys():
        reader = instance.get_reader(_action)
        # Dict reader of the respective action
        for row in reader:
            # Country id
            _country = h.convert_label_to_id(row.get('Country/Region'))
            # Latest value i.e. last column of the ordered dict
            _key = list(row.keys())[-1]
            _val = int(row.get(_key))

            # Aggregation
            if _country in result:
                _cnty_data = result.get(_country)
                if _action in _cnty_data:
                    _cnty_data[_action] += _val
                else:
                    _cnty_data[_action] = _val
            else:
                # Data model for the new record
                result[_country] = dict()
                result[_country][_action] = _val
                result[_country]['label'] = row.get('Country/Region')
                result[_country]['last_updated'] = str(parse(_key))
                result[_country]['lat'] = row.get('Lat')
                result[_country]['long'] = row.get('Long')
    return result
def filter_by_country(instance, country):
    """
    Show the record given country name
    :param instance: instance of the class
    :param country: str
    :return: dict
    """
    if not country:
        raise errors.ValidationError("Missing parameter country")

    _countries = get_all_records_by_country(instance)
    country_id = h.convert_label_to_id(country)

    for _country in _countries:
        if country_id == _country:
            res = _countries.get(_country)
            return res
    raise errors.CountryNotFound(
        "Given country not found. "
        "Run available countries method to see all available countries")
def filter_by_province(instance, province):
    """
    Show record for the given province.
    :param instance: instance of the class
    :param province: str
    :return: dict
    """
    if not province:
        raise errors.ValidationError("Missing value province")

    _provinces = get_all_records_by_provinces(instance)
    province_id = h.convert_label_to_id(province)

    for _province in _provinces:
        if province_id == _province:
            res = _provinces.get(province_id)
            return res

    raise errors.ProvinceNotFound(
        "Given province not found. "
        "Run available provinces method to see all available provinces")