Python生産カレンダー

画像



まえがき





私がアナリストとして働いていたとき、同僚と私は改善のために配達時間を計算するほぼ毎日の必要がありました。 たとえば、タスクは次のとおりでした。明日+ 40営業日後の完了の配達日を計算することです。 分析部門の作業中および管理中に、この機能は自動化に至りませんでしたが、特にこれは初心者が基本的なPython構造に慣れるのに役立つ素晴らしいシンプルなプロジェクトであるため、修正することにしました。



このモジュールへの慣れを先延ばしにしないために、単純にコマンドラインに入力してください:

pip install prod-cal
      
      







この構成で開発されたため、プロジェクトがPython 2.7およびWindows 7で動作することを保証します。



パッケージを収集してPyPiにレイアウトする方法については説明しません。このトピックに関する非常に詳細な記事があります。初心者でもこのタスクに対処できると言うだけなので、新しいモジュールを作成することを考えている場合は、長いボックスに入れないでください複雑なことは何もありません。



この記事の主な目的は、このモジュールのデバイスを分解し、コミュニティによる開発の展望を概説することです。



カレンダーでカレンダーを作成しないようにするには、標準のcalendar.Calendarモジュールのすべてのメソッドを使用できます。





プロジェクト構成





インストール後、プロジェクトはC:\ Python27 \ Lib \ site-packages \ prodcalで利用可能になります。パッケージを仮想環境にインストールした場合は、<home directory wirthで探します。 環境> \ Lib \サイトパッケージ\ prodcal



プロジェクトをまったくインストールすることはできませんが、 PyPi Webサイトから直接ダウンロードしてください。 次に、プロジェクトでコードを解凍して直接使用します。



このプロジェクトは、次のファイルで構成されています(すべて拡張子が* .py)。





使用例
 from procal import ProdCal my_first_prod_cal = ProdCal() #    1  my_first_prod_cal.is_work_day(2016, 5, 1) #    my_first_prod_cal.is_work_day(2016, 4, 1) #    my_first_prod_cal.is_work_day(2016, 4, 2) #     ( ) my_first_prod_cal.is_work_day(2016, 2, 20) #     my_first_prod_cal.is_work_day(date(2016, 5, 1) #      (today - ) my_first_prod_cal.is_work_day('today') #      (yesterday - ) my_first_prod_cal.is_work_day('yesterday') #      (tomorrow - ) my_first_prod_cal.is_work_day('tomorrow') #        my_first_prod_cal.count_work_days([2016, 4, 1], [2016, 4, 30]) my_first_prod_cal.count_work_days([2016, 5, 1], [2016, 5, 31]) my_first_prod_cal.count_work_days([2016, 6, 1], [2016, 6, 30]) #        my_first_prod_cal.count_work_days(date(2016, 4, 1), date(2016, 4, 30)) my_first_prod_cal.count_work_days(date(2016, 5, 1), date(2016, 5, 31)) my_first_prod_cal.count_work_days(date(2016, 6, 1), date(2016, 6, 30)) #      (today, yesterday, tomorrow) my_first_prod_cal.count_work_days('today', date(2016, 4, 30)) my_first_prod_cal.count_work_days('yesterday', date(2016, 4, 30)) my_first_prod_cal.count_work_days('tomorrow', date(2016, 4, 30)) #           () my_first_prod_cal.count_work_days([2016, 4, 1], 30) my_first_prod_cal.count_work_days('today', 30) #        my_first_prod_cal.count_holidays([2016, 4, 1], [2016, 4, 30]) my_first_prod_cal.count_holidays([2016, 5, 1], [2016, 5, 31]) my_first_prod_cal.count_holidays([2016, 6, 1], [2016, 6, 30]) #        my_first_prod_cal.count_holidays(date(2016, 4, 1), date(2016, 4, 30)) my_first_prod_cal.count_holidays(date(2016, 5, 1), date(2016, 5, 31)) my_first_prod_cal.count_holidays(date(2016, 6, 1), date(2016, 6, 30)) #      (today, yesterday, tomorrow) my_first_prod_cal.count_holidays('today', date(2016, 4, 30)) my_first_prod_cal.count_holidays('yesterday', date(2016, 4, 30)) my_first_prod_cal.count_holidays('tomorrow', date(2016, 4, 30)) #           () my_first_prod_cal.count_holidays([2016, 4, 1], 30) my_first_prod_cal.count_holidays('today', 30) #       my_first_prod_cal.get_date_by_work_days([2016, 4, 1], 21)) my_first_prod_cal.get_date_by_work_days('today', 21)
      
      









実装



生産カレンダーの構造



すべての実稼働カレンダーは、prodcalsサブディレクトリに個別のファイルとして配置されます。 ファイル名形式acc。 小文字のISO国コード。 たとえば、ロス。 実稼働カレンダーはru.pyファイルにあります。



