Beispiel #1
0
def pivot_data(forecast_path, start_date, end_date, f_log):
    service.log('Соединение всх таблиц, группированных по месяцам в одну',
                f_log, False)
    file_name = service.naming(start_date, end_date, period_name='Month')
    service.log('Загрузка данных из таблицы остатков: ' + file_name, f_log,
                True)
    df_rest = pd.read_csv(forecast_path + file_name,
                          sep=',',
                          encoding='cp1251')
    df_rest.rename(columns={'Остаток': 'СреднийОстаток'}, inplace=True)
    file_name = service.naming(start_date,
                               end_date,
                               period_name='Month',
                               count=2)
    service.log('Загрузка данных из таблицы продаж: ' + file_name, f_log, True)
    df_sell = pd.read_csv(forecast_path + file_name,
                          sep=',',
                          encoding='cp1251')
    df_sell.rename(columns={'Whouse': 'Склад'}, inplace=True)
    df_sell.rename(columns={'Art': 'Артикул'}, inplace=True)
    df_sell.rename(columns={'Qnty': 'Продано'}, inplace=True)
    service.log('Соединение остатков и продаж', f_log, True)
    result = pd.merge(df_rest,
                      df_sell,
                      how='left',
                      on=['Артикул', 'Склад', 'Year_Month'])
    del df_sell, df_rest
    result = result.fillna(0)
    file_name = service.naming(start_date,
                               end_date,
                               period_name='Month',
                               count=3)
    service.log(
        'Загрузка данных из таблицы кол-ва дней на остатке: ' + file_name,
        f_log, True)
    df_count = pd.read_csv(forecast_path + file_name,
                           sep=',',
                           encoding='cp1251')
    service.log('Соединение остатков и продаж с количеством дней на остатке',
                f_log, True)
    result = pd.merge(result,
                      df_count,
                      how='left',
                      on=['Артикул', 'Склад', 'Year_Month'])
    result = result.fillna(0)
    result['Продано'] = np.around(result['Продано'], decimals=0)
    result = result.astype({'Продано': 'int64'})
    result['ДнейНаОстатке'] = np.around(result['ДнейНаОстатке'], decimals=0)
    result = result.astype({'ДнейНаОстатке': 'int64'})
    file_name = service.naming(start_date, end_date, count=4)
    service.log('Запись данных: ' + file_name, f_log, True)
    result.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    del df_count, result, start_date, end_date, file_name, forecast_path
Beispiel #2
0
def client_qty_by_day(request_path, forecast_path, config, start_date,
                      end_date, f_log):
    service.log('Расчет количества уникальных клиентов в день', f_log, False)
    service.log('Подключение к SQL серверу', f_log, True)
    con = pymssql.connect(host=config[0],
                          user=config[1],
                          password=config[2],
                          database=config[3])
    service.log('Подключение установлено', f_log, True)
    # Загружаем текст запроса
    f = open(request_path + 'AvgSale.txt')
    set_clqnty_request = f.read()
    f.close()
    # Загружаем фрейм
    service.log('Чтение из БД', f_log, True)
    df_clqnty = pd.read_sql(set_clqnty_request.format(start_date, end_date),
                            con)
    service.log('Чтение данных завершено', f_log, True)
    con.close()
    df_clqnty = df_clqnty.astype({'Period': 'datetime64'})
    service.log('Обработка данных', f_log, True)
    df_clqnty = pd.pivot_table(df_clqnty,
                               values='СреднийОтпуск',
                               index=['Артикул', 'Склад'],
                               aggfunc=np.mean,
                               fill_value=0)
    df_clqnty['СреднийОтпуск'] = np.around(df_clqnty['СреднийОтпуск'],
                                           decimals=2)
    df_clqnty = df_clqnty.reset_index()
    start_date = datetime.datetime.strptime(start_date.replace(",", "-"),
                                            '%Y-%m-%d').date()
    end_date = datetime.datetime.strptime(end_date.replace(",", "-"),
                                          '%Y-%m-%d').date()
    # Имя файла для записи
    file_name = service.naming(start_date, end_date, 'Day')
    service.log('Запись данных в файл: ' + file_name, f_log, True)
    df_clqnty.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    del df_clqnty, file_name
