2

私は3 つのオブジェクトを持つ Python を持っていlistます: (例: タイトル)と別の(例: 名前)。tuplesstringdatestring

例:

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'),
]

それから私はパターンを持っています:

からdateまでdate、(少なくとも)日/週/月/年あたりの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 itemfalse

もう一つの例:

  • Int_2 (日/週/月) あたり (少なくとも) Int_1 個のアイテム (作品) がありますか?
    • 1 日あたり 1 つの作業は、指定された日付範囲の 1 日ブロックあたり少なくとも 1 つのアイテムを意味します。1 週間に 2 作品ということは、日付範囲の各週 (または 7 日間のブロック) に少なくとも 2 作品ということです。

fromもちろん、リストを反復処理して、一致するアイテムとuntilパターンを見つけることができます。

しかし、それらを残りのルールと一致させて、それが正の一致か負の一致かを確認することについて、私は本当に混乱しています。

私の質問:

  • アルゴリズムを構築し、ルールのリストとパターン (y 日または週または月または年ごとに x 項目) を提供し、それが一致するかどうかを確認するにはどうすればよいですか?

著者が報酬のロックを解除するかどうかに関係なく、特定のデータ (リスト) とルール (パターン) が与えられるアプリケーションの小さなコンポーネントに取り組んでいます。

ほとんどのアルゴリズムを含む udacity のいくつかの Python クラスを完了しましたが、実際にはこれを回避する方法を見つけることができません。

これまでのところ、私はこれを考えました:

  1. 指定された日付範囲でリスト アイテムをフィルター処理します。
  2. 範囲内の範囲ブロックを計算します: d1 から d2 までの 1 日 = 5 日 - d1 から d2 までの 1 週間 = 3 週間
  3. int上記で計算した範囲でループを作成します。
  4. ループの各ステップで、週、月、年を日に変換します。
  5. 金額を開始日に追加し、アイテムが日付範囲に一致するかどうかを確認します。
  6. 日付範囲の次の開始に金額を追加して繰り返します。

ただし、これは機能せず、ブロックを日に変換することはまったく効率的ではないと思います。

ありがとうございました。

4

3 に答える 3

1

次の設計を使用します。一連の作業を反復処理して「適切な」作業を生成するメイン ジェネレータ関数。日付範囲、1 日あたり、1 週間あたり、1 か月あたりの 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))))
于 2013-11-09T12:06:18.137 に答える
1

試合が従わなければならないルールのより良い例を投稿できますか? 期間ごとに著者ごとに特定の数のアイテムを探していますか? または、ある期間の特定のエントリを探して、そのエントリが誰に属しているかを見つけますか? それはソートに影響します。

最終的には、このデータに対してソート アルゴリズムを使用する必要があると思いますが、正しい方法で行えば、これは恐ろしいことではありません。

あなたの質問の下部から、n 期間 (日/週/月) ごとに x 個のアイテムを検索し、作成者を特定する場合、少し面倒かもしれないと思います。著者の数が限られている場合は、それを裏返して各著者の配列を作成し、そこにアイテムと日付を保存する方が簡単かもしれません。次に、各作成者に対してテスト ループを実行し、すべてのエントリをチェックして、要件に適合しているかどうかを確認します。

Python クラスについては、MIT OpenCourseware の 6.00 Introduction to Computer Science and Programming が非常に優れています。http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/で見つけることができます>

于 2013-11-09T11:41:03.930 に答える
1

パターンが次の場合:

start_date から
end_date まで
期間あたり X アイテム

次に、パターンに一致するかどうかを調べるために、関数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)]
于 2013-11-10T02:38:13.140 に答える