Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

ロジクールの新作キーボードMX Keys は本当にガチプログラマー向けなのか?

今日はキーボードの話をします。

f:id:hirokiky:20191115220707j:plain
MX Keysキーボード

はい。これが ロジクールMX Keys X800というキーボードです 。つい最近の19年9月27日に販売されはじめたそうです。 パット見の印象は正直派手さのない印象ですが、 クリエイター、プログラマーといったパワーユーザー向けの製品だそうです

www.logicool.co.jp

というのもこのキーボード、どうやらPRの一貫かでロジクールさんから送られてきました。 僕で大丈夫なんでしょうか。気の利いた発言ができない僕なので、少し申し訳ない気もしつつ受け取りました。

自宅のキーボードはMiSTEL BAROCCOで満足しているので、ちょうど何も無かったオフィスの環境でMX Keysを試しました。 macOSと繋いで使ってみたときの感想になります。

ロジクール MX Keysキーボードの感想

f:id:hirokiky:20191114145245j:plain

正直に言うと、 僕個人はぺらぺらしたキーボードはあまり好きではありません 。 そしておそらくですが、プログラマーでガチでキーボードが好きだという人は、ブロックっぽいキーボードが好きだと思います。 なので、 このロジクールMX Keysはそもそも(コアな趣味の)プログラマーの選択肢に入らないのでは? とすら思います。

ロジクールMX Keysの打鍵感は、けっこう良い

でも、 使ってみると意外と良い感触です

数日使った感じも、かなり打鍵感は良いです。ペラペラキーボードにありがちな、ペチペチした感触ではありません。 クニッと、ポコッと、良い抵抗感で入っていく感じです。薄いキーボードと、普通の分厚いキーボードの間くらいの印象です。

キートップも緩やかにくぼみがついていて、フィット感も良いです。 薄いキーボードの中では生涯で一番良い感触 だと思います。

キー配列、レイアウトについて

キー配列はJISですが、僕は日英両対応なので問題なく良かったです。 ただ僕は普段、Dvorak配列を当てはめて使ってるので、Qwerty配列的に使いやすいかどうかは知りません。

ハードウェアレベルでのキーマッピングができないのもオタク的には物足りない感はありますが、ぶっちゃけmacならKarabinerElementsを使えば良いですよね。 (ハードレベルでキー変えるとか入力パターン設定とか、冷静に考えてそんなに要る?って思う)。

僕的にロジクールMX Keysのイケてないところ

ただ、僕的にはやはりイケてないところはあります

  • 横が長すぎ
    • ラップトップの上にキーボードを載せて使えない
    • HHKB、BAROCCOのような短いキーボードが好きな僕にとっては大きすぎ
    • テンキーって要らないですよね。数字もブラインドで入力できれば不要です
  • 分割キーボードでない
    • 慣れると分割キーボードが楽すぎる
  • 良いけどやっぱりペラペラキー

細かな良いところ

まぁ悪いところばかりではありません。

  • Bluetoothキーボードってやっぱいいよね
    • Bluetoothでありながらスラッとしたデザインでまとまってて良い
  • macOSのMissionControlを(ドライバーを入れれば)キーから呼び出せたりは便利
  • キーボードのバックライトが上品かつカッコイイです。
  • Escキーが大きいのも良い
    • が、Emacsユーザーなのでそれほど興味はない

総評: わりとオススメはするが、僕にとっては、ギリ候補にはなるレベル

ロジクールMX Keysを買うとして、どうでしょうか? 比較的安価な値段で、とてもクオリティ高く使いやすいです。14,500円分の価値は十分あると思います。素直に良い製品だなぁと思います。

例えばMacbookのうっっすいキーボードが嫌で、 Apple純正のワイヤレスキーボードを買おうかなと思ってる人にはロジクールMX Keysもオススメします 。 ドライバーもよくできてて使い勝手もいいので、テンキーが好きならMX Keysはオススメです。

