Анализ данных с использованием объектов времени и даты - PullRequest
2 голосов
/ 13 августа 2010

У меня довольно уникальная проблема, которую я пытаюсь решить:

На основании данных этого примера (фактические данные - это очень много записей и не менее 4 на карту в день):

serial, card, rec_date, rec_time, retrieved_on
2976 00040  2010-07-29 18:57 2010-07-31 13:37:31 
2977 00040  2010-07-30 09:58 2010-07-31 13:37:31
2978 00040  2010-07-30 15:33 2010-07-31 13:37:31
2979 00040  2010-07-30 16:13 2010-07-31 13:37:31
2980 00040  2010-07-30 19:41 2010-07-31 13:37:31

Записи взяты из системы часов.

Что я хочу сделать, это взять определенную группу записей, отфильтрованных по card и rec_date, а затем определить, как долго человек работал в течение дня и продолжительность каждого рабочего периода, сколько перерывов он / она взяла, и в конце недели получи общее количество отработанных часов.

Из приведенного выше списка 2977 - это регистрация, затем 2978 - это проверка и т. Д.

Хотя я заблудился, как это сделать, поэтому я подумал, что у кого-то есть идея.

Я использую простой класс для хранения этих данных после импорта в другое место:

class TimeClock(models.Model):
  serial = models.CharField(max_length = 16)
  card_no = models.CharField(max_length = 10)
  rec_date = models.DateField()
  rec_time = models.TimeField()
  oper_date = models.DateTimeField(default=datetime.today)

Ответы [ 2 ]

2 голосов
/ 14 августа 2010

Очевидно, что класс TimeClock - сам по себе - не подходит для того, что вы делаете.

Вам необходимо суммировать TimeClock для создания WorkIntervals, с которыми вы можете работать. Это пары строк TimeClock, которые показывают (теоретический) начало и конец рабочего периода.

Если кто-то не успевает вовремя, вы совершенно не можете понять, что происходит. Это не «сложно», это невозможно.

Кроме того, если кто-то работает после полуночи, вы не можете понять, что происходит. Это не «сложно», это невозможно.

Но мы притворимся, что никто не работает после полуночи, и никто не может войти или выключиться (хахаха)

def make_pairs( tc_query_set ):
    start = None
    for row in tc_query_set:
         if start is None:
             start= row
             continue
         elif start.card == row.card and start.rec_date == row.rec_date:
             yield start, row
             start= None
         else:
             # May as well raise an exception -- the data cannot the processed
             yield start, None 
             start= row

Вы используете это следующим образом.

data = TimeClock.objects.order_by('card','rec_date','rec_time').all()
for start, end in make_pairs( data ):
    WorkIntervals.objects.create( start.card, start.rec_date, start.rec_time, end.rec_time, ... )

Теперь вы можете работать с интервалами. Если бы было возможно их создать.

1 голос
/ 13 августа 2010

Ну, здесь есть куча отдельных проблем.Я предполагаю, что вы уже получили отфильтрованные данные, так что ваш журнал выглядит как все события для уникальной карты в определенный день.Предположим, эти данные хранятся в виде списка строк в log.Тогда:

import datetime
def dates( log ):
    ''' Yields consecutive datetimes in the log. '''
    for event in log:
        yield datetime.datetime.strptime( event[ 12 : 28 ], "%Y-%m-%d %H:%M" )

def time_clocked_in( log ):
    assert not len( log ) % 2
    total_time = datetime.timedelta( 0 )
    event_dates = dates( log )
    try:
        while 1:
            total_time -= next( event_dates ) - next( event_dates )
    except StopIteration:
        pass
    return total_time

log = [
    "2977 00040  2010-07-30 09:58 2010-07-31 13:37:31",
    "2978 00040  2010-07-30 15:33 2010-07-31 13:37:31",
    "2979 00040  2010-07-30 16:13 2010-07-31 13:37:31",
    "2980 00040  2010-07-30 19:41 2010-07-31 13:37:31"
]

print( time_clocked_in( log ) )
>>> 9:03:00
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...