Рассчитать посещаемость из файла CSV, созданного с использованием устройства biometri c - PullRequest
1 голос
/ 04 апреля 2020

Во-первых, я начинающий в Python, и я впервые пишу сценарий для личного проекта, поэтому будьте осторожны в своих ответах.

Входные данные

I иметь несортированный CSV-файл с временем входа всех сотрудников за данный месяц, который выглядит следующим образом:

13,03 / 02/2020 09: 43
12,03 / 02/2020 10: 26
10,03 / 02/2020 12: 12
13,03 / 02/2020 18: 22 * ​​1010 * 12,03 / 02/2020 18: 23
13,03 / 03/2020 09: 51
12,03 / 03/2020 10: 38
10,03 / 03/2020 12: 02
13,03 / 03/2020 18: 28
12,03 / 03/2020 18:29

, где первый столбец - идентификатор сотрудника, а второй столбец - время входа / выхода из системы.

Я хочу узнать лучший / наиболее эффективный способ считывания времени входа из запишите и вычислите:

Выход

Basi c:
1. Сколько дней сотрудник находился в офисе
2. общее рабочее время сотрудника за каждый день

Employee ID - xxxx

Date        Duration  
DD/MM/YY    hh:mm:ss
DD/MM/YY    hh:mm:ss
DD/MM/YY    hh:mm:ss

Total No. of Working Days in this month: 

Дополнительно:
Рассчитать wh ich были воскресными днями и добавьте эти дни к своей посещаемости в качестве подарка
Еще более продвинутый:
Сравните с онлайн-календарем Google для региона, чтобы найти выходные дни в этом месяце для этого региона и добавить эти праздники к их посещаемости

Мой логин c:

  1. Прочитайте файл CSV, извлеките время входа и сохраните его в отсортированном списке. Это создает список списков примерно так:
[['10', '03/02/2020 12:12'],['10', '03/03/2020 12:02'], ['10', '03/06/2020 15:12'], ['10', '03/07/2020 16:18'], ['10', '03/08/2020 11:04'], ['10', '03/08/2020 11:05'], ['10', '03/09/2020 11:27'], ['10', '03/10/2020 17:06'], ['10', '03/11/2020 22:13'], ['10', '03/12/2020 11:13'], ['10', '03/13/2020 11:57'], ['10', '03/14/2020 11:29'], ['10', '03/16/2020 10:32'], ['10', '03/17/2020 17:37'], ['10', '03/18/2020 12:24'], ['10', '03/19/2020 15:38'], ['10', '03/19/2020 15:45'], ['10', '03/20/2020 15:26']]
Преобразуйте этот список в отсортированный словарь, чтобы все времена входа сотрудника были сохранены вместе в списке. Чтобы выглядеть примерно так:
{'10':['03/02/2020 12:12','03/02/2020 15:38','03/08/2020 11:05'],  
'12':['03/03/2020 11:27','03/03/2020 12:02','03/03/2020 18:29'],  
'13':['03/16/2020 10:32','03/16/2020 11:57','03/16/2020 19:04']}

и так далее ...

... где, "ключом" словаря является идентификатор сотрудника и "значение" список времени входа / выхода из системы, отсортированный по дате

Для каждого идентификатора сотрудника, для каждого дня, рассчитайте разницу во времени между временем первого входа в систему и временем последнего выхода из системы (определенно будет несколько записей) с использованием функции timedelta для datetime module

Создайте файл Excel, который выглядит как ожидаемый результат, показанный выше

The Question

Кажется как довольно простая и простая задача, и все же ...

Я застрял при попытке объединить список списков в правильный словарь с идентификатором сотрудника в качестве ключа и списком всех их времен входа в систему как Значение. Попытка Google найти возможное решение привела меня к https://thispointer.com/python-how-to-convert-a-list-to-dictionary/. Но это не помогает моей проблеме, потому что я пытаюсь извлечь очень конкретную c информацию из того же списка.

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

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

PS: У меня есть посмотрел на pandas, но, кажется, нет необходимости учиться с нуля для этой простой задачи.
Кроме того, следующий шаг, вычисление разницы во времени, может быть более сложным, чем я себе представляю, поэтому любая помощь по этому вопросу будет очень приветствую.
Кроме того, я не прошу писать код для меня. Я хочу выучить этот прекрасный язык, чтобы я мог выздороветь и быстро создавать такие сценарии.

Если вы сделали это так далеко, спасибо, что нашли время! Ты делаешь мир лучше :)

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Ниже вы найдете один пример вывода для сотрудника (ID: 13), файл, созданный моим сценарием, называется Посещаемость ID-13 2020-04-05.txt .

Обратите внимание на два ограничения импорта моего скрипта:
1) он создает файлы .txt, а не .xlsx
2) Требуется только минимум дневное время и вычтите его из максимального времени того же дня.

