セットプチフォッカ

勉強したアウトプット、ときどきフォッカチオ作っていました

スマホ中毒改善のために空き箱でスマホケースを作る

スマホをついつい触ってしまう...

勉強中もそうなんですが、ベッドにもスマホを持ち込んでしまって、色々と質を落としているのが最近の問題点でした。

毎週1回、個人のGKPTを振り返っていて、この問題に対しては以下のような議論がなされました。

  • スマホを金庫に入れれば良いのでは?
    • 休憩中にすぐ見られない。
    • しまうのと出すのが億劫になって結局継続できなさそう
  • スマホを触らない、持っていかないという鉄の意志を持つ
    • 意志の力に頼るのは根本的解決にならない
  • スマホの定位置を机の上にもうけるのはどうだろう?
    • 見える位置にあると結局触る
    • 視覚的に見えない位置に収納すると良いのでは?
    • あまり遠い場所に置くと、スマホをなくす問題が発生する
  • 机の近くで、かつ見えにくい位置にシュッとしまえるケースがあれば捗りそう

捗りそう...!?

で、プロトタイプ作ってみた

f:id:ikmbear:20220205090821j:plain

というわけでプロトタイプ作成です。イメージ図はこんな感じ。

右利き & モニターの右側にMacを置いているので、机の左側面にスマホケースを作れると、「離着席時にはスマホがよく見え、作業時には視界に入らない」という感じにできそう、っていう魂胆です。

f:id:ikmbear:20220205090831j:plain

次は材料探し。プロトタイプってことで家にある材料を探したら、FILCOのキーキャップの空き箱がありました。これを使います。

f:id:ikmbear:20220205090840j:plain

開いてほしい方向と、実際に箱が開く方向があべこべだったので、カッターで無理やりくり抜きました。不器用なんで辛かった...。

f:id:ikmbear:20220205090849j:plain

机に接着して完成です。両面テープも家にはなかったんで、ビニールテープでHOT LIMITにしています。

いざ装填!

f:id:ikmbear:20220205090858j:plain

設計通り、スマホがシュッと入りました!

目論見通り、作業中は左側に全然意識が向かず、スマホを触る時間が格段に減りました。びっくりするほどに睡眠の質もめちゃくちゃ上がりました!スマホ恐るべし...。

一つ難点があるとすれば、貼り付けがあまりにも適当すぎるので、定期的に押さえつける必要があることくらいでしょうか。

やっぱり人間ってのは定位置が決まっていると、うまく整理・整頓できるもんですね。トヨタの片付けが言っている「姿置き」ってやつですね。

このプロトタイプでしばらく持ちそうですが、HOT LIMITが解放されてしまったら、ちゃんとしたの作ろうと思います。

Steepで使えるコマンドを見てみよう

資料はこちら

speakerdeck.com

昨日omotesando.rb#71で話したネタです。元々はRails7から追加されたActiveModel::APIの話をしようと思っていたんですが、資料作ろうと思った翌日にTechRachoで紹介されていたのでやめました。

資料にも書いたのですが、RubyMineでLSPがうまく起動できませんでした...。

github.com

一応ここに書いてある方法でやっているんですけど、なんかがうまくいっていないみたいなので、継続調査していきたいと思います。

わたしがRubyMineを使う理由

f:id:ikmbear:20220203082003p:plain

「RubyMineの何がいいのか?」という問い

みなさんRubyMine使っていますか?昨今のエディタシェアでは、やはりVSCodeが一番大きなパイを占めているような感じですが、私はRubyMineが好きなのでずっとRubyMineを使っています(一部例外で、LiveShareを使いたいとか、Slidevのスライドを作る時だけVSCodeを使っています)。

そんな中、FJORD BOOT CAMPで「みんながおすすめするのでRubyMine使ってみたけど、他のエディタに比べて何がいいんだろう」という質問が出てきました。

