nikkie-ftnextの日記

イベントレポートや読書メモを発信

Pythonで備える2021春アニメ

f:id:nikkie-ftnext:20210407214953p:plain

はじめに

四月と言ったら「君の嘘」。nikkieです。
気づけば桜🌸が咲き(そして散り)、アニメファンとしてはウキウキの新クールです。

クールの頭には、アニメイトタイムズさんの一覧でざっと眺め、「0話切り」をしています。
今回も眺めていたところ、「パースして手元で見て、放送開始日順に並び替えられるのでは?」と思い付き、Pythonでやってみました1

目次

動作環境

HTMLのパースには以下を使います:

beautifulsoup4    4.9.3

なお、対象のHTMLはブラウザの機能でダウンロードして、パースの実装を試行錯誤しています。
試行錯誤の際にサーバに不要なリクエストが飛ぶのは望まないので、ローカルにダウンロードしました。

Pythonで0話切り

対象のHTML

開発者ツールで覗くと、sectionタグとasideタグによる2カラム構成です。
sectionタグの中には、大まかには以下の構造でアニメの情報が詰まっています(今回興味あるところだけ抜き出しました)。

<h2 id="1">アニメ1</h2>
<table>
<tr>
<td>放送<br>スケジュール</td>
<th>2021年4月X日</th>
</tr>
<tr>
...
</tr>
</table>
...

<h2 id="2">アニメ2</h2>
<table>
<tr>
<td>放送<br>スケジュール</td>
<th>2021年4月Y日</th>
</tr>
<tr>
...
</tr>
</table>
...

パース戦略

h2タグとtableタグがセットになって、春クールのアニメ分並んでいます。
h2タグはアニメのタイトル以外にも使われているのですが、アニメのタイトルで使う場合id属性が指定されているという特徴がありました2
この作りを利用して、sectionタグの中身から以下を抜き出しました:

  • id属性が指定されたh2タグ
  • tableタグ

これらの数が一致することを確認しました!
あとは、tableタグの中の「放送スケジュール」の行の日付をdatetime.dateに変換して、放送開始日順に並び替えます。

スクリプトはこちら:

取り組んで知った技術的なトピック

beautifulsoup4でHTMLタグのid属性を扱う

soup.find_all("タグ") で見つかった1個1個のタグ(Tag)について、タグの属性(attribute)3を扱えました!

h2タグについて

  • id属性を持つか判定:has_attr("id")4
  • id属性の値:get_attribute_list("id")5リストで返ります)

refindallfinditerの違い

matches = re.finditer(r"(\d{4})年(\d{1,2})月(\d{1,2})日", schedule)
for m in matches:
    ...

正規表現を使い、放送日を表す文字列 schedule から finditer全てのマッチオブジェクトを取り出します6
今クールに再放送するために、本放送日と合わせて複数の日付が載っているケースがありました(例:ニジガク)。

https://docs.python.org/ja/3/library/re.html#finding-all-adverbs-and-their-positions

パターンの全てのマッチについて、マッチしたテキスト以上の情報が必要なら、文字列ではなく マッチオブジェクト を返す finditer() が便利です。

個々のマッチオブジェクト m

  • m.group(0)正規表現にマッチした文字列全体
  • m.group(1), m.group(2), ...がキャプチャの()に対応

します7

感想

手元でタイトル眺め、気になるものは詳細を確認して、今期の0話切りは終了です。
気になってた漫画タイトルのアニメ化が多く、楽しみです🤩

今クールは全部で80作品ほどあり、「こんなにあるのか」と驚きました。
続き物や深夜帯でない枠は含んでいないので、1クール100本くらいのアニメが流れているんですね!

スクラップ:心ない言葉との向き合い方、寝言は寝て言え / 反論より専念

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
アウトプットする身として、「心ない言葉はちょっとした恐怖だな」と思っています。
この3月に心ない言葉との向き合い方のヒントを2件見かけました。
後々見返せるように、記事にまとめます。

目次

寝言は寝て言え

3/6のOSC2021 Online/Springで聞いた、モウフカブールさんのトーク作っては捨てる時代の過ごし方』。

トーク自体も分かりやすいですが、心ないレビューに対して「寝言は寝て言え」とバッサリ!

Twitterや購入者に好評であれば、「ネガティブなレビュー1件だけを気にしなくていいんだ」という気づきがありました。

また、「自分の目で確かめる」「誰かが褒めた本が必ずしもいい本ではない」というのも共感です。

反論より専念