ファイルには、NON_WORK_DAY_DICTとWORK_DAY_DICTの2つの辞書が含まれます。これらは同じ構造を持ち、最初の辞書は休業日(休日)を記述し、2番目の辞書は就業日から週末への転送を記述します。 辞書は土曜日と日曜日の「標準的な」非稼働日を示していません。

カレンダーは2つのネストされた辞書で記述されます。月は1年に投資され、月の値は日のリストです。

カレンダーを操作するために、is_valueメソッドが実装された別個のクラスProdDictが作成され(標準ディクショナリから継承)、ディクショナリで渡された値の存在に応じてTrueまたはFalseを返します。 このクラスは、エントリの日付のみを受け入れます。 ProdDictクラスの実装は、prod_dictファイル(prodcalsサブディレクトリにあります)に記述されています。



ProdCalクラスの実装



引数を指定せずにこのクラスを作成できます。この場合、デフォルトのカレンダー(ロシア語)が使用されます。 使用するカレンダーを指定する場合、名前付き引数locale = <value>を渡す必要があります。ここで、valueは任意のレジスタのISO国コードです。 ウクライナの生産カレンダーを作成する例:

 from prodcal import ProdCal my_prod_cal = ProdCal(locale='UA')
      
      





現在サポートされている国は、ベラルーシ、ジョージア、カザフスタン、ロシア、ウクライナです。



ProdCalクラスメソッド

is_work_day



入力:日付、リスト(int付き)、引数のタプル、文字列( 'today'、tomorrow '、' yesterday 'のみをサポート)

出力:bool



説明:就業日であるかどうか設定日を確認します。



注:便宜上、このメソッドおよび他のすべてのメソッドには、サービス関数を説明するセクションで説明されているように、日付を引数として便利な形式で渡す機能があります。



count_work_days、count_holidays



入力:開始日、終了日(期間)、上記の日付形式。

出力:int



説明:特定の期間(count_work_daysの場合)の稼働日数をカウントし、count_holidaysの場合は休日の数をカウントします。



get_date_by_work_days



入力:開始日、int

出力:日付



説明:指定された稼働日数の終了日を計算します。



サービス機能の説明



サービス機能はservice.pyファイルにあることを思い出させてください。

最も単純なget_date_today関数は、渡された値を必要な日付に変換します。実装は最も控えめです(辞書からの選択など、より効率的な構築のために探究心を書き換えることを提案します)。



 def get_date_today(day): today = datetime.today().date() if 'today' == day: return today elif 'yesterday' == day: return today - timedelta(days=1) elif 'tomorrow' == day: return today + timedelta(days=1) raise ValueError('Unknown string format', day)
      
      







さまざまな形式で日付を使用する可能性の魔法(正しく表現されている場合)は、キャスト関数に実装されています。

キャスト関数の実装
 def cast(start_date, end_date): if isinstance(start_date, (tuple, list)) and isinstance(end_date, (tuple, list)): start_date, end_date = date(*start_date), date(*end_date) if isinstance(start_date, str): start_date = get_date_today(start_date) elif isinstance(start_date, (tuple, list)): start_date = date(*start_date) if isinstance(end_date, (tuple, list)): end_date = date(*end_date) elif isinstance(end_date, int): end_date = calc_days_by_int(start_date, end_date) if isinstance(start_date, date) and isinstance(end_date, date): pass else: raise ValueError("Unknown format for parse")
      
      







全体の考え方は非常に単純です。渡された引数の型を確認し、すべてを日付に合わせて返します。 理解できない場合は、例外をスローしてください。



別の興味深い場所はget_prodcals関数です。これは、渡された値に応じて、prodcalsサブディレクトリから目的のカレンダーをロードします。 これは、モジュールへのパスとして渡された文字列を解釈するimportlib標準ライブラリのimport_module()関数を使用して可能です。 例:import_module( 'prodcal.prodcals.ru')は、prodcals import ruと同等です。 この関数を使用する主なポイントは、ロードするカレンダーを明示的に指定することではありません。これにより、サポートがさらに容易になります。



新しいカレンダーのサポート



新しいカレンダーは、config.pyファイルに新しいカレンダーを追加し、テストを作成し、カレンダーをprodcalsサブディレクトリにロードすることでサポートされます。 さらに、これ以上行う必要はありません。



開発計画



すでにビジネスを始めている場合は、グローバルに解決する必要があります。世界中のすべての本番カレンダーをサポートしてください。



また、たとえば、送信された時間の日付と時刻の計算、Python3での互換性テストの作成、いくつかのエラーの修正など、いくつかの新しい関数を追加する予定です。



ロシア語を話すユーザーの場合、この記事はモジュールのドキュメントとして機能しますが、それ以外の場合は別のドキュメントを作成する必要があります。



これとプロジェクトの開発に参加したいすべての人のために、このリポジトリが利用可能です。



感謝の気持ち



私に加えて、チェリャビンスクのアルカディ・アリストフがこのプロジェクトに参加しています。



All Articles