{"id":"scope-local","slug":"local-variables","title":"Local variables","text":"The **scope** of a variable is the part of the program where the variable can be used. Variables created inside a function, its parameters included, are **local** to that function: they exist only inside it, and only while it runs. When the function returns, they are gone:\n\n```python\ndef greet(name):\n    message = f\"Hello, {name}!\"\n    print(message)\n\n\ngreet(\"Ada\")\nprint(message)\n```\n\n```output\nHello, Ada!\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 7, in <module>\n    print(message)\n          ^^^^^^^\nNameError: name 'message' is not defined\n```\n\nThe function printed its greeting, but outside the function there is no variable `message`. The same goes for the parameter `name`. To get a value out of a function, the function returns it, and the caller stores the return value in a variable of its own.\n\n### Same name, different variables\n\nBecause a function's variables are its own, a function can use a name that the main program also uses, and the two don't disturb each other:\n\n```python\ndef double(number):\n    result = number * 2\n    print(\"Inside:\", result)\n    return result\n\n\nresult = 10\nanswer = double(4)\nprint(\"Outside:\", result)\nprint(\"Answer:\", answer)\n```\n\n```output\nInside: 8\nOutside: 10\nAnswer: 8\n```\n\nThere are two variables called `result` here: one in the main program, with the value 10, and one inside `double`, which exists only during the call. Setting the function's `result` to 8 leaves the main program's `result` alone. This is what makes functions safe to use: you can call a function without knowing which names it uses inside.\n\n### Each call starts afresh\n\nLocal variables are created again on every call, so they don't remember anything from the call before:\n\n```python\ndef count_visit():\n    visits = 0\n    visits += 1\n    print(\"Visits:\", visits)\n\n\ncount_visit()\ncount_visit()\ncount_visit()\n```\n\n```output\nVisits: 1\nVisits: 1\nVisits: 1\n```\n\n### Global variables\n\nAs the module on functions showed, variables created in the main program, outside every function, are **global**. A function can read a global variable, and it sees the value the variable has at the moment of the call:\n\n```python\ntax_percent = 25\n\n\ndef with_tax(price):\n    return price * (100 + tax_percent) / 100\n\n\nprint(with_tax(80))\ntax_percent = 10\nprint(with_tax(80))\n```\n\n```output\n100.0\n88.0\n```\n\nReading globals like this works, but the function depends on something outside it, and you saw in the module on functions how that leads to bugs. Usually it's clearer to give the function what it needs as a parameter. The next step shows what happens when a function tries to change a global variable.\n","task":"What does this program print? Type each line it prints.\n","kind":"predict","seed":"def change(x):\n    x = x + 1\n    print(\"in:\", x)\n\n\nx = 5\nchange(x)\nprint(\"out:\", x)\n","solution":"def change(x):\n    x = x + 1\n    print(\"in:\", x)\n\n\nx = 5\nchange(x)\nprint(\"out:\", x)\n","hints":["The parameter `x` is a local variable of `change`, separate from the `x` of the main program.","Inside the function the local `x` becomes 6. The main program's `x` is still 5."],"tests":[{"name":"Output","stdin":"","expect":"in: 6\nout: 5","hidden":false}],"require":[],"forbid":[],"lines":["in: 6","out: 5"],"more":[{"task":"The program should print the area of two rooms, but it stops with a `NameError`. Fix it so the function returns the area and the main program prints the returned value. It should print:\n\n```\nKitchen: 12\nLiving room: 30\n```\n","kind":"code","seed":"def area(width, height):\n    result = width * height\n\n\nif __name__ == \"__main__\":\n    area(3, 4)\n    print(\"Kitchen:\", result)\n    area(5, 6)\n    print(\"Living room:\", result)\n","solution":"def area(width, height):\n    return width * height\n\n\nif __name__ == \"__main__\":\n    kitchen = area(3, 4)\n    print(\"Kitchen:\", kitchen)\n    living_room = area(5, 6)\n    print(\"Living room:\", living_room)\n","hints":["`result` is a local variable of `area`, so the main program can't see it. The function has to hand the value out with `return`.","Store each return value in a variable of the main program, `kitchen = area(3, 4)`, or print the call directly: `print(\"Kitchen:\", area(3, 4))`."],"tests":[{"name":"Test 1","stdin":"","expect":"Kitchen: 12\nLiving room: 30","hidden":false},{"name":"area(7, 3)","stdin":"","call":"area(7, 3)\n","expect":"21","hidden":true,"returns":true},{"name":"area(2, 2)","stdin":"","call":"area(2, 2)\n","expect":"4","hidden":true,"returns":true}],"require":[{"pattern":"\\breturn\\b","message":"Make `area` return the area with `return`."}],"forbid":[{"pattern":"\\bglobal\\b","message":"Use `return` instead of `global` to get the result out of the function."},{"pattern":"print\\(\\s*\"\"\\s*,\\s*(12|30)\\b","message":"Print the value that `area` returns, not a number typed by hand."}]},{"task":"What does this program print? Type each line it prints.\n","kind":"predict","seed":"greeting = \"Hi\"\n\n\ndef greet(name):\n    print(greeting, name)\n\n\ngreet(\"Ada\")\ngreeting = \"Hello\"\ngreet(\"Bo\")\n","solution":"greeting = \"Hi\"\n\n\ndef greet(name):\n    print(greeting, name)\n\n\ngreet(\"Ada\")\ngreeting = \"Hello\"\ngreet(\"Bo\")\n","hints":["`greet` reads the global variable `greeting`. It has no variable of its own with that name.","A function sees the value a global variable has at the moment of the call, and the second call comes after the main program changed it."],"tests":[{"name":"Output","stdin":"","expect":"Hi Ada\nHello Bo","hidden":false}],"require":[],"forbid":[],"lines":["Hi Ada","Hello Bo"]}]}