直近見かけたのが、みかん本(『ゼロからのOS自作入門』)のAmazonレビューの件。

西尾さんのコメントを見て、勇気づけられました。

「ちゃんと読んでくれる人を大切にすべき」

どちらのケースも裏にあるのは、ちゃんと読んでくれる人を大切にすべきということなのかなと思います。

スレッドて西尾さんが共有していた「反論より専念」も必見感。

反論で失った時間は戻ってこない
→プロジェクトに有益な専念をしよう

心ない言葉に削られそうになったときは、このエントリを見返そうと思います。

P.S. アニメに脱線:ウマ娘 ライスシャワー

※注意:ここから先は趣味のアニメ話全開になります。

「間もなく出走開始」から「3年」後にリリースされたゲームが好評のウマ娘
今期はアニメを楽しませてもらってますが、心ない言葉で思い出したのがライスちゃん(ライスシャワー 🐴🍚🚿)1
あるウマ娘に「無敗の三冠」という大記録がかかったレースでライスちゃんは見事勝つ👏んですが、大記録達成を望んでいた観客から心ない言葉をかけられる2んですよね😭

ただ彼女、裏でめっちゃ泣いてるんですけど、芯は強く「専念」して結果出しているんです!
なんか、この話題とつながるなーと思いました。

なお、最近TLに絵師さんのライスちゃんが流れてきて、私はほっこりしています。
ゲームで人気だったら嬉しいですねー。


  1. 7,8話です😭 https://anime-umamusume.jp/story/?id=07

  2. 記録がかかった側に勝ってほしい気持ちもすごく分かりますが、周りが手を抜いた勝負(八百長)を見たいわけではないと思います。ガチで勝負している以上、記録がかかった側が負けてしまうことだってありますし、応援していた側としてすごく残念な気持ちも分かりますが、ライスちゃんを責めるのだけは違うんと思うんですよ

振り返り:やはり俺のPyCon JP 2020スタッフ活動はまちがっていた。

f:id:nikkie-ftnext:20210325211020p:plain

はじめに

やっはろー! nikkieです。
今週は宿願のためにお休みにしています1
時間ができると自分の身を見つめ直せるものですね。
昨年のPyCon JPスタッフ活動を振り返ってみました2

※最初に断っておきますが、この記事の内容は、nikkie個人の見解です。PyCon JP 2021についての情報は PyCon JP Blog をご確認ください。

目次

私の熱いPyCon JP 2020スタッフ活動

PyCon JP 2020は8月末にオンライン開催しました 🙌 🎉

2019年のスタッフ経験を活かし、コンテンツチームのリーダーとして全力疾走しました💃

  • タイムテーブルドラフト作成
  • プロポーザル募集
  • プロポーザルレビュー
  • スピーカーとのコミュニケーション
  • キーノートスピーカーとのやり取り引継ぎ
  • タイムテーブルにトークを配置

コンテンツまわりの設計・運営をリードした形です。

※あくまでリードであって、独力でやったという気は毛頭ありません。他のスタッフに相談しながらPyCon JPを作り上げていきました(議論をリードできるよう、たたき台をたくさん作りました)。

間違い1: ワンマンプレー

全力疾走した結果カンファレンスは開催できましたが、コンテンツまわりは私一人に集中し、極度の属人化の中ワンマンプレー(力技)💪🏋️‍で解決したという状況でした。
もし私の身になにかあったら、コンテンツまわりは総崩れしていたんじゃないかと思います🙀

ワンマンプレーのきっかけは「自分でやるのが早い」と思ってしまったことです3
「キーノートスピーカーとのやり取り引継ぎ」とありますが、当初は別の担当者がいました。

キーノートスピーカーとのやり取りは、担当者が用意した文面をスタッフでレビューしてから送付します4
英語の文面になるとレビューで大きく手戻りすることが多く、「レビューしている自分が一から文面を考えているのと変わらなくないか?」と魔😈が差しました。
そこからの英語でのやり取りは私が主導権を奪ってしまい、なし崩し的に、キーノートスピーカーとの全連絡を担当することになりました5

間違い2: 「早さ」が要求され、余裕がなかった

間違い1を深堀ります。
なぜ「自分でやるのが早い」と思ってしまったのか、なぜ「早さ」を優先したのか
それは、手戻りが許容できないほどタスクが山積み🏔だったから、つまりデスマーチ💃💃💃だったからではないかと思います。

  • 大きく手戻りできる余裕がない
  • 大きく手戻ったらリカバリできない

