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の方が高機能みたいだが重い。

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

2019年4月19日金曜日

今年の桜も終り

sakura

今年の桜も終り。

お団子は無かったけど、花鎮祭(はなしずめのまつり)に出会えたのよかった。 たまたま遭遇したイベント(亀岡の出雲大神宮)。 ちょうど神楽?をやっていた。

肩に乗ったり、掛け合いもジョーク混りで面白かった。 チャリなんで長居できず残念な気分になった。 後で知ったのだけど、伊勢大神楽らしい。

「出雲風流花踊り」というのがメインらしいが チャリなんで、時間がなかった。雨乞いと豊作祈願祈願らしい。あってるかな。

ぶらぶらしていて、何かに出会えるのポタリンの楽しみ。 梅雨の前に、もっと出掛けたいと思った一日。

2019年4月15日月曜日

Emacs の org-mode で export 先を指定

これまで、org-modeからexportする場合、 ディレクトリとかファイル名は指定できないと思い込んでいた。 で、コピペを多用していたが、なんのことはない。 プリアンブルで指定すれば良いだけだった( これだから素人は困る)。

#+EXPORT_FILE_NAME:  ~/work/temp.md

ここで知った。

サブツリーでoverwriteできると記載されている。 私の環境ではダメか、と思ったが、export時に c-s でexport対象をsubtree にすればOKだった。 org-narrow-to-subtree で作業すれば、なんとなく幸せかも。

subtree内にPROPERTIESのブロックが無いのに、subtreeをexportしようとすると、 ファイルバッファのデフォルト?が使われて上書きされたりするので注意が必要。 PROPERTIESブロックにカーソルを置いてexportする癖をつけないと。

うまく設定できれば、静的サイトジェネレータ配下への移動が簡素化できる。
mkdocsに挑戦してみるかも。

2019年4月5日金曜日

Emacsのpython(elpy)関係を見直し(201912up)

今回は、python関係を見直してみた。 あくまで初心者用なので、projectとかtestとかは考えてない。 補完と文法チェックが出来ればよし。

環境は、debian(buster)で、pyenvを使って3.7。 virturalenvは使わず、globalにしている。 モジュールは、pipでインスト。

emacsは26.1で、use-package + ivy + company な環境。
company-jedi は使ってない。

基本はいつもどおり、コピペ。

(201912)pyvenv, jedi-core

pipenv  から  require  されているので、pyenv だけ有効にした。(210912)

  (use-package pyvenv :ensure t)

これまで pyenv-mode を使ってたが、 elpy が pyvenv を使っているので、 今回、 pyvenv にした。

