2019年4月27日土曜日

Pythonで第三金曜日とか求めてみた

Pythonで第三火曜日とかを求めてみた。 単純に、ゴミ出し日を、 khal で登録してみたかったから。

いくつか見付けることができたが、 calendarを使う方法と、 dateutilを使う方法を試してみた。 出発点は、 ここ だったかな。

calendar を使う

ゴミ出しは、月毎なので、こちらの方が感覚に合うように思う。

#!~/.pyenv/shims/python
"""Calendat module test."""

import sys
import logging

from calendar import Calendar, TextCalendar

import logzero

LOG_FORMAT = "%(color)s[%(module)s.%(funcName)s:%(lineno)3d]%(end_color)s %(message)s"
FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT)
logzero.setup_default_logger(formatter=FORMATTER)
logzero.logfile("./log000.log", maxBytes=3e5, backupCount=3)
logzero.loglevel(logging.DEBUG)

def match_weekday(c_year, c_month, c_wday, c_oweek):
    """Calc date of n-th weekday."""
    # c_year, c_month = 2019, 5
    # c_wday = 5   # Monday is Zero
    # c_oweek = 2  # 1st weeek is Zero

    # 指定されて曜日だけのリスト作成
    weday_list = Calendar(firstweekday=0).monthdayscalendar(c_year, c_month)
    sel_wekday = [x[c_wday] for x in weday_list if x[c_wday] != 0]

    # 指定された週の日付を返す
    try:
        match_date = sel_wekday[c_oweek]
    except IndexError:
        match_date = -1

    return match_date


def main():
    """Do main."""
    #

    wday_char = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    week_char = ["1st", "2nd", "3rd", "4th", "5th"]

    r_year, r_month = 2019, 5
    r_weday = 4  # Zero is Monday
    r_oweek = 2  # 1st weekday is Zero

    # 指定された年、月のカレンダーの表示
    tcalendar = TextCalendar(firstweekday=r_weday)
    print(tcalendar.formatmonth(r_year, r_month))

    match_day = match_weekday(r_year, r_month, r_weday, r_oweek)

    logzero.logger.info(
        "\n* {0:s} {1:s}({2:02d}/{3:02d}) 不燃ゴミ".format(
            week_char[r_oweek], wday_char[r_weday], r_month, match_day
        )
    )

    logzero.logger.info(
        "\n* khal new -a garbage {0:4d}{1:02d}{2:02d} 不燃ゴミ".format(
            r_year, r_month, match_day
        )
    )

    sys.exit()


if __name__ == "__main__":
    main()
    sys.exit()
#

   $ python t15_calendar.py
         May 2019
   Fr Sa Su Mo Tu We Th
                   1  2
    3  4  5  6  7  8  9
   10 11 12 13 14 15 16
   17 18 19 20 21 22 23
   24 25 26 27 28 29 30
   31

   [t15_calendar.main: 88]
       * 3rd Fri(05/17) 不燃ゴミ
   [t15_calendar.main: 94]
       * khal new -a garbage 20190517 不燃ゴミ

dateutil を使う

ゴミ収集日なので、4週めまででよい。
もっと複雑なことをやるためのツールという印象。

datetimeなので、該当日が休日かどうかも判定させてみた。 休日の判定は、 jpholiday を使ってみた。

#!~/.pyenv/shims/python
"""dateutil and jpholiday module test."""

import sys
import logging
import datetime
from calendar import TextCalendar

import logzero
import jpholiday
from dateutil.rrule import MONTHLY, rrule

LOG_FORMAT = "%(color)s[%(module)s.%(funcName)s:%(lineno)3d]%(end_color)s %(message)s"
FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT)
logzero.setup_default_logger(formatter=FORMATTER)
logzero.logfile("./log000.log", maxBytes=3e5, backupCount=3)
logzero.loglevel(logging.DEBUG)


def match_weekday2(c_year, c_month, c_wday, c_oweek):
    """Calc date of n-th weekday."""
    # c_year, c_month = 2019, 5
    # c_wday = 5   # Monday is Zero
    # c_oweek = 2  # 1st weeek is 1

    # 指定されて年、月の開始日
    dt_stday = datetime.date(c_year, c_month, 1)

    # 指定されて年、月の1日から4つめまでの指定曜日リストから選択
    try:
        match_date = rrule(
            freq=MONTHLY, dtstart=dt_stday, byweekday=c_wday, count=4
        )[c_oweek]
    except IndexError:
        # 該当がなければ、負
        match_date = -1

    return match_date


def main():
    """Doing a read viking file for make class."""
    #

    r_year, r_month = 2019, 5
    r_weday = 4  # Zero is Monday
    r_oweek = 0  # 1st weekday is Zero

    tcalendar = TextCalendar(firstweekday=0)
    print(tcalendar.formatmonth(r_year, r_month))

    match_day = match_weekday2(r_year, r_month, r_weday, r_oweek)
    if rr_day != -1:
        mes_str = match_day.strftime("\n* %m-%d %a 不燃ゴミ")
        if jpholiday.is_holiday_name(match_day.date()):
            # 休日だったら、追加
            mes_str += ": {0:s}".format(
                jpholiday.is_holiday_name(match_day.date()))
        logzero.logger.info(mes_str)