そんな状況だったから、「自分でやるのが早い」と考えて、ワンマンプレーをした。
実際2020年は開催までの半年間、絶えず緊急かつ重要なタスクに追われていたと、振り返って思います。

間違い3: 振り返って思うと、オーバースペックだったかもしれない

間違い2のデスマーチだったという点を掘り下げます。
準備しているときはデスマーチ💃とも感じずに、可能な限りの時間をPyCon JPに捧げていたわけですが、「現地開催と同じ、参加者1000人規模のカンファレンスをオンラインで実現する」ことを私は前提にしていました。

現地開催と同じ1000人の参加者は、実際集まりませんでした6
「参加者1000人規模」というのは私の思い込みに過ぎず、スタッフが動ける範囲に合わせてスコープを調整してよかったわけですね。

なお、「現地開催と同じ」という思い込みの裏には、PyCon JP 2019でのコンテンツの「レベルが低い」問題7があったと思います。
「コンテンツチームリーダーとしてカイゼンせねば」と、力が入っていました💪

間違い4: カンファレンスの"運用"が見えていなかった

別の事象として、私1人がタスクをこなすだけでカンファレンスは回らないという過ちも犯しました。

タスクをこなす中で決めたことは他のスタッフに周知し、私以外でも運用できようにする必要があります。
「他のスタッフも運用できる」という点は考えから抜け落ちていました。
自分のタスクリストに引継ぎ事項の用意📝を入れたら、会期直前はタスクが溢れました😫

会期近くに参加してくださった経験豊富なスタッフの助けもあり、立て直しはできたのですが(本当に感謝です!)、DevOpsで言うOpsが見えていなかったというのは教訓です。

間違い5: 一個人の休日全部使わないと開催できない状況はどうなのか?

いま振り返って思うのがこの点です。
実際作業は進み、PyCon JP 2020は開催できたのですが、カンファレンスの裏に休日を全部捧げた存在がいるという過程🛣は、あまり健全ではないのではないかと思うのです。

「健全ではない😷」というのは、冗長性がないことを懸念しています。
サーバもスケールアウトして負荷分散するのですから、一人が一身に抱えるよりも、最低でもペアで、できるならもっと多くの人で分担して負荷分散するのが望ましいと考えています。

一人がめっちゃ頑張る🏋️‍より大きいタスクをみんなで持つ(みんなでちょっとずつ出し合う👨‍👩‍👧‍👦)のが、コミュニティのあるべき姿だと私は思っています。
全部捧げる一人の一見「ヒーロー」のような存在は、コミュニティにはいらないのではないでしょうか。

今後について少し

2021年は座長を務めます8が、2020と同じ活動量ができる自信は今のところ全くありません。

2019, 2020と打ち込んだPyCon JPスタッフ活動は、私にとって新しい発見が少なく、淡々とこなすべき「作業」のようになりました。
以前転職エントリにも書いたのですが、私は手を動かして得られるものがある作業が好きです。
淡々と感じられるスタッフ作業と自分が夢中になれること、この交差点⚔️を見つけて、今年のスタッフ活動に取り組んでいきたいと思います9

終わりに

ヒッキー、いつもそうじゃん。
できないのにできる範囲でって言って、それで結局なんとかするの。すっごい無理して

PyCon JP 2020が終わった後、『やはり俺の青春ラブコメはまちがっている。完』を見ていたとき、上のセリフ(9話)が「ニッキー」に空耳しました。

できないのにできる範囲でって言って、それで結局なんとかするの。すっごい無理して
ここにPyCon JP 2020の振り返りが集約されていると思います。
PyCon JP 2020が開催できたという成果を胸に、犯した数々の間違いを改善する方法を探して🔍、引き続きスタッフ活動していきます。

2020年にスタッフ活動でご一緒した皆さま、お疲れさまでした!🙌👏
(2021年もぜひぜひよろしくお願いします!)

最後に、PyCon JP 2020のすべての参加者の皆さま(スピーカー、スポンサー、スタッフ全部含めて)に、個人的にお礼申し上げます。ありがとうございました。

P.S. PyCon JP 2021 仲間募集中!!🙏🙏

チャンネル登録じゃなくて、スタッフ登録、よろしくお願いします!

先日のOSC2021 Online/Springでスタッフ活動について話しました。
自分の言葉で伝えられたと思っているので、よろしければご覧ください。


  1. 過去の記事でもたびたび「やはり間違う」という表現をしており、『俺ガイル』を意識した言い回しにしています

  2. 2020年8月のみんなのPython勉強会で知った『その仕事、全部やめてみよう』の 「俺がやったほうが早い病」の治し方 は参考になりました。 ref: https://nikkie-ftnext.hatenablog.com/entry/stapy-60-half-report:ref

  3. 古いですし、メンテされてないですが、参考までに:キーノート(未着手) — PyCon JP 運営マニュアル 0.1 ドキュメント

  4. 本業の傍ら進める作業ということで「黙っている人は存在しない」となりやすく、私が担当に切り替わっていました。コミュニケーション面でカイゼンの余地はあったかもしれませんが、2020年のタスクの詰め込み具合(間違い2 参照)だと根本解決に時間をかけづらい状況だったと感じています。

  5. connpassの参加者が561名ということを言っています。公式発表の詳しい情報はこちら:PyCon JP Blog: PyCon JP 2020 参加者数について

  6. 当時書き、いくつかコメントもいただいた記事がこちら:雑記 | #pyconjp 2019のトークはレベルが低かったのか? 〜台湾・シンガポールのPyConに参加して〜 - nikkie-ftnextの日記

  7. PyCon JP Blog: PyCon JP 2021 座長決定

  8. 先に述べた「ヒーローはいらないのではないか」といったIssueはワクワクするので、交差点の候補はあります

イベントレポート | ラクス おすすめの技術書 LT会 で11冊+αの推し技術書と出会いました #itbookslt

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
推しって尊いですし、推しについての熱い語りは聞いていてワクワクしますよね。
オススメの技術書📚(※広義の推し)についてのLT会に参加してきました。

目次

勉強会の概要

【LT増枠】おすすめの技術書 LT会 【登壇初心者の方大歓迎】 - connpass

今回のLT(ライトニングトーク)は おすすめの技術書 をテーマに行います!
技術書に関わることならなんでもOK!
皆さんのおすすめの技術書についてお話を聞かせてください。

ラクスさんは毎週LT会開催されててすごいですよね。
たびたびLTさせてもらっていますし1、興味を持ったテーマのときには聞きに行っています。

ハッシュタグ#itbookslt でした。
このクエリで後からでも振り返れるんじゃないかと思います:
https://twitter.com/search?q=(%23itbookslt)%20until%3A2021-03-25%20since%3A2021-03-24&src=typed_query&f=live

積読リスト入りした本たち

積読リスト、オーバーフローしてます2(嬉しい悲鳴!)。

『Goならわかるシステムプログラミング』

Goならわかるシステムプログラミング(PDF版のみ)

『開眼! JavaScript

SQLアンチパターン

『ふつうのLinuxプログラミング 第2版』

『パターン、Wiki、XP』

「ベック vs. コプリエン」のスライドでチラッと見かけて、検索したら興味持ちました。

紹介された本たち

Twitterにリンクを流して実況してました。

終わりに

冒頭のツイートの通り、めちゃくちゃよかったです。

「ベック vs. コプリエン」はしびれました。
比較してオススメしたら、あんなに面白くなるんだ」と目からウロコでした。

あとはstraceコマンドですね。
システムコール見られる、ヤバい!

登壇者、参加者、主催のラクスの皆様、ありがとうございました。

翔泳社祭2021をPythonを使って満喫する

はじめに

千葉の名物、踊りと祭り!同じ阿呆なら踊らにゃ sing a song! nikkieです。
昨日・一昨日はデブサミお疲れさまでした!
デブサミと合わせて翔泳社祭が開催されています(2/25(木)まで!)

こういったセールで対象本がスプレッドシートで公開されているのがもの珍しく、せっかくなのでPythonで満喫することにしました1

f:id:nikkie-ftnext:20210220182918p:plain

目次

Pythonを使って満喫する流れ

  1. 公開されているスプレッドシート2のデータを取得し、ローカルに保存する
  2. 条件を指定して、検索してみる

お祭り参加準備

スプレッドシート上のデータ取得は、ダウンロードでもよいですが、「なるべく自動化したい」とSheets APIを叩く方法を選択しました。
※準備が煩わしく感じる方は、csvやxlsx形式でダウンロードして、検索にガッツリ取り組んでもいいと思います👍

Googleアカウントがあれば、以下の手順でお祭りの参加権を得られます。

  1. Google Cloudのコンソールが見られるように設定します
    • 記憶が曖昧ですが、Googleアカウントがあれば、無料トライアルとして使い出せると思います3
  2. 必要に応じてプロジェクトを作ります
  3. プロジェクトを選択して、Sheets APIを有効にします4

