PyQチームのtsutomuです。
今回は、PyQで書き間違いなどが原因で判定NG
となったときのチェックポイントと、その解消方法を詳しく説明します。
PyQで判定に使われている方法は?
実は、PyQの判定方法は1通りではなく、数種類の方法が使われています。
その中の1つがunittestを使う方法です。
unittestはPythonの標準のライブラリーで、単体テストを行うためのものです。
unittestによるテスト結果の読み方を学ぶことで、PyQで判定が不合格になったときの解消方法もわかります。
実際のクエストの判定結果を見てみよう
ここでは、具体的な例としてクエスト「for文を使ったリストを1行で作れるリスト内包表記を学ぼう」で使われている判定結果を見てみましょう。
写経で作成する正解のコードが下記になります。この関数は、0から9の二乗のリストを返しています。
def main(): return [i ** 2 for i in range(10)]
判定ボタンを押してみましょう。下記のように出力され判定がOKになります。
. ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
unittestの出力はシンプルですね。すべてのテストをクリアすると、最終行のOK
が出力されます。
続いて、下記のように間違えた場合の結果を見てみましょう。
二乗(**
)にすべきところが掛け算(*
)になっています。
def main(): return [i * 2 for i in range(10)]
判定ボタンを押すと下記のように出力されます。
F ====================================================================== FAIL: test_list_comprehension (tests.TestMain.test_list_comprehension) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/appuser/work/tests.py", line 8, in test_list_comprehension self.assertEqual( AssertionError: Lists differ: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] != [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] First differing element 1: 2 1 - [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] + [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
テストでNGになった場合は、最終行にFAILED
と表示されます。
テストがNGの時の出力結果は長くなることが多いです。
これは、間違えた原因を特定して素早く修正できるように情報を増やしているためです。怖がらずに確認していきましょう。
最初の4行は、unittestでテストが失敗したときの特有の出力です。
今は「テストが期待する結果と、自分が書いたコードの実際の値が異なっていた」程度で捉えればOKです。
次の「Traceback
」からの3行は、失敗したテストコード(PyQが判定に使っているコード)の場所に関する情報です。
テストコードは自分で書いたものではないので、参考程度に確認すればよいでしょう。
続く「AssertionError
」からが重要な情報になります。
「Lists differ: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] != [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
」は、2つのリスト(自分のコードの実際の結果と期待する結果)が異なることを意味しています。
その後の行に同じ情報がよりわかりやすく表示されているので、そちらを確認しましょう。
First differing element 1: 2 1 - [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] + [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
下2行に-
で始まる行と、+
で始まる行があります。-
で始まる行が実際の出力を表し、+
で始まる行が期待する出力を表しています。
また、First differing element 1
は、2つのリストが最初に異なる要素の位置とその内容を示しています。
今回の場合、「element 1
が2つ目の要素で異なっており、その内容が2
と1
で異なっている」を表しています。
要素の位置は0から数え始めるため、もし最初の要素が異なっていたらelement 0
と表示されます。
場合によっては最初の文字の異なる位置が下記のように「-
」などの文字で示されることもあります(下記は, 100
が余分な場合です)。
AssertionError: '[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]' != '[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]' - [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ? ----- + [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
これらの情報をもとに、コードのどの部分を間違えているのか原因を探していきましょう。
間違えている箇所が分かれば、修正内容についても考えやすくなります。
なお、クエストによってはunittestの出力結果がそのまま使われていないこともあります。
その場合は、まずは期待する結果と実際の結果を比較して、出力の違いを解消するようにしていきましょう。
まとめ
PyQの判定で不合格になる時の対処法は大まかに以下の通りです。
- 判定結果の出力を確認する
-
で始まる行と+
で始まる行を確認し、実際の出力と期待する出力の違いを把握する- 上記の情報を元に、どこが間違っているか原因を見つける
- コードを修正し、再度判定を実行する
なお、今回説明したunittestライブラリーについては、PyQの下記のパートで学習できます。