ただ、僕が買うとしたら「ギリ候補になる」くらいでしょうか。 理由は、 プログラマー向けな良いキーボードは他にたくさんあるから です。 他にも良い製品はたくさんあるので、それを調べてから買っても遅くはないでしょう。

ロジクールMX Keysに14,500円を出すなら、僕ならもう少し頑張ってHHKB Professinal2を買うか、(当時の定価でなら)MiSTEL BAROCCO MD600が17,000円で買うほうが良いです(好みの問題で)。

f:id:hirokiky:20191115222024j:plain
MiSTEL BAROCCO MD600

「薄型の普通目なキーボードが好き」「でも、打鍵感が良く疲れないキーが欲しい!」という人にはロジクールMX Keysをオススメします 。 でも、プログラマー向けでカッコイイキーボード欲しいなぁと思うなら、HHKB Type-S をまず検討して欲しいです。

PFU キーボード Happy Hacking Keyboard Professional2 Type-S 無刻印/白 PD-KB400WNS

PFU キーボード Happy Hacking Keyboard Professional2 Type-S 無刻印/白 PD-KB400WNS

間違いないから。

他にオススメの記事

ロジクールMX Master3ってマウスも貰ったけど、 そっちはもっと気に入ったから次に書きます

この記事もオススメ

blog.hirokiky.org

Djangoのマイグレーションで実行される処理(とSQL)を確認する方法

Djangoマイグレーションで実行される処理(とSQL)を確認する方法を説明します。

先日の記事では「Djangoマイグレーションを無停止で反映する方法」を説明しましたが、そのためにはマイグレーションでどんなSQLが実行されるかが重要になります。

blog.hirokiky.org

もちろんマイグレーションファイルを開いて見れば分かりますが、Djangoのコマンドから便利に確認したり、実際に発行されるSQLを確認しておくほうが安全です。

実行されるマイグレーションのプランを確認する

Djangomigrate --plan コマンドを使って、実行されるマイグレーションのプランを確認できます。 この例では blog アプリの 00010002 というマイグレーションが適応されていない状態です。

python manage.py migrate --plan
Planned operations:
blog.0001_initial
    Create model Post
blog.0002_post_published_at
    Add field published_at to post

--plan を見るとそれぞれのマイグレーションでどのような処理が実行されるかが分かります。 この例では以下の意味になります。

  • 0001: モデルPostを作成する
  • 0002: postにpublished_atフィールドを追加する

両方のマイグレーションファイルともテーブルやカラムを追加するものなので、(基本的に)Webアプリのリリース前にマイグレーションを実行できます。

マイグレーションで実行されるSQLを確認する

migrate --plan で内容を確認できるとはいえ、実際にマイグレーションで実行されるSQLを確認しておくほうが安心です。 Djangoにおいてマイグレーションで実行されるSQLを確認するには、 sqlmigrate コマンドを使います。 アプリケーション名 <app_name>マイグレーションの名前 <migration_name> を指定して使います。

python manage.py sqlmigrate <app_name> <migration_name>

例えば blog アプリの 0002_post_published_at.py マイグレーションファイルで実行されるSQLを確認するには、以下のようにします。

python manage.py sqlmigrate blog 0002

こうすることで 0002_post_published_at.py が反映されるときに実行されるSQLが表示されます。

BEGIN;
--
-- Add field published_at to post
--
ALTER TABLE `blog_post` ADD COLUMN `published_at` datetime(6) NULL;
COMMIT;

SQLの内容を見ることで、マイグレーション実行時にどのような処理がデータベースに行われるかが分かります。 Webアプリを無停止のままマイグレーションを反映するときは、このSQLの内容に応じてどのようにリリースすべきかが変わります。

本番環境と同じデータベースバックエンドを使って確認しよう

ただし、 sqlmigrate の結果は settings で使われているデータベース(DATABASES 設定の内容)に応じて結果は変わります。 必ず運用している環境と同じデータベースバックエンドを使ってSQLを確認しましょう。 例えば、上記の例はMySQLバックエンドで出力しましたが、SQLite3バックエンドでは以下のような別のSQLになります。

BEGIN;
--
-- Add field published_at to post
--
CREATE TABLE "new__blog_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "published_at" datetime NULL, "body" text NOT NULL);
INSERT INTO "new__blog_post" ("id", "body", "published_at") SELECT "id", "body", NULL FROM "blog_post";
DROP TABLE "blog_post";
ALTER TABLE "new__blog_post" RENAME TO "blog_post";
COMMIT;

まとめ

以下2つのコマンドを使ってマイグレーションの内容を確認しましょう。

これでマイグレーションSQLの内容が分かったらWebアプリを無停止でマイグレーションをできるかを検討しましょう。

blog.hirokiky.org

DjangoマイグレーションをWebアプリが無停止のまま安全に反映する方法

f:id:hirokiky:20191101104548j:plain

Djangoはデータベースマイグレーションの機能を持っています。 ですが、 実際、Djangoマイグレーションってどう使うの? という疑問が多いかと思います。

docs.djangoproject.com

この記事では、 マイグレーションを稼働中のアプリケーションに、無停止でどう反映すれば良いのか を説明します。 前提としてWebアプリ、データベースは本番環境に1系統づつあるとします。

基本的に無停止でマイグレーションを実行するのは 絶対に安全という方法ではないので、動作確認などをして慎重に反映する必要があります

無停止でマイグレーションを反映する基本

マイグレーション無停止で行う場合、「マイグレーションとアプリのリリースはどちらを先にすべきか」 という話になります (マイグレーションをするということは、アプリケーションの変更も必要になります)。

上記ではない場合、アプリケーションを停止する時間が必要になります(アプリケーションを停止、マイグレーションを実行、アプリケーションを変更して実行する)。

マイグレーションの3種類

アプリケーションを無停止のままマイグレーションを反映するには、まずマイグレーションの種類を判断する必要があります。 ここでは大きく分けて3つのマイグレーションと考えられます。

追加、変更、削除それぞれのマイグレーションをどう反映するのかが重要です。

動作確認は必要

無停止でマイグレーションを実行するのは、Webアプリが誤動作を起こすリスクを持っています。 方法は後述しますが、アプリケーションの作り方によって問題が発生し得ます。また、動作が保証される状態でもありません。 本番環境へリリースする前に、マイグレーションを実行しても問題ないか開発環境で必ず動作確認しましょう

マイグレーションを実行するタイミング

アプリケーションを無停止でマイグレーションを実行するには種類と実行するタイミングが重要です。 それぞれマイグレーションの種類ごとに、稼働中のWebアプリにマイグレーションを実行する方法を説明します。

テーブル、カラムを追加するマイグレーションの場合

テーブル、カラムの追加をするマイグレーションは、アプリのリリースより前に実行できます。

テーブル、カラムが増えたところで、Django製のアプリケーションには基本的に影響がありません。 ですので、Webアプリケーションのリリース前にマイグレーションを実行します。

  1. マイグレーションを実行する
  2. Webアプリケーションをリリースする

f:id:hirokiky:20191101104548j:plain
追加するマイグレーションを無停止で反映

テーブルやカラムが増えても、既存のDjango製のWebアプリケーションの動作や、通信量には影響がありません。 DjangoSQLを実行するときに、取得するフィールド(カラム)を全て指定するからです。

ただし、DjangoのQuerySetでextraやrawを使う場合や、生SQLを実行する場合はこの限りではありません。 アプリケーション内に影響するプログラムは無いかは事前にちゃんと確認しましょう。

カラムの削除をするマイグレーション

カラムの削除をする場合は、先にWebアプリケーションをリリースします。 アプリケーションが先にリリースされることで削除対象のフィールド(カラム)は使われなくなります。

  1. Webアプリケーションのリリース
  2. マイグレーション実行