というわけで今回は一利用者として「私がRubyMineを使う理由」を述べてみました。

世界中の開発者体験が機能として実装されている

VSCodeもかなり便利ですよね。拡張機能を追加していけば「RubyMineではこんなことできるよ」の大多数はVSCodeでもできると思います。これはVimEmacsを使った場合でも同じで、つまりフルパワー状態の単純な機能比較によっては、普段使用していて馴染んでいるエディタにRubyMineが勝る点はあまりないかもしれません。

ではRubyMineを使用するメリットは何かというと 「世界中の開発者体験が、あらかじめ機能として実装されていること」 です。

たしかにVSCodeプラグインを追加すれば、RubyMine相当の機能を動かせるかもしれませんが、それはその機能にあなたが 「気がついた」 場合です。使えたら便利だけど読むには細かいGitコマンドのオプションや、DBの操作方法の全てに気がつくことができるでしょうか?少なくとも私には難しそうです。

RubyMineを運営するJetBrains社は毎年開発者に対して調査を実施し、製品開発のためにJetBrains製のエディタのドッグフーディングを行なっています。これによりRubyMineには、世界中の開発者が「これは開発によく使うし、あると便利」と思っている機能が最初から、つまり 「気がつかなくても」 使えるようになっているわけです。

1人で学習を進めているいまだからこそ、私は世界中の開発者の動きを学習の補助輪とするために、RubyMineを使用しています。

コマンド操作が全部「見える」から

RubyMineの操作は基本的にすべてGUI上で実行されます。

そのため、コマンドで実行すると複雑な操作も、実際にどういうことをやっているのかイメージがつきやすいです。

例えばGitのrebase は最たる例で、よくわからないけど必要だから...とコマンドライン上でやると、「なんかよくわかんない...」「変な感じで取り込まれてしまった...」となりがちです。

Untitledf:id:ikmbear:20220203071125p:plain

これをRubyMine上でやると、すべてを画面操作として実行できるので、

  • 実際にどういう作業ができるのか
  • 今自分が行った操作はどのような結果になるのか

が画面上で確認できるため、そのコマンドでできること、自分がやっていることのイメージがしやすくなります。いわばRubyMineが各コマンドの「図解!〇〇」的な役割を担うわけですね。

もちろんGUICUIへの変換は必要になりますが、コマンドの実行イメージがあるおかげで、CUIで実行する際にも意図通りに実行しやすくなり、実行への恐怖感も薄れます。

はじめこそ、ちゃんと整備された道具を使ったほうがいい

私は高校時代に初めてギターにさわり、パン作りを始めました。

ギターの方は安いアコギを買ってしまったがために、弦高が高くてしばらくバレーコードが弾けなかったのですが、友達の高いギターはとても弾きやすくて、それを借りて練習しているうちに、安い方のアコギでもバレーコードが弾けるようになりました。

パン作りの方はずっと独学でやっていたのですが、大学時代にアルバイトで実際に製パンをやらせてもらえることになり、そのときに初めて整備された環境でパンを作ったことで、一気にパン作りのコツを掴むことができました。4年分の成長が3日で追い越されるくらいのブレイクスルーでした。

双方の話に通じるのは、「初めから整備された環境でやっていれば、もっと早く成長できたのに」ということです。何も最高級の環境を整えろというわけではありませんが、最初のうちは「どんな道具が必要か」がわからず「正しい型」もわかっていない状態です。

そんな状態だからこそ、はじめのうちこそRubyのためのフルマネージドなIDEであるRubyMineを使うのがいいんじゃないかなと思っています。

「弘法筆を選ばず」と言いますが、そもそも弘法って達人の域の話なので、個人的には「初めのうちは筆を選んでいけ」という気持ちです。

おわりに

というわけで今回は「私がRubyMineを使う理由」をお届けしました。

私自身も初学者であるがゆえに、全体的に初学者向けの内容になってしまいました(ある程度プログラミングできる人は、自分の欲しい機能とか開発スタイルでエディタを選ぶ気がするんだ...)。

speakerdeck.com

以前FJORD BOOT CAMPの中で行われたLT会でも「初心者こそ!RubyMineで始めよう!」という話をさせていただきましたが、やはり最適化された開発フローをエディタを通じて学べるからこそ、自分のようなエンジニア未経験者でもお金を払ってRubyMineを使用する価値はあると思っています。

とはいえ、エディタってやっぱりエンジニアの道具の中で一番大きい部分なので、最後は「自分が使いたいエディタ」で楽しく開発するのがいいんじゃないですかね、と雑にしめて終わりにしたいと思います。

宣伝:RubyMine入門は無料で読めます!

この記事を読んで、「RubyMine使ってみようかな...でも使いこなせるか不安...」と思った方、ZennでRubyMine入門という無料で読める電子書籍を出しています!

zenn.dev

基本的な操作からGit、エディタの見た目変更まで、RubyMine初心者に必要な内容を詰め込んだ一冊になっているので、ぜひに!

OSS gateにビギナーとして参加しました!

f:id:ikmbear:20220130112941p:plain

昨日 OSS Gateオンラインワークショップ にビギナーとして参加してきました!

OSS Gateとは?(引用)

OSS Gate」とはOSS開発に参加していない人が参加する人に変わる「入り口」を提供する取り組みです。

OSS開発に未参加の人向けに参加方法を伝える場を継続的に提供することにより、OSS開発に参加する人を増やすことができるのではないか。それを実現することが「OSS Gate」という取り組みの目的です。

参考:OSS Gateへようこそ!

oss-gate.doorkeeper.jp

参加した理由

OSS Gateのアンケートには一つだけ書いたんですが、よくよく考えると3つくらいありました。

  1. いつもOSSにお世話になっているので、自分もそこに貢献したいと思ったから
  2. 2020年にCOVID-19のサイトがOSSとして作成された時に、自分はIT業界で働いているのに何もできなくて、ちゃんと勉強して社会の役に立ちたいと思ったことが原点の一つとしてあるから
  3. OSSに限らず)不満に対して文句を言うんじゃなくて、それを改善できるように生きていきたいと思っている。そのための手段としてプログラミングを学び始めたから

というような思いが常々あって、でもやっぱり見ず知らずの人にパッチとかIssueを送るのはちょっと気がひけるので、背中を押してもらうために参加しました。

作業内容

イベント自体は10:30〜17:00まで、そのうち手を動かしている時間は11:00~15:00すぎくらいまででした(途中で休憩あり)。

今回はオンライン開催だったので、Discord上で作業を進めました。作業ログを見て適宜サポーターさんからボイスチャット & 後述の作業ログのコメントで「いいですね〜」「こういうところを見てみるのもいいかも」みたいなサポートをもらいつつ進める感じです。

作業内容としては、貢献したいOSSを選んで、それを公式のドキュメントに則って動かす中で改善した方がいいこと、エラーになったことを投げるという形式だったので、私は最近利用したMarkdownを使ってスライドが作れるツールのSlidevを対象にすることにしました。

github.com

OSS Gateの特徴として、作業中は常に作業ログを取っていきます。実際に私が取った作業ログはこんな感じです。

github.com

以前、「ログ駆動開発」というテーマでLTを行ったことがあって、自分も普段から作業時は全部ログを書いているんですが、これに似ているかな〜とか思いました。

ikmbear.hatenablog.com

成果物

作成したIssue

というわけで実際に投げたIssueがこちらになります!

f:id:ikmbear:20220130111402p:plain

github.com

Slidevには作成したスライドのExport機能があって、これがplaywright-chromiumというパッケージに依存しています。

