Рубрики
Без рубрики

Сделайте комплексное планирование простым с помощью Rateoboard, библиотека Python

Автор оригинала: FreeCodeCapm Team.

Максимом Мамаевым

Съемка это библиотека Python, которая создает расписания рабочих периодов и выполняет расчеты календаря над ними. Вы можете построить стандартные календари рабочего дня, а также различные другие графики, простые или сложные.

Вы можете найти документацию здесь .

Проверьте репо GitHub здесь .

Найти его на Pypi здесь .

История

Это началось с корпуса головного числа. Наша компания представила KPI с участием дохода на одного работника, поэтому нам нужно было узнать средний годовой численность персонала каждой команды. Я уже писал сценарии Python, поэтому я не запугался.

Чтобы получить головную головку, мне пришлось рассчитать количество рабочих дней, каждый сотрудник провел с компанией в течение года. Pandas справится с этим в сек, я подумал. Но вышло, что панд не мог.

Русский бизнес календарь громоздки. Они обменяют будни по субботам или воскресеньям, чтобы заполнить пробелы между праздниками и выходными. Например, вы должны прийти к работе в субботу в феврале, чтобы быть возмещены с бесплатным понедельником, предшествующим праздничным вторник где-то в мае.

Схема для каждого года уникальна. Календарь Business Day PandaS поддерживает только односторонние поправки на праздничные наблюдения. Итак, я мог бы превратить рабочий день в выходной день, но не наоборот.

Тогда были операторы в колл-центре, и мое беспокойство качало в другой путь. Они работают в сдвигах различной длины, а одна смена, а затем три сдвига. Чтобы получить статистику Call Center, мне не нужен календарь бизнес-дня. Тем не менее, мне пришлось сосчитать количество сдвигов определенного оператора в течение определенного периода времени.

И, наконец, проблема заблепов. В моем местном автосалоне Honda механики работают на альтернативных еженедельных графиках: понедельник, вторник, суббота и воскресенье на этой неделе, а в среду по пятницу на следующей неделе. Я хотел всегда служить конкретным механиком, потому что другой когда-то однажды запутал тормоза. Я хотел простого способа определить следующую смену «моего» механика.

Эти случаи имеют общий фундамент. Их решения полагаются на график «дежурный» и «внедренные» периоды времени. Мы должны быть в состоянии построить разнообразные структурированные графики, подходящие для разных случаев бизнеса. Запросы и расчеты, проводимые по расписанию, должны различать «дежурный» и «внедренные» периоды.

Я не смог найти пакет Python, который предоставил средства для строительства и запрашивания таких расписаний. Как это произошло, у меня было немного свободного времени, чтобы написать это сам.

Концепция

Съемка это библиотека Python, которая создает расписания рабочих периодов и выполняет расчеты календаря над ними. Сами эти объекты называются кассовыми платами.

Существует три основных шага в рассуждении о съемке.

Вы начинаете с интервала времени, который устанавливает границы вашего календаря. Все будет ограничено этим интервалом. Это называется кадром (ссылкой). Рамка состоит из базовых блоков. Базовый блок – самый маленький период времени, который вам нужен для измерения вашего календаря. Например, если вы причина в условиях рабочих дней, то базовый блок – это день. В качестве альтернативы, если вы построете график нескольких часов сдвигов, то базовый блок – один час.

На следующем шаге вы определяете правила разметки кадра в рабочие копии. Работы – это периоды времени, которые вы заботитесь о. Они составляют ваш календарь. Это рабочие места, которые вы хотите запланировать или рассчитывать. В стандартных рабочих днях календарь рабочее место – это день (и базовый блок – это день, поэтому они совпадают).

В колл-центре рабочее место – это несколько часов, когда определенный сдвиг операторов на обязательном порядке. Базовый агрегат, вероятно, будет один час, и каждое рабочее место содержит (возможно, различное) количество базовых блоков.

Последовательность рабочих потоков, заполняющих раму, называется временной шкалой.

Наконец, вы создаете один или несколько расписаний. Расписание похоже на трафарет, проложенный по временной шкале. Его цель состоит в том, чтобы рассказать о дежурных рабочихницах от внедорожников.

