はじめに
実務未経験からエンジニア転職を目指して、現在転職活動中です。
企業の方からサイト経由で「可読性が悪い」とフィードバックいただいたので、ここは読みづらいだろうなと思ったところを修正しています。
やろうとしている処理
rubyXLというRubyのライブラリを使ってPDFから取得したテキストデータをエクセルに書き出します。
元のコード
pdf_data.each_with_index do |subject_data, sub_i|
worksheet.add_cell(sub_i + 1, 0, subject_number)
worksheet.add_cell(sub_i + 1, 1, "CHIBA#{sub_i + 1}")
worksheet.add_cell(sub_i + 1, 2, pdf_data[sub_i][0])
worksheet.add_cell(sub_i + 1, 3, pdf_data[sub_i][1])
worksheet.add_cell(sub_i + 1, 4, pdf_data[sub_i][2])
worksheet.add_cell(sub_i + 1, 5, pdf_data[sub_i][3])
worksheet.add_cell(sub_i + 1, 6, pdf_data[sub_i][4])
worksheet.add_cell(sub_i + 1, 7, pdf_data[sub_i][5])
worksheet.add_cell(sub_i + 1, 8, pdf_data[sub_i][6])
worksheet.add_cell(sub_i + 1, 9, pdf_data[sub_i][7])
worksheet.add_cell(sub_i + 1, 10, pdf_data[sub_i][8])
worksheet.add_cell(sub_i + 1, 11, pdf_data[sub_i][9])
worksheet.add_cell(sub_i + 1, 12, pdf_data[sub_i][10])
end
pdf_data
には、以下のように1人ずつのデータが配列で格納されています。
[["4", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "1", "3", "3", "23"],
["5", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "2", "5", "3", "27"]]
2次元配列から1人分ずつ取り出して、Excelの1行ごとに1列目から13列目に書き出します。
Excelに書き出したいデータは以下のとおりです。
- 1列目:index + 1
- 2列目:指定の文字列 + index
- 3列目以降:pdf_data配列から該当する人のデータを順番に書き出す
add_cellメソッドの使い方
require 'rubyXL'
workbook = RubyXL::Workbook.new
worksheet.add_cell(0, 0, 'A1') # Sets cell A1 to string "A1"
第1引数と第2引数で入力するセルを指定して、第3引数で値を指定します。
- 第1引数:n行目
- 第2引数:n列目
- 第3引数:入力する値
出典:https://github.com/weshatheleopard/rubyXL
失敗
pdf_data.each_with_index do |subject_data, subject_i|
subject_num = subject_i + 1
subject_data.each_with_index do |score, score_i|
if score_i == 0
worksheet.add_cell(subject_num, score_i, subject_num)
elsif score_i == 1
worksheet.add_cell(subject_num, score_i, "CHIBA#{subject_num}")
else
worksheet.add_cell(subject_num, score_i, score)
end
end
pdf_data
配列の中の1人分のデータの要素数が11で、
その中でループを回して1回目と2回目は値を取り出さず、
3回目以降に値を取り出しているため、
最後の2つ分が取得できていません。
試したこと①
Excelに書き出す処理を行う前に、pdf_data配列を以下のように変更しました。
before:[[1人目の得点データ], [2人目の得点データ]・・・
after:[1, 指定の文字列+1, [1人目の得点データ], [2, 指定の文字列+2, 2人目の得点データ]・・・
こうすれば、pdf_data
配列の中の1人分のデータの要素数が13になるので、残りの2列分も書き出されるようになると考えました。
pdf_data = pdf_data.map.with_index do |subject_data, i|
subject_data.unshift(i)
subject_data.insert(1, "CHIBA#{i}")
end
pdf_data.each_with_index do |subject_data, subject_i|
subject_num = subject_i + 1
subject_data.each_with_index do |score, score_i|
worksheet.add_cell(subject_num, score_i, score)
end
end
[[0, "CHIBA0", "4", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "1", "3", "3", "23"],
[1, "CHIBA1", "5", "3", "2", "読みとり不可", "3", "2", "読みとり不可", "2", "5", "3", "27"]]
別のメソッドでバグが発生
pdf_data
は別のメソッドに渡してそこでも使っていたため、別のメソッドでバグが生じました。
その結果、このように一致すべき値がズレて表示されてしまいました。
試したこと②
map
メソッドで配列を元の配列自体を変更するのではなく、Railsのdeep_dup
メソッドで複製しました。
変更後のコード
pdf_scores_with_id = pdf_data.deep_dup
pdf_scores_with_id.map.with_index do |subject_data, i|
subject_data.unshift(i)
subject_data.insert(1, "CHIBA#{i}")
end
pdf_scores_with_id.each_with_index do |subject_data, subject_i|
subject_num = subject_i + 1
subject_data.each_with_index do |score, score_i|
worksheet.add_cell(subject_num, score_i, score)
end
end
最後に
変数がデータを示すのは当たり前なので、pdf_data
という変数名は良くないと思いました。pdf_scores
に修正します。