jediは、elpy-module-companyがあるので、jedi-core を インストすれば良いようだ。 elpy-module-company and company-jedi are kind of redondant( https://github.com/jorgenschaefer/elpy/issues/1397)

下の設定は無効化。

   (use-package pyvenv :ensure t
    :mode ("\\.py\\'" . pyvenv-mode)
    :interpreter ("python" . pyvenv-mode)
    :after projectile
    :config
     (use-package jedi-core :ensure t
      :config
       (add-hook 'python-mode-hook 'jedi:setup)
       (setq jedi:complete-on-dot t)
       (setq jedi:use-shortcuts nil)
    )
   )

pipenv, jedi-core(201906)

pipenv を使ってみようと、 変更してみた。 pipenv 自体の使い方は、以下など参考にしてやってみた。

これまでは、home ディレクトリ全体を、pyenv で 3.7 にしてあるだけで、 作業フォルダ毎の仮想環境は使っていなかった。

まだ、一つの作業でしか試してないが、 なんとか使えているように思う。 のだが、emacsの反応が少し遅くなった?ように感じる。

projectile は一応動いているかも、という状態で意識的に使ってないない。 まあ、プロジェクトなんて僅かだから。

  (use-package pipenv :ensure t
    :diminish (pipenv-mode . "penv")
    :hook (python-mode . pipenv-mode)
    :init
    (setq pipenv-with-projectile nil)  ;; Disable Projectile integration
    ;; まだ使い熟せてないし、理解もできてないから。
    ;; (setq
    ;;  pipenv-projectile-after-switch-function
    ;;  #'pipenv-projectile-after-switch-extended)
    :config
    (setq pipenv-with-flycheck nil)
    ;; Use the pipenv env. when searching for Flycheck executables.
    )
    ;; [updata 201912]
    ;;
    ;; (use-package pipenv :ensure t
    ;; :hook (python-mode . pipenv-mode)
    ;; :custom
    ;;  (pipenv-projectile-after-switch-function #'pipenv-projectile-after-switch-extended)
    ;; )
    ;; C-c C-p a   pipenv-activate
    ;; C-c C-p d   pipenv-deactivate
    ;; C-c C-p s   pipenv-shell

   (use-package jedi-core :ensure t
    :config
     (add-hook 'python-mode-hook 'jedi:setup)
     (setq jedi:complete-on-dot t)
     (setq jedi:use-shortcuts nil) ; M-. and M-,
   )

pipenv のメモ

ディレクトリ作成、移動、インスト

  $ mkdir hoge
  $ cd hoge

  # 仮想環境の構築
  # $ pipenv install
  $ pipenv --python 3.7,3
  # $ pipenv --python 2.7.14  Python 2.7.14 を使う

  # PipfileとPipfile.lockが作成される。
  #  + Pipfile => 設定ファイル
  #  + Pipfile.lock => インストールしたライブラリ情報

Pipenvシェルを有効化、パッケージ管理

  $ pipenv shell
  $ pipenv install pylint
  $ pipenv install --dev epc
  # pipenv install --dev XXXX   開発時しか使わないなら
  $ exit  ::停止

  # emacs で使うやつ。
  #   epc, jedi, autopep8, pylint, yapf, isort, black
  #   black は --pre が必要だった
  # Pipfile に記述して、
  #   $ pipenv update
  # で全パッケージをインスト、更新できる

python-mode

elpyを使うには python-mode が事前に有効になっている必要がある。 折り畳みは、buildinの outline-minor-mode を使っている。

Debian のパッケージでインストされる /usr/share/emacs/26.1/lisp/progmodes/python.el.gz を使うようにした。 (201908)

   ;; [add 201912]
   (add-to-list 'interpreter-mode-alist '("python3" . python-mode))
   ;;
   (use-package python-mode :ensure nil
     :mode ("\\.py\\'" . python-mode)
     :interpreter ("python" . python-mode)
     ;; :after pyvenv-mode
     :config
     (python-mode)  ;; (201912)
     (setq python-indent-guess-indent-offset-verbose nil)  ;; (201912)
     ;; Non-nil means to emit a warning when indentation guessing fails.
     ;;
     (setq electric-indent-local-mode nil)
     (setq py-smart-indentation t)  ;; new in ver 6.2.4
     ;;
     (setq electric-indent-local-mode -1)
     ;; (setq indent-tabs-mode nil)  ;; original nil  (201912)
     ;; (setq py-indent-tabs-mode nil)  ;; original nil
     ;; (setq python-indent-offset 4)  ;; default 4
     ;;

     ;; (setq python-check-command "~/.pyenv/shims/pylint")  ;; 重複、コメントアウト
     (setq python-shell-interpreter "python")  ;; (201912)
     (setq python-shell-completion-native-disabled-interpreters '("python"))  ;; (201912)
     ;; (setq python-shell-interpreter-args "-i")  ;; original "-i"
     ;;
     (flymake-mode nil)  ;; (201912)
     (outline-minor-mode t)

     (setq python-check-command "~/.pyenv/shims/pylint")  ;; (201912)
     ;;
     ;; (201912) move to eldoc config.
     ;; (eldoc-mode t)
     ;; (setq eldoc-echo-area-use-multiline-p t)
     ;; (setq eldoc-idle-delay 3)
     ;; (setq eldoc-minor-mode-string nil)
     ;; (setq python-fill-docstring-style 'pep-257) ;; original pep-257
    )

elpy(includ company)

基本の設定に、上記と、gtags があれば、初心者の私には十分だと思うが、 elpy を入れると編集が少し楽になると感じている。

   (use-package find-file-in-project :ensure t
    :after projectile
    )
   ;;

   (use-package elpy :ensure t
    :diminish (elpy-mode . "elpy")
    :after python-mode
    :hook (python-mode . elpy-enable)
    ;; ここを elpy-mode にすると、python-modeになってないと怒られる。
    ;:init
    ;(package-initialize) ;; 無くても大丈夫そう
    :config
    (elpy-mode)
    ;for emacs26.1 is a new flymake.
    (when (require 'flycheck nil t)
     (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
     (add-hook 'elpy-mode-hook 'flycheck-mode))
    (setq elpy-syntax-check-command "pylint")
    ; flake8 がうまく動いてくれないから。きっとversionが附合してない。
    ; 初心者にはpylintよりflake8が向いていると、どこかで読んだ記憶がある。
    (delete 'elpy-module-highlight-indentation elpy-modules)
    ;; elpy は https://github.com/antonj/Highlight-Indentation-for-Emacs
    ;; を使ってる。

    ;; https://www.reddit.com/r/emacs/comments/8i4x57/is_it_possible_to_disable_elpy_minibuffer_output/
    ;; Original value was when-shell-not-visible  (201912)
    (setq elpy-shell-echo-output nil)

    ;; https://github.com/jorgenschaefer/elpy/issues/1416   (201912)
    (setq elpy-eldoc-show-current-function nil)

    (outline-minor-mode t)  ;; (201912)
    (flymake-mode nil)  ;; (201912) 記入漏れ
    )

elpy-config の結果は以下。

    Elpy Configuration

    Virtualenv........: None
    RPC Python........: 3.7.3 (/home/hogehoge/.pyenv/shims/python)
    Interactive Python: python (/home/hogehoge/.pyenv/shims/python)
    Emacs.............: 26.1
    Elpy..............: 1.18.0
    Jedi..............: 0.15.1
    Rope..............: 0.14.0
    Autopep8..........: 1.4.4
    Yapf..............: 0.29.0
    Black.............: 19.3b0
    Syntax checker....: pylint (/home/hogehoge/.pyenv/shims/pylint)
  • elpy-module-company が上手く使えているのかは不明。それなりに使えていると思う。

  • shell buffer、TEST、Djangoは使ってない。

  • C-c C-r r (elpy-refactor) は rope を使うらしいが、理解できてない。

    リファクタリング (refactoring) とは、コンピュータプログラミングにお いて、プログラムの外部から見た動作を変えずにソースコードの内部構造を 整理することである。wikipedia

  • flymake は flychek のキーバインドを使う。

    elpyのキーバインドは、flycheckに対応していないようだ。

  • カーソル移動は普通。

    カーソルのブロック単位での移動は c-up/down(at the line head), right/left

  • 対象領域の移動させるのは M-up/down (elpy-nav-move-line-or-region-up/down)

    インデントは M-left/right (elpy-nav-indent-shift-left/right)

  • searchは、 counsel-git-grepdeadgrep を主に使うので、elpyの機能は使ってない?

    • c-c c-f (elpy-find-file: Find a file in the current project)
    • C-c C-s (elpy-rgrep-symbol)
    • M-TAB (elpy-company-backend)
  • naviは、 counsel-gtags を使ってるので、elpyの機能はほとんど使ってない。

    • M-. / M-* (elpy-goto-definition) (pop-tag-mark)
    • C-x 4 M-. (elpy-goto-definition-other-window)
    • C-c C-o (elpy-occur-definitions) imenu-list より見易い。
  • C-c C-d (elpy-doc) try and find the documentation for that object

  • C-c C-r f (elpy-format-code)

  • C-c C-r i (elpy-importmagic-fixup) は使えてない。

  • C-c C-e (elpy-multiedit-python-symbol-at-point)

    うまく動かない。occur を使えばよさそう。

importmagic, py-isort

import関係は、このふたつ。 importmagic は便利そうなんだが使えてない。 結局、 py-isort を叩いている。

   ;;  止め。リアルタイムで動くのは、遅くなるから。(201912)
   ;;(use-package importmagic :ensure t
   ;; :defer t
   ;; :diminish importmagic-mode
   ;; :after python-mode
   ;; :config
   ;; (add-hook 'python-mode-hook 'importmagic-mode))

   (use-package py-isort :ensure t
    :defer t
    :after python-mode
   )

highlight-indent-guides(201908up)

インデントガイドは、highlight-indent-guidesを使っている。 インデントガイドは必要だ。
elpy で使ってるやつにすればよかったかもと思ったが、 他でも使うと思うので、汎用性のあるやつとして選んだのだと思う。

(use-package highlight-indent-guides :ensure t
 :diminish highlight-indent-guides-mode
 :hook
  (prog-mode . highlight-indent-guides-mode)
  (rst-mode . highlight-indent-guides-mode)
 :config
  (setq highlight-indent-guides-method 'column)  ;; fill,column,character
  (setq highlight-indent-guides-auto-enabled t)  ;; automatically calculate faces.
)

まだ使えてないものが多いのだが、 一応、使えているような気になれてるので、 よし、としておこう。

Emacs の lsp の設定、なう(202310)

前回さらしてから、さらに1年。そう、3年めになる。 が、今回は一段と自信がない。 環境は、 Debian GNU/Linux 12 (bookworm) + emacs(29.1)。consult + company。 embark は未だに使ってない。 用途は、メモ と ...