total = 0 の書き忘れ
用意していない名前にいきなり足そうとすると NameError になります。ループの前に必ず初期値を置きます。
レッスンの本文で注意している点を、つまずきの側から51件ぶん並べ直しました。書いた覚えのある形が見つかったら、 そのままレッスンに戻って前後を読めます。
total = 0 の書き忘れ用意していない名前にいきなり足そうとすると NameError になります。ループの前に必ず初期値を置きます。
return をループの中に書いてしまうreturn total がインデントの内側にあると、1 周目で関数が終わってしまい、最初の 1 件だけが返ります。return はループの外、for と同じ深さより手前に置きます。
total = total + prices と書くと、数値とリストを足すことになり TypeError です。足すのは取り出した 1 件の price です。
i = i + 1 を書き忘れると、同じ 1 件を永久に読み続けます。手元で試すときは、止まらなくなったら Ctrl + C で強制終了できます。
i = i + 1 を break の前に置いてしまう位置そのものは動きますが、終了 を items に入れてしまう順番になっていないか、必ず読み返します。取り込むのは 終了 ではない行だけです。
while の条件を i <= len(inputs) にしてしまう最後の 1 件を読んだあと、存在しない位置を読もうとして IndexError になります。件数が 3 なら読める位置は 0 と 1 と 2 までです。
range(1, last_day, step) と書くと最終日が出ません。last_day まで含めたいなら last_day + 1 です。
day + "日目" は TypeError になります。str(day) で文字列に変えてからつなぎます。
step に 0 を渡してしまうrange の刻み幅に 0 は使えず、ValueError になります。刻み幅は必ず 0 以外です。
break と continue を取り違える0 円を飛ばすつもりで break を書くと、最初の 0 円で集計が止まってしまいます。飛ばしたいのか終わりたいのか、書く前に決めます。
continue の下に処理を書いて実行されると思い込むcontinue より下の行は、その周では絶対に動きません。「書いたのに動かない」の原因になりがちです。
while で continue を使ってカウンタを飛ばすwhile の中で continue すると、カウンタを進める行を飛ばしてしまい無限ループになります。while と continue の組み合わせは特に慎重に扱います。
enumerate(names) のままだと 0. りんご から始まります。人に見せる一覧なら enumerate(names, 1) です。
i + ". " は数値と文字列の足し算になり TypeError です。str(i) を挟みます。
result = result + str(i) + ". " + name + "\n" と書くと、最後の行のうしろにも改行が残ります。改行は行の 手前 に足すと、この問題が起きません。
zip に渡し忘れるfor name, price in names: と書くと、品名 1 文字ずつを 2 つに分けようとして ValueError になります。組にするには zip が要ります。
name + " " + price は TypeError です。str(price) を挟みます。
zip は短いほうで止まり、余った分を黙って捨てます。件数が合うことを前提にするなら、len を比べて確かめる処理を別途書きます。
line = "" を外側のループより前に書くと、すべての行がつながってしまいます。行ごとにリセットする必要があります。
内側でも i を使うと、外側の i が上書きされて表が崩れます。外側は i、内側は j のように分けます。
break が外側まで効くと思い込むbreak と continue は、いちばん内側のループ 1 つにしか効きません。内側で break しても、外側は次の周に進みます。
一覧の最後と 合計 がつながって 1 行になります。行を足すときは必ず "\n" を先に足します。
record["price"] は数値なので、str を挟まないと TypeError です。record["category"] は最初から文字列なのでそのままつなげます。
記録が 0 件でもループは静かに 0 周で終わるため、エラーは出ません。記録がありません の行が抜けたまま気づかない、というのがありがちです。
def greet_user(name) とコロンを書かないと SyntaxError です。字下げがないと IndentationError になります。字下げは半角スペース 4 つに揃えます。
greet_user とだけ書くと、関数そのものを指すだけで実行されません。greet_user("たろう") とかっこを付けて初めて動きます。
return を書かずに print で済ませる画面には出ますが、戻り値は None になります。採点は戻り値を見るので、必ず return で返します。
位置引数は前から順に入ります。split(people, total) のように順を取り違えると、エラーは出ないのに答えだけが狂います。いちばん見つけにくい種類のバグです。
add_tax() のように渡し忘れると TypeError になり、missing 1 required positional argument と教えてくれます。多すぎても同じく TypeError です。
/ と // を取り違えるprice * 110 / 100 は小数の 132.0 になります。132 とは別の値なので、テストは落ちます。整数が欲しいときは // です。
def f(budget=3000, total) は SyntaxError です。既定値のある引数は必ず後ろにまとめます。
呼び出しをまたいで同じものが使い回されます。None を既定値にして関数の中で作り直します。
>= にすると 3000 円ちょうどでもオーバー扱いになります。> と >= のどちらが仕様かを確かめてから書きます。
format_record("りんご", 120, categoly="食費") のように綴りを間違えると TypeError になり、unexpected keyword argument と出ます。定義側の綴りを確認します。
format_record("りんご", 120, "食費", category="日用品") は、category に位置とキーワードの両方から値が来るので TypeError です。どちらか片方にします。
str を忘れて数値を連結するname + " " + price は TypeError です。金額は数値なので、str(price) で文字列にしてからつなぎます。第 2 章でやった変換がここでも要ります。
return を 2 行書くreturn total の次の行に return average と書いても、2 行目には決して届きません。return は関数を終わらせるので、1 つの return にカンマで並べます。
total, average, count = total_and_average(prices) は ValueError です。not enough values to unpack と出ます。
0 件で ZeroDivisionError になります。テストには必ず空の場合を入れて確かめます。
divmod(people, total) と書くと divmod(3, 1000) になり、商が 0 で余りが 3 という意味の分からない答えが返ります。エラーが出ないぶん厄介です。
この環境の判定はリスト形式なので、return divmod(total, people) では通りません。q, r = divmod(...) で受けてから [q, r] にします。
0 除算を考えていない人数 0 で ZeroDivisionError です。入口で弾きます。
UnboundLocalError になります。global で押し切らず、引数と戻り値の形に直します。
add_record(records, "りんご", 120, "食費") とだけ書いて records = を付けないと、新しいリストは捨てられ、何も増えません。エラーが出ないぶん気づきにくい間違いです。
キーは name と price と category の 3 つです。namae などと書くと、あとで取り出すときに落ちます。
lambda に return を書くlambda r: return r["price"] は SyntaxError です。lambda は式なので、return は書きません。
key に呼び出した結果を渡すkey=lambda r: r["price"]() のようにかっこを付けると、金額を関数として呼ぼうとして TypeError になります。渡すのは関数そのものです。
sort と sorted を取り違えるrecords.sort() は元のリストを並べ替えて None を返します。新しいリストが欲しいときは sorted です。戻り値が None になっていたら、まずここを疑います。
キーは count total remaining over の 4 つです。1 つでも綴りが違うと、受け取る側が取り出せません。
total の初期化を忘れるfor の前に total = 0 を書かないと NameError です。合計を作るときの定番の手順です。
over を文字列にする"オーバー" のような文字列ではなく、True か False の真偽値を入れます。判定結果は真偽値で返し、言葉にするのは表示側の仕事です。