Расписание нуждается в том, чтобы работать с тем, чтобы объявить рабочее место на дежурстве или внедрении. Вот почему вы предоставляете метку для каждого рабочего местоположения, либо, скорее правило для маркировки их, пока кадр помечен на временную шкалу. Каждое расписание определяет функцию селектора, которая проверяет метку рабочего потока и возвращает TRUE для рабочихshifts Ondown и False в противном случае. Если вы не переопределите его, временная шкала сопровождается графиком по умолчанию, селектор которого возвращает логическое значение метки.

Иногда вы хотите определить несколько графиков для той же временной шкалы. Например, в колл-центре будет расписание колл-центра в целом и отдельное расписание для каждой команды операторов. Та же рабочее место может быть найден дежурным под некоторыми расписаниями и внедрением под другим.

Работа съемки +. Точнее, Съемка это коллекция работы Расписание на основе определенного Сроки Рабочие изменения построен по ссылке Рамка Отказ

После того, как у вас есть oteloader, вы можете выполнить полезную работу: выполнять расчеты календаря, чтобы решить такие проблемы, как описанные в прологе.

Каждое вычисление, выполненное с oteo Roade-Aware. Призывным методом «видит» только рабочие копии с указанными пошлинами и игнорирует других. Чтобы раскрыть обязанности рабочих средств, метод должен быть предоставлен график. Следовательно, каждое вычисление на oteoboard параметризовано с обязанностью и расписанием.

По умолчанию обязанность «включено» и расписание является графиком по умолчанию oteloboard. Например, если вы звоните count () Без аргументов на некотором интервале reamoboard вы получите количество рабочих потоков в интервале, который объявлен дежурным в рамках графика по умолчанию. Эти значения по умолчанию облегчают жизнь, потому что на практике вы захотите справиться в основном с рабочими модами на работе.

API

Документация полной доски доступна на Прочитайте документы Отказ

Пакет может быть установлен с обычным Установка PIP Unlight Отказ

Установите розъемку

Самый простой способ начать – использовать предварительно обработанный календарь, который отправляется с пакетом. Давайте пройдем регулярный календарь рабочего дня для Соединенных Штатов.

 >>> import timeboard.calendars.US as US >>> clnd = US.Weekly8x5()

Clnd Объект представляет собой съемную панель (экземпляр Timeboard.myboard класс). Он имеет только одно расписание по умолчанию, которое выбирает рабочие дни в качестве рабочих ширдей, в то время как выходные, а также наблюдения за федеральными праздниками США объявляются.

Инструменты для создания собственной фотографии будут кратко рассмотрены позже после того, как мы смотрим на то, что вы можете сделать с помощью съемки.

Играть с рабочими потоками

Вызов экземпляра reoarboard CLND () С одной точкой во времени извлекает рабочее место, которое содержит эту точку. Как то, что у вас есть рабочее место, вы можете запросить свой долг:

Это определенная дата рабочего дня?

>>> ws = clnd('27 May 2017')>>> ws.is_on_duty()False

Действительно, это была суббота.

Вы также можете посмотреть в будущее или в прошлом от текущего рабочего местоположения:

Когда был следующий рабочий день?

>>> ws.rollforward()Workshift(6359) of 'D' at 2017–05–30

Возвращенное рабочее место имеет порядковый номер 6359 года и представляет собой день 30 мая 2017 года, который, кстати, был вторник после праздника дня памяти.

Если бы мы завершили проект в 22 рабочих дня, начиная с 01 мая 2017 года, когда был бы наш крайний срок?

>>> clnd('01 May 2017') + 22Workshift(6361) of 'D' at 2017–06–01

Это так же, как:

>>> clnd('01 May 2017').rollforward(22)Workshift(6361) of 'D' at 2017–06–01

Играйте с интервалами

Призыв CLND () Благодаря другому набору параметров создается объект, представляющий интервал на календаре. Интервал ниже содержит все рабочие копии месяца мая 2017 года:

>>> may2017 = clnd('May 2017', period='M')

Сколько рабочих дней было там в мае?

>>> may2017.count()22

Сколько выходных?

>>> may2017.count(duty='off')9

Сколько часов работы?

>>> may2017.worktime()176