Beispiel #3
0
def aggr_sales(path, request_path, forecast_path, config, start_date, end_date,
               f_log):
    service.log('Расчет деневной статистики продаж и агрегирование по месяцам',
                f_log, False)
    service.log('Подключение к SQL серверу', f_log, True)
    con = pymssql.connect(host=config[0],
                          user=config[1],
                          password=config[2],
                          database=config[3])
    service.log('Подключение установлено', f_log, True)
    # Загружаем текст запроса
    f = open(request_path + 'requestSell.txt')
    set_sell_request = f.read()
    f.close()
    # Загружаем фрейм
    service.log('Чтение из БД', f_log, True)
    df_sell = pd.read_sql(set_sell_request.format(start_date, end_date), con)
    service.log('Чтение данных завершено', f_log, True)
    df_sell = df_sell.astype({'Period': 'datetime64'})
    con.close()
    # Формирование даты из строки для запроса
    start_date = datetime.datetime.strptime(start_date.replace(",", "-"),
                                            '%Y-%m-%d').date()
    end_date = datetime.datetime.strptime(end_date.replace(",", "-"),
                                          '%Y-%m-%d').date()
    # Список складов с сопоставлением для агрегации
    df_whouse = pd.read_excel(path + 'infWhouse.xlsx')
    service.log('Обработка данных по дням:', f_log, True)
    df_sell = df_sell.merge(df_whouse, 'left', on='WH')
    df_sell = pd.pivot_table(df_sell,
                             values='Qnty',
                             index=['Art', 'Period', 'Whouse'],
                             aggfunc=np.sum,
                             fill_value=0)
    df_sell = df_sell.reset_index()
    # Имя файла для записи
    file_name = service.naming(start_date, end_date, 'Day')
    service.log('Запись данных продаж по дням: ' + file_name, f_log, True)
    df_sell.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    service.log('Формирование сводной по месяцам:', f_log, True)
    df_date = pd.to_datetime(start_date) + pd.to_timedelta(
        np.arange(((end_date - start_date).days + 1)), 'D')
    df_date = df_date.to_frame()
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['index'])
    df_date.rename(columns={0: 'Period'}, inplace=True)
    df_date = df_date.astype({'Period': 'datetime64'})
    for index, row in df_date.iterrows():
        df_date.at[index, 'Year_Month'] = datetime.datetime.strftime(
            df_date.at[index, 'Period'], "%Y_%m")
    df_sell = df_date.merge(df_sell, 'left', on='Period')
    df_sell = pd.pivot_table(df_sell,
                             values='Qnty',
                             index=['Art', 'Year_Month', 'Whouse'],
                             aggfunc=np.sum,
                             fill_value=0)
    df_sell = df_sell.reset_index()
    # Имя файла для записи
    file_name = service.naming(start_date, end_date, period_name='Month')
    service.log('Запись данных: ' + file_name, f_log, True)
    df_sell.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    del df_sell, df_whouse, df_date, index, row, file_name, request_path, forecast_path
Beispiel #4
0
def set_ABT(path, forecast_path, start_date, end_date, f_log):
    service.log('Создание базовой аналитической таблицы', f_log, False)
    # Календарь
    df_date = pd.to_datetime(start_date) + pd.to_timedelta(
        np.arange(((end_date - start_date).days + 1)), 'D')
    df_date = df_date.to_frame()
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['index'])
    df_date.rename(columns={0: 'Period'}, inplace=True)
    df_date = df_date.astype({'Period': 'datetime64'})
    df_date['Year_Month'] = df_date['Period'].map(
        lambda x: str(x.year) + '_' + service.fill_month(x.month))
    # Определение максимальной даты в календаре
    period_count = df_date['Period'].count() - 1
    max_date = df_date.at[period_count, 'Period']
    # Дата начала прогнозируемого месяца
    max_date = max_date + datetime.timedelta(days=1)
    # Количество дней в прогнозируемом месяце
    #days = calendar.monthrange(max_date.year, max_date.month)[1]
    df_date = df_date.groupby('Year_Month').count()
    df_date = df_date.reset_index()
    df_date.rename(columns={'Period': 'ДнейВМесяце'}, inplace=True)
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['index'])
    file_name = service.naming(start_date, end_date)
    service.log('Загрузка данных из сводной таблицы: ' + file_name, f_log,
                True)
    df_rest = pd.read_csv(forecast_path + file_name,
                          sep=',',
                          dtype={
                              'Year_Month': 'object',
                              'Склад': 'object',
                              'Артикул': 'object',
                              'СреднийОстаток': 'float64',
                              'Продано': 'int64',
                              'ДнейНаОстатке': 'int64'
                          },
                          encoding='cp1251')
    service.log('Данные загружены', f_log, True)
    df_rest = df_date.merge(df_rest, 'left', on='Year_Month')
    service.log('Добавление количества дней в каждом месяце', f_log, True)
    df_rest = df_rest.sort_values(by=['Артикул', 'Склад', 'Year_Month'])
    #df_rest = df_rest.query("Склад == 'Новосибирск' and (Артикул == '2750' or Артикул == '2696')")
    # Перестановка столбцов
    df_rest = column_shift(df_rest, 1, 3, 0, False)
    df_rest = column_shift(df_rest, 3, 5, 1, True)
    file_name = service.naming(start_date, end_date, count=2)
    service.log('Загрузка данных из сводной таблицы: ' + file_name, f_log,
                True)
    df_status = pd.read_csv(forecast_path + file_name,
                            sep=',',
                            encoding='cp1251')
    service.log('Данные загружены', f_log, True)
    df_rest = df_rest.merge(df_status, 'left', on=['Артикул', 'Склад'])
    service.log('Соединение таблиц', f_log, True)
    del df_status
    # Перестановка столбцов
    df_rest = column_shift(df_rest, 3, 6, 4, True)
    df_rest['IsImputation'] = False
    df_rest['Forecasted'] = False
    # Перестановка столбцов
    df_rest = column_shift(df_rest, 7, 8, 4, True)
    # Соединяем никальные значениz Год_месяц из df_date со всеми артикулами и складами
    # Декартово произведение трех таблиц, соединяем с df_rest. Получим строку прогноза
    # Уникальные значениz артикулов
    #df_art = pd.DataFrame(pd.unique(df_rest['Артикул']), columns=['Артикул'])
    # Уникальные значениz складов
    #df_whouse = pd.DataFrame(pd.unique(df_rest['Склад']), columns=['Склад'])
    file_name = service.naming(start_date, end_date, count=3)
    service.log('Запись данных: ' + file_name, f_log, True)
    df_rest.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    del df_rest, file_name, df_date, max_date, period_count
