{"id":"terminology-errors-debugging","slug":"errors-and-debugging","title":"Errors and debugging","text":"The **syntax** of a programming language is its set of rules for how code is written: an `if` line ends with a colon, a block is indented, a string has quotes at both ends. When code breaks a rule, Python can't read the program, so it runs none of it and reports a **syntax error**:\n\n```python\nspeed = 50\nif speed > 40\n    print(\"Slow down!\")\n```\n\n```crash\n  File \"main.py\", line 2\n    if speed > 40\n                 ^\nSyntaxError: expected ':'\n```\n\nA program with correct syntax can still go wrong. An error that happens while the program runs is a **runtime error**. Python stops at the line it can't carry out, and the lines before it have already run:\n\n```python\npizzas = 3\npeople = 0\nprint(\"Sharing the pizzas...\")\nshare = pizzas / people\nprint(share)\n```\n\n```output\nSharing the pizzas...\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 4, in <module>\n    share = pizzas / people\n            ~~~~~~~^~~~~~~~\nZeroDivisionError: division by zero\n```\n\n`NameError`, `TypeError` and `ValueError` are runtime errors too. The traceback names the line that was running, and its last line says what went wrong. The real cause may be somewhere else, though: here the mistake is that `people` is 0.\n\n### Bugs and debugging\n\nThe trickiest mistakes cause no error at all: the program runs, but its result is wrong. A mistake like that is a **bug**, and finding and fixing bugs is called **debugging**. In this game, every full 1000 points earn a bonus life, and 3 bonus lives or more earn a medal. A player with 3000 points should get the medal, but doesn't:\n\n```python\npoints = 3000\nlives = points % 1000\nif lives > 3:\n    print(\"Medal earned!\")\nprint(\"Game over.\")\n```\n\n```output\nGame over.\n```\n\nA simple and very effective way to debug is to add **debugging prints**: extra `print` lines that show the values of variables and conditions while the program runs. Here the program never shows how many lives it worked out, or what it decided about the medal, so print both, each with a label:\n\n```python\npoints = 3000\nlives = points % 1000\nprint(\"lives:\", lives)\nprint(\"medal condition:\", lives > 3)\nif lives > 3:\n    print(\"Medal earned!\")\nprint(\"Game over.\")\n```\n\n```output\nlives: 0\nmedal condition: False\nGame over.\n```\n\nNow you can check each value against what you expected. 3000 points are three full thousands, but `lives` is 0, so the line that calculates it is wrong: `%` gives the remainder, what's left over after the full thousands. The number of full thousands is `points // 1000`. With that fixed, the prints say `lives: 3` but still `medal condition: False`. The value is right now, so the condition must be wrong: \"3 or more\" is `lives >= 3`, and `lives > 3` leaves out exactly 3.\n\nNotice that 3000 was a good number to try. Bugs like `>` instead of `>=` only show up right at a limit, so test with the limits themselves as well as with ordinary values. And when the bug is fixed, remove the debugging prints, or the checks on this site will see them in the output.\n","task":"This program has four syntax errors. Fix them one at a time (Python reports one error at a time), so the program works like this:\n\n```\nHow many tickets? 6\nGroup discount!\nTotal: 50 euros\n```\n","kind":"code","seed":"tickets = int(input(\"How many tickets? \")\nprice = tickets * 10\nif tickets >= 5\n    print(\"Group discount!\")\n     price = price - 10\nprint(\"Total: \" + str(price) + \" euros)\n","solution":"tickets = int(input(\"How many tickets? \"))\nprice = tickets * 10\nif tickets >= 5:\n    print(\"Group discount!\")\n    price = price - 10\nprint(\"Total: \" + str(price) + \" euros\")\n","hints":["Press Check and read the message. It names a line, and the `^` mark shows where Python got stuck. Fix that one, then check again.","The first message is about the last line: its last string has no closing quote. Line 1 opens two parentheses, `int(` and `input(`, but closes only one.","The `if` line must end with a colon, and both lines in its block need the same indentation, four spaces."],"tests":[{"name":"Test 1","stdin":"6\n","expect":"How many tickets? 6\nGroup discount!\nTotal: 50 euros","hidden":false},{"name":"Test 2","stdin":"2\n","expect":"How many tickets? 2\nTotal: 20 euros","hidden":true},{"name":"Test 3","stdin":"5\n","expect":"How many tickets? 5\nGroup discount!\nTotal: 40 euros","hidden":true}],"require":[],"forbid":[],"more":[{"task":"This quiz never says `Correct!`, not even when the answer is right. Add debugging prints to find out why: print the value of the condition, and the type of `answer`. Then fix the bug and remove the debugging prints. With the right answer it prints:\n\n```\nWhat is 6 * 7? 42\nCorrect!\nThanks for playing.\n```\n","kind":"code","seed":"answer = input(\"What is 6 * 7? \")\nif answer == 42:\n    print(\"Correct!\")\nprint(\"Thanks for playing.\")\n","solution":"answer = int(input(\"What is 6 * 7? \"))\nif answer == 42:\n    print(\"Correct!\")\nprint(\"Thanks for playing.\")\n","hints":["Try `print(\"condition:\", answer == 42)` and `print(type(answer))` right after the `input` line.","`input` always returns a string, and the string `\"42\"` is not equal to the number `42`.","Convert the answer into an integer with `int(...)` around the `input` call, or compare it with the string `\"42\"`."],"tests":[{"name":"Test 1","stdin":"42\n","expect":"What is 6 * 7? 42\nCorrect!\nThanks for playing.","hidden":false},{"name":"Test 2","stdin":"41\n","expect":"What is 6 * 7? 41\nThanks for playing.","hidden":true},{"name":"Test 3","stdin":"24\n","expect":"What is 6 * 7? 24\nThanks for playing.","hidden":true}],"require":[],"forbid":[]},{"task":"This program should print the average of two exam scores, but it stops with an error. Fix it. Once it runs, check its result too: the average of 80 and 90 is 85, and there's a second bug.\n\n```\nFirst score: 80\nSecond score: 90\nAverage: 85.0\n```\n","kind":"code","seed":"first = input(\"First score: \")\nsecond = input(\"Second score: \")\naverage = first + second / 2\nprint(f\"Average: {average}\")\n","solution":"first = int(input(\"First score: \"))\nsecond = int(input(\"Second score: \"))\naverage = (first + second) / 2\nprint(f\"Average: {average}\")\n","hints":["The error says Python can't divide a `str` by an `int`. Which type does `input` return?","Convert both inputs with `int(...)`. Then the program runs, but prints 125.0 for 80 and 90.","Division comes before addition, so only `second` is divided by 2. Put the sum in parentheses."],"tests":[{"name":"Test 1","stdin":"80\n90\n","expect":"First score: 80\nSecond score: 90\nAverage: 85.0","hidden":false},{"name":"Test 2","stdin":"7\n8\n","expect":"First score: 7\nSecond score: 8\nAverage: 7.5","hidden":true},{"name":"Test 3","stdin":"100\n0\n","expect":"First score: 100\nSecond score: 0\nAverage: 50.0","hidden":true}],"require":[],"forbid":[]}]}