Сотрудник был на сотрудников с 3 апреля 2017 года, до 15 мая 2017 года. Какую порцию апрельской зарплаты компании вложили их?

Обратите внимание, что звонок CLND () С кортежом из двух точек во времени производит интервал, содержащий все рабочие копии между этими точками, включительно.

>>> time_in_company = clnd(('03 Apr 2017','15 May 2017'))>>> time_in_company.what_portion_of(clnd('Apr 2017', period='M'))1.0

Действительно, 1-й и 2 апреля в 2017 году упал на выходные, поэтому начал 3-й, сотрудник проверил все рабочие дни в месяц.

И какая часть мая?

>>> time_in_company.what_portion_of(may2017)0.5

Сколько дней работник работал в мае?

Оператор умножения возвращает пересечение двух интервалов.

>>> (time_in_company * may2017).count()11

Сколько часов?

>>> (time_in_company * may2017).worktime()88

Сотрудник был на персонале с 01 января 2016 года по 15 июл 2017 года. Сколько лет этот человек работал в компании?

>>> clnd(('01 Jan 2016', '15 Jul 2017')).count_periods('A')1.5421686746987953

Построить собственную розъемку

С целью введения я просто погрузился на два примера. Если кажется слишком крутым, пожалуйста, найдите тщательное обсуждение строительных инструментов в Проектная документация Отказ

Оператор импорта для этого раздела:

>>> import timeboard as tb

Позвольте мне вернуться к графику рабочей копии в автосалоне, который я упомянул в прологе. Механик работает в понедельник, вторник, суббота, и воскресенье на этой неделе, а в среду, четверг и пятницу на следующей неделе; Затем билетневный цикл повторяется. Съемка создается следующим кодом:

>>> biweekly = tb.Organizer(marker='W',...     structure=[[1,1,0,0,0,1,1], [0,0,1,1,1,0,0]])>>> clnd = tb.Timeboard(base_unit_freq='D', ...     start='01 Oct 2017', end='31 Dec 2018', ...     layout=biweekly)

Это имеет смысл смотреть в последнее утверждение первым. Это создает съемную панель по имени Clnd Отказ Первые три параметра определяют раму, чтобы быть последовательностью дней (‘ d ‘) с 01 октября 2017 года по 31 декабру 2018 года. Макет Параметр говорит, как организовать кадр в временную шкалу рабочей экономии. Эта работа поручено на Организатор назван Биклин Отказ

Первое утверждение создает это Организатор который принимает два параметра: Маркер и структура Отказ Мы используем Маркер размещать следы на раме. Марки – это вехи, которые разделяют кадру в подкадры или «охватывающие». В примере Marker = 'W' помещает знак в начале каждой календарной недели. Следовательно, каждый промежуток представляет собой неделю.

структура Параметр говорит, как создавать рабочие копии в каждом промежутке. Первый элемент структура список [1,1,0,0,0,1,1] , применяется к первому диапазону (то есть до первой недели нашего календаря). Каждый базовый блок (то есть каждый день) в диапазоне становится рабочем местом. Рабочая копия получают этикетки из списка, в порядке.

Второй элемент структура список [0,0,1,1,1,0,0] , аналогично применяется ко второму промежутку (вторая неделя). После этого, так как мы не получили больше элементов, а структура воспроизводится в циклах. Следовательно, третья неделя обслуживается первым элементом структура , четвертая неделя на вторую, и так далее.

В результате наша временная шкала становится последовательностью дней, помеченных номером 1 Когда механик на дежурстве и с номером 0 когда он или она нет. Мы не указали ни одного расписания, потому что график, который построен по умолчанию подходит нам нормально. Расписание по умолчанию рассматривает логическое значение метки, поэтому 1 Переводится в «дежурство» и ноль в «Off Duty».

С помощью этой области мы можем сделать какие-либо расчеты, которые мы сделали ранее с бизнес-календарем. Например, если человек был нанят на этот график с 4 ноября 2017 года, и зарплата оплачивается ежемесячно, какая часть ноябрьской заработной платы заработала?

>>> time_in_company = clnd(('4 Nov 2017', None))>>> nov2017 = clnd('Nov 2017', period='M')>>> time_in_company.what_portion_of(nov2017)0.8125