Beispiel #5
0
def set_status(request_path, forecast_path, threshhold, config, start_date,
               end_date, f_log):
    service.log('Расчет статусов номенклатуры', f_log, False)
    service.log('Подключение к SQL серверу', f_log, True)
    con = pymssql.connect(host=config[0],
                          user=config[1],
                          password=config[2],
                          database=config[3])
    service.log('Подключение установлено', f_log, True)
    # Загружаем текст запроса списка артикулов
    f = open(request_path + 'requestArt.txt')
    sql_art = f.read()
    f.close()
    # Загружаем список артикулов
    service.log('Чтение из БД', f_log, True)
    df_art_all = pd.read_sql(sql_art, con)
    con.close()
    del con, sql_art
    service.log('Чтение данных завершено', f_log, True)
    # Календарь
    df_date = pd.to_datetime(start_date) + pd.to_timedelta(
        np.arange(((end_date - start_date).days + 1)), 'D')
    df_date = df_date.to_frame()
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['index'])
    df_date.rename(columns={0: 'Period'}, inplace=True)
    df_date = df_date.astype({'Period': 'datetime64'})
    df_date['Year_Month'] = df_date['Period'].map(
        lambda x: str(x.year) + '_' + service.fill_month(x.month))
    df_date = df_date.groupby('Year_Month').count()
    df_date = df_date.reset_index()
    df_date.rename(columns={'Period': 'DayCount'}, inplace=True)
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['index'])
    file_name = service.naming(start_date, end_date)
    service.log('Загрузка данных из сводной таблицы: ' + file_name, f_log,
                True)
    # Year_Month,Склад,Артикул,СреднийОстаток,Продано,ДнейНаОстатке
    df_rest = pd.read_csv(forecast_path + file_name,
                          sep=',',
                          dtype={
                              'Year_Month': 'object',
                              'Склад': 'object',
                              'Артикул': 'object',
                              'СреднийОстаток': 'float64',
                              'Продано': 'int64',
                              'ДнейНаОстатке': 'int64'
                          },
                          encoding='cp1251')
    df_rest = df_date.merge(df_rest, 'left', on='Year_Month')
    df_rest['Отличие'] = np.where(
        df_rest['ДнейНаОстатке'] < (df_rest['DayCount'] - threshhold), 1, 0)
    service.log('Загрузка уникальных артикулов', f_log, True)
    # Артикул
    df_art = pd.DataFrame(pd.unique(df_rest['Артикул']), columns=['Артикул'])
    df_art = df_art.reset_index()
    df_art = df_art.drop(columns=['index'])
    service.log('Загрузка уникальных складов', f_log, True)
    # Склад
    df_whouse = pd.DataFrame(pd.unique(df_rest['Склад']), columns=['Склад'])
    df_whouse = df_whouse.reset_index()
    df_whouse = df_whouse.drop(columns=['index'])
    full_set = set(df_art_all['Артикул'])
    del df_art_all, df_date
    # Присваиваем статус - Для тех артикулов у которых не было статистики продаж или остатков, назначаем статусы вручную
    present_set = set(df_art['Артикул'])
    df_art_all = pd.DataFrame(full_set.difference(present_set))
    del full_set, present_set
    df_art_all.rename(columns={0: 'Артикул'}, inplace=True)
    #Артикул,Склад,IsEmpty,IsNew,IsGap
    index = pd.MultiIndex.from_product(
        [df_art_all['Артикул'], df_whouse['Склад']],
        names=['Артикул', 'Склад'])
    df_art_all = pd.DataFrame(index=index).reset_index()
    df_art_all['IsEmptySale'] = True
    df_art_all['IsEmpty'] = True
    df_art_all['IsGap'] = False
    df_art_all['IsNew'] = False
    del df_whouse
    # Расчет признаков для тех артикулов, у которых есть статистика
    service.log('Загрузка завершена', f_log, True)
    service.log('Расчт признаков: Наличие продаж; Остатка; Разрыв в остатке',
                f_log, True)
    df_rest = df_rest.sort_values(by=['Артикул', 'Склад', 'Year_Month'])
    #df_rest = df_rest.query("Склад == 'Новосибирск' and (Артикул == '2750' or Артикул == '2696')")
    #df_rest = df_rest.query("Склад == 'Питер'")
    #df_rest = df_rest.query("Склад == 'Ботаково' and (Артикул == '11' or Артикул == '4382' or Артикул == 'фк380')")
    # Расчет сводных признаков до артикула за месяц на складе
    df_rest['ID'] = df_rest['Артикул'] + df_rest['Склад']
    df_rest1 = pd.pivot_table(
        df_rest,
        values=['Продано', 'СреднийОстаток', 'Отличие', 'DayCount'],
        index=['Артикул', 'Склад'],
        aggfunc={
            'Продано': np.sum,
            'СреднийОстаток': np.sum,
            'Отличие': np.sum,
            'DayCount': 'count'
        },
        fill_value=0)
    df_rest1 = df_rest1.reset_index()
    df_rest1['ID'] = df_rest1['Артикул'] + df_rest1['Склад']
    df_rest1 = df_rest1.drop(columns=['Артикул', 'Склад'])
    df_rest1.rename(columns={
        'DayCount': 'ВсегоМес',
        'Продано': 'ВсегоПродано',
        'СреднийОстаток': 'СрОстЗапериод',
        'Отличие': 'ВсегоОтличие'
    },
                    inplace=True)
    result = df_rest.merge(df_rest1, 'left', on='ID')
    del df_rest1
    #Year_Month DayCount Склад Артикул СреднийОстаток Продано ДнейНаОстатке Отличие ВсегоМес ВсегоОтличие ВсегоПродано СрОстЗапериод
    df_rest = df_rest.drop(columns=['ID'])
    # Отбрасываем по месячные данные, оставляем только агрегированные по артикулу, по складу
    result = result.drop(columns=[
        'ID', 'Year_Month', 'DayCount', 'СреднийОстаток', 'Продано',
        'ДнейНаОстатке', 'Отличие'
    ]).drop_duplicates()
    #Склад	Артикул	ВсегоМес	ВсегоОтличие	ВсегоПродано	СрОстЗапериод
    result['IsEmptySale'] = np.where(result['ВсегоПродано'] == 0, True, False)
    result['IsEmpty'] = np.where(result['СрОстЗапериод'] == 0, True, False)
    result['IsGap'] = np.where(result['ВсегоОтличие'] != 0, True, False)
    result = result.drop(
        columns=['ВсегоМес', 'ВсегоОтличие', 'ВсегоПродано', 'СрОстЗапериод'])
    # Ищем новинки только среди тех артикулов, которые имели разрыв в остатках
    service.log('Определение новинок', f_log, True)
    df_art = pd.DataFrame(pd.unique(result.query("IsGap == True")['Артикул']),
                          columns=['Артикул'])
    df_art = df_art.reset_index()
    df_art = df_art.drop(columns=['index'])
    df_art['1'] = 1
    # Формируем исходный фрейм со статистикой по тем артикулам, для которых будем расчитывать статус новинки
    df_res = df_rest.drop(
        columns=['Продано', 'DayCount', 'Отличие', 'СреднийОстаток'])
    df_res = df_res.merge(df_art, 'left', on='Артикул')
    del df_art, df_rest
    df_res = df_res.dropna(how='any')
    df_res = df_res.drop(columns=['1'])
    df_res = df_res.reset_index()
    df_res = df_res.drop(columns=['index'])
    df_res['ID'] = df_res['Артикул'] + df_res['Склад']
    # date_count - количество месяцев всего
    # head_count - количество месяцев, остатка в которых не должно быть, для того, чтобы считать позицию новой
    date_count = pd.DataFrame(pd.unique(df_res['Year_Month']),
                              columns=['Year_Month'])['Year_Month'].count()
    head_count = date_count - threshhold
    # Разделяем исходный фрейм на два, в первом те месяцы, в которых не должно быть остатка
    # во втором, месяцы с остатком
    df_head = df_res.groupby('ID').head(head_count).reset_index(drop=True)
    df_tail = df_res.groupby('ID').tail(threshhold).reset_index(drop=True)
    del date_count, head_count, threshhold
    # Создаем соответствующие сводные за период по складу и артикулу
    df_head = pd.pivot_table(df_head,
                             values=['ДнейНаОстатке'],
                             index=['Артикул', 'Склад'],
                             aggfunc={'ДнейНаОстатке': np.sum},
                             fill_value=0)
    df_tail = pd.pivot_table(df_tail,
                             values=['ДнейНаОстатке'],
                             index=['Артикул', 'Склад'],
                             aggfunc={'ДнейНаОстатке': np.sum},
                             fill_value=0)
    # Присваиваем статус новинки
    df_head['IsNew'] = np.where(df_head['ДнейНаОстатке'] == 0, True, False)
    df_tail['IsNew'] = np.where(df_tail['ДнейНаОстатке'] > 0, True, False)
    # Если оба условия True присваиваем окончательны статус
    df_res = df_head.merge(df_tail, 'left', on=['Артикул', 'Склад'])
    # Соединяем с результирующим фреймом и проставляем в нем, False, для остальных позиций
    del df_head, df_tail
    df_res['IsNew'] = np.where(
        (df_res['IsNew_x'] == True) & (df_res['IsNew_y'] == True), True, False)
    df_res = df_res.drop(
        columns=['ДнейНаОстатке_x', 'ДнейНаОстатке_y', 'IsNew_x', 'IsNew_y'])
    df_res = df_res.reset_index()
    result = result.merge(df_res, 'left', on=['Артикул', 'Склад'])
    del df_res
    result = result.fillna(False)
    # Добавляем номенклатуру без продаж и остатков
    service.log('Добавление статусов номенклатуры без статистики', f_log, True)
    result = result.append(df_art_all, sort=False)
    result = result.reset_index()
    result = result.drop(columns=['index'])
    file_name = service.naming(start_date, end_date, count=2)
    service.log('Запись данных: ' + file_name, f_log, True)
    result.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    del df_art_all, end_date, forecast_path, request_path, result, start_date, file_name
