はじめに
プログラミングスクール(SiiD)でJavaScriptを勉強中の初心者です。今はPaizaのスキルチェックで練習しています。
この記事は、同じくPaizaで練習中の初心者の方向けです。コードを書くときに「1ステップごとにconsole.log()で中身を確認しながら進める」やり方に変えたら、詰まることが減った話を書きます。
※Paizaの問題はルールで公開できないので、この記事のコードは自分で作った似たような問題でやります。
前のやり方(うまくいかなかった)
前の自分は、問題文を読んだら最後まで一気にコードを書いて、書き終わってから実行していました。
一発で正解ならいいのですが、不正解だったときがつらい。どこが悪いのか分からないので、コード全体をにらんで悩む時間がとても長くなります。1行目が悪いのか、最後の行が悪いのかも分かりません。
今のやり方
今は、1ステップ書くごとにconsole.log()を入れて、「今この変数に何が入っているか」を確認してから次に進むようにしています。
- 入力を受け取る → ログで中身を見る
- splitで分割する → ログで中身を見る
- 数値に変換する → ログで中身を見る
- 計算する → ログで結果を見る
「想定どおりの値が入っているか」を毎回たしかめるので、ズレたらその場で気づけます。だから間違えても、疑う場所がすごく狭くて済みます。
実際のコード例
問題(自作): 1行目に人数N、2行目以降にN人の点数が1行ずつ入力されます。全員の合計点を出力してください。
3
80
65
90
235
確認しながら書いたバージョン
// 標準入力を全部まとめて文字列で受け取る
const input = require('fs').readFileSync('/dev/stdin', 'utf8');
// ステップ1: 入力をそのまま画面に出して確認
console.log('入力そのまま:', input);
// ステップ2: 変数linesに input を改行で分割した配列を代入
const lines = input.split('\n');
console.log('split後:', lines);
// ステップ3: 変数nに lines[0](1行目)を数値に変換して代入
const n = Number(lines[0]);
console.log('人数n:', n, typeof n); // typeofで型も一緒に表示
// ステップ4: 変数scoresに 点数部分だけ切り出して数値に変換した配列を代入
const scores = lines.slice(1, 1 + n).map(Number);
console.log('点数の配列:', scores);
// ステップ5: 変数sumに0を入れて、ループで点数を1つずつ足していく
let sum = 0;
for (let i = 0; i < scores.length; i = i + 1) {
sum = sum + scores[i]; // sumに i番目の点数を足す
}
console.log('合計:', sum);
実行すると、ログはこんな感じで出ます。
入力そのまま: 3
80
65
90
split後: [ '3', '80', '65', '90', '' ]
人数n: 3 number
点数の配列: [ 80, 65, 90 ]
合計: 235
ログを見ると気づけること
split後: のログをよく見ると、配列の最後に空文字 '' が混ざっています。入力の最後に改行があると、こうなります。
頭の中だけでコードを書いていると、この '' の存在にはまず気づけません。「2行目から全部を点数にする」と書いていたら、'' まで計算に入ってバグっていたはずです。だから人数nを使って slice(1, 1 + n) で必要な分だけ切り出しています。
こういう「実行して初めて分かること」をログで見られるのが、このやり方のいちばんの良さだと思います。
提出用に消したバージョン
デバッグ用のログを消して、答えの出力だけ残します。
const input = require('fs').readFileSync('/dev/stdin', 'utf8');
const lines = input.split('\n');
const n = Number(lines[0]);
const scores = lines.slice(1, 1 + n).map(Number);
let sum = 0;
for (let i = 0; i < scores.length; i = i + 1) {
sum = sum + scores[i];
}
console.log(sum);
工夫していること
ログにラベルを付ける
console.log(lines) だけだと、ログが増えたときにどれがどれか分からなくなります。console.log('split後:', lines) のように日本語のラベルを付けると迷子になりません。
typeofも一緒に出す
標準入力で受け取った値は、見た目が数字でも中身は文字列です。console.log(n, typeof n) のようにtypeofも出すと、「"3"と3」の取り違えにすぐ気づけます。
ちなみに文字列のまま足し算すると '80' + '65' は '8065' になります。ログの配列表示でクォート付き('80')なら文字列、クォートなし(80)なら数値、という見分け方も覚えておくと便利です。
Paizaで提出する前の注意
Paizaのスキルチェックは、出力が完全一致しているかで判定されます。だから、デバッグ用のconsole.log()が1個でも残っていると、ロジックが合っていても不正解になります。
答えの出力もconsole.log()を使うので、「デバッグ用のログを消す」=「答え以外のログを全部消す」ということです。提出前のチェックを習慣にしています。
まとめ
- 最後まで一気に書いてから実行すると、間違えたとき疑う範囲が広すぎてつらい
- 1ステップごとにconsole.log()で中身を確認すると、ズレたその場で気づける
- ログには日本語のラベルとtypeofを付けると分かりやすい
- Paizaは出力の完全一致で判定されるので、提出前にデバッグ用ログは全部消す
エラーは「早く・小さく」見つけるのがいちばん安全、というのが今回の学びです。同じように詰まっている方の参考になればうれしいです。
初投稿なので、間違いや改善点があればコメントで教えてもらえるとうれしいです。