nikkie-ftnextの日記

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

翔泳社祭2022をPythonとjqを使って満喫する

はじめに

千葉の名物、踊りと祭り!同じ阿呆なら踊らにゃ sing a song! nikkieです。

先日(2/17,18)デブサミがあったんですね。
ということは、翔泳社翔泳社さんの電子書籍が50%割引で買えるセール)も開催中だ!(2/24(木)までだそうです)

昨年は「Pythonを使って満喫」しましたが、今年はアップデート版をお送りします。

目次

Pythonとjqを使って満喫する流れ

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

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

お祭り参加準備

read onlyで公開されているスプレッドシートからデータを取得するために、OAuthクライアントIDを準備します(手順は2021の記事を参照ください)。
オーバーエンジニアリングと感じられた方は、csvやxlsx形式でダウンロードしてもいいと思います2
スプレッドシートが公開されているのはとてもありがたいですね。

動作環境

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

gspread              5.1.1
jsonlines            3.0.0

2021から両ライブラリともメジャーバージョンアップしていますね!
gspreadはv3 → v5、jsonlinesはv2 → v3)

jqのバージョンは以下です。

$ jq --version
jq-1.6

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

2021同様、gspreadで取得します。

import gspread
import jsonlines

client = gspread.oauth()
spreadsheet = client.open_by_key(
    "1vS3-vAVH7-vRMaDP_c_rRf2uKHq-yjQGTKr0Cpggz2U"
)
worksheet = spreadsheet.worksheet("対象一覧")  # 2021とワークシート名が異なります

list_of_dicts = worksheet.get_all_records(head=2)  # ヘッダーは2行目と指定
price_sorted = sorted(
    list_of_dicts, key=lambda row: row["定価\n (本体価格+税)"], reverse=True
)

with jsonlines.open("shoeisha_fes_2022.jsonl", "w") as writer:
    writer.write_all(price_sorted)
  • jqコマンドを練習したく3JSON Lines形式で書き出しました
  • ヘッダが2行目であることを指定します(2行目の各セルの値が辞書のキーになります)
  • 価格順に並べ替えたいのですが、jqでできるかぱっと分からず、取得したデータを価格の降順に並べ替えてから保存することにしました

対象本データを見て

対話モードで確認してみました(pythonコマンドの-iオプション4)。

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

>>> from collections import Counter
>>> category1_counter = Counter(book["カテゴリ①"] for book in list_of_dicts)
>>> for category1, count in category1_counter.most_common():
...   print(f"{category1}: {count}")
...
PC技術_専門: 372
ビジネス_専門: 234
IT資格: 167
PC技術_入門: 161
クリエイティブ: 137
ビジネス_入門: 125
PC一般: 119
生活実用: 93
一般資格: 88
理工書: 71
医療福祉: 62
福祉資格: 42
一般書: 36

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

PC技術_専門(372冊)とPC技術_入門(161冊)、合計533冊の内訳です。

>>> tech_category2_counter = Counter(book["カテゴリ②"] for book in list_of_dicts if book["カテゴリ①"].startswith("PC技術"))
>>> for category2, count in tech_category2_counter.most_common():
...   print(f"{category2}: {count}")
...
プログラミング・開発: 211
ネットワーク・サーバ: 89
開発管理: 69
Webプログラミング: 52
人工知能・機械学習: 36
データベース: 35
LINUX・UNIX: 15
データサイエンス: 11
ハードウェア・自作: 9
パソコンソフト: 3
パソコン一般: 3

jqでフィルタ

shoeisha_fes_2022.jsonl がスプレッドシートJSON Lines形式で書き出したファイルです。

$ jq -c 'select(."カテゴリ①" | startswith("PC技術"))' shoeisha_fes_2022.jsonl > technical_books_2022.jsonl
$ jq -c 'select(."Kindle 50%割引" | contains("https://www.amazon.co.jp/"))' technical_books_2022.jsonl > kindle_technical_2022.jsonl
  • カテゴリ①が「PC技術_専門」「PC技術_入門」の書籍を抜き出し、technical_books_2022.jsonlに保存
  • Kindleで買える(=AmazonのURLが記載されている)書籍を抜き出し、kindle_technical_2022.jsonlに保存
    • Kindleで買えない書籍は「対象外」記載のようです

例えば、書名に「Python」と入っている書籍を抽出してみましょう。
(表記ゆれを警戒し(※気にし過ぎかも)、小文字に揃えてから、「python」を含むかで抜き出します)

$ jq -c 'select(."商品名" | ascii_downcase | contains("python"))' kindle_technical_2022.jsonl > python_kindle_technical_2022.jsonl

