def retrieve_user_mobility_data_single_user(dbcc, user_id, current_date, predicted_date):
    history_date = calculate_mp_history_date(current_date)

    current_week_date_range = support.unix_weeks_timestamp_to_date_range(
        support.date_to_unix_weeks_timestamp(current_date)
    )
    history_week_date_range = support.unix_weeks_timestamp_to_date_range(
        support.date_to_unix_weeks_timestamp(history_date)
    )
    begin_of_history_week = history_week_date_range.min_range
    end_of_current_week = current_week_date_range.max_range

    current_day = support.calc_day(current_date)
    predicted_day = support.calc_day(predicted_date)
    applicable_days = support.difference_of_days(current_day, predicted_day)

    con = dbcc.retrieve_connection(db_layout.MPFetched.database_name)
    select = "*"
    table = db_layout.MPFetched.table_name
    layout_dict = dict(db_layout.MPFetched.layout)
    user_id_sql = layout_dict["user_id"].format_to_db_value(user_id)
    end_date_sql = layout_dict["date"].format_to_db_value(end_of_current_week)
    start_date_sql = layout_dict["date"].format_to_db_value(begin_of_history_week)
    applicable_days_sql = map(layout_dict["day"].format_to_db_value, applicable_days)

    applicable_days_query = " AND (day = " + " OR day = ".join(applicable_days_sql) + ")"

    where_query = (
        "WHERE user_id = "
        + user_id_sql
        + " AND date <= "
        + end_date_sql
        + " AND date >= "
        + start_date_sql
        + applicable_days_query
    )

    err.log_error(err.INFO, "Retrieving data for MP between " + str(history_date) + " and " + str(current_date))
    mysql_rows = con.retrieve(select, table, where_query)

    result = []
    for mysql_row in mysql_rows:
        result.append(db_layout.MPFetched.object_from_mysql_row(dbcc, mysql_row))

    return result
def retrieve_user_mobility_data_single_user(dbcc, user_id, current_date,
                                            predicted_date):
    history_date = calculate_mp_history_date(current_date)

    current_week_date_range = support.unix_weeks_timestamp_to_date_range(
        support.date_to_unix_weeks_timestamp(current_date))
    history_week_date_range = support.unix_weeks_timestamp_to_date_range(
        support.date_to_unix_weeks_timestamp(history_date))
    begin_of_history_week = history_week_date_range.min_range
    end_of_current_week = current_week_date_range.max_range

    current_day = support.calc_day(current_date)
    predicted_day = support.calc_day(predicted_date)
    applicable_days = support.difference_of_days(current_day, predicted_day)

    con = dbcc.retrieve_connection(db_layout.MPFetched.database_name)
    select = "*"
    table = db_layout.MPFetched.table_name
    layout_dict = dict(db_layout.MPFetched.layout)
    user_id_sql = layout_dict["user_id"].format_to_db_value(user_id)
    end_date_sql = layout_dict["date"].format_to_db_value(end_of_current_week)
    start_date_sql = layout_dict["date"].format_to_db_value(
        begin_of_history_week)
    applicable_days_sql = map(layout_dict["day"].format_to_db_value,
                              applicable_days)

    applicable_days_query = " AND (day = " + " OR day = ".join(
        applicable_days_sql) + ")"

    where_query = ("WHERE user_id = " + user_id_sql + " AND date <= " +
                   end_date_sql + " AND date >= " + start_date_sql +
                   applicable_days_query)

    err.log_error(
        err.INFO, "Retrieving data for MP between " + str(history_date) +
        " and " + str(current_date))
    mysql_rows = con.retrieve(select, table, where_query)

    result = []
    for mysql_row in mysql_rows:
        result.append(
            db_layout.MPFetched.object_from_mysql_row(dbcc, mysql_row))

    return result
