nikkie-ftnextの日記

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

dataclassを使って、Pythonで値オブジェクトを実装する

はじめに

アタイも挑戦したい、管理人みたいに1
ジョゼと虎と魚たち』めっちゃいいですよね? nikkieです。

タイトルの値オブジェクトとは、値を扱うための専用クラス2です。
これを「Python@dataclasses.dataclassを使って書いたらどうなるのか」手を動かしました。
この記事は、分かったことの備忘録です。

おことわり:「今の自分が書いたらこんな感じかな」というのをまとめました。
技術的な誤りや伸びしろにお気づきの際は、コメントやTwitter @ftnext までお知らせいただけると大変ありがたいです。

目次

「アタイ」ヒロインならぬ、「アタイ」オブジェクトについてです

経緯

先日TECH StreetさんのPythonエンジニア勉強会Pythonのobjectについて10分話しました。

紹介した例は、値オブジェクトやファーストクラスコレクションを意識して実装しています。
準備の中で『現場で役立つシステム設計の原則』を参照したところ、「意識しているけど、値オブジェクトやファーストクラスコレクションにはできていないなー」と、目の前に広がる圧倒的な伸びしろを感じました。
そこで、LTとは別に実装を突き詰める機会を設けました。
今回は、値オブジェクト編のアウトプットです。

値オブジェクトとは

※『現場で役立つシステム設計の原則』の1章を参考にしています

値オブジェクトの実装は「基本データ型のインスタンス変数を1つか2つ持つだけの小さなクラス」3です。
基本データ型をインスタンス変数としてラップして、独自の型(クラス)を作ると捉えています。
値オブジェクトを使う目的は、業務のニーズに合っていない基本データ型の代わりに、業務のニーズに合わせた値の範囲を使うためと理解しました。

値オブジェクトの利点はいくつも紹介されています。
イチオシはこちら、関数の引数がめちゃくちゃ分かりやすくなりますね!

def amount(unit_price: Money, quantity: Quantity) -> Money:
    if quantity.is_discountable():
        return discount(unit_price, quantity)
    return unit_price.multiply(quantity.value)

1章の「『型』を使ってコードを分かりやすく安全にする」のJavaのコードをPythonで書き直してみました。
第1引数がMoney型、第2引数がQuantity型という型ヒントが分かりやすいと思います。

値オブジェクトの実装要件

  • 基本データ型を属性として1つか2つ持つ
    • 👉 簡単な例で練習したいので、1つにします
  • 不変
    • 👉 @dataclass.dataclass()frozen引数にTrueを指定します
    • ドキュメントによると「frozen: 真 (デフォルト値は False) の場合、フィールドへの代入は例外を生成します。 これにより読み出し専用の凍結されたインスタンスを模倣します。」4
  • 完全コンストラク
    • 「オブジェクトの生成時に、オブジェクトの状態を完全に設定してしまう」5
    • コンストラクタで、業務のニーズに合わせた値の範囲か検証します
    • 👉 @dataclass.dataclass()では__init__が自動で作られますが、完全コンストラクタにするために自分で書くことにしました

値オブジェクトの例:競走馬名

TECH StreetさんでのLTの題材にした競走馬名を表すクラスを例に選びました。

※競走馬の名前を値オブジェクトにするというのは、業務アプリケーションからかけ離れていると思います。
今回の取り組みは「値オブジェクトの実装方法」を見つける練習なので、これでいきます🐴

日本における馬名登録のルール6

  • カタカナ9文字以内7
  • 「ヰ」・「ヱ」は使用できない
  • 2文字以上9文字以内

馬の名は。値オブジェクト RaceHorseName 🐴

完成したコード

from __future__ import annotations

import re
from collections.abc import Iterable
from dataclasses import dataclass
from typing import ClassVar


