【Advent Calendar 2021】点字メーカープログラム

概要

本記事は Calendar for Rubyプログラミング問題にチャレンジ! -改訂版・チェリー本発売記念- | Advent Calendar 2021 - Qiitaの15日目です。
入力されたローマ字に対応する点字をテキストで出力するプログラムを作成するという企画です。

詳細な内容についてはREADMEをご覧ください。

Pull Request

https://github.com/JunichiIto/tenji-maker-challenge/pull/24

ロジックの解説

方針

企画の内容を見て、しばらく考えて頭に浮かんだ方針が次の3つです。

  1. YAMLで変換対象となるローマ字の点字をすべて定義して利用する
  2. Arrayで点字をうまく表現してなんとかする
  3. Matrixで点字をうまく表現してなんとかする

メリット・デメリットを整理してみました。

メリット デメリット
YAML シンプルといえばシンプル 将来もし点字パターンが変わることがあるならそのときの修正にコストがかかりそう
点字を理解している人にとって、YAMLを見たときに正しさがパッと見でわかる
Array Ruby実装経験者は扱いに慣れている 点字のしくみ・概念に沿った実装ができない?
Matrix 点字のしくみ・概念に沿った実装ができる Ruby実装経験者でも扱ったことのあることが少なそうで、Matrix自体の理解にかかるコストがある

私の心情も整理してみました。

ポジティブ ネガティブ
YAML なんとなく伊藤さんが求めるものではない気がする
Array AtCoderでグリッド問題を配列で解こうとしたときに混乱した経験があるので不安
Matrix イケている感じがする Matrixを利用したコードを書いた経験がほぼなく不安

採用案

Matrix案を採用しました。
採用理由は次の通りです。

  • 点字のしくみ・概念に沿った実装ができる
    • 実装当初は確信を持つことができていません
  • (イケている感じがする)

処理の流れ

メイン処理の流れは次の図の通りです。

メイン処理の流れ
メイン処理の流れ

  • ローマ字を点字と同等の3行2列のMatrixに変換します
    • 各要素は点があれば1、なければ0
      • 最終的に1'o'へ、0'-'へ変換します
  • 空白(セパレーター)も3行1列のMatrixに変換します
    • 各要素は-1
      • 最終的に-1' 'へ変換します
12/19 追記

よくよく考えると空白を-1で表現しないほうが 心残りなこと に記載した疎結合も解消できていいなと思ったのでリファクタしてみました。

https://github.com/mfham/tenji-maker-challenge/pull/2 https://github.com/mfham/tenji-maker-challenge/pull/3

※企画が終わるまではフォーク元のPRに反映されないようにしたいので、上記PRはRevertしてあります。

コードのアピールポイント

点字のしくみ・概念に沿った実装

全視情協:点字とは - 点字のしくみに記載の通り、点字は①②④の点を組み合わせて母音を表し③⑤⑥の点を組み合わせて子音(行)を表します。
その概念をそのまま実装で表現しました。
もし将来他の開発者が追加実装をすることになったとしても、すんなり実装に入れるのではないかと思っています。

変換処理の切り出し

心残りなこと

縦3点、横2点での表現が縦N点、横M点へ変更になるときの考慮

点字は縦3点、横2点の6点で表現されています。
おそらく近い将来も変わることはない気がするのですが、もしかしたら点字の世界にも絵文字・顔文字のような表現方法が生まれるかもしれません。

その場合、6点では足りなくなるのではないか?
そのときのことも考え、縦N点、横M点に変更されることになっても柔軟に対応できるような実装にしたいという思いがありました。

しかし今回そのことを考慮した実装ができませんでした。

密結合の解消

今回、空白(セパレーター)を表すMatrixをMatrix[[-1], [-1], [-1]]としました。
たとえば、各要素の値を-1から-2に変更しようとした場合、空白を表すMatrixの定義だけでなく最終的に変換するロジックの定義も合わせて修正する必要があります。
この関係性を知らずに片方だけを-2へ変更するとバグが起きます。

ここら辺をうまく実装したかったのですが、力及ばずでした。

Converterの設計

実装の考え方については コードのアピールポイント に記載しています。
実装中にデザインパターンとして知られるStrategyパターンが頭に浮かびましたが、深く理解しておらず理解する時間もとることができず、なんちゃって実装になっている気がしています。

オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 | Sandi Metz, 髙山 泰基 |本 | 通販 | Amazonを購入したので、設計全般やデザインパターンについて学びなおします。

プロを目指す人のためのRuby入門[改訂2版] 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plus) | 伊藤 淳一 |本 | 通販 | Amazonも購入したので、合わせて勉強しなおします。

新規作成した部分のテストコード

もともと用意されているテストコードがパスすればよいとはいえ、新規作成した部分のテストコードは作成すべきでした。

参加した感想

初めてのAdvent Calendarへの参加

初めてAdvent Calendarに参加しました。
先輩が「こういうのあるよー」とリンクを共有してくださり、数時間悩んだ結果、えいやでぽちっと参加を決めました。
1ヵ月近く時間があったにもかかわらず、当日23:20現在、この本文を書いています。 パーキンソンの法則 - Wikipediaですね・・・。

他の誰かがやりたいであろう枠を自分がとっているので、そのプレッシャーを感じながら毎日過ごしていました。
他人から見られるというほどよいプレッシャーのおかげで、頭を悩ませながらなんとか設計・実装できてよかったです。

他の方の実装・記事もこれからゆっくり読みたいと思います。

点字

今回参加するまで、点字のしくみなど点字のことについてほぼ知らない状態でした。
設計・実装を進める中で、参考リンクとして紹介されていたページを何度も読みなおし、点字の歴史などを調べるくらいまで興味が湧いていることに気付きました。

  • 将来9点や12点で顔文字に相当するような表現は生まれるだろうか?
  • 世界の点字はどうなっているのだろうか?文章を右から読む国ではどういう点字が使われているのだろうか?
  • 左から読んでいくので、のような濁音は最初に濁点があるとお知らせする(始めにを表す点があってその後ろに清音(五十音)がある)と読みやすい。なるほど、おもしろい
  • 表面に点字がついているキーボードは販売されていないのかな?

この後も引き続き点字のことを理解していく予定です。

伊藤さんへのメッセージ

企画していただきありがとうございました。
緊張しながらも楽しみながら取り組むことができました。

もし機会があれば、伊藤さんが今回の仕様を実装する様子を見てみたい(ライブコーディング、動画)です。

  • どのようなことを考えて設計するのか
  • どのような情報(点字Rubyドキュメント、自分用メモ、その他)を参照するのか
  • どういう順番で実装するのか
  • どんな拡張機能やツールを使っているのか
  • 設計から実装までどのくらい時間がかかるのか

素敵な企画、ありがとうございました!