{"id":"return-values-trying-out","slug":"trying-out","title":"Trying out your functions","text":"In the last module, you tried out a function by adding a call under its definition. Such calls have a catch. The checks of a function task **load** your program, the way Python loads a module, and then call your function themselves, with arguments of their own. Loading runs all the code at the top level of the file, so your own calls run too: they print extra lines before each check, and an `input()` among them stops the check, because the check types no input.\n\nSo the code that tries out your functions needs a place that runs when you run the program, but not when the checks load it. That place is a block at the end of the file:\n\n```python\ndef stars(count):\n    print(\"*\" * count)\n\n\nif __name__ == \"__main__\":\n    stars(3)\n    stars(5)\n```\n\n```output\n***\n*****\n```\n\n`if __name__ == \"__main__\":` is a condition, and the code indented under it is called the **main block**. When you run the file, the condition is true and the block runs. When a check loads the file to call your function, the condition is false and the block is skipped. Module 31 explains how that works. For now, remember the rule: **code that tries out your functions by hand goes under `if __name__ == \"__main__\":`**. (A program that only uses its own functions, like most examples in the lessons, can call them at the top level: no check calls its functions on their own.)\n\nFrom now on, the starter code of a function task has a main block with a call or two:\n\n```python\ndef stars(count):\n    pass\n\n\nif __name__ == \"__main__\":\n    stars(3)\n```\n\nAs before, `pass` holds the place of the body until you write it. Change the calls in the main block as much as you like: the checks ignore them. **Run with my input** runs your file as a program, main block included.\n\n### When a check fails\n\nA failing check shows the call it made. The quickest way to see what goes wrong is often to make the same call yourself: copy it into the main block and run the program. Then you get Python's whole error message:\n\n```python\ndef initial(name):\n    print(name[0] + \".\")\n\n\nif __name__ == \"__main__\":\n    initial(\"Grace\")\n    initial(\"\")\n```\n\n```output\nG.\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 7, in <module>\n    initial(\"\")\n    ~~~~~~~^^^^\n  File \"main.py\", line 2, in initial\n    print(name[0] + \".\")\n          ~~~~^^^\nIndexError: string index out of range\n```\n\nAs you saw in the last module, a traceback through a function has two parts. Read it from the bottom up: the last line names the error, the part above it shows the line in the function where it happened (line 2, in `initial`), and above that is the call that led there (line 7). Here the call gave an empty string, which has no character at index 0, so the function needs to handle that case on its own.\n\n### Debugging prints\n\nSome bugs don't stop the program: it just prints the wrong thing. To see what happens inside a function, print its variables at the spot you want to see. This function should print the sum of the numbers from 1 to `limit`, but for 4 it prints 6 instead of 10:\n\n```python\ndef sum_up_to(limit):\n    total = 0\n    number = 1\n    while number < limit:\n        total += number\n        print(\"number:\", number, \"total:\", total)\n        number += 1\n    print(\"Sum:\", total)\n\n\nif __name__ == \"__main__\":\n    sum_up_to(4)\n```\n\n```output\nnumber: 1 total: 1\nnumber: 2 total: 3\nnumber: 3 total: 6\nSum: 6\n```\n\nThe debugging print shows that the loop stops after 3, so the 4 is never added. The condition should be `number <= limit`. Once the bug is fixed, remove the debugging print: the checks compare everything your function prints.\n","task":"The function `banner` works, but the calls that try it out are at the top level, so they print extra lines whenever the checks load the program. Move the two calls under `if __name__ == \"__main__\":` at the end of the file. Run the program, and it prints:\n\n```\n==\nHi\n==\n=======\nWelcome\n=======\n```\n","kind":"code","seed":"def banner(text):\n    print(\"=\" * len(text))\n    print(text)\n    print(\"=\" * len(text))\n\n\nbanner(\"Hi\")\nbanner(\"Welcome\")\n","solution":"def banner(text):\n    print(\"=\" * len(text))\n    print(text)\n    print(\"=\" * len(text))\n\n\nif __name__ == \"__main__\":\n    banner(\"Hi\")\n    banner(\"Welcome\")\n","hints":["Add the line `if __name__ == \"__main__\":` after the function, at the left edge, with no indentation.","Indent the two calls by 4 spaces under it, so they belong to the main block."],"tests":[{"name":"Run as a program","stdin":"","expect":"==\nHi\n==\n=======\nWelcome\n=======","hidden":false},{"name":"banner(\"Python\")","stdin":"","call":"banner(\"Python\")\n","expect":"======\nPython\n======","hidden":true}],"require":[{"pattern":"^if __name__ == [\"']__main__[\"']:","flags":"m","raw":true,"message":"Add the line `if __name__ == \"__main__\":` at the left edge, after the function."}],"forbid":[{"pattern":"^banner\\(","flags":"m","message":"A call at the left edge runs when the checks load the program. Indent the calls under `if __name__ == \"__main__\":`."}],"more":[{"task":"The function `middle_letter(word)` prints the letter in the middle of a word (for a word of even length, the second of the two middle letters). A check calls `middle_letter(\"\")` and the program crashes. Make the function print `(empty)` when the word is empty, and the middle letter otherwise. For example, `middle_letter(\"cat\")` prints:\n\n```\na\n```\n","kind":"code","seed":"def middle_letter(word):\n    print(word[len(word) // 2])\n\n\nif __name__ == \"__main__\":\n    middle_letter(\"cat\")\n    middle_letter(\"door\")\n","solution":"def middle_letter(word):\n    if word == \"\":\n        print(\"(empty)\")\n    else:\n        print(word[len(word) // 2])\n\n\nif __name__ == \"__main__\":\n    middle_letter(\"cat\")\n    middle_letter(\"door\")\n","hints":["Add the call `middle_letter(\"\")` to the main block and run the program, to see the error the check sees.","The empty string has no character at index 0, so check for the empty string before you use an index.","`if word == \"\":` prints `(empty)`, and `else:` prints the middle letter as before."],"tests":[{"name":"middle_letter(\"cat\")","stdin":"","call":"middle_letter(\"cat\")\n","expect":"a","hidden":false},{"name":"middle_letter(\"\")","stdin":"","call":"middle_letter(\"\")\n","expect":"(empty)","hidden":false},{"name":"middle_letter(\"door\")","stdin":"","call":"middle_letter(\"door\")\n","expect":"o","hidden":true},{"name":"middle_letter(\"python\")","stdin":"","call":"middle_letter(\"python\")\n","expect":"h","hidden":true}],"require":[],"forbid":[]},{"task":"The function `countdown(start)` should count down from `start` to 1, one number per line, and then print `Go!`. It forgets the last number. Find the bug (a debugging print helps) and fix it. `countdown(3)` should print:\n\n```\n3\n2\n1\nGo!\n```\n","kind":"code","seed":"def countdown(start):\n    number = start\n    while number > 1:\n        print(number)\n        number -= 1\n    print(\"Go!\")\n\n\nif __name__ == \"__main__\":\n    countdown(3)\n","solution":"def countdown(start):\n    number = start\n    while number > 0:\n        print(number)\n        number -= 1\n    print(\"Go!\")\n\n\nif __name__ == \"__main__\":\n    countdown(3)\n","hints":["Add `print(\"number is now\", number)` after the loop, before `Go!`, and run the program. Where does the loop stop?","The loop stops when `number` is 1, before printing it. The condition must still be true for 1.","Change the condition to `number > 0` (or `number >= 1`), and remove any debugging print."],"tests":[{"name":"countdown(3)","stdin":"","call":"countdown(3)\n","expect":"3\n2\n1\nGo!","hidden":false},{"name":"countdown(1)","stdin":"","call":"countdown(1)\n","expect":"1\nGo!","hidden":true},{"name":"countdown(5)","stdin":"","call":"countdown(5)\n","expect":"5\n4\n3\n2\n1\nGo!","hidden":true}],"require":[],"forbid":[]}]}