wc -lで表示した行数

    1707 shoeisha_fes_2022.jsonl
     533 technical_books_2022.jsonl
     475 kindle_technical_2022.jsonl
      35 python_kindle_technical_2022.jsonl

Pythonに関係する本

JSON Linesから見たいフィールドだけを抜き出します。
1行に、値段、Amazonへのリンク、書名の3点を表示しています。
値段に単位をつけたり、書名を『』でくくったりするためにjoinを使いました。

$ jq -r '[([."定価\n (本体価格+税)", "円"] | join("")), ."Kindle 50%割引", (["『", ."商品名", "』"] | join(""))] | join(" ")' python_kindle_technical_2022.jsonl

出力を見ると、みんなのPython勉強会(stapy)で取り上げた本がいくつも見つかりました!
「おー、あの回で紹介された本だー!」と一スタッフとして嬉しくなり、続く紹介コーナーを書きました。

『実践Django

2021/08のstapyで著者の芝田さんに話していただきました。

めちゃくちゃ詳しくて学びがたくさんなこの本、中でもDjangoのテストの書き方が私には役立ってます。

『スラスラわかるPython 第2版』

先月(2022/01)のstapyで著者の岩崎さんに話していただきました5

私は対象読者からは外れていると思うのですが、「Pythonを学んでみたい」方はこの機にいかがでしょうか?
半額ですし、2版が出るということはそれなりに売れていて定評があるということだと思います。

Python FlaskによるWebアプリ開発入門』

2022/01のstapy懇親会で知った本!

気になっていたので、半額のこの機に購入ですね。

『AIエンジニアのための機械学習システムデザインパターン

著者の澁井さんは、2021/06にstapy懇親会でLT、2021/07のstapy外伝でティアフォーさんのMLOpsを紹介されていました6

機械学習モデルをサーブするAPIk8sクラスタにデプロイするということを日常的にやっている身としては、この本からIstioがめちゃくちゃ便利だと思い知らされました。

『テスト駆動Python

最近読んでいて、pytestのキャッチアップにオススメの一冊。

監修のやっとむさん(安井 力さん)には、2019/06のstapyで話していただきました。
https://youtu.be/T7Tqt0fJG1A?t=4600 からアーカイブを見られます。

『見て試してわかる機械学習アルゴリズムの仕組み 機械学習図鑑』

2019/08のstapyで紹介された1冊。

https://youtu.be/gKrQVJ1v7WM?t=2654 からアーカイブを見られます。

この本は、2019年に「Google のエンジニアたちが選んだプログラミングに関する書籍 10 冊」(中学校及び高等学校に寄贈)にも入っています!

本当に分かりやすくて、実は私もこっそり読んでいます。

終わりに

翔泳社さん、今年もスプレッドシートの公開、ありがとうございます。
全然本屋さんに行かなくなってしまいましたが、書店の大きな本棚の前に立っている感覚でした(セール品以外は目に入らない状況でもありますが)。
昨年も書きましたが、Webへの公開を検討いただけると嬉しいです(JSONで取得できると、翔泳社祭、もっと盛り上がると思うんです!)

jqコマンドの素振りにもなりましたね。
jqコマンド、わざわざPython書かなくてもJSON Linesをフィルタできるので結構いい感じです。
これはまたの機会にアウトプットしたいですね。

ザッピングを終えたので、あとは2/24(木)までに吟味して購入しようと思います。
気になる書籍が多すぎて、ヨサンハンイナイデナンテエラベナイヨー

参考までに、ザッピングコマンド

$ jq -r '[([."定価\n (本体価格+税)", "円"] | join("")), ."Kindle 50%割引", (["『", ."商品名", "』"] | join("")), ."発売日"] | join(" ")' technical_books_2022.jsonl > technical_books_2022.txt

  1. https://docs.google.com/spreadsheets/d/1vS3-vAVH7-vRMaDP_c_rRf2uKHq-yjQGTKr0Cpggz2U/edit#gid=0

  2. Pythoncsv.DictReaderを使って読み込んで、JSON Lines形式で書き出し、この記事に合流できると思います。

  3. JSON Linesをjqコマンドで扱う方法、『jqハンドブック』で完全に理解した! - nikkie-ftnextの日記

  4. スクリプトかコマンドを実行した後にインタラクティブモードに入ります。」 https://docs.python.org/ja/3/using/cmdline.html#cmdoption-i

  5. トークは大変興味深く、そこで出た質問を調べてみたら学びがありました。👉 1月の #stapy で挙がった2つの質問に回答します:キーワード専用引数はいつから? 位置専用引数の使い所は? - nikkie-ftnextの日記

  6. 直近の 第16回 MLOps 勉強会(Online) - connpass によると、澁井さん現在はLaunchable, Inc.在籍のようです