簡體   English   中英

如何將日期列表與模式匹配?

[英]How to match a list of dates to a pattern?

我有一個帶有三個對象的tuples的Python list :一個string (例如:title), date和另一個string (例如:name)。

例:

scientific_works = [
    ('SW 1', datetime.date(2000, 10, 15), 'auth 1'),
    ('SW 2', datetime.date(2000, 11, 3), 'auth 1'),
    ('SW 3', datetime.date(2000, 11, 4), 'auth 1'),
    ('SW 4', datetime.date(2000, 12, 1), 'auth 1'),
]

然后我有一個模式:

datedate ,(至少) int從項目listint天/周/月/年

例:

from  datetime.date(2000, 11, 1)
until datetime.date(2000, 11, 30)
1 item per day

我想要該算法做什么:

  • 給定該列表和該模式,過濾出的項目是否符合規則?

在示例的情況下,此模式將匹配2個項目,所有這些項目均符合此處的規則: 1 item complete per day ,但是,由於每天的區塊中都沒有an item ,因此算法將返回false

另一個例子:

  • 每個Int_2(每天/每周/每月)是否至少有Int_1個項目(作品)?
    • 每天進行1項工作,則意味着在給定的日期范圍內,每1天至少要有1個項目。 每周2次作品意味着日期范圍內每周至少2次作品(或7天)。

我可以遍歷列表,並找出哪些項目匹配fromuntil模式,當然。

但是,對於將它們與其余規則進行匹配,以查看其是肯定的還是否定的,我確實感到困惑。

我的問題:

  • 如何構造算法,為其提供列表和規則模式(每個y天或每周或每月或每年x個項目),並查看是否匹配?

我正在為應用程序的一個小組件工作,無論作者是否解鎖獎勵,給定的數據(列表)和規則(模式)。

我已經完成了udacity的幾個Python類,包括大多數算法,但確實找不到解決方法。

到目前為止,我想到了這一點:

  1. 過濾具有給定日期范圍的列表項。
  2. 計算范圍內的范圍塊:從d1到d2的1天= 5天-從d1到d2的3周= 3周
  3. 在上面計算的int范圍內創建一個循環。
  4. 在循環的每個步驟中,將周,月,年轉換為天。
  5. 將金額添加到開始日期,然后查看項目是否與日期范圍匹配。
  6. 將金額添加到日期范圍的下一個開始並重復。

但是,這不起作用,我也不認為將塊轉換為幾天是完全有效的。

謝謝。

您能否發布一個更好的示例來說明比賽必須遵循的規則? 您是否在每個時間段尋找每位作者一定數量的項目? 或者,您是在一段時間內尋找某些條目,然后找到它們所屬的人? 這將影響排序。

我認為您最終將不得不對這些數據使用排序算法,如果以正確的方式進行操作,這並不可怕。

從問題的底部開始,我認為如果您每n個時間段(天/周/月)搜索x項,然后確定作者,則可能會有些混亂。 如果您的作者人數有限,可能更容易將其翻轉並為每個作者創建一個數組,然后將項目和日期存儲在其中。 然后,您只需對每個作者運行一個測試循環,即可檢查他們的所有條目以查看它們是否符合要求。

對於Python類,MIT OpenCourseware的6.00《計算機科學與編程簡介》非常好。 可以在以下網址找到它: http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/ >

我將使用以下設計:主生成器函數,它在工作序列上進行迭代並產生“好”的函數; 以及一組可實現特定規則的可插拔過濾器,例如日期范圍,每天,每周,每月N個項目等。

下面是一個小例子來說明這個想法:

from datetime import date
from pprint import pprint

scientific_works = [
    ('SW 1', date(2000, 10, 15), 'auth 1'),
    ('SW 2', date(2000, 11, 3), 'auth 1'),
    ('SW 3', date(2000, 11, 4), 'auth 1'),
    ('SW 4', date(2000, 11, 5), 'auth 1'),
    ('SW 5', date(2000, 12, 1), 'auth 1'),
    ('SW 6', date(2000, 12, 15), 'auth 1'),
    ('SW 7', date(2000, 12, 18), 'auth 1'),
    ('SW 8', date(2000, 12, 22), 'auth 1'),
]

def filter_works(works, *filters):
    for work in works:
        good = True
        for fil in filters:
            good = good and fil(work)
        if good:
            yield work

class RangeFilter(object):
    def __init__(self, from_date, to_date):
        self.from_date = from_date
        self.to_date = to_date

    def __call__(self, work):
        return self.from_date <= work[1] <= self.to_date


class WorksPerMonthFilter(object):
    def __init__(self, limit):
        self.limit = limit
        self._current_month = date.min
        self._current_number = 0

    def __call__(self, work):
        month = date(work[1].year, work[1].month, 1)
        if month == self._current_month:
            self._current_number += 1
        else:
            self._current_month = month
            self._current_number = 1
        return self._current_number <= self.limit


if __name__ == '__main__':
    pprint(list(filter_works(scientific_works, RangeFilter(date(2000, 10, 1), date(2000, 11, 30)), WorksPerMonthFilter(2))))
    pprint(list(filter_works(scientific_works, RangeFilter(date(2000, 10, 1), date(2000, 12, 31)), WorksPerMonthFilter(2))))
    pprint(list(filter_works(scientific_works, RangeFilter(date(2000, 10, 1), date(2000, 12, 31)), WorksPerMonthFilter(3))))

如果模式是:

from  start_date
until end_date
X items per period

然后找出是否scientific_works圖案,的模擬匹配numpy.histogram()函數可以使用:

import datetime
import numpy as np

ts = datetime.date.toordinal # or any monotonic numeric `date` function 
hist = np.histogram(map(ts, (date for title, date, name in scientific_works)),
                    bins=map(ts, daterange(start_date, end_date, period))[0]
does_it_match = all(x >= X for x in hist)

哪里:

def daterange(start_date, end_date, period):
    d = start_date
    while d < end_date:
        yield d
        d += period

例:

>>> from datetime import date, timedelta
>>> list(daterange(date(2000, 1, 1), date(2000, 2, 1), timedelta(days=7)))
[datetime.date(2000, 1, 1), datetime.date(2000, 1, 8),
 datetime.date(2000, 1, 15), datetime.date(2000, 1, 22),
 datetime.date(2000, 1, 29)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM