{"id":"more-features-pass-and-loop-else","slug":"pass-and-loop-else","title":"pass, and loops with else","text":"### pass\n\nYou know `pass` from the starter code of function tasks: it's a statement that does nothing. It exists because a block can't be empty: after `if`, `for`, `while`, `def` or `except`, Python wants at least one indented line. When a block should do nothing, at least for now, `pass` fills the place:\n\n```python\ndef save_report(data):\n    pass  # to do: write the report to a file\n\n\nsave_report([1, 2, 3])\nprint(\"The program runs, though save_report does nothing yet\")\n```\n\n```output\nThe program runs, though save_report does nothing yet\n```\n\nA function whose body is only `pass` returns `None`. Leave the `pass` out, and Python can't read the program, even with a comment in the block, because Python skips comments:\n\n```python\ndef save_report(data):\n    # to do: write the report to a file\n\nprint(\"Done\")\n```\n\n```crash\n  File \"main.py\", line 4\n    print(\"Done\")\n    ^^^^^\nIndentationError: expected an indented block after function definition on line 1\n```\n\n`pass` is also how you ignore an error on purpose: `except ValueError:` followed by an indented `pass` catches the error and does nothing about it.\n\n### Loops with else\n\nA `for` or `while` loop can have an `else` block. It runs when the loop ends normally, after its last round, but not when `break` ends the loop. That fits searching: if the search found nothing, the loop never hit `break`:\n\n```python\ndef first_negative(numbers):\n    for number in numbers:\n        if number < 0:\n            print(\"First negative:\", number)\n            break\n    else:\n        print(\"No negative numbers\")\n\n\nfirst_negative([4, -2, 7, -9])\nfirst_negative([1, 2, 3])\n```\n\n```output\nFirst negative: -2\nNo negative numbers\n```\n\nWithout the `else`, the usual way is a helper variable such as `found = False`, set to `True` before the `break` and checked after the loop. The `else` block does the same with fewer lines.\n\n### Watch the indentation\n\nThe loop's `else` is lined up with `for`, not with `if`. Indent it one level deeper and it becomes an ordinary `else` of the `if`, which runs for every number that isn't negative:\n\n```python\nfor number in [4, 7, 9]:\n    if number < 0:\n        print(\"First negative:\", number)\n        break\n    else:\n        print(\"No negative numbers\")\n```\n\n```output\nNo negative numbers\nNo negative numbers\nNo negative numbers\n```\n","task":"What does this program print? Type each line it prints.\n","kind":"predict","seed":"for word in [\"tea\", \"coffee\", \"juice\"]:\n    if len(word) > 5:\n        print(\"Long word:\", word)\n        break\nelse:\n    print(\"No long words\")\n\nfor word in [\"tea\", \"milk\"]:\n    if len(word) > 5:\n        print(\"Long word:\", word)\n        break\nelse:\n    print(\"No long words\")\n","solution":"for word in [\"tea\", \"coffee\", \"juice\"]:\n    if len(word) > 5:\n        print(\"Long word:\", word)\n        break\nelse:\n    print(\"No long words\")\n\nfor word in [\"tea\", \"milk\"]:\n    if len(word) > 5:\n        print(\"Long word:\", word)\n        break\nelse:\n    print(\"No long words\")\n","hints":["The loop's `else` runs only when the loop ends without `break`.","In the first loop, `coffee` has 6 letters, so the loop prints it and breaks: its `else` is skipped.","The second loop never breaks, so its `else` runs."],"tests":[{"name":"Output","stdin":"","expect":"Long word: coffee\nNo long words","hidden":false}],"require":[],"forbid":[],"lines":["Long word: coffee","No long words"],"more":[{"task":"The program should add up the numbers in a line of comma-separated values and skip anything that isn't a number. The `except` block is meant to do nothing, but it's empty, so Python can't even read the program. Fix it, so that it prints, for example:\n\n```\nValues: 12,x,30,,8\nTotal: 50\n```\n","kind":"code","seed":"values = input(\"Values: \").split(\",\")\ntotal = 0\nfor value in values:\n    try:\n        total += int(value)\n    except ValueError:\n        # skip anything that isn't a number\n\nprint(\"Total:\", total)\n","solution":"values = input(\"Values: \").split(\",\")\ntotal = 0\nfor value in values:\n    try:\n        total += int(value)\n    except ValueError:\n        # skip anything that isn't a number\n        pass\n\nprint(\"Total:\", total)\n","hints":["A comment doesn't count as the contents of a block. Python needs a statement there.","Add an indented `pass` under the comment in the `except` block."],"tests":[{"name":"Test 1","stdin":"12,x,30,,8\n","expect":"Values: 12,x,30,,8\nTotal: 50","hidden":false},{"name":"Test 2","stdin":"1,2,three\n","expect":"Values: 1,2,three\nTotal: 3","hidden":true},{"name":"Test 3","stdin":"a,b\n","expect":"Values: a,b\nTotal: 0","hidden":true}],"require":[{"pattern":"\\bpass\\b","message":"Fill the empty block with `pass`."}],"forbid":[]},{"task":"Write a program that asks for a PIN code at most three times. The right PIN is `4321`. For a right one it prints `Welcome!` and stops asking; for a wrong one, `Wrong PIN`. After three wrong tries it prints `Card locked`. Use a loop with an `else` block for the last message. For example:\n\n```\nPIN: 1111\nWrong PIN\nPIN: 4321\nWelcome!\n```\n","kind":"code","seed":"# Write your program here.\n","solution":"# Write your program here.\nfor attempt in range(3):\n    pin = input(\"PIN: \")\n    if pin == \"4321\":\n        print(\"Welcome!\")\n        break\n    print(\"Wrong PIN\")\nelse:\n    print(\"Card locked\")\n","hints":["A `for` loop over `range(3)` gives three tries. Read the PIN inside it with `input(\"PIN: \")`.","When the PIN is right, print `Welcome!` and `break`. Otherwise print `Wrong PIN`.","Put `else:` lined up with `for`, after the loop. It runs only when all three tries were used without `break`."],"tests":[{"name":"Test 1","stdin":"1111\n4321\n","expect":"PIN: 1111\nWrong PIN\nPIN: 4321\nWelcome!","hidden":false},{"name":"Test 2","stdin":"4321\n","expect":"PIN: 4321\nWelcome!","hidden":true},{"name":"Test 3","stdin":"1\n2\n3\n","expect":"PIN: 1\nWrong PIN\nPIN: 2\nWrong PIN\nPIN: 3\nWrong PIN\nCard locked","hidden":true},{"name":"Test 4","stdin":"0000\n1234\n4321\n","expect":"PIN: 0000\nWrong PIN\nPIN: 1234\nWrong PIN\nPIN: 4321\nWelcome!","hidden":true}],"require":[{"pattern":"^([ \\t]*)(for|while)\\b[^\\n]*\\n(\\1[ \\t]+[^\\n]*\\n|[ \\t]*\\n)*\\1else\\s*[:]","flags":"m","message":"Print `Card locked` in an `else` block of the loop, lined up with `for` (or `while`)."}],"forbid":[]}]}