これがない場合には、コマンド側はnpm i playwright-chromiumをするように例外を投げるのですが、一方でドキュメントにはnpm i -D playwright-chromium、つまりdevDependenciesとして追加をするように推奨していて齟齬があり、ここを統一した方がいいのでは?というIssueを立てました。

サポーターさんにも👍をいただいたポイントなのですが、この2つの文言が追加された経緯をGit Blameで辿っていけたのがよかったです。

遡っていくと、これらの文言は全く同じコミットで追加されていることがわかり、「書き間違いというか表記揺れかな?」と思えたことが主張の安心材料になりました。

気づき

午前中にさわっていた時は「エラーにはなったけど、別にログを見ればわかるからここはフィードバックポイントじゃないかな〜」と思っていたんですけど、サポーターのDaipomさんとPiroさんが書いていただいたコメントから、間接的にですが「あれ?案内している文言が違うかも」と気がつくことができました。自分でやるときはちょっとでも「ん?」と思ったところは一旦視点を変えて見つめ直すのがいいかな〜と思いました!

あとはIssueの下書きが出来上がった際に、「やっていないことを書いてみると文意が伝わりやすくなるかも」「こういう返答も想定されるので、自分のお気持ちも書いておくといいかも」といったアドバイスをもらうことができました。前にkoicさんの動画でみたと思うんですが、「なぜそれを取り込む必要があるのか」「そのための判断材料」を意識して書いていくのがやっぱり大切なんだと、自分でやってみて感じました✍️

前提知識として何が必要か?

OSSを動かした際のポイントをフィードバックする」というプログラムなので、そのOSSに対してめちゃくちゃ詳しくないといけないということはないかな〜という印象です。

技術的な前提としては

  • Git / GitHubが使える
  • 黒い画面が使える

ってところですかね。実際私も、ブラウザでドキュメント読む→ターミナルでインストールする→ブラウザ上でIssueを立てるって感じでした。

あとは対象となるOSSを自分で決める必要があるので、最近使ったアプリをちょっと思い出しておくといいかもです(私は当日ふと頭に出たのでSlidevにしましたが、Gemとかでもよかったかも)。なおOSSかどうか、Issueをたてるポイントがありそうかは、プログラムの中で確認するので事前チェックは不要です。

感想

参加する前は「本当にこの時間内でIssueを立てられるのかな?」と内心不安だったんですが、本当に立てることができて、驚き & とても嬉しかったです!

OSS Gateの目的として「自分1人でもOSSに参加できるようになる(気持ちになる)」という点があるのですが、今回実際にIssueを立てることでこれからもやっていけそうだな!と感じました。

(...実際にOSS Gate終了後に今回扱ったSlidevの別件の対応の準備を始めました💪)

OSS貢献へのあと一歩が踏み出せなかった理由に「こんなんで大丈夫なのかな?」という気持ちがきっとあったのですが、今回サポーターの皆さんに自分のやっていることを「承認」してもらえたり、「客観視」した上でアドバイスをもらえたことで、自分1人の中に沈み込んでいた不安が大きく開けた気持になりました!

今回の挑戦をステップに、どんどんOSSの世界を楽しみたいと思えるイベントでした!サポートいただいた皆さん、ありがとうございました!!!!😊


余談

...当日Piroさんに言えなかったんですけど、「シス管系女子全部持ってます!初めてLinuxの勉強する時に買いました!」とここに書き残しておきます😅

f:id:ikmbear:20220130111448p:plain

おわりに:次回OSS Gateのご案内と気になる方へ

OSS Gateは定期的に開催されていて次回は3/8みたいです。

oss-gate.doorkeeper.jp

参加できるサポーター枠によって、ビギナーとして参加できる方の数も変わってくるのですが、ビギナーには「サポーターを1人以上連れてくるビギナー」枠があります。

「サポーターを1人以上連れてくるビギナー」枠

  • 今回のワークショップに「サポーター」で参加する人を見つけ、自分は「ビギナー」で参加する枠です。
  • 実際に「サポーター」の登録者が1人増えたら繰り上がります。
  • どの「サポーター」がどの「サポーターを1人以上連れてくるビギナー」に対応しているかはわからないので一番最初に登録していた「サポーターを1人以上連れてくるビギナー」が繰り上がります。

もし「OSS Gate興味あるけど、枠もいっぱいだし...」という方がいたら、次回開催に限らず、お声がけいただければサポーターとして参加しようと思うので、コメント欄でもTwitterでもお気軽にご連絡ください!

⚡️K-Rubyと銀座Railsで自作Gemの話をしました!⚡️

  • 自作Gemの話をしてきました!
  • プロモーション活動の成果
  • 登壇してみて感じたこと
  • 自分の中の発表に関するQ&A
    • 自己PRはあさましいか?
    • 初心者が話して迷惑じゃないか?
    • 同じことを何度も言うのは申し訳ないか?
  • チャンスを掴む握力も才能って杉江さんが言ってる
  • 銀座RailsもK-RubyもLT枠募集中みたいです!
  • おわりに

自作Gemの話をしてきました!

K-Rubyと銀座Railsで先日作成した自作Gemの話をしてきました!

続きを読む

日本の地方公共団体コードをパースするGemをリリースしました

f:id:ikmbear:20220118162141p:plain

作ったもの

f:id:ikmbear:20220118162056p:plain

jp_local_govという日本の地方公共団体コードを市区町村の情報にパースしてくれるGemを作りました。人生初Gemリリースです🎉

github.com

rubygems.org

「そもそも地方公共団体コードってなんやねん」方も多いと思いますが、

全国地方公共団体コード(ぜんこくちほうこうきょうだんたいコード)[注釈 1]は、日本地方公共団体につけられた、数字3または5桁または6桁の符号(コード)で ある。コードが与えられる地方公共団体とは、都道府県市町村特別区一部事務組合地方開発事業団広域連合、加えて、地方公共団体ではないが行政区東京都区部である。

全国地方公共団体コード - Wikipedia

というものです。JIS規格にも指定されています。

3桁、5桁、6桁とありますが、ルール的には

  • 上2桁が都道府県、
  • 続く3桁が市区町村
  • 残りの1桁がチェックディジット

になっているので、このGemでは6桁フルの状態をパースできるようになっています。

READMEにも書いているのですが、jp_prefectureのアイデアに多大に影響を受けています。

github.com

作った背景

今作っているサービスで必要だったからです。

ざっくりいうと公共料金を計算するサービスで、その計算のための料率が市区町村ごとに違うために、市区町村ごとにレコードを持つ必要がありました。

で、市区町村だけのテーブルをもつのもなんだか微妙だし、市区町村のための管理画面をもつのも面倒だったので、「Gemでできないかな〜」と思っていたのですが、似たようなアイデアのGemは更新が数年前...。

...みたいなことを、FJORD BOOT CAMP内で日報に書いたら、メンターさんから「作ってみては」とアドバイスが。

「ちょっと難しいかも...」と思いつつも、内心「作ってみたい、MY FIRST GEM」という思いが心の中に溢れてきたので、作ることにしました!

使い方

だいたいREADMEに書いてある通りなんですが、英語なので日本語でも書きます。

インストール

一応Ruby3.0.0以上が対象です。

普通にインストールするか

gem install jp_local_gov

Gemfileを使ってインストールします

# Gemfile
gem 'jp_local_gov'
bundle install

必要に応じてrequire します。

require 'jp_local_gov'