Pythonの動作環境として以下を準備しました5

gspread              3.7.0
jsonlines            2.0.0

公開されているスプレッドシートのデータ取得

Sheets API (v3) のラッパーライブラリ、gspreadを使います。

認証には2通りの方法があります:

  • サービスアカウントを使う
  • OAuthクライアントIDを使う

対象のスプレッドシートをサービスアカウントに共有することで、プログラムから読み書きできるようになります。
今回のスプレッドシートは公開されており、サービスアカウントがそもそも共有できるのか不明でした6
そこで、OAuthクライアントIDを選びました。

OAuthクライアントIDの設定

新規プロジェクトを作って設定したところ、以前よりもステップ数が増えていました。

  1. 「OAuth 同意画面」をまず設定する(設定していないとOAuthクライアントIDが発行できない)

    • User type: 外部(Google Workspaceでないと内部は選べないようです)
    • スコープは絞って設定しても、gspreadのデフォルトの設定で上書きされるようでした
    • Test users: 設定しないとGoogleアカウントでのログインがそもそも許可されず、gspreadがうまく動きませんでした7。だいぶ厳しくなった印象です f:id:nikkie-ftnext:20210220184652p:plain
  2. 「認証情報」のうち「OAuthクライアントID」を作成する

gspreadを使って、スプレッドシートにアクセス

import gspread

gc = gspread.oauth()
sh = gc.open_by_key("1ayVJ3dXDosu4kQFTQ6fA8Q9LhpgCfh0S26KeWGq6MPU")  # 翔泳社祭のスプレッドシートのID
worksheet = sh.worksheet("全点")
list_of_lists = worksheet.get_all_values()

list_of_listsは1行を表すリストのリストです。
1行目の空行を無視したり、辞書形式に整形したりしてからローカルに保存します。
保存したデータを読み込んで、検索や絞り込みを実装すればいいですね!

対象本データを見て

カテゴリ①(H列)の取る値

PC技術_専門: 336
ビジネス_専門: 204
IT資格: 151
PC技術_入門: 146
クリエイティブ: 134
ビジネス_入門: 115
PC一般: 104
生活実用: 81
一般資格: 68
理工書: 63
医療福祉: 51
福祉資格: 30
一般書: 28

スプレッドシートで各カテゴリ1-2冊見ると、私の興味関心は

  • PC技術_専門
  • PC技術_入門

482冊でした。

PC技術本にしぼった時にカテゴリ②(I列)の取る値

プログラミング・開発: 188
ネットワーク・サーバ: 79
開発管理: 61
Webプログラミング: 43
データベース: 35
人工知能・機械学習: 31
LINUX・UNIX: 14
パソコン一般: 9
データサイエンス: 8
ハードウェア・自作: 8
デザイン: 2
子どもプログラミング: 2
パソコンソフト: 1
ゲームプログラミング: 1

入門と専門を合わせてカテゴリ②の取るあたいを見ています。
「プログラミング・開発」カテゴリは入門が多いのかもしれません(仮説)。

💰お買い得本リスト

一律50%オフなので、高いものほどこの機に買うのがお得ということになりますね。
PC技術本を通常価格+税(F列)の降順に出してみます。

割引額が大きいトップ20はこちら!!
※URLの有無やメモは見ていないので、求めている形態で買えない可能性もあります。

『実用Common Lisp』 ¥9200
『詳解UNIXプログラミング 第3版』 ¥8300
『C++プライマー 第5版』 ¥7800
『ストラウストラップのプログラミング入門』 ¥7800
『エンタープライズアプリケーションアーキテクチャパターン』 ¥5800
『マスタリングVMware vSphere 5.5』 ¥5800
『ディジタル回路設計とコンピュータアーキテクチャ 第2版』 ¥5400
『コンピュータネットワークとインターネット 第6版』 ¥5400
『Oracleデータベースセキュリティ セキュアなデータベース構築・運用の原則』 ¥5200
『実践ドメイン駆動設計』 ¥5200
『アジャイルソフトウェア要求』 ¥5200
『ディシプリンド・アジャイル・デリバリー エンタープライズ・アジャイル実践ガイド』 ¥5200
『エリック・エヴァンスのドメイン駆動設計』 ¥5200
『Splunkユーザーのためのデータ分析実践バイブル SPLとMLTKを駆使した前処理から機械学習の手続きまで』 ¥5000
『低レベルプログラミング』 ¥4800
『Akka実践バイブル アクターモデルによる並行・分散システムの実現』 ¥4800
『CRI ADX2で作るゲームサウンド制作ガイド [CRI ADX2公式ガイド]』 ¥4800
『DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで』 ¥4600
『ブラウザハック』 ¥4600
『プログラマのためのSQL 第4版 すべてを知り尽くしたいあなたに』 ¥4600

