{"id":"loop-conditions-three-parts","slug":"three-parts","title":"Start, condition, update","text":"A loop that counts needs three things. Here they are in a loop that prints the times of a bus that leaves every two hours:\n\n```python\nhour = 9  # 1. the start value\nwhile hour <= 17:  # 2. the condition\n    print(f\"{hour}:00\")\n    hour += 2  # 3. the update\n```\n\n```output\n9:00\n11:00\n13:00\n15:00\n17:00\n```\n\n1. **Initialization**: before the loop, the variable in the condition gets its first value. Here `hour` starts at 9.\n2. **Condition**: at the top of the loop, it decides whether another round runs.\n3. **Update**: in the body, the variable changes, so that every round brings the loop closer to its end. Here `hour` grows by 2 in every round, so sooner or later `hour <= 17` is false.\n\nIf one of the three is missing or wrong, the loop goes wrong too.\n\n### Forgetting the start value\n\nWithout an initialization, the variable doesn't exist yet when Python first checks the condition:\n\n```python\nwhile total < 100:\n    total += 30\nprint(total)\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 1, in <module>\n    while total < 100:\n          ^^^^^\nNameError: name 'total' is not defined\n```\n\nThe fix is a line before the loop that gives `total` its start value, such as `total = 0`.\n\n### Forgetting the update\n\nWithout an update, the condition never changes. If it's true once, it stays true forever:\n\n```python\nhour = 9\nwhile hour <= 17:\n    print(f\"{hour}:00\")\n```\n\nThis prints `9:00` again and again, without end: an infinite loop, like the ones in the last module. On your own computer you stop such a program with **Ctrl+C**. On this site, a program that runs for more than a few seconds, or prints a huge amount, is stopped for you, with a note that says so.\n\nA sneakier way to lose the update is to forget its indentation:\n\n```python\nhour = 9\nwhile hour <= 17:\n    print(f\"{hour}:00\")\nhour += 2\n```\n\n`hour += 2` isn't indented, so it isn't part of the body. Only the indented lines repeat; this line would run once the loop is over, and the loop is never over.\n\nThe update can also go the wrong way. With `hour -= 2`, `hour` gets smaller in every round and stays below 17 forever. So before you run a loop, ask yourself: does every round take a step toward making the condition false?\n","task":"This program should print `Round 1` to `Round 4` and then `Game over`, but it never stops. Fix it.\n\n```\nRound 1\nRound 2\nRound 3\nRound 4\nGame over\n```\n","kind":"code","seed":"round_number = 1\nwhile round_number <= 4:\n    print(f\"Round {round_number}\")\nround_number += 1\nprint(\"Game over\")\n","solution":"round_number = 1\nwhile round_number <= 4:\n    print(f\"Round {round_number}\")\n    round_number += 1\nprint(\"Game over\")\n","hints":["Which lines repeat? Only the indented lines under the `while` are part of the loop.","The update `round_number += 1` is outside the loop, so the loop never reaches it. Indent it with four spaces, like the `print` above it."],"tests":[{"name":"Output","stdin":"","expect":"Round 1\nRound 2\nRound 3\nRound 4\nGame over","hidden":false}],"require":[],"forbid":[],"more":[{"task":"Fill in the start value, the condition and the update, so the program prints the battery levels below and then `Empty`.\n\n```\n100\n75\n50\n25\nEmpty\n```\n","kind":"fill","seed":"battery = [[100]]\nwhile [[battery > 0‖battery >= 25‖battery > 24]]:\n    print(battery)\n    [[battery -= 25‖battery = battery - 25]]\nprint(\"Empty\")\n","solution":"battery = 100\nwhile battery > 0:\n    print(battery)\n    battery -= 25\nprint(\"Empty\")\n","hints":["The first number printed is the start value. Each number is 25 less than the one before.","The loop should go on while there's still something left in the battery, so compare `battery` with 0.","The update makes `battery` 25 smaller: `battery -= 25`."],"tests":[{"name":"Output","stdin":"","expect":"100\n75\n50\n25\nEmpty","hidden":false}],"require":[],"forbid":[]},{"task":"Write a program that asks for two whole numbers with the prompts `From: ` and `To: `, and prints every whole number from the first one to the second one, in order. If the first number is greater than the second, it prints no numbers at all.\n\n```\nFrom: 4\nTo: 7\n4\n5\n6\n7\n```\n","kind":"code","seed":"first = int(input(\"From: \"))\nlast = int(input(\"To: \"))\n","solution":"first = int(input(\"From: \"))\nlast = int(input(\"To: \"))\nnumber = first\nwhile number <= last:\n    print(number)\n    number += 1\n","hints":["Name the three parts first. The start value is the first number, the loop goes on while the number is at most the last one, and the update adds 1.","Use a variable that starts at `first`: `number = first`. Then loop `while number <= last:`.","If the first number is greater than the second, the condition is false from the start, so the loop prints nothing on its own."],"tests":[{"name":"Test 1","stdin":"4\n7\n","expect":"From: 4\nTo: 7\n4\n5\n6\n7","hidden":false},{"name":"Test 2","stdin":"10\n10\n","expect":"From: 10\nTo: 10\n10","hidden":true},{"name":"Test 3","stdin":"9\n3\n","expect":"From: 9\nTo: 3","hidden":true},{"name":"Test 4","stdin":"-2\n1\n","expect":"From: -2\nTo: 1\n-2\n-1\n0\n1","hidden":true}],"require":[],"forbid":[{"pattern":"while\\s+True","message":"Write the loop with a condition instead of `while True`."}]}]}