Beispiel #6
0
def count_day_in_stock(forecast_path, start_date, end_date, f_log):
    service.log('Расчет количества дней на остатке по месяцам', f_log, False)
    # Календарь
    df_date = pd.to_datetime(start_date) + pd.to_timedelta(
        np.arange(((end_date - start_date).days + 1)), 'D')
    df_date = df_date.to_frame()
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['index'])
    df_date.rename(columns={0: 'Period'}, inplace=True)
    df_date = df_date.astype({'Period': 'datetime64'})
    df_date['Year_Month'] = df_date['Period'].map(
        lambda x: str(x.year) + '_' + service.fill_month(x.month))
    file_name = service.naming(start_date, end_date, period_name='Day')
    service.log('Загрузка данных из таблицы остатков: ' + file_name, f_log,
                True)
    # Таблица остатков по дням - Артикул,Period,Склад,Остаток
    df_rest = pd.read_csv(forecast_path + file_name,
                          sep=',',
                          dtype={
                              'Артикул': 'object',
                              'Period': 'object',
                              'Склад': 'object',
                              'Остаток': 'int64'
                          },
                          encoding='cp1251')
    df_rest = df_rest.astype({'Period': 'datetime64'})
    # Таблица среднего отпуска товара по дням - Period,Артикул,Склад,СреднийОтпуск
    file_name = service.naming(start_date,
                               end_date,
                               period_name='Day',
                               count=2)
    service.log(
        'Загрузка данных из таблицы среднего отпуска товара по дням: ' +
        file_name, f_log, True)
    df_clqnty = pd.read_csv(forecast_path + file_name,
                            sep=',',
                            dtype={
                                'Period': 'object',
                                'Артикул': 'object',
                                'Склад': 'object',
                                'СреднийОтпуск': 'float64'
                            },
                            encoding='cp1251')
    df_rest = df_rest.merge(df_clqnty, 'left', on=['Артикул', 'Склад'])
    df_rest = df_rest.astype({'Period': 'datetime64'})
    df_rest = df_date.merge(df_rest, 'left', on='Period')
    service.log('Данные загружены', f_log, True)
    del df_clqnty, df_date
    # Артикул,Склад,Year_Month,ДнейНаОстатке
    df_rest['ДнейНаОстатке'] = np.where(
        df_rest['Остаток'] > df_rest['СреднийОтпуск'], 1, 0)
    df_rest = pd.pivot_table(df_rest,
                             values='ДнейНаОстатке',
                             index=['Year_Month', 'Артикул', 'Склад'],
                             aggfunc=sum,
                             fill_value=0)
    df_rest = df_rest.reset_index()
    cols = df_rest.columns.tolist()
    #Перестановка столбцов
    col = cols[0]
    cols[0] = cols[1]
    cols[1] = cols[2]
    cols[2] = col
    df_rest = df_rest[cols]
    #Запись
    file_name = service.naming(start_date,
                               end_date,
                               period_name='Month',
                               count=3)
    service.log('Запись данных: ' + file_name, f_log, True)
    df_rest.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    del col, cols, df_rest, end_date, file_name, forecast_path, start_date