id指定の検索(JpLocalGov.find

地方公共団体コード(String)を指定することで、地方公共団体の情報を取得することができます。

chiyodaku = JpLocalGov.find("131016")
# => #<JpLocalGov::LocalGov:0x00007fe706a8f148 @code="131016", @prefecture_code="13", @prefecture="東京都", @prefecture_kana="トウキョウト", @city="千代田区", @city_kana="チヨダク", @prefecture_capital=false>
chiyodaku.code
# => "131016"
chiyodaku.prefecture_code
# => "13"
chiyodaku.prefecture
# => "東京都"
chiyodaku.prefecture_kana
# => "トウキョウト"
chiyodaku.city
# => "千代田区"
chiyodaku.city_kana
# => "チヨダク"
chiyodaku.prefecture_capital
# => false

この後のメソッドでも共通ですが、取得できる情報は

です。

ひらがなとか英字とかも追加するのは苦ではないんですが、総務省が出している元データは漢字とカタカナだけなのと、あんまりユースケースが見つからなかったので、一旦出していません。

あと東京都の都庁所在地は一応「東京」って習ったと思うんですが、「新宿」として登録しています。

条件指定での検索(JpLocalGov.where

上記の取得できる情報をキーとして、ハッシュを渡すことで、指定した条件に合致する市区町村の情報が配列で返ってきます。

なお複数の条件を指定した場合はAND検索になります。

misato = JpLocalGov.where(city: "美郷町")
# => [#<JpLocalGov::LocalGov:0x00007fb1c594cb08 @code="054348", @prefecture_code="05", @prefecture="秋田県", @prefecture_kana="アキタケン", @city="美郷町", @city_kana="ミサトチョウ", @prefecture_capital=false>, #<JpLocalGov::LocalGov:8 @code="324485", @prefecture_code="32", @prefecture="島根県", @prefecture_kana="シマネケン", @city="美郷町", @city_kana="ミサトチョウ", @prefecture_capital=false>, #<JpLocalGov::LocalGov:0x00007fb1c1a3ce40 @code="454311", @prefecture="宮崎県", @prefecture_kana="ミヤザキケン", @city="美郷町", @city_kana="ミサトチョウ", @prefecture_capital=false>]
misato.map { "#{_1.prefecture}:#{_1.city}" }
# => ["秋田県:美郷町", "島根県:美郷町", "宮崎県:美郷町"]

JpLocalGov.where(prefecture: "東京都", prefecture_capital: true)
# => [#<JpLocalGov::LocalGov:0x00007fb1c219e418 @code="131041", @prefecture_code="13", @prefecture="東京都", @prefecture_kana="トウキョウト", @city="新宿区", @city_kana="シンジュクク", @prefecture_capital=true>]

JpLocalGov.where(prefecture: "東京")
# => nil
# Exact match search. You should specified "東京都" instead of "東京".

全件検索(JpLocalGov.all

すべての地方公共団体の情報を取得したい場合に使用します。戻り値は配列です。

JpLocalGov.all
# =>  [#<JpLocalGov::LocalGov:0x00007fdf3a9c6758 @code="011002", @prefecture_code="01", @prefecture="北海道", @prefecture_kana="ホッカイドウ", @city="札幌市na="サッポロシ", @prefecture_capital=true>, #<JpLocalGov::LocalGov:0x00007fdf3a9c6730 @code="011011",...

Railsだと、collection_select を使用することで、すべての市区町村のコンボボックスを簡単に作ることができます。

ランダムな地方公共団体情報の生成(JpLocalGov::Random

ランダムな地方公共団体情報から、指定したプロパティを返します。

JpLocalGov::Random.code
# => "281077"
JpLocalGov::Random.city
# => "大島町"
JpLocalGov::Random.city_kana
# => "チュウオウシ"
JpLocalGov::Random.prefecture
# => "青森県"
JpLocalGov::Random.prefecture_code
# => "46"
JpLocalGov::Random.prefecture_kana
# => "ヒョウゴケン"

一応想定するケースとしては、FactoryBotで地方公共団体コードを指定する際に、決めうちではんく探索的なテストデータを作成しておきたいという場合を想定しています。

後述しますが、Railsで使用する場合はDBに保持するカラムはlocal_gov_code だけなので、その他のプロパティのメソッドはあまり使い所がないかもしれません笑

補足として、あくまでプロパティ単位でしかランダムな値を生成しないので、ランダムな地方公共団体インスタンスを作成する場合は、

JpLocalGov.find(JpLocalGov::Random.code)

という具合に呼んでやる必要があります。需要があれば、JpLocalGov::Random.new みたいなのを作るかもです。

Railsでの使用(基本)

このGemをModelクラスにincludeすることで、そのモデル内でlocal_govenment というメソッドが使えるようになります。

jp_local_gov :<地方公共団体コードを保存したカラム名> とすることで、そのカラム(地方公共団体コード)から、都道府県名や市区町村の情報を展開することができるようになります。

# app/models/insurance_fee.rb:
class InsuranceFee < ActiveRecord::Base
  # local_gov_code:String

  include JpLocalGov
  jp_local_gov :local_gov_code
end
insurance_fee = InsuranceFee.new
insurance_fee.local_gov_code = "131016"
insurance_fee.local_government.city
# => "千代田区"

なおカラム「地方公共団体コード」の作成時、型はStringにする必要があります。

Railsでの使用(バリデーション)(JpLocalGov.valid_code?

地方公共団体コードのチェックのためのメソッドを設けているので、これをカスタムバリデーションに組み込むことで、地方公共団体コードのチェックができます。

class InsuranceFee < ApplicationRecord
  include JpLocalGov
  jp_local_gov :local_gov_code

  ## カスタムバリデーションで利用する
  validate :valid_code?

  def valid_code?
    unless JpLocalGov.valid_code?(local_gov_code)
      errors.add(:local_gov_code, "is not valid code")
    end
  end
end

実施しているチェックは

  • コードが文字列かどうか
  • コードが正しい長さか(6文字)
  • チェックディジットを満たしているか
  • 正しい都道府県コードを持っているか

です。

チェックディジットについては、地方公共団体コードの仕様に記載があります。

f:id:ikmbear:20220118162309p:plain

11 検査数字

全国地方公共団体コードにおける検査数字は、電算処理にあたって、不正なコードが使わ れないよう第6桁目をチェック用としたもので、次の方式により算出した数字とする。 (方式) 第1桁から第5桁までの数字に、それぞれ6.5.4.3.2を乗じて算出した積の和を 求め、その和を11で除し、商と剰余(以下「余り数字」という。)を求めて、11と余り 数字との差の下1桁の数字を検査数字とする。 ただし、積の和が11より小なるときは、検査数字は、11から積の和を控除した数字と する。

出典:https://www.soumu.go.jp/main_content/000137948.pdf

実装としてはこんな感じです。ボリューム的にもプログラミングのちょうどいい問題だと感じていて、結構好きな仕様です。

CHECK_DIGITS_INDEX = 5
CHECK_BASE = 11

sub_total = code.chars
                .take(CHECK_DIGITS_INDEX)
                .map.with_index { |digit, index| digit.to_i * (CHECK_DIGITS_INDEX - index + 1) }
                .sum
candidate = (CHECK_BASE - sub_total % CHECK_BASE) % 10
check_digits = sub_total > CHECK_BASE ? candidate : CHECK_BASE - sub_total
code[CHECK_DIGITS_INDEX] == check_digits.to_s

なお最初はチェックディジットだけのチェックでいいかなと思っていたんですが、チェックディジットを満たしていても、都道府県コードがイレギュラーになるケースに後から気がつきました。

'481238' # 都道府県は47までなので、こんな市区町村はない

# 第1桁から第5桁までの数字に、それぞれ6.5.4.3.2を乗じて算出した積の和を求める
80

# その和を11で除し、商と剰余(以下「余り数字」という。)を求めて、11と余り数字との差の下1桁の数字を検査数字とする。
8  # 存在しない市区町村だけど、チェックディジットを満たす

なので、都道府県コード(1..47)のチェックも入っています。

仕組み

f:id:ikmbear:20220118161859p:plain

そこまで複雑なGemではないのですが、一応こういう仕組みです。

総務省|地方行政のデジタル化|全国地方公共団体コード

情報の元は総務省のこのページです。手順的には以下のような感じです。

  1. 元データ(PDF)をGem:pdf-readerで読み取る
  2. sqliteにぶん投げる
  3. sqlite内でソートを行う
  4. 都道府県ごとにSELECTしてJSONに出力する
  5. 出力されたJSONを使って地方公共団体コードをパースする

このGemは地方公共団体コードの情報が命なので、この処理自体をRakeタスクとして登録して、GitHub Actionsで1ヶ月に1回、自動でPRを作成する形式にしています。

今後の展望

まだIssueにも登録していませんが、ここらへんはやりたいなと思っています。

JpLocalGov.all政令指定都市の行政区を除外する

「区」って東京のイメージが強いですが、実は各都道府県の政令指定都市には区があります。例えば札幌市には中央区や東区があります。

市区町村を選択するのに、ここら辺を選択したい場合もあれば、「札幌市」という市区町村の単位だけがあればいいケースもあると思っています(私のアプリもそうです)。

なので、これをオプションで除外できるようにしたいです。一応、都道府県コードに続く3桁の決まりでなんとか除外できそうなので、近いうちに入ると思います。

YARDでドキュメントを書く

@params とかかいてあるあれです。

このGemはRBSを使っているので、それが半分ドキュメントの役割を果たしている感じもしますが、まだまだ普及率も高くないことと、自分自身が書いてみたいので、これも時間ができたらやる予定です。

RubyバージョンでのテストのCIを実行する

強いGemのCIで走っているあれです。

今はリポジトリruby-versionをおいて、それをGitHub Actionsで参照するようにしているのですが、これを各Rubyバージョンで実行できるようにしたいです。

どうやってやるのかわからんですが。

曖昧検索、一つのプロパティに対して複数条件検索、OR検索

今実装しているwhere は完全一致検索かつAND検索で、一つのプロパティに対して一つの条件しか指定できないんですが、ここら辺をもうちょっと柔軟にしたいです。

あんまり使う機会ないんですけど、なんかできたら良さそうな感じするじゃないですか。

変更差分の見える化

リリースしてからまだ時間が立ってないので、地方公共団体コードの変更は起こっていないんですが、変更が発生した場合になんかいい感じに見せられないかな〜とぼんやり思っています。

終わりに

というわけで、地方公共団体コードをパースしてくれるGem「jp_local_gov」をリリースしたというお話でした。

前にもnpmを作ったことはあったのですが、今回はちゃんと実践的に使えるものを作ったので、いろいろと学びも多かったし、楽しかったです😄

(npmの話はこちら) ikmbear.hatenablog.com

市区町村まで必要になるケースってそんなに多くないかもですが、もしこのGemを作っていただける方がいるなら嬉しいです!バグや要望はIssueにお気軽に登録してください!

github.com

最近のScrapboxの使い方(2021/12)

f:id:ikmbear:20211015135059p:plain

ikmbear.hatenablog.com

2ヶ月前にこんな記事を書きましたが、微妙に進化している & LT会でScrapboxについてお話ししたので、現状のカスタマイズをソースコードと合わせてご紹介します。

  • UserScriptとUserCSS
  • UserScript
    • テンプレート
      • 仕組み
      • 日報テンプレート
      • じぶんRelease Notesテンプレート
    • 今日のページに移動するボタン
    • チェックボックスなどを表示する
  • UserCSS
    • ピン留めされたページを別の段として表示する
    • セクション用の見出しCSS
  • 運用方法
    • 概要
    • 日報 & ライフログ
    • じぶんReleaseNotes(週報)
    • 月次ページ
  • Scrapbox用クライアント
続きを読む