存在に気づいていなかった本も含まれていたので、祭りを満喫しようと取り組んでみてよかったなと思います😃

アジャイルソフトウェア要求

アジャイルソフトウェア要求

終わりに

こういったセールでのスプレッドシートの公開、めちゃめちゃありがたいですね!
翔泳社さん、ありがとうございます。
他の出版社さんのセールでもスプレッドシートで公開していただけたら探しやすくて助かります。

なお、スプレッドシートの機能に「Webに公開(publish)」があります。

publishしたスプレッドシートのURLにalt=jsonを指定するとJSON形式でシートの内容が取得できます8
publish版も用意してもらえると喜ぶ人は増えそうです。

スプレッドシートをノーコードツールと組み合わせればWebアプリもできるわけですよね。
次回のお祭りでは今回ここでやったような計数や検索が可能な、Webアプリが公開されているかもしれませんね。


  1. Pythonを使ったのは好みです。Sheets APIの呼び出し、または、CSVの読み取りができればいいので、Pythonに限らずお好きな言語でお祭りを楽しんでください!

  2. https://docs.google.com/spreadsheets/d/1ayVJ3dXDosu4kQFTQ6fA8Q9LhpgCfh0S26KeWGq6MPU/edit#gid=0

  3. https://cloud.google.com/getting-started?hl=ja

  4. 別のヘルプですが、操作方法の参考として。(Google Sheets APIだけ有効にすれば済みます) https://support.google.com/workspacemigrate/answer/9222865?hl=ja

  5. ローカルに保存するファイル形式にjsonlinesを選択しました

  6. サービスアカウントは未検証です。うまく行ったら教えてください

  7. gspreadGoogleアカウントでログインできると、認証情報を保存します。以降はそれを自動で更新して使うようです

  8. ref: Google Sheets as JSON Endpoint. Section 1: Creating a Google Sheet | by Clark Jason Ngo | Medium

「あってもなくても同じなら捨てる」という片付けの考え方が(こんまりメソッドと)プログラミングに通じていました

はじめに

生まれたときめき。あの日から世界は、変わり始めたんだ! nikkieです。
片付けについて自分のスタンスを人に説明する機会がありました。
それをきっかけに脳内で技術ネタもそれ以外も繋がったので、アウトプットしてみました。

目次

片付けのスタンス:あってもなくても同じなら捨てる

新卒入社した会社の社長が「あってもなくても同じなら捨てる」を徹底していた影響で、私もこのスタンスです。

「あってもなくても同じなら捨てる」を貫くのは大変で、「後で使うかもしれないから取っておこう」という道が絶えず誘惑してきます。
特にプライベートは念のため取ってあるものが多く(片付け後回しにしがちなんです🙈)、年末は「取ってあったけど結局使ってないよね」というものを発掘しながら捨てていました。

片づけと言ったらこんまり

私のこんまりメソッドの認識は「ときめかなかったら捨てる」というものです。
海外ではkondo, konmariが片付けの意で使われているそうですね1

年末の発掘では「取ってあったけど結局使ってない」ものは「ときめきもしないから」とガンガン捨てました。

言い換えるなら、オッカムの剃刀

「あってもなくても同じなら捨てる」は、「オッカムの剃刀」にも通じると思います。

Wikipediaによると

「ある事柄を説明するためには、必要以上に多くを仮定するべきでない」とする指針

私の理解ですが、

  • XとYを仮定して、Aが導ける
  • Xを仮定して、Aが導ける

この場合、後者の方が仮定が最小限なので、好ましいことになります。

仮定Yはあってもなくても(Aが導けるという点では)同じなので、捨てられるわけですね2

さらに関連してKISSの原則

Keep It Simple, Stupid または Keep it Short and Simple

オッカムの剃刀とKISSの原則の関連は『プリンシプル・オブ・プログラミング』より。

Wikipedia によると

その意味するところは、設計の単純性(簡潔性)は成功への鍵だということと、不必要な複雑性は避けるべきだ、ということである。