def prepare_pykov_chain_with_single_user_mobility_states(
    grouped_by_date_grid_by_minute_of_day_mp_fetched, current_day_str, predicted_day_str
):
    list_of_day_str_applicable = support.difference_of_days(current_day_str, predicted_day_str)

    from_to_user_entry_dict = {}
    for date, grid_by_minute_of_day_mp_fetched in grouped_by_date_grid_by_minute_of_day_mp_fetched.items():
        if support.calc_day(date) in list_of_day_str_applicable:

            # It seems this day is a contender in the prediction.
            # For each minute of the day look at the cell id(source) and look at the next because that is the destination
            # Each pair of source and destination should be added to the from_to user_entry_dict (date doesn't matter anymore as link is formed)
            # Using the source as the key and adding the destination to the list

            i = 0
            for source_mp_fetched in grid_by_minute_of_day_mp_fetched:
                if i == common_config.MINUTES_IN_A_DAY - 1:
                    # We have reached the end of the day, must look at the next if possible in the next day

                    next_date = date + support.Range.RESOLUTION_DATETIME_DAY
                    if support.calc_day(next_date) in list_of_day_str_applicable:
                        # It seems the adjoining day is also a contender in the prediction. Configure the destination correctly
                        destination_mp_fetched = grouped_by_date_grid_by_minute_of_day_mp_fetched[next_date][0]
                    else:
                        # There is no connection to the next day
                        destination_mp_fetched = None
                else:
                    # In the middle of the day, destination is next in the grid
                    destination_mp_fetched = grid_by_minute_of_day_mp_fetched[i + 1]

                if destination_mp_fetched:
                    source_user_entry = UserEntry(
                        source_mp_fetched.day, source_mp_fetched.minute_of_day, source_mp_fetched.cell_id
                    )
                    destination_user_entry = UserEntry(
                        destination_mp_fetched.day, destination_mp_fetched.minute_of_day, destination_mp_fetched.cell_id
                    )

                    # Add it to the from to user entry dict but with the source_user_entry as key
                    # Add it as a key if it doesn't exist yet
                    if source_user_entry in from_to_user_entry_dict:
                        from_to_user_entry_dict[source_user_entry].append(destination_user_entry)
                    else:
                        from_to_user_entry_dict[source_user_entry] = [destination_user_entry]

                i += 1

    # Calculate all percentages the same from and to user entry coincide
    pykov_chain_entries = {}
    for starting_user_entry, destinations in from_to_user_entry_dict.items():
        starting_key = starting_user_entry.to_pykov_key()
        total_amount = float(len(destinations))
        grouped_by_cell_id = support.group_by(destinations, lambda user_entry: user_entry.cell_id)

        for destination_cell_id, destinations_with_same_cell_id in grouped_by_cell_id.items():
            destination_key = destinations_with_same_cell_id[0].to_pykov_key()
            amount_of_destinations_with_same_cell_id = len(destinations_with_same_cell_id)
            percentage = float(amount_of_destinations_with_same_cell_id) / total_amount

            pykov_chain_entries[starting_key, destination_key] = percentage

    return pykov.Chain(pykov_chain_entries)
def prepare_pykov_chain_with_single_user_mobility_states(
        grouped_by_date_grid_by_minute_of_day_mp_fetched, current_day_str,
        predicted_day_str):
    list_of_day_str_applicable = support.difference_of_days(
        current_day_str, predicted_day_str)

    from_to_user_entry_dict = {}
    for date, grid_by_minute_of_day_mp_fetched in grouped_by_date_grid_by_minute_of_day_mp_fetched.items(
    ):
        if support.calc_day(date) in list_of_day_str_applicable:

            #It seems this day is a contender in the prediction.
            #For each minute of the day look at the cell id(source) and look at the next because that is the destination
            #Each pair of source and destination should be added to the from_to user_entry_dict (date doesn't matter anymore as link is formed)
            #Using the source as the key and adding the destination to the list

            i = 0
            for source_mp_fetched in grid_by_minute_of_day_mp_fetched:
                if i == common_config.MINUTES_IN_A_DAY - 1:
                    #We have reached the end of the day, must look at the next if possible in the next day

                    next_date = date + support.Range.RESOLUTION_DATETIME_DAY
                    if support.calc_day(
                            next_date) in list_of_day_str_applicable:
                        #It seems the adjoining day is also a contender in the prediction. Configure the destination correctly
                        destination_mp_fetched = grouped_by_date_grid_by_minute_of_day_mp_fetched[
                            next_date][0]
                    else:
                        #There is no connection to the next day
                        destination_mp_fetched = None
                else:
                    #In the middle of the day, destination is next in the grid
                    destination_mp_fetched = grid_by_minute_of_day_mp_fetched[
                        i + 1]

                if destination_mp_fetched:
                    source_user_entry = UserEntry(
                        source_mp_fetched.day, source_mp_fetched.minute_of_day,
                        source_mp_fetched.cell_id)
                    destination_user_entry = UserEntry(
                        destination_mp_fetched.day,
                        destination_mp_fetched.minute_of_day,
                        destination_mp_fetched.cell_id)

                    #Add it to the from to user entry dict but with the source_user_entry as key
                    #Add it as a key if it doesn't exist yet
                    if source_user_entry in from_to_user_entry_dict:
                        from_to_user_entry_dict[source_user_entry].append(
                            destination_user_entry)
                    else:
                        from_to_user_entry_dict[source_user_entry] = [
                            destination_user_entry
                        ]

                i += 1

    #Calculate all percentages the same from and to user entry coincide
    pykov_chain_entries = {}
    for starting_user_entry, destinations in from_to_user_entry_dict.items():
        starting_key = starting_user_entry.to_pykov_key()
        total_amount = float(len(destinations))
        grouped_by_cell_id = support.group_by(
            destinations, lambda user_entry: user_entry.cell_id)

        for destination_cell_id, destinations_with_same_cell_id in grouped_by_cell_id.items(
        ):
            destination_key = destinations_with_same_cell_id[0].to_pykov_key()
            amount_of_destinations_with_same_cell_id = len(
                destinations_with_same_cell_id)
            percentage = float(
                amount_of_destinations_with_same_cell_id) / total_amount

            pykov_chain_entries[starting_key, destination_key] = percentage

    return pykov.Chain(pykov_chain_entries)