2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rubyプログラミング問題にチャレンジ! -改訂版・チェリー本発売記念-Advent Calendar 2021

Day 13

点字メーカーを作ってみた! ~チェリー本改訂版発売記念アドベントカレンダー企画~

Last updated at Posted at 2021-12-13

##はじめに
この記事はRubyプログラミング問題にチャレンジ! -改訂版・チェリー本発売記念の点字メーカープログラム作成したので、それについての解説記事です。

  • 作成した人
  • Ruby歴半年、今年6月からエンジニア転職を目指して毎日働きながら学習継続中
  • 新卒で地元のメーカーに就職した社会人2年目の23歳


  • なぜこちらの企画に参加したのか
  • 伊藤さんのコードレビューを受けれるかもしれないから
  • チェリー本を愛用しているため、形ある貢献がしたかったから
  • Qiitaでアウトプットがしたかったから(初記事です)


  • 完成したプログラムのプルリク↓

##お題の概要
今回作成したプログラムは、入力されたローマ字に対応する点字をテキストで出力します。
以下が実行例です。

tenji_maker = TenjiMaker.new
puts tenji_maker.to_tenji('A HI RU')
#=> o- o- oo
#   -- o- -o
#   -- oo --

puts tenji_maker.to_tenji('KI RI N')
#=> o- o- --
#   o- oo -o
#   -o -- oo
  • 点字の点には半角小文字のoを、出力されない部分には半角ハイフン-をつける
  • 点字と点字の間は上の実行例のように、半角スペースで区切る
  • ローマ字から点字への変換は以下のサイトに従う

Screen Shot 2021-10-28 at 6.39.12.png
引用 全視情協:点字とは - 点字のしくみ

このお題の詳細はRead Meで詳しく書かれてあるので、ここまでにします。
それでは解説をしていきます。

##ロジックの解説
このお題を突破するには、大きく分けると以下の3つの処理が必要だと思いました。

番号 処理内容
1 入力されたローマ字を読み取る処理 (どのローマ字が入力されたのか、何文字目なのか、何文字入力されたのか)
2 ローマ字を点字に変更する処理
3 点字を出力する処理 (どの点字を入力するのか、何文字目に変更した点字を出力するのか、何文字点字を出力するのか)

そしてこれに準じて、作ったメソッドは3つあり、
1,3の入力されたローマ字の読み取り、出力を担当するread_and_output
2の主に母音の処理を担当する,judge_mother_text
2の母音以外のその他処理を担当するjudge_others_text

本出力を行うto_tenjiメソッドの中身は下記になります。

tenji_maker.rb
 def to_tenji(text)
    read_and_output(text)
 end

全体のロジックを図解すると下記のような感じです。

phonto 10.JPG

ローマ字を読み取り、点字を出力するread_and_outputメソッドについて

まずこのメソッドの全体的な流れとしては下記コードでコメントアウトした箇所のような形です。

tenji_maker.rb
def read_and_output(text) 
#1.入力された文字を取得

#2.その文字を自作メソッド(judge_mother_text, judge_others_text)を用いて、ローマ字から点字に変換

#3.ローマ字から点字に変換した字を返す
end

そして下記の「何文字入力されたのか」と「どんなローマ字が入力されたのか」の処理によって、
#1.入力された文字を取得することができます。

tenji_maker.rb
# 1.入力された文字を取得
def read_and_output(text)  
 nil_number = text.count(' ')  #半角の空白をカウント
 text_number = nil_number + 1  #文字数を取得
 text_array = text.split       #入力された文字ごとに配列の要素として格納 
(省略)...
end

例えば、「A HI RU」が入力されたときに
text_number = 3
text_array = ["A" "HI" "RU"]
という形になります。
なので、text_arrayは配列として扱われ、入力された文字列を配列として扱うことができるようになりました。
この時点で、下記のように入力された文字を1字ずつ扱うことができます。

p text_array[0]
#"A" 