@dataclass(frozen=True)
class RaceHorseName:
    """カタカナの馬名を表すクラス"""

    value: str
    MIN_LENGTH: ClassVar[int] = 2
    MAX_LENGTH: ClassVar[int] = 9
    INVALID_CHARACTERS: ClassVar[Iterable[str]] = ("ヰ", "ヱ")

    def __init__(self, value: str):
        # 完全コンストラクタの実装例
        length = len(value)
        if length < self.MIN_LENGTH:
            raise ValueError(f"不正: {self.MIN_LENGTH} 文字未満")
        if length > self.MAX_LENGTH:
            raise ValueError(f"不正: {self.MAX_LENGTH} 文字超")
        if not self.is_katakana_only(value):
            raise ValueError("不正: カタカナではない文字")
        if self.does_include_invalid_characters(value):
            raise ValueError(f"不正: 使用禁止文字 {self.INVALID_CHARACTERS} を含む")
        object.__setattr__(self, "value", value)

    @staticmethod
    def is_katakana_only(string: str) -> bool:
        return bool(re.fullmatch(r"[\u30A0-\u30FF]+", string))

    @classmethod
    def does_include_invalid_characters(cls, string: str) -> bool:
        return any(c in string for c in cls.INVALID_CHARACTERS)

不変なことの確認

>>> rice = RaceHorseName("ライスシャワー")
>>> rice.value = "ミホノブルボン"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'value'

frozen=Trueにより、ラップした値を変更できません

frozen=True を dataclass() デコレータに渡すことで、不変性の模倣はできます。 このケースでは、データクラスは __setattr__() メソッドと __delattr__() メソッドをクラスに追加します。 これらのメソッドは起動すると FrozenInstanceError を送出します。8

完全コンストラクタであることの確認

  • 2文字未満:ラ
  • 9文字超:トッテモライスシャワー
  • カタカナではない文字を含む:ライスshower
  • 使えないカタカナ:ラヰスシャワー

いずれもValueErrorが送出されます

>>> RaceHorseName("らイスシャワー")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 不正: カタカナではない文字

実装ポイント

frozen=Trueと完全コンストラク

イニシャライザ(__init__)でvalue属性に値を代入する必要があります。
これは以下の書き方をする必要がありました。

object.__setattr__(self, "value", value)

frozen=True を使うとき、実行する上でのわずかな代償があります: __init__() でフィールドを初期化するのに単純に割り当てることはできず、 object.__setattr__() を使わなくてはなりません。9

イニシャライザでself.value = valueと書くと、以下が出てしまいます(frozenにしたのでごもっともなのですが、けっこう焦りました)。

dataclasses.FrozenInstanceError: cannot assign to field 'value'

これは object.__setattr__()10で回避できました。

dataclassのクラス変数

typing.ClassVarを初めて知りました。

クラス変数であることを示す特別な型構築子です。11

フィールドが ClassVar の場合、フィールドとは見なされなくなり、データクラスの機構からは無視されます。12

dataclassのクラス変数の理解があやふやだと分かって、いくつか手を動かしました。
型ヒントをつけなければクラス変数 なんですね。

@dataclass
class C:
    a: int
    b: int = 0
    d = "Class var"
>>> c = C(108)
>>> c
C(a=108, b=0)
>>> c.d
'Class var'
>>> C.d
'Class var'

クラス変数dに型ヒントを付けるときにClassVarを使うという理解です。
これで型チェッカーの支援を受けられるとのこと13
クラス変数の扱いをさらに深めたければ、@dataclasses.dataclassの実装を見ることになりそうです。

脱線:すべてカタカナのチェック

最後に値オブジェクトとは別の話題を。
文字列がすべてカタカナかの判定は https://note.nkmk.me/python-re-regex-character-type/#_7 を参考にしています。

Future works

今回書いたコードは暫定解(よりよい方法で棄却されうる)と思っているので、今後試したい事項を挙げておきます:

終わりに

値オブジェクト、dataclassfrozen=Trueを知っていた14ので、ぱぱっと実装できるかと思いきや、意外と時間がかかりました。
完全コンストラクタの実装で、値の検証に使う変数やメソッドをクラスに持たせていき、「競走馬名をクラスで表現できた!」と満足しています😃