f:id:hirokiky:20191101104612j:plain
削除するマイグレーションを無停止で反映する方法

削除対象のカラムが完全に使われなくなったことを確認してからマイグレーションを実行できます。 ただし「カラムが絶対にWebアプリ内で使われていない」ことを確認するのは大変です。慎重に確認した後、マイグレーションを実行しましょう。

カラムを変更するマイグレーション

カラムを変更するマイグレーションの場合は注意が必要です。 マイグレーションを無停止で実行できるかどうかはマイグレーションの内容によります。

例えばカラム名を変更するマイグレーションは無停止ではリリースできません。 どちらを先に実行しても、稼働中のWebアプリケーションに影響を与えます。

f:id:hirokiky:20191101104027j:plain
変更するマイグレーションを反映する方法

  • 無停止でリリースできない
    • テーブル、カラム名の変更
    • カラムの型を変更
  • 無停止でリリースできる(可能性がある)
    • カラムの最大長などを変更
    • インデックスの追加、削除

マイグレーションの内容を理解して、無停止で安全に反映できるかを確認しましょう。 カラムの最大長変更なども、稼働中のアプリケーションに影響を与えますので注意しましょう。

マイグレーションが複数ある場合

カラムの追加するマイグレーション、削除するマイグレーションが複数ある場合、Webアプリが無停止のままでは同時に反映できません。 その場合はひとつひとつマイグレーションの実行と、アプリケーションのリリースをする必要があります。

Djangoマイグレーションを1つづつ実行する方法は別のブログ記事で説明します。

まとめ

Webアプリを無停止のままマイグレーションを反映するには、マイグレーションの内容を理解してリリースする必要があります。

改めてになりますが、本番環境にリリースする前には開発環境で動作確認しましょう。 開発環境で、無停止でリリースできることを確認してから本番環境でリリースしましょう。

Djangoマイグレーションの内容を確認する方法や、1つづつ反映する方法は別のブログ記事で説明します。

続きはこちらです!

blog.hirokiky.org

ブログ記事に書くPythonコードはPEP8を厳密に守るべき?

ブログに書くコードスニペットはPEP8を厳密に守るべきでしょうか。

pep8-ja.readthedocs.io

ブログ記事に書くPythonコードはPEP8を気にしすぎなくて良いのでは

僕はブログ記事に書くPythonコードは、PEP8をそこまで気にしないで良いと思っています。 ブログに書くコードはブログの記事中で読まれるので、普通のコードのようにエディターなどで読まれるコードとは違うからです。

  • エディターでプログラムを読むときとブログで読むときは違う
  • 開発プロジェクト内では必要な、書き方の統一がブログには不要
  • てきとうに伝えたいだけなので厳密に気にするのは面倒

もちろんブログ記事内でも読みにくいコードは記事にとって良くないですし、PEP8を全く考慮しない書き方を「この書き方が良いものだ」と伝えるのは良くないです。 ですが、自分の記事で厳密に気にしすぎたり、まして他人のブログ記事に「PEP8準拠していないぞ」とわざわざ言う必要は無いと思います。 僕もPEP8は守ろうと思っていますが、ブログ記事内で守っていないこともあります。

PEP8を守って読みにくいとき

ブログ記事にPythonコードを書いて、PEP8を守ると読みにくくなるときがあります。 例えば以下のようなPythonコードを見ると、 main() 関数の上2行が間延びして見えるときがあります。

import os

HERE = os.path.dirname(__file__)


def main():
    print(HERE)

このくらいのコードをいくつか連続して書くと、ブログ記事は読みにくくなると思います。 PEP8違反にはなりますが、行を詰めたほうが読みやすい場合もあると思います。

HERE = os.path.dirname(__file__)

def main():
    print(HERE)

むしろ import os も分かりきっているので書かなくて良いかなという気すらします。 ブログという媒体においては、下の例のほうが大切だと思います。