次に入力されたローマ字を点字に変換する処理を行います。 そして、点字は下の画像(ちなみに「あ」)のように1文字が3行2列と決まっていて、 ![スクリーンショット 2021-12-13 4.46.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584967/3c769ac6-8767-a50d-9ecf-75a3156e7f7a.png) 2文字以上になると,3行2列が空白を通して、連なっていきます。 ![スクリーンショット 2021-12-13 5.14.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1584967/829a4c4a-1100-692f-b655-ee4194dcfb5d.png) *引用 [全視情協:点字とは \- 点字のしくみ](http://www.naiiv.net/braille/?tenji-sikumi)*

上記の性質を利用して、点字用の変数配列@tenji_str1,@tenji_str2,@tenji_str3を作成し、取得した文字数(text_number) × --  ( one_letter)を代入しました。

例えば「A HI RU」が入力された場合、各配列型変数に入る値は下表のようになります。1文字3列分です。なのでこの場合だと、「A」が[0,1,2],「HI」が[3,4,5],「RU」が[6,7,8]
また、各文字の3列目には何も入ってないわけではなく、半角の空白が入っています。

| 点字1文字「あ」 | [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] |
|:---|:---:|:---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|@tenji_str1|- |- | |- |- | |- |-| |
|@tenji_str2|- |- | |- |- | | -|-| |
|@tenji_str3|- |- | |- |- | | -|-| |

以上の処理が、下記になります。

tenji_maker.rb
#2.入力された文字を自作メソッド(judge_mother_text, judge_others_text)を用いて、ローマ字から点字に変換
def read_and_output(text)  
...(省略)

   one_letter = '-- '
   @tenji_str1 = one_letter * text_number #点字1行目
   @tenji_str2 = one_letter * text_number #点字2行目
   @tenji_str3 = one_letter * text_number #点字3行目

(省略)...
end

次にeach_with_indexで、入力されたtext_arrayに格納された配列型のローマ字を1字ずつループさせることで、ループ内で点字に変換していきます。

tenji_maker.rb
#2.入力された文字を自作メソッド(judge_mother_text, judge_others_text)を用いて、ローマ字から点字に変換
def read_and_output(text)  
...(省略)

   text_array.each_with_index do |text, num|
    judge_mother_text(text, num * 3) #母音処理
    judge_others_text(text, num * 3) #母音以外を処理
   end

(省略)...
end

次にローマ字から変換した点字が代入された@tenji_str1,@tenji_str2,@tenji_str3を1つの文字列stringとしてread_and_outputの返り値とします。

tenji_maker.rb
#3.ローマ字から点字に変換した字を返す
def read_and_output(text)  
...(省略)

   string = @tenji_str1.rstrip + "\n" <<  @tenji_str2.rstrip + "\n" << @tenji_str3.rstrip
   string
end

以上が入力されたローマ字を読み取り、点字を出力する処理を扱うread_and_outputメソッドのロジック解説でした。

母音のローマ字を点字に変更するjudge_mother_textメソッドについて

ここからはどうやって母音のローマ字を点字に変換したのかというロジックを解説していきます。
前提として、以下のようにすでに-が代入された状態の点字出力用の3つの変数が渡された状態で、処理を開始します。

点字1文字 [i] [i+1] [i+2]
@tenji_str1 - (1番) - (4番)
@tenji_str2 - (2番) - (5番)
@tenji_str3 - (3番) - (6番)

結論から始めるとcase wheninclude?を用いて、各ローマ字の母音が含まれている場合、指定箇所にoを入力する。といった処理です。

例をあげると、

tenji_maker.rb
def judge_mother_text(text,number)
 i = number
    case 
    when text.include?('A') #textにAが含まれている場合に下記処理を実行
    @tenji_str1[i] = 'o' #1番にoを代入

    ...省略

    end
end

Aが入力されたので、1番にoを代入。といった形で母音が含まれている文字ごとにoを指定位置に代入し、入力されたローマ字に準じて、点字に変換します。

母音以外のその他ローマ字を点字に変更するjudge_others_textメソッドについて

ここからはどうやって母音以外のローマ字を点字に変換したのかというロジックを解説していきます。
前提として、点字の子音(母音以外)は母音(あ、い、う、え、お)との組み合わせでできます。

どういうことかというと点字の「あ,い,う」と「か,き,く」を見比べるとわかるのですが(下記画像参照)、か行は母音の点に6番の点を加えただけ。なので、
母音 + 6番 = か行

スクリーンショット 2021-12-13 21.49.26.png
スクリーンショット 2021-12-13 21.49.50.png

この調子でサ行もいっちゃいましょう。
母音 + 5番 + 6番 = さ行
スクリーンショット 2021-12-13 21.53.02.png
引用 全視情協:点字とは - 点字のしくみ

ということで子音は母音との組み合わせでできていることを説明しました。
そして、この法則をうまく利用したのがjudge_others_textメソッド

case正規表現を用いて、任意の字から始まっている2字のローマ字がある場合、指定箇所にoを代入する。といった処理です。

例を上げると、「K」から始まる2字のローマ字には6番にoを代入する。
もっと詳細に言えば「KA」が入力されている場合、judge_mother_textで「A」を点字に変換後、judge_others_textで「K」を点字に変換します。

以上のようなロジックで子音のローマ字を点字に変換する処理を行っていました。

tenji_maker.rb
 def judge_others_text(text,number)
    i = number
    case text
    when /K\D/ #Kから始まる2文字の場合、下記処理を実行
    @tenji_str3[i+1] = 'o' #6番にoを代入
    ...省略

    end
end

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

頑張ったところ

  • 変換された点字を出力するロジックの実装

点字の文字数がどれだけでも3行であるという特徴(このプログラム課題上では)を活かして、@tenji_str1,@tenji_str2,@tenji_str3
の3つの文字列型変数を作り、最後にまとめて1つの文字列stringにまとめて返したロジックは我ながらよく頑張って考え抜いた箇所です。

苦労したところ

  • ローマ字を点字に変換するところ

「や行」,「わ」などの例外部分は特に母音の出力がデフォルトとは違うので、苦労しました。

工夫したところ

  • splitメソッドを用いて入力されたローマ字の文字列を分割し、配列として扱ったところ

  • 正規表現を用いて子音(母音以外)の条件分岐をしたところ

##全体を通しての感想
まだ使ったことのないメソッドを使ったり、
点字について深く知ることができたり、
Qiitaの記事で自分の書いたコードをアウトプットしたり、
初めてのこと尽くしでしたが、なんとかやり切ることができ、ホッとしています。

エンジニア転職に向けて、Rubyの総復習をこのプログラム課題を通してできたので、大変勉強になりました!

伊藤さんにメッセージ

チェリー本にはいつも大変お世話になっております。
またQiitaの良質な記事にもいつも助けられています。
これからも勝手ですがお世話になります!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?