次は、ファーストクラスコレクション編です!(執筆時期は未定です)


  1. アタイつながりで持ってきました😝 https://youtu.be/P5LLhoKfI1E?t=36

  2. 増田 亨『現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法』 (Japanese Edition) 1章 (Kindle の位置No.687). Kindle 版.

  3. 『現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法』 (Kindle の位置No.689-690)

  4. https://docs.python.org/ja/3/library/dataclasses.html#dataclasses.dataclass

  5. 『現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法』 (Kindle の位置No.735-736)

  6. 馬名登録のルール、けっこう面白かったです。「オレハマッテルゼ」なんてあるんですね🤣 類似しているとNGだそうですが、「チョウカイテイオー」は却下で、「ナイキシャトル」は採用🤔

  7. 「アルファベットの馬名と合わせて登録する」そうですが、今回は考えません。だって、ウマ娘、カタカナの印象が強いじゃないですか!

  8. https://docs.python.org/ja/3/library/dataclasses.html#frozen-instances

  9. https://docs.python.org/ja/3/library/dataclasses.html#frozen-instances

  10. https://docs.python.org/ja/3/reference/datamodel.html#object.__setattr__ (URL末尾の__setattr__が太字になってしまいます😢)

  11. https://docs.python.org/ja/3/library/typing.html#typing.ClassVar

  12. https://docs.python.org/ja/3/library/dataclasses.html#class-variables

  13. Here ClassVar is a special class defined by the typing module that indicates to the static type checker that this variable should not be set on instances. ref: https://www.python.org/dev/peps/pep-0526/#class-and-instance-variable-annotations

  14. hoboroさんのトークで知りました。詳しくは イベントレポート | オンラインで開催された #pycon_shizu 、私の知らないPythonがいくつもありました! - nikkie-ftnextの日記

自分用 2021年Python関連アウトプット先カレンダー(カンファレンス・技術同人)

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

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。

昨年の夏は、世界各地のPyConでオンライン登壇しました。

今年の夏も近づいてきて、プロポーザル募集中のカンファレンスもいくつか見かけるようになりました。
自分用のメモとしてPython関連のアウトプット先(カンファレンス中心)をまとめます1

英語・日本語関係なくリストアップしましたが、ここにあるものはごく一部です2
また、この記事をメンテナンスしていくかは未定です3

目次

カンファレンス

PyCon Taiwan 2021(プロポーザル 〜4/26(月))

8/20(金)〜22(日) 開催。リモートスピーカーも歓迎

Django Congress JP 2021(プロポーザル 〜5/12(水))

7/3(土) 長野で開催(オンライン参加もあり)

Euro Python 2021(プロポーザル 4/26(月)〜)

7/26(月)〜8/1(日) オンライン開催

Speaker Mentorship Programなるものがあるようです(申込 〜4/26)

In the EuroPython community, we emphasize the importance of diversity and inclusion. We also encourage and support potential first-time speakers. To help us achieve the goal, we will have the Speaker Mentorship program for EuroPython 2021.

PyCon APAC 2021(プロポーザル 〜8/26(木))

11/18(木)〜11/23(火) 開催

技術同人誌

技書博 #5(サークル申込 〜4/26(月))

6/19(土) 会場開催

技術書典 #11(サークル申込 〜5/23(日))

7/10(土)から16日間
7/11(日)は会場開催

終わりに

2020年登壇の夏で得た知見を PyCon mini Hiroshima 2020 でアウトプットしたところ、

嬉しいフィードバックをいただきました!

今年は抱えているものが多いので、カンファレンスで1回でも登壇することがチャレンジングだと認識しています。
ただ、小さいアウトプットをブログ記事に積み重ねてネタは蓄積できそうなので、2022以降に向けて力を蓄える方針でやっていこうかなと思っています。


  1. PyCon JP 2021 座長としての活動もあり、昨年と同様の登壇量は現実的でないと思っています。もしかするとこの記事自体が代償行動なのかもしれません

  2. すべてを網羅したい方には https://www.python.org/events/python-events がPyConを洗い出す手がかりになると思います

  3. pyhack Slack の #pycon-overseas に情報が集まるのでオススメです。ref: https://ftnext.github.io/2020_slides/pyconhiro_Oct_connect_global/slide.html#/7/1

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