Во втором примере мы построим oteloadra для колл-центра. Колл-центр работает круглосуточно в сдвигах различной длины: 08:00 до 18:00 (10 часов), 18:00 до 02:00 (8 часов) и 02:00 до 08:00 (6 часов ). График оператора состоит из одного сдвига на службу, за которым следует три сдвига вне нагрузки. Следовательно, необходимы четыре команда операторов. Они обозначены как «A», «B», «C» и «D».

>>> day_parts = tb.Marker(each='D', ...     at=[{'hours':2}, {'hours':8}, {'hours':18}])>>> shifts = tb.Organizer(marker=day_parts, ...     structure=['A', 'B', 'C', 'D'])>>> clnd = tb.Timeboard(base_unit_freq='H', ...     start='01 Jan 2009 02:00', end='01 Jan 2019 01:59',...     layout=shifts)>>> clnd.add_schedule(name='team_A', ...    selector=lambda label: label=='A')

Есть четыре ключевых отличия от случая дилерского вида. Мы рассмотрим их один за другим.

Во-первых, базовый блок кадров теперь является одночасовым периодом ( base_unit_freq = 'h' ) вместо однодневный период дилерского календаря.

Во-вторых, ценность Маркер Параметр Организатора теперь является сложным объектом вместо одной частоты календаря, это было раньше. Этот объект является экземпляром Маркер класс. Он используется для определения правил для размещения следов на раме, когда простое разделение рамы в однородные календарные агрегаты недостаточно. Подпись маркера выше практически читаемой – говорит: поместите знак на Каждый день (‘D’) в 02:00, 08:00 и 18:00 часов Отказ

В-третьих, ценность структура Сейчас проще: это одноуровневый список меток команд. Когда элемент структура Не является нетеримом на этикетках, но только один ярлык, его приложение к промежутоку производит одно рабочее место, которое буквально охватывает промежуток.

В нашем примере самый первый пролет состоит из шести одночасовых базовых единиц, начиная с 2, 3, 4 … 7 часов утра 01 января 2009 года. Все эти базовые блоки объединяются в одно рабочее место с этикеткой «A» Отказ Второй пролет включает десять одночасовых базовых блоков, начиная с 8, 9, 10 … 17 часов. Эти базовые блоки объединяются в одно рабочее место с этикеткой «B» и так далее. Когда все этикетки были сделаны, структура воспроизводится, поэтому пятый пролет (08: 00: 00-17: 59: 59 на 01 января 2009 года) становится рабочем для метки «A».

Чтобы повторить, если элемент структура это список меток, каждая базовая единица пролета становится рабочим потенциалом и получает метку из списка. Если элемент структура Это одна этикетка, все базовые блоки диапазона объединены, чтобы сформировать одно рабочее место, которое получает эту метку.

И, наконец, мы явно создали график команды A. Расписание по умолчанию не служит нашей цели, поскольку она возвращается «всегда дежурным». Это верно для колл-центра в целом, но не так для конкретной команды. Для нового расписания мы поставляем имя и функцию селектора, которая возвращает true для всех рабочих средств, помеченных с помощью «A». Для практического использования вы захотите создать графики для других команд.

Этот розетки так же хороши для работы с любыми другими. Однако на этот раз нам придется явно указать график, который мы хотим использовать.

>>> schedule_A = clnd.schedules['team_A']

Сколько сдвигов работали операторы команды SIT в ноябре 2017 года?

>>> nov2017 = clnd('Nov 2017', period='M', schedule=schedule_A)>>> nov2017.count()22

И сколько часов было всего?

>>> nov2017.worktime()176

Человек был использован как оператор в команде A с 4 ноября 2017 года. Зарплата оплачивается ежемесячно. Какая часть заработной платы ноябрь заработала сотрудник?

>>> time_in_company = clnd(('4 Nov 2017',None), schedule=schedule_A)>>> time_in_company.what_portion_of(nov2017)0.9090909090909091

Больше используйте случаи

Вы можете найти больше случаев использования (взято почти из реальной жизни) в Jupyter ноутбук который является частью Проектная документация Отказ

Пожалуйста, не стесняйтесь использовать Съемка И не стесняйтесь оставлять отзывы или открытые вопросы на Github Отказ