例えば人に何かを説明するとき、仮定が多くなると説明は複雑になっていきますよね。
KISSの原則を適用すると、オッカムの剃刀を指針にするときと同様に、仮定は少なく、説明は単純・簡潔になると思います。

先人もシンプルさをかく語りき

KISSの原則で言及されるシンプルさは、『プログラマが知るべき97のこと』にもエッセイがありますね。

美しいコードとは、突き詰めれば、シンプルなコードのことです。システムを構成する各部分が全てシンプルで、個々の部分が担う責務も最小限に抑えられていて、部分どうしの関連もシンプル、そんなコードです

「こんなコード、私も書けるようになりたい!」とときめきます。

コードはシンプルなものであるべきです。変数や関数、宣言といった構成要素はできる限り減らすべきです。余分な行、余分な変数…、ともかく余分なものが少しでもあれば、即座に消すようにします。残るべきは、アルゴリズムを完成させ、必要な演算をすべて処理するための、必要最小限の要素だけです。

使わなくなった変数やモジュールが見つかったら「あってもなくても同じ」でもあるので、すぐ消しますね。

Pythonでキーワード引数の渡し方の好み

※これは好みの話です。

Pythonでは関数の引数はいくつかの指定方法が許されています。
(※ドキュメントの言葉を使うと、位置またはキーワード引数の話です)

def parrot(voltage, action='voom'):
    pass
parrot(1000)                                          # 1 positional argument
parrot(voltage=1000)                                  # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments

私は位置引数voltageをあえてvoltage=1000と指定するのを好みません。
「キーワード引数として渡した方があとでコードを読む人にとって分かりやすい」という意見も聞きますし、チームで書く中で取られた選択だとしたら納得感もあります。
ですが、私としては「この位置の引数が何を受け取るかはドキュメントを見れば分かるから、わざわざ書く必要はない」という考えです。
この考え方にも「あってもなくても同じなら捨てる」が現れているかもと今回気づきました。

終わりに

「あってもなくても同じなら捨てる」というスタンスがプログラミングにも通じるという気付きがあったのでまとめました。

P.S. 人の気持ちは例外!

「あってもなくても同じなら捨てる」は人の気持ちには適用されないようです。
その例が『四月は君の嘘』。
主人公 公生は、あってもなくても同じならある方を選んでいます!3

いてもいなくても一緒なら
一緒にいるよ

片付けとは評価軸が異なるってことですね😜


  1. 「こんまり」が米国でブレイク!片付け番組がNetflixで大ウケの理由 | 海外セレブウォッチャーさかいもゆるの セレブ胸キュン☆通信 | mi-mollet(ミモレ) | 明日の私へ、小さな一歩!(1/2) より。ときめきは海外では「Spark joy」だそうです

  2. オッカムの剃刀」は機械学習の分野では、精度指標に対して同程度のスコアの2つのモデルがあるとき、パラメタ数の少ない単純な方を選ぶべきという指針としても聞きますね。ref: Occamの剃刀 - 機械学習の「朱鷺の杜Wiki」

  3. 「あってもなくても同じなら捨てる」立場からすると、公生の選択は不合理なのですが、不合理ゆえに愛が示されていることになるのかなと(そして椿は愛として受け取ったのだと)思いました ref:『世界は贈与でできている』(4章)(この本についてもまたの機会にアウトプットしたいです)

Sphinxでクロスリファレンスを機能させるためには、includeするファイルをrst以外の拡張子にすべきと身をもって学びました

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
技術同人誌執筆以来使っているドキュメンテーションツールSphinxで、includeするファイルはrst以外の拡張子にするべきということを知りました。

Tips: you should use other extensions for included documents (cf .txt).

目次

要するに

Sphinxにはrefnumrefを使ったクロスリファレンスの仕組み1があります。
セクションの直前にラベルを付けて、それを参照できます(ドキュメントにある例)。

.. _my-reference-label:

Section to cross-reference
--------------------------

This is the text of the section.

It refers to the section itself, see :ref:`my-reference-label`.

これを使ったところ、PDFのビルドに限っては、includeしたファイルの中のラベルを参照することができませんでした。
HTMLでは参照できる2のですが、PDFになると参照できませんprobrefとラベルそのものが出てしまっています)。
出力先によって動きが違う理由に見当が付かず、「悔しくって死にそう」でした。

f:id:nikkie-ftnext:20210209213340p:plain

Issueを漁っていたところ、冒頭で紹介したものに出会い、解消できました。
includeするファイルはrst以外の拡張子にする必要がありました。