なにかの戒律を厳密に守る(強いる)ことよりも、場所や場合によって一番良い方法で書くのが良いのではないでしょうか。

PEP8を読んでみる

PEP8を開いてみると、あまり厳密に気にしすぎるのは違うよねと書いています。

### 一貫性にこだわりすぎるのは、狭い心の現れである

スタイルガイドは一貫性に関するものです。
このスタイルガイドに合わせることは重要ですが、プロジェクトの中で一貫性を保つことはもっと重要です。
一番重要なのは、特定のモジュールや関数の中で一貫性を保つことです。

しかし、一貫性を崩すべき場合があることも知っておいてください
 - つまり、このスタイルガイドが適用されない場合があります。
疑問に思ったときは、あなたの判断を優先してください。
他の例を調べ、一番良さそうなものを決めて下さい。そして、躊躇せずに質問して下さい!

https://pep8-ja.readthedocs.io/ja/latest/

まとめ

PEP8は可読性のために大切だと思いますが、ブログ記事に書くPythonコードまでそこまで細かく気にする必要は無いと思います。

他にオススメの記事

blog.hirokiky.org

invokeで実行されるコマンドをプロジェクトルートから実行する方法

invoke(pyinvoke)というプロジェクト管理用のツールを使っていたときに出た疑問の解決方法を説明します。 とはいえ、私自身もまだこの方法で良いのか疑問なので、より良い方法を知っている人はぜひ教えてください。

invoke(pyinvoke)とは

プロジェクトでの開発を進める際に、よくあるコマンド操作をまとめておくことがよくあります。 例えば不要なファイルを削除したり、フォーマッターを適用したり、本番用にビルドしたりなどがあります。 invoke(pyinvoke)を使うとPythonでシェルでのコマンド操作を簡単に書けるようになります。

www.pyinvoke.org

invokeでプロジェクトルートから実行する

invoke でコマンドを実行(c.run(...))するときは、invoke ... を実行したパスでコマンドが実行されます。 invoke のタスクを定義したファイルは以下のように走査されますが、実行パスは変わりません。

docs.pyinvoke.org

ですが、例えばフォーマッターを全体に適応したいときなどはプロジェクトルートからコマンドを実行したくなります。 例えば以下のようなプロジェクト構成のとき、 mymodule 以下で invoke ... としても、 tasks.py を含むディレクトリーから実行したいときです。

+- tasks.py
+- setup.py
+- mymodule
    +- foo.py
    +- bar.py

そういう場合は、以下のように tasks.py を書くと良いでしょう。

import os

from invoke import task


HERE = os.path.dirname(__file__)


@task
def mytask(c):
    c.run("...")

こうすると、 invoke mytask はプロジェクトルート(tasks.py を含むディレクトリー)で実行されます。 私はプロジェクト全体のフォーマットを整えるタスクに活用しています。

@task
def format(c):
    c.run("black .")
    c.run("isort -rc .")

このプロジェクトルートから実行する方法については、invokeのドキュメントやIssueを調べても良い回答は見つかりませんでした。 唯一近そうなのがこのIssueでした。

github.com

もしより良い方法を知っている方がいれば教えてください。

仕事の精度、家政の精度。なぜ核家族の育児は大変なのか

家事、育児の話題続きで申し訳ないです。 今僕が育児休暇中なので考える機会が多いのです。

ですがこういう課題の多い分野ほどビジネスチャンスが大きいと思うので、記録として残しておきます。

仕事の"精度"と家政の"精度"は大きく違う

仕事と家政の違いは何でしょうか?働きに外に出る人と専業主夫/婦の揉める種として以下のような話を聞きます。

  • 私の外仕事のほうが大変だ
  • 私は毎日24時間仕事してるようなものだ

僕は仕事と家政の違いは以下のように分けて考えるべきだと思います

  • 一般的な仕事: 80%〜120%の精度の仕事を、週に5回、8時間働く
  • (自宅における)家政、育児: 40%〜60%の精度の仕事を、週に7回、12時間働く