Beispiel #7
0
def aggr_rest(path, rest_path, forecast_path, num_files, start_date, end_date,
              f_log):
    service.log('Группировка остатка по дням и по месяцам в отдельные файлы',
                f_log, False)
    service.log('Загрузка данных из таблиц:', f_log, True)
    # Загружаем фрейм-список складов
    df_whouse = pd.read_excel(path + 'infWhouse.xlsx')
    df_whouse.rename(columns={"WH": "Склад"}, inplace=True)
    # df_rest - Period, Остаток, Артикул, Склад
    df_rest = pd.DataFrame()
    for i in range(1, num_files + 1):
        # Дата файла
        date = service.get_date(start_date.year + ((i - 1) // 12),
                                i - 12 * ((i - 1) // 12))
        # Имя файла
        file_name = service.naming(date, period_name='Day')
        # Чтение даных
        df_rest = df_rest.append(
            pd.read_csv(rest_path + file_name, sep=',', encoding='cp1251'))
        # Запись в лог
        if i > 1:
            service.log(
                file_name + ' Загружен. Операций соеденения произведено: ' +
                str(i - 1), f_log, True)
        else:
            service.log(file_name + ' Загружен', f_log, True)
    del date, i
    df_rest = df_rest.astype({'Period': 'datetime64'})
    service.log('Данные загружены', f_log, True)
    service.log('Агрегация складов', f_log, True)
    df_rest = df_rest.merge(df_whouse, 'left', on='Склад')
    df_rest = df_rest.drop(columns=['Склад'])
    df_rest.rename(columns={'Whouse': 'Склад'}, inplace=True)
    df_rest = pd.pivot_table(df_rest,
                             values='Остаток',
                             index=['Артикул', 'Period', 'Склад'],
                             aggfunc=np.sum,
                             fill_value=0)
    df_rest['Остаток'] = np.around(df_rest['Остаток'], decimals=2)
    df_rest = df_rest.reset_index()
    service.log('Загрузка уникальных артикулов', f_log, True)
    # Артикул
    df_art = pd.DataFrame(pd.unique(df_rest['Артикул']), columns=['Артикул'])
    df_art = df_art.reset_index()
    df_art = df_art.drop(columns=['index'])
    service.log('Загрузка уникальных складов', f_log, True)
    # Склад
    df_whouse = pd.DataFrame(pd.unique(df_rest['Склад']), columns=['Склад'])
    df_whouse = df_whouse.reset_index()
    df_whouse = df_whouse.drop(columns=['index'])
    service.log('Группировка по дням', f_log, True)
    # Запись файла по дням
    file_name = service.naming(start_date,
                               end_date,
                               period_name='Day',
                               count=2)
    service.log('Запись данных: ' + file_name, f_log, True)
    df_rest.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Данные записаны', f_log, True)
    service.log('Группировка по месяцам', f_log, True)
    df_rest['Year_Month'] = df_rest['Period'].map(
        lambda x: str(x.year) + '_' + service.fill_month(x.month))
    df_rest = pd.pivot_table(df_rest,
                             values='Остаток',
                             index=['Артикул', 'Year_Month', 'Склад'],
                             aggfunc=np.mean,
                             fill_value=0)
    df_rest = df_rest.reset_index()
    df_rest['Остаток'] = np.around(df_rest['Остаток'], decimals=2)
    service.log('Соединение с календарем', f_log, True)
    # Календарь
    df_date = pd.to_datetime(start_date) + pd.to_timedelta(
        np.arange(((end_date - start_date).days + 1)), 'D')
    df_date = df_date.to_frame()
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['index'])
    df_date.rename(columns={0: 'Period'}, inplace=True)
    df_date = df_date.astype({'Period': 'datetime64'})
    df_date['Year_Month'] = df_date['Period'].map(
        lambda x: str(x.year) + '_' + service.fill_month(x.month))
    df_date = df_date.groupby('Year_Month').count()
    df_date = df_date.reset_index()
    df_date = df_date.drop(columns=['Period'])
    index = pd.MultiIndex.from_product(
        [df_date['Year_Month'], df_whouse['Склад'], df_art['Артикул']],
        names=['Year_Month', 'Склад', 'Артикул'])
    df_date = pd.DataFrame(index=index).reset_index()
    df_rest = df_date.merge(df_rest,
                            'left',
                            on=['Year_Month', 'Склад', 'Артикул'])
    df_rest = df_rest.fillna(0)
    # Запись файла по имесяцам
    file_name = service.naming(start_date,
                               end_date,
                               period_name='Month',
                               count=2)
    service.log('Запись данных: ' + file_name, f_log, True)
    df_rest.to_csv(forecast_path + file_name, encoding='cp1251', index=False)
    service.log('Запись завершена', f_log, True)
    del df_date, df_rest, df_art, df_whouse, end_date, index, path, start_date, file_name, rest_path, forecast_path,
Beispiel #8
0
def main():
    global level_counter
    global counter
    global score
    import service
    import menu
    import random
    import pygame as pg
    import pygame
    pg.init()
    from pygame import font
    pg.time.set_timer(pg.USEREVENT, 1000)

    game_name = 'ВКИ Dungeon'
    pg.display.set_caption(game_name)

    levels = ['level_1.txt', 'level_2.txt', 'level_3.txt']
    level_quality = len(levels)

    timer = 5
    cs = 40

    #создание матрицы для карты уровня
    cells = 16
    lvl = [0] * cells
    for i in range(cells):
        lvl[i] = [0] * cells
    lvl_file = open(levels[level_counter], 'r')

    for i in range(cells):
        strings = lvl_file.readline()
        clean = strings.split()
        for j in range(cells):
            lvl[i][j] = int(clean[j])


##    lvl_file.close()

    darkness = [
        1
    ] * cells  #создание препятсвия для глаз поверх лабиринта, чтобы игрок не мог сразу узнать, куда ему идти, а исследовал уровень
    for i in range(cells):
        darkness[i] = [1] * cells

    player = pg.image.load('player.png')
    wall = pg.image.load('wall.png')
    floor = pg.image.load('floor.png')
    exit_lvl = pg.image.load('door_ex.png')
    money = pg.image.load('money.png')
    dark = pg.image.load('dark.png')
    enemy = pg.image.load('enemy.png')
    game_bg = pg.image.load('game_bg.jpg')
    live = pg.image.load('live.png')

    screenX = 1200
    screenS = cs * cells
    screen = pg.display.set_mode((screenX, screenS))
    screen.blit(game_bg, [0, 0])

    text_color = [240, 250, 255]
    txt_bg_color = [45, 40, 43]
    font = pg.font.Font('progresspixel.ttf', 20)
    pg.draw.rect(
        screen, txt_bg_color,
        [screenS + cs, cs, screenX - screenS - 2 * cs, screenS - 2 * cs])

    def draw_map():  #рисование уровня
        for i in range(cells):
            for j in range(cells):
                x = cs * j
                y = cs * i
                if lvl[i][j] == 6:  #игрок
                    screen.blit(floor, [x, y])
                    screen.blit(player, [x, y])
                    ip = i
                    jp = j

                    darkness[i][j] = lvl[i][
                        j]  #в области, близкой к игроку препятствие для глаз исчезает
                    darkness[i + 1][j] = lvl[i + 1][j]
                    darkness[i - 1][j] = lvl[i - 1][j]
                    darkness[i][j + 1] = lvl[i][j + 1]
                    darkness[i][j - 1] = lvl[i][j - 1]
                    darkness[i + 1][j - 1] = lvl[i + 1][j - 1]
                    darkness[i - 1][j + 1] = lvl[i - 1][j + 1]
                    darkness[i - 1][j - 1] = lvl[i - 1][j - 1]
                    darkness[i + 1][j + 1] = lvl[i + 1][j + 1]

                    if i + 2 < cells:  #чтобы игрок изначально знал, что впереди враг или выход с уровня
                        if (lvl[i + 2][j] == 3
                                or lvl[i + 2][j] == 10) and lvl[i + 1][j] != 0:
                            darkness[i + 2][j] = lvl[i + 2][j]
                        if (lvl[i - 2][j] == 3
                                or lvl[i - 2][j] == 10) and lvl[i - 1][j] != 0:
                            darkness[i - 2][j] = lvl[i - 2][j]
                    if j + 2 < cells:
                        if (lvl[i][j + 2] == 3
                                or lvl[i][j + 2] == 10) and lvl[i][j + 1] != 0:
                            darkness[i][j + 2] = lvl[i][j + 1]
                        if (lvl[i][j - 2] == 3
                                or lvl[i][j - 2] == 10) and lvl[i][j - 1] != 0:
                            darkness[i][j - 2] = lvl[i][j - 2]

                if lvl[i][j] == 0:  #стена
                    screen.blit(wall, [x, y])
                elif lvl[i][j] == 2:  #пол
                    screen.blit(floor, [x, y])
                elif lvl[i][j] == 3:  #выход с уровня
                    screen.blit(exit_lvl, [x, y])
                elif lvl[i][j] == 5:  #игровые очки
                    screen.blit(floor, [x, y])
                    screen.blit(money, [x, y])
                elif lvl[i][j] == 10:  #враг
                    screen.blit(floor, [x, y])
                    screen.blit(enemy, [x, y])

                if darkness[i][j] == 1:  #препятсвие для глаз
                    screen.blit(dark, [x, y])
        return (ip, jp)

    def control(i, j, ip, jp):  #передвижение игрока
        if event.key == pg.K_UP:
            i = ip - 1
        elif event.key == pg.K_DOWN:
            i = ip + 1
        elif event.key == pg.K_LEFT:
            j = jp - 1
        elif event.key == pg.K_RIGHT:
            j = jp + 1
        return (i, j)

    def moving(i, j, ip, jp, lvl, lives, sp_in, spell_change,
               spell_result):  #передвижение
        global level_counter
        global score

        if lvl[i][j] == 0:
            i = ip
            j = jp

        if lvl[i][j] == 2:
            lvl[i][j] = 6  #игрок переходит на следующую клетку
            lvl[ip][jp] = 2  #предыдущая клетка закрывается полом
            ip = i
            jp = j

        if lvl[i][j] == 5:
            lvl[i][j] = 6
            lvl[ip][jp] = 2
            ip = i
            jp = j
            score += 1

        if lvl[i][j] == 3:  #переход на новый уровень
            level_counter += 1
            lvl[i][j] = 6
            lvl[ip][jp] = 2
            ip = i
            jp = j

        if lvl[i][j] == 10:
            lenemy, lives, sp_in, spell_change, spell_result = pve(
                lives, sp_in, spell_change, spell_result)
            if lenemy <= 0:
                lvl[i][j] = 6
                lvl[ip][jp] = 2
                ip = i
                jp = j

        ip, jp = draw_map()
        return (i, j, ip, jp, lvl, lives, sp_in, spell_change, spell_result)

    liters = str('qwertyuiasdfghjklzxcvbnm')
    litq = len(liters)
    lives = 10
    sp_in = ''
    spell_change = True
    spell_result = ''

    def pve(lives, sp_in, spell_change, spell_result):  #боевая система
        lives_enemy = 1
        spell = ''
        spell_len = random.randint(5, 8)

        if spell_change == True and spell_result == '':  #предотвращает изменение выводимой на экран комбинации букв, если игрок вводит ее
            for i in range(spell_len):
                f = random.randint(0, litq - 1)
                spell += str(liters[f])
            spell_result = spell
        spell_change = False

        text = font.render('Введи ' + spell_result + ' на клавиатуре', 0,
                           text_color)
        pg.draw.rect(screen, txt_bg_color,
                     [screenS + 2 * cs, 6 * cs, 10 * cs, cs], 0)
        screen.blit(text, [screenS + 2 * cs, 6 * cs])
        inp_text = font.render('', 0, text_color)
        answer = ''

        inp = True
        kd = pg.key.name(event.key)
        if kd == 'return':
            answer = sp_in
            inp = False
            spell_change = True

        if kd != 'return' and kd != 'backspace' and kd != 'left' and kd != 'right' and kd != 'up' and kd != 'down':
            sp_in = sp_in + kd

        if kd == 'backspace':
            kd = ''
            a = len(sp_in) - 1
            sp_in = sp_in[0:a]

        inp_text = font.render(sp_in, 0, text_color)
        pg.draw.rect(screen, txt_bg_color,
                     [screenS + 2 * cs, 7 * cs, 10 * cs, cs], 0)
        screen.blit(inp_text, [screenS + 2 * cs, 7 * cs])
        pg.draw.rect(screen, txt_bg_color,
                     [screenS + 2 * cs, 8 * cs, 10 * cs, cs], 0)
        if inp == False:
            if answer == spell_result:
                lives_enemy -= 1
                spell_result = ''
                sp_in = ''
                text = font.render('Ты изгнал монстра', 0, text_color)
                screen.blit(text, [screenS + 2 * cs, 8 * cs])

            elif lives > 0:
                lives -= random.randint(1, 3)
                spell_result = ''
                sp_in = ''
                text = font.render('Монстр ударил тебя', 0, text_color)
                screen.blit(text, [screenS + 2 * cs, 8 * cs])

        return (lives_enemy, lives, sp_in, spell_change, spell_result)

    ip, jp = draw_map()
    i = ip
    j = jp
    gameprocess = True
    while gameprocess:
        text = font.render('Сокровища: ' + str(score), 0, text_color)
        pg.draw.rect(screen, txt_bg_color,
                     [screenS + 3 * cs, 3 * cs, 10 * cs, cs], 0)
        screen.blit(text, [screenS + 3 * cs, 3 * cs])
        screen.blit(money, [screenS + 10 * cs, 3 * cs])

        text = font.render('Здоровье: ' + str(lives), 0, text_color)
        pg.draw.rect(screen, txt_bg_color,
                     [screenS + 3 * cs, 4 * cs, 10 * cs, cs], 0)
        screen.blit(text, [screenS + 3 * cs, 4 * cs])
        screen.blit(live, [screenS + 10 * cs, 5 + 4 * cs])

        if level_counter == counter + 1 and level_counter < level_quality:  #когда счетчик уровней изменяется, программа запускается заново
            counter = level_counter
            gameprocess = False

        if level_counter >= level_quality:
            lives = 0

        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()

            if lives <= 0:
                score = 0
                level_counter = 0
                text = font.render("Game over. Приготовьтесь вводить ник", 0,
                                   text_color)
                screen.blit(text, [screenS + cs, 0])
                if event.type == pg.USEREVENT:
                    timer -= 1
                if timer <= 0:
                    service.naming()

            if event.type == pg.KEYDOWN:
                i, j = control(i, j, ip, jp)
                i, j, ip, jp, lvl, lives, sp_in, spell_change, spell_result = moving(
                    i, j, ip, jp, lvl, lives, sp_in, spell_change,
                    spell_result)
                if event.key == pg.K_ESCAPE:
                    score = 0
                    menu.menu()
        pg.display.flip()