サンプルドキュメント

上記Issueに添付されたファイルを例にします。

.
├── Makefile
├── _build
├── conf.py
├── index.rst
├── make.bat
├── section1.rst
├── subsec1.rst
└── subsec2.rst

index.rst

sections1.rstからなるtoctreeです。

.. toctree::
   :maxdepth: 2
   :caption: Contents:

   section1

section1.rst

subsec1.rst と subsec2.rst をincludeしています。
参照しているラベル probref は subsec1.rst にあります。

Section 1
=========

Labels in included files cannot be referenced.

.. include:: subsec1.rst
.. include:: subsec2.rst

Subsection 3
------------

References also do not work from parent document: :ref:`probref`

subsec1.rst

「Subsection 1」に probref ラベルを付けています。

.. _probref:

Subsection 1
------------

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt
ut labore et dolore magna aliquyam erat, sed diam voluptua.

subsec2.rst

subsec1.rst にあるラベル probref を参照しています。

Subsection 2
------------

References do not work from other included document: :ref:`probref`

環境

PDFビルドには sphinxdoc/sphinx-latexpdf:3.3.1DockerHub)を使いました。4

PDFビルドコマンド

docker run --rm -v $PWD:/docs sphinxdoc/sphinx-latexpdf:3.3.1

作られたPDFではラベルが参照できず、probrefというラベル名が表示されています(図を再掲します)

f:id:nikkie-ftnext:20210209213340p:plain

解決策

probref ラベルを定義したファイル subsec1.rst を subsec1.rst.txt のように拡張子をrst以外に変更すると解決します。

合わせて、section1.rst の include も更新します。

.. 変更がないので省略

.. include:: subsec1.rst.txt
.. include:: subsec2.rst

.. 変更がないので省略

f:id:nikkie-ftnext:20210209214354p:plain

「Subsection 1」とラベルが指すセクションの名前が表示されていますね🙌

解決する理由

前掲のIssueでは、includeされたドキュメントが二度処理されたためと説明されていました。

  1. section1.rst の処理で、subsec1.rst と subsec2.rst を include したドキュメントとなる(probref ラベルが section1に定義される)
  2. Sphinx*.rst という名前のファイルを検索することで、 subsec1.rst もドキュメントとして処理される。これにより probref ラベルが subsec1にも定義される5

同じラベルが2回現れるため、Sphinxは混乱し、最初の画像のようにリファレンスが壊れるとのことでした。

裏付けるように以下のwarningも出ています。

/docs/subsec1.rst:4: WARNING: duplicate label probref, other instance in /docs/section1.rst

include するファイルを subsec1.rst.txt とリネームすると、上記の2で処理されなくなります。
これにより、同じラベルが2回出てこなくなるということですね!

Sphinxのドキュメント6には include ディレクティブについて

単純に一つのファイルを別のファイルに"挿入"する場合、 include ディレクティブを使えます。

という注釈があるのですが、この「一つのファイル」がrst以外のファイルという前提があったことが分かりました。

拡張子を変えたあとの色分け設定(VSCode

nikkieはVSCodeを使っていますが、subsec1.rst.txtを開くと、rstファイルで見られた色分けがされません(文字は白一色です)。

これは、Select Language Mode から reStructuredText を選択することで解決しました。

(追記)選択を頻繁に繰り返していたので .vscode/settings.jsonfiles.associations を設定しました。

    "files.associations": {
        "*.rst.txt": "restructuredtext"
    }

終わりに

rstファイルを分割して include して使っていましたが、これはプラクティスに反していたことを身をもって体験しました。
拡張子を変えたことで、refnumrefでラベルが参照されるようになり、心の平穏を取り戻しました。

Sphinxの動きはまだまだブラックボックスですが、昨年のPyCon JPの以下はチェックしようと思います。


  1. https://www.sphinx-doc.org/ja/master/usage/restructuredtext/roles.html#role-ref

  2. f:id:nikkie-ftnext:20210209213249p:plain

  3. make htmlの実行に使いました。PDFビルドに使うDockerイメージとSphinxのバージョンを合わせる意図でバージョン指定しています。

  4. リポジトリhttps://github.com/sphinx-doc/docker 。DockerでLaTeXビルド環境が立ち上がってとても助かっています!

  5. 元のコメントでは subsec2.rst ですが、ラベルがある subsec1.rst のことを言っているのだと理解しました

  6. https://www.sphinx-doc.org/ja/master/usage/restructuredtext/directives.html#table-of-contents