一般的に仕事というのはまず100%が当たり前という世界です。 手順があるのであれば、その手順を間違えないことが大切になってきます。そのうえでプラスアルファを出せればより良いと捉えられます (もちろんクリエイティブな仕事はこの限りではありませんが、基本にある考え方は理解してもらえると思います)。

一方、自宅における家政というのはかなり精度が低くて良いです。 四角い角と丸く掃いたところで、売上が落ちるようなことはありません。 一日トイレ掃除をサボっても、まぁ生きてはいけるでしょう。お客様商売のようなシビアさはありません (気を遣う必要がある親族と同居している、配偶者が細かい点に厳しい場合などは精度が求められますが、これも基本的な部分は理解してもらえると思います)。

育児の大変さは、精度を高めようとすることだ

育児が大変なのは、その家政において精度が求められる(求めてしまう)ことにあります。 内的な要因としても「命を預かる以上」という責任感が産まれますし、「よく育てたい」という気持ちや、親戚の期待、子供への社会の厳しさ(泣き声に苦情がくる)もあって仕事に高精度を求められがちです。 ですが前述したようにこの仕事は言ってしまえば7D24Hに近い仕事です。そこで100%以上の精度を常に出していると燃え尽きてしまいます。

たしかに「子供が泣かないようにしないと」「ちゃんと消毒しないと」「ミルクをあげてちゃんと体重を増やさないと」など気にすべきことは多いです。ですがこれらすべてに100%の精度を求めると仕事が多すぎます。 「まぁ泣いてもいいや」「サカザキ菌なんてそうそういないやろ」「それなりに体重増えてるし大丈夫やろ」くらいの雑な気持ちでいかないといけません。

なので 育児は仕事ができる人ほど辛い ものだと思います。 予測不能で、論理的に解釈不可能で、膨大な仕事があるからです。でも、雑で良いんです。

育児は核家族には不可能。でもなぜ外注しにくいのか

育児をしてみて感じたのは、人類の子供というものが核家族で育てるようにできていないことです。 子供の世話をしながら家事も仕事もするというのは不可能です。現代においては社会保障制度がある程度充実しているので誤魔化しながら運用されていますが、そもそも不可能と言うべきです。

とはいえ親族に頼れというのも前時代的です。 では「代行」を使うのはなぜ難しいのでしょう。

それは「家事・育児代行」とすると「一般的な仕事」になり、80%〜120%の精度が求められるようになるから です。 とくに育児であれば命を預かる仕事なので、精度は100%以上を求められるでしょう。それを発注するとなると自分でやるより割高になるのは無理ありません。

100%の仕事として24時間の仕事を依頼するとなると、もちろん数万円単位の支払いとなります。 家政として自分でやったり親戚に任せるのであれば、50%くらいの精度ですが、それほど高額な仕事にはなりません(一日子供を親に預けていて、5万円、10万円を支払うことはないでしょう)。

だからといって「50%の精度の育児」を買う人はいないでしょう。命を預ける仕事だからです。 この 仕事に期待する精度の意識差 が、核家族を追い込むことになっています。

解決策は?

僕が考えるなかでは、信頼をベースにした仕事の依頼しかないと感じています。 お金が動くと100%精度の仕事を求められるので、贈与経済のような信頼を元にしたやり取りがうまくいくかもしれません。 信頼し合える人たち同士が、お互いに50%の仕事を担保し合えるような関係です。 今の社会では親族くらいしかありませんが、そういったコミュニティーを形成するサービスというのは考えられます(田舎の閉鎖的になったコミュニティーにも問題はあるので)。

ともあれ、局所最適化した都市型経済というのは、東京で毎日通勤電車に乗る単身者に向いたものなのだなと感じています。

皆さんのアイディアで、ぜひ日本の核家族(そして僕)を救ってください。