if __name__ == "__main__":
    main()
    sys.exit()
#


   $ python t15_dateutil.py
         May 2019
   Mo Tu We Th Fr Sa Su
          1  2  3  4  5
    6  7  8  9 10 11 12
   13 14 15 16 17 18 19
   20 21 22 23 24 25 26
   27 28 29 30 31

   [t15_dateutil.main:114]
       * 05-03 Fri 不燃ゴミ: 憲法記念日

これを、今月と来月について、 まとめて表示させたのが以下。


$ python garbage_date.py 
  
     2019-05 (current month)
    
     !!  check
     khal list -a pubs 20190501 30d
    
     khal new -a pubs 20190507 空缶、危険、有害ゴミ :: garbage
     khal new -a pubs 20190514 古紙、布, ペットボトル :: garbage
     khal new -a pubs 20190521 空瓶、ガラス :: garbage
     khal new -a pubs 20190528 燃えないゴミ :: garbage
    
     2019-06 (Next month)
    
     khal list -a pubs 20190601 29d
    
     khal new -a pubs 20190604 空缶、危険、有害ゴミ :: garbage
     khal new -a pubs 20190611 古紙、布, ペットボトル :: garbage
     khal new -a pubs 20190618 空瓶、ガラス :: garbage
     khal new -a pubs 20190625 燃えないゴミ :: garbage

ターミナル上のコピペで作業できるようになった。よしとしよう。

2019年4月25日木曜日

Emacsのrst-modeの設定見直し

markupでのメモ作業は、orgがメインだが、 たまにmarkdownと reStructuredText( rst )を直接使う。sphinxとPelicanを使ってるから。

emacsの設定方法は、 orgやmarkdownについては比較的容易に見付けることができるが、 rst の方はなんとも、 という状況みたい。コピペなんで。

これまでは、標準の rst-modeyasnippetflycheck (rstでは、sphinx-build) を 併せて使ってきている。

ちなみに、rst-mode の使っている機能は、

  • headerの設定
  • tocリスト (imenuで十分だったりする)

ぐらいで特に必須ではないように思う。 listさえ使ってない状況。 当然、効率は著しく悪い。 使い方は、 ネットで探すより rst.el に含まれる英語のドキュメントの方が 私には適切に思えたのだが。

一番不満なのが、outlineが使えないこと。 outlineは、一応、outline-minor-mode を使っているが、 headerを上手に認識してくれず、サポート外のように思える。

そこで今回 move-text を入れてみた。 line-up/down region-up/downが使えれば、 yank,paste とかとの併用で、それなりに改善されるかもと考えたから。

    (use-package rst :ensure nil :defer t
     :bind( :map rst-mode-map
            ("C-c r" . rst-preview-by-eww)
            ("C-M-<down>" . move-text-down)
            ("C-M-<up>" . move-text-up)
          )
     :mode
      ("\\.rst\\'"  . rst-mode)
      ("\\.rest\\'" . rst-mode)
     :config
      (add-hook 'rst-adjust-hook 'rst-toc-update)
      (setq indent-tabs-mode nil)
      (setq electric-indent-mode t)
      (setq electric-quote-mode nil)
      ;
      (defun rst-preview-by-eww ()
        (interactive)
        (message (buffer-file-name))
        (call-process "pandoc" nil nil nil
                      (buffer-file-name)
                      "-o"
                      "/tmp/rst.html")
        (let ((buf (current-buffer)))
          (eww-open-file "/tmp/rst.html")
          (switch-to-buffer buf)
          (pop-to-buffer "*eww*")))
     ;
    (use-package move-text :ensure t)
    )

結果として、随分ましになったように思う。 lineでもregionでも上下移動が可能になる。 で、慣れてくれば当然、 promote/demote が欲くなるが.....

rst.el 自体はメンテされているようで、 Debian(buster)のrst.elはemacs26.1までだが、 公式ページのヤツは26.2のようだ。 エキスパートの方達はどう使っているのか不思議。

なお、pandocを使ってewwでpreviewしている(どこかのコピペ)が、 これは、flycheckをオフにして、previewでチェックする、 という使い方になっている。まあ、短かい文章だし、 見た目の確認の必要性はそれほど感じなていない。

riv.vimの方が高機能みたいだが重い。

ちょっとだけ前進したかも。まだまだ先は長そう。 しかし、達人はどう使っているのだろう。

麻のボディタオル

2018年の秋(まだ、自転車を封印してない)、 近江上布伝統産業会館 で、興味からボディタオルを購入した。 お、よかった。: 自然派パン工房 ふるさとの道 ほぼ毎日風呂で使ってきて、ついに寿命がきたようだ。 お店の方に、「糸が痩せて破れてくる」まで使える、と...