Ограничение 2 также означает, что когда кто-то вошел в систему в один день, т.е. 02 марта, и вышел из системы на следующий день 03 марта, в столбце продолжительности В выходном файле вы найдете «Нет выхода из системы на этот день». Кроме того, если человек входит в систему и выходит несколько раз в день, то есть для перерыва, эти времена будут игнорироваться.
Однако это будет отдельный вопрос, который является частью ваших задач.

Пример выходного файла: Посещаемость ID-13 2020-04-05.txt

ID сотрудника - 13

Дата Продолжительность
02/03/2020 8: 39: 0
03/03/2020 8: 37: 0

Мой код / ​​pandas решение:

#!/usr/bin/env python3
import pandas as pd
from pathlib import Path
import numpy as np
import datetime
from math import floor

def time_to_delat(t):
    """Convert datetime.time object with hour and minute to datetime.timedelta object"""
    dt = datetime.timedelta(hours=t.hour, minutes=t.minute)
    return dt
def trans_form_tostring(dt):
    hours = dt.seconds//3600
    minutes = (dt.seconds//60)%60
    seconds = dt.seconds%60
    return f"{hours}:{minutes}:{seconds}"

def main():
    # set path to csv
    path_to_csv = Path("C:/Test/tmp_csv.csv")
    # set names for the columns
    header = ['ID','Datetime']
    # read the csv as pandas dataframe
    df = pd.read_csv(path_to_csv, names = header,parse_dates=True)
    # Convert the column 'Date' to a datetime object
    df['Datetime'] = pd.to_datetime(df['Datetime'])
    df['Date'] = df['Datetime'].dt.date
    df['Time'] = df['Datetime'].dt.time

    for ID in df.ID.unique():
        # Iterate over every unique ID of employee and Filter for a single ID
        one_employee = df[df['ID']==ID].sort_values(by='Date')
        # Get the earliest start time of a day and the latest time of a day
        start_per_day = one_employee.groupby('Date')['Time'].min()
        end_per_day = one_employee.groupby('Date')['Time'].max()
        # Convert array of datetime.time objects to array of datetime.timedelta objects
        start_per_day_dt = np.array([time_to_delat(x) for x in start_per_day])
        end_per_day_dt = np.array([time_to_delat(x) for x in end_per_day])
        # get the duration for a single day
        delta_per_day = [trans_form_tostring(x) for x in (end_per_day_dt - start_per_day_dt)]
        # Create an empty list dates for the attendance
        attended_days = []
        for i,working_day in enumerate(one_employee.Date.unique()):
            if delta_per_day[i] == "0:0:0":
                delta_per_day[i] = "No Logout for this day"
            day = working_day.strftime("%d/%m/%Y")
            attended_days.append(f"{day}\t{delta_per_day[i]}")
        create_excel_output(ID,attended_days,Path("C:/Test"))

def create_excel_output(ID, dates,outpath=None):
    protocol_file = f"Attendance of ID-{ID} {datetime.date.today()}.txt"
    if outpath is not None:
        protocol_file = outpath / f"Attendance of ID-{ID} {datetime.date.today()}.txt"
    employee = f"Employee ID - {ID}"
    with open(protocol_file,'w') as txt:
        txt.write(employee+"\n\n")
        txt.write("Date\tDuration\n")
        for line in dates:
            txt.write(line)
            txt.write("\n")

if __name__ == '__main__':
    main()
0 голосов
/ 04 апреля 2020

Я думаю, вы просто ищете способ конвертировать список списков в dict, попробуйте это:

from collections import defaultdict
import pprint
l = [['10', '03/02/2020 12:12'],['10', '03/03/2020 12:02'], ['10', '03/06/2020 15:12'], ['10', '03/07/2020 16:18'], ['10', '03/08/2020 11:04'], ['10', '03/08/2020 11:05'], ['10', '03/09/2020 11:27'], ['10', '03/10/2020 17:06'], ['10', '03/11/2020 22:13'], ['10', '03/12/2020 11:13'], ['10', '03/13/2020 11:57'], ['10', '03/14/2020 11:29'], ['10', '03/16/2020 10:32'], ['10', '03/17/2020 17:37'], ['10', '03/18/2020 12:24'], ['10', '03/19/2020 15:38'], ['10', '03/19/2020 15:45'], ['10', '03/20/2020 15:26'], ['11', '03/19/2020 15:45'], ['11', '03/20/2020 15:26'], ['12', '03/19/2020 15:45'], ['12', '03/20/2020 15:26']]
datesByEmployee = defaultdict(list)
for ll in l:
    datesByEmployee[ll[0]].append(ll[1])
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(dict(datesByEmployee))

Это даст вам:

{   '10': [   '03/02/2020 12:12',
          '03/03/2020 12:02',
          [...]],
'11': ['03/19/2020 15:45', '03/20/2020 15:26'],
'12': ['03/19/2020 15:45', '03/20/2020 15:26']}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...