From b47c18c0628e125fba07b2675f25ac3229ff4187 Mon Sep 17 00:00:00 2001 From: Louis Oliphant <ltoliphant@wisc.edu> Date: Sun, 15 Sep 2024 18:28:37 -0500 Subject: [PATCH] lecture 7 function scope --- .../Lec_07_Function_Scope.ipynb | 501 +++++++++++++ .../Lec_07_Function_Scope_Solution.ipynb | 688 ++++++++++++++++++ 2 files changed, 1189 insertions(+) create mode 100644 f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope.ipynb create mode 100644 f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope_Solution.ipynb diff --git a/f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope.ipynb b/f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope.ipynb new file mode 100644 index 0000000..447c3ff --- /dev/null +++ b/f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope.ipynb @@ -0,0 +1,501 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8aca3edd-417f-45d9-86a8-96cecdca7c21", + "metadata": {}, + "source": [ + "## Warmup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d95fb89e-e5e9-4051-b2d9-3d3b47d05a47", + "metadata": {}, + "outputs": [], + "source": [ + "# Warmup 1\n", + "# TODO: Create a function called add_em_up() which takes in three inputs\n", + "# and returns the sum of those three numbers\n", + "\n", + "## Function definition goes here\n", + "\n", + "\n", + "# Your function should work correctly with the following function call\n", + "print(add_em_up(1,2,3))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b3016f9-b1ba-4ee6-b9f7-cf3dc0c3e3d3", + "metadata": {}, + "outputs": [], + "source": [ + "# Warmup 2\n", + "# TODO: Create a function called box() which takes 3 inputs:\n", + "# size (which should have a default value of 3)\n", + "# corner_symbol (which should have a default value of '+')\n", + "# side_symbol (which should default to the value of '*')\n", + "#\n", + "# The function should return a box made of characters of the proper size.\n", + "# The function should work with the function calls at the bottom of this cell\n", + "\n", + "# Function definition goes here\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "# Function should work correctly with all of the following function calls\n", + "print(box())\n", + "# output should be\n", + "# +***+\n", + "# * *\n", + "# * *\n", + "# * *\n", + "# +***+\n", + "\n", + "print(box(1,corner_symbol='*',side_symbol='-'))\n", + "# output should be\n", + "# *-*\n", + "# - -\n", + "# *-*\n", + "\n", + "# Write another function call using the default value for the corner symbol, but\n", + "# provide new values for the size and side_symbol\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "14a4daee-908b-4a68-90c9-3df5b3edb502", + "metadata": {}, + "source": [ + "## Reminder\n", + "\n", + "- Recall how to define functions using a header and body\n", + "- Assign parameters their values using positional arguments, keyword arguments, and default values\n", + "- Return a value from a function\n", + "- Use the debugger to step through execution of a function" + ] + }, + { + "cell_type": "markdown", + "id": "82184a18", + "metadata": {}, + "source": [ + "# Function Scope\n", + "\n", + "## Reading\n", + " * [Python for Everybody, 5.11 - 5.16](https://runestone.academy/ns/books/published//py4e-int/functions/toctree.html)\n", + " * [Downey Chapter 3 - Parameters and Arguments to the end of the chapter](https://greenteapress.com/wp/think-python-2e/)\n", + "\n", + "## Learning Objectives\n", + "\n", + "* Explain the concept of **scope** and the difference between a **local** variable and a **global** variable.\n", + "* Label variables as local or global and state the scope of the variable\n", + "* Explain the terms **call stack** and **frame**\n", + "* Identify as code is executed when frames are created and destroyed on the call stack and what the content of the frames will be\n", + "\n", + "#### Exam Conflict Form\n", + " * [Exam 1 - October 2nd, 5:45 pm](https://cs220.cs.wisc.edu/f24/surveys.html)\n", + " * [Exam 2 - November 6th, 5:45 pm](https://cs220.cs.wisc.edu/f24/surveys.html)\n", + " * [Final - December 14th, 7:25 pm](https://cs220.cs.wisc.edu/f24/surveys.html)\n", + " \n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "d1cd1813-b3bf-4069-a431-02b8c6d5237d", + "metadata": {}, + "source": [ + "## Definitions\n", + "\n", + "The **scope** of a variable is the area of the program where the variable is recognized and can be used. Python has two scopes, **global** (the variable can be used everywhere) and **local** (the variable can be used within the function in which it was defined).\n", + "\n", + "As a program is executed, the **callstack** stores information (i.e. variables) about the active local environments. Each time a function is called, a new **frame** is placed on the callstack. Each time a function finishes, its frame is removed from the callstack.\n", + "\n", + "Turn on the debugger and place a breakpoint on the first line of code in the cell below and \"step in\" the execution of the code in the cell until the cell finishes. Then do the same for the cell below that. Watch the \"callstack\" and \"variables\" portion of the debugger." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a805200-5bf8-42d4-a15a-6257d1a93416", + "metadata": {}, + "outputs": [], + "source": [ + "def f():\n", + " x = 1\n", + " print(x)\n", + "\n", + "def g():\n", + " y = 2\n", + " print(y)\n", + "\n", + "def h():\n", + " z = 3\n", + " print(z)\n", + "\n", + "f()\n", + "g()\n", + "h()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91b01530-6e3d-4098-bf83-f2a44100644c", + "metadata": {}, + "outputs": [], + "source": [ + "def f():\n", + " x = 1\n", + " print(x)\n", + " g()\n", + "\n", + "def g():\n", + " y = 2\n", + " print(y)\n", + " h()\n", + "\n", + "def h():\n", + " z = 3\n", + " print(z)\n", + "\n", + "f()" + ] + }, + { + "cell_type": "markdown", + "id": "300337e1", + "metadata": {}, + "source": [ + "Now do the same to practice pieces of code at the [Interactive Python Tutor](https://cs220.cs.wisc.edu/s23/materials/lec-07.html).\n", + "\n", + "Notice the following:\n", + "\n", + "- A global scope holds the variables defined outside of any function AND the functions themselves\n", + "- When a function starts, a new frame is placed on the callstack\n", + "- When a function ends, the frame is removed from the callstack\n", + "- The local variables (i.e. those created inside of a function) are placed within that function's frame\n", + "- A function can call another function, causing multiple frames to be on the callstack at the same time\n", + "\n", + "Be aware that the \"variable\" section in the debugger has a drop-down letting you switch between the global and the local frame. Also notice that you can click on the items in the callstack to have the \"local\" variables be displayed for that active frame.\n", + "\n", + "Use the debugger with the code in the cell below to step through the execution of the code. Watch as each of the local frames are created and use the callstack switch between these local frames to see the variable x in each of those frames." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "253366ee-3eab-49f4-a137-e78885124ad9", + "metadata": {}, + "outputs": [], + "source": [ + "def f():\n", + " x = 1\n", + " print(x)\n", + " g()\n", + "\n", + "def g():\n", + " x = 2\n", + " print(x)\n", + " h()\n", + "\n", + "def h():\n", + " x = 3\n", + " print(x)\n", + "\n", + "f()" + ] + }, + { + "cell_type": "markdown", + "id": "96c7c201-3635-46c8-a227-cedbbb6722b7", + "metadata": {}, + "source": [ + "## Using Python Tutor\n", + "\n", + "Now use the [Python Tutor](https://cs220.cs.wisc.edu/s23/materials/lec-07.html) to watch and execute the code for each of the lessons. You can also execute the code using the debugger. Make sure you understand each of the lessons or concepts being taught.\n", + "\n", + "**Lesson 1: Functions don't execute unless they are called**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6932120-b5dd-48e2-836c-a889a7b27a9d", + "metadata": {}, + "outputs": [], + "source": [ + "def set_x():\n", + " x = 100\n", + "\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "id": "54aabfd7-3572-40bc-bb25-286947f9b14a", + "metadata": {}, + "source": [ + "**Lesson 2: Variables created in a function die after function returns**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b24429f-972d-4957-9c8a-39b182157ae7", + "metadata": {}, + "outputs": [], + "source": [ + "def set_x():\n", + " x = 100\n", + "\n", + "set_x()\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "id": "7b3bccbb-1eba-4490-a4b4-441ce937a3ab", + "metadata": {}, + "source": [ + "**Lesson 3: Variables start fresh every time a function is called again**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "244882dd-818f-419c-98d3-4cafa60310ff", + "metadata": {}, + "outputs": [], + "source": [ + "def count():\n", + " x = 1\n", + " x += 1\n", + " print(x)\n", + "\n", + "count()\n", + "count()\n", + "count()" + ] + }, + { + "cell_type": "markdown", + "id": "1ceeba4d-e2c6-45d6-80b6-ad90733723a4", + "metadata": {}, + "source": [ + "**Lesson 4: you can't see the variables of other function invocations, even those that call you**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca7b26b0-6518-4061-972d-d5caec39a298", + "metadata": {}, + "outputs": [], + "source": [ + "def display_x():\n", + " print(x)\n", + "\n", + "def main():\n", + " x = 100\n", + " display_x()\n", + "\n", + "main()" + ] + }, + { + "cell_type": "markdown", + "id": "62f3a27f-3db3-4492-ae0d-d1ca295e66e9", + "metadata": {}, + "source": [ + "**Lesson 5: you can generally just use global variables inside a function**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67257372-92a2-46e7-81c2-8746004cacc5", + "metadata": {}, + "outputs": [], + "source": [ + "msg = 'hello' # global, outside any func\n", + "\n", + "def greeting():\n", + " print(msg)\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "0964c63c-6e0c-4234-b347-eda94c5f3b73", + "metadata": {}, + "source": [ + "**Lesson 6: if you do an assignment to a variable in a function, Python assumes you want it local**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "124ba158-7ee0-49ac-85ad-8dcb767d9c9c", + "metadata": {}, + "outputs": [], + "source": [ + "msg = 'hello'\n", + "\n", + "def greeting():\n", + " msg = 'welcome!'\n", + " print('greeting: ' + msg)\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "a7df0197-9e2a-42a6-a7b9-fd062436783d", + "metadata": {}, + "source": [ + "**Lesson 7: assignment to a variable should be before its use in a function, even if there's a a global variable with the same name**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f516f74e-dfe0-4726-9203-5082b81c123a", + "metadata": {}, + "outputs": [], + "source": [ + "msg = 'hello'\n", + "\n", + "def greeting():\n", + " print('greeting: ' + msg)\n", + " msg = 'welcome!'\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "a1f6e7e9-e48e-4de9-8b01-6308a1a91f04", + "metadata": {}, + "source": [ + "**Lesson 8: use a global declaration to prevent Python from creating a local variable when you want a global variable**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04962da5-4178-4361-929b-f068703c2998", + "metadata": {}, + "outputs": [], + "source": [ + "msg = 'hello'\n", + "\n", + "def greeting():\n", + " global msg\n", + " print('greeting: ' + msg)\n", + " msg = 'welcome!'\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "205e3043-afd2-4c5f-b37a-3bc8067f2f31", + "metadata": {}, + "source": [ + "**Lesson 9: in Python, arguments are \"passed by value\", meaning reassignments to a parameter don't change the argument outside**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c2188eb-eb00-4023-92a0-8be153cef28e", + "metadata": {}, + "outputs": [], + "source": [ + "def f(x):\n", + " x = 'B'\n", + " print('inside: ' + x)\n", + "\n", + "val = 'A'\n", + "print('before: ' + val)\n", + "f(val)\n", + "print('after: ' + val)" + ] + }, + { + "cell_type": "markdown", + "id": "4633aafe-0cdc-4ded-a867-ad232e16c7b4", + "metadata": {}, + "source": [ + "**Lesson 10: it's irrelevant whether the argument (outside) and parameter (inside) have the same variable name**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "733ba7d9-6aa9-42c2-bbbd-97d55a86c191", + "metadata": {}, + "outputs": [], + "source": [ + "x = 'A'\n", + "\n", + "def f(x):\n", + " x = 'B'\n", + " print('inside: ' + x)\n", + "\n", + "print('before: ' + x)\n", + "f(x)\n", + "print('after: ' + x)" + ] + }, + { + "cell_type": "markdown", + "id": "066458da", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "You have learned about variable **scope**, specifically **local** and **global** scope. You have watched as **frames** are created and placed on the **callstack**. These frames are used for storing local variables. And you have learned about the rules for what variables you can access from within a function." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope_Solution.ipynb b/f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope_Solution.ipynb new file mode 100644 index 0000000..1d44ff3 --- /dev/null +++ b/f24/Louis_Lecture_Notes/07_Function_Scope/Lec_07_Function_Scope_Solution.ipynb @@ -0,0 +1,688 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8aca3edd-417f-45d9-86a8-96cecdca7c21", + "metadata": {}, + "source": [ + "## Warmup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d95fb89e-e5e9-4051-b2d9-3d3b47d05a47", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6\n" + ] + } + ], + "source": [ + "# Warmup 1\n", + "# TODO: Create a function called add_em_up() which takes in three inputs\n", + "# and returns the sum of those three numbers\n", + "\n", + "## Function definition goes here\n", + "def add_em_up(num1, num2, num3):\n", + " return num1+num2+num3\n", + "\n", + "# Your function should work correctly with the following function call\n", + "print(add_em_up(1,2,3))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "3b3016f9-b1ba-4ee6-b9f7-cf3dc0c3e3d3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+***+\n", + "* *\n", + "* *\n", + "* *\n", + "+***+\n", + "\n", + "*-*\n", + "- -\n", + "*-*\n", + "\n", + "+@@@@@@@+\n", + "@ @\n", + "@ @\n", + "@ @\n", + "@ @\n", + "@ @\n", + "@ @\n", + "@ @\n", + "+@@@@@@@+\n", + "\n" + ] + } + ], + "source": [ + "# Warmup 2\n", + "# TODO: Create a function called box() which takes 3 inputs:\n", + "# size (which should have a default value of 3)\n", + "# corner_symbol (which should have a default value of '+')\n", + "# side_symbol (which should default to the value of '*')\n", + "#\n", + "# The function should return a box made of characters of the proper size.\n", + "# The function should work with the function calls at the bottom of this cell\n", + "\n", + "# Function definition goes here\n", + "def box(size=3,corner_symbol='+',side_symbol='*'):\n", + " top_and_bottom = corner_symbol + (size*side_symbol) + corner_symbol + '\\n'\n", + " middle = side_symbol + (' '*size) + side_symbol + '\\n'\n", + " middles = middle*size\n", + " return top_and_bottom + middles + top_and_bottom\n", + "\n", + "\n", + "# Function should work correctly with all of the following function calls\n", + "print(box())\n", + "# output should be\n", + "# +***+\n", + "# * *\n", + "# * *\n", + "# * *\n", + "# +***+\n", + "\n", + "print(box(1,corner_symbol='*',side_symbol='-'))\n", + "# output should be\n", + "# *-*\n", + "# - -\n", + "# *-*\n", + "\n", + "# Write another print of the function's return value where\n", + "# uses the default value for the corner symbol, but\n", + "# provide new values for the size and side_symbol\n", + "\n", + "print(box(7,side_symbol='@'))" + ] + }, + { + "cell_type": "markdown", + "id": "14a4daee-908b-4a68-90c9-3df5b3edb502", + "metadata": {}, + "source": [ + "## Reminder\n", + "\n", + "- Recall how to define functions using a header and body\n", + "- Assign parameters their values using positional arguments, keyword arguments, and default values\n", + "- Return a value from a function\n", + "- Use the debugger to step through execution of a function" + ] + }, + { + "cell_type": "markdown", + "id": "82184a18", + "metadata": {}, + "source": [ + "# Function Scope\n", + "\n", + "## Reading\n", + " * [Python for Everybody, 5.11 - 5.16](https://runestone.academy/ns/books/published//py4e-int/functions/toctree.html)\n", + " * [Downey Chapter 3 - Parameters and Arguments to the end of the chapter](https://greenteapress.com/wp/think-python-2e/)\n", + "\n", + "## Learning Objectives\n", + "\n", + "* Explain the concept of **scope** and the difference between a **local** variable and a **global** variable.\n", + "* Label variables as local or global and state the scope of the variable\n", + "* Explain the terms **call stack** and **frame**\n", + "* Identify as code is executed when frames are created and destroyed on the call stack and what the content of the frames will be\n", + "\n", + "#### Exam Conflict Form\n", + " * [Exam 1 - October 2nd, 5:45 pm](https://cs220.cs.wisc.edu/f24/surveys.html)\n", + " * [Exam 2 - November 6th, 5:45 pm](https://cs220.cs.wisc.edu/f24/surveys.html)\n", + " * [Final - December 14th, 7:25 pm](https://cs220.cs.wisc.edu/f24/surveys.html)\n", + " \n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "d1cd1813-b3bf-4069-a431-02b8c6d5237d", + "metadata": {}, + "source": [ + "## Definitions\n", + "\n", + "The **scope** of a variable is the area of the program where the variable is recognized and can be used. Python has two scopes, **global** (the variable can be used everywhere) and **local** (the variable can be used within the function in which it was defined).\n", + "\n", + "As a program is executed, the **callstack** stores information (i.e. variables) about the active local environments. Each time a function is called, a new **frame** is placed on the callstack. Each time a function finishes, its frame is removed from the callstack.\n", + "\n", + "Turn on the debugger and place a breakpoint on the first line of code in the cell below and \"step in\" the execution of the code in the cell until the cell finishes. Then do the same for the cell below that. Watch the \"callstack\" and \"variables\" portion of the debugger." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6a805200-5bf8-42d4-a15a-6257d1a93416", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n" + ] + } + ], + "source": [ + "def f():\n", + " x = 1\n", + " print(x)\n", + "\n", + "def g():\n", + " y = 2\n", + " print(y)\n", + "\n", + "def h():\n", + " z = 3\n", + " print(z)\n", + "\n", + "f()\n", + "g()\n", + "h()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "91b01530-6e3d-4098-bf83-f2a44100644c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n" + ] + } + ], + "source": [ + "def f():\n", + " x = 1\n", + " print(x)\n", + " g()\n", + "\n", + "def g():\n", + " y = 2\n", + " print(y)\n", + " h()\n", + "\n", + "def h():\n", + " z = 3\n", + " print(z)\n", + "\n", + "f()" + ] + }, + { + "cell_type": "markdown", + "id": "300337e1", + "metadata": {}, + "source": [ + "Now do the same to practice pieces of code at the [Interactive Python Tutor](https://cs220.cs.wisc.edu/s23/materials/lec-07.html).\n", + "\n", + "Notice the following:\n", + "\n", + "- A global scope holds the variables defined outside of any function AND the functions themselves\n", + "- When a function starts, a new frame is placed on the callstack\n", + "- When a function ends, the frame is removed from the callstack\n", + "- The local variables (i.e. those created inside of a function) are placed within that function's frame\n", + "- A function can call another function, causing multiple frames to be on the callstack at the same time\n", + "\n", + "Be aware that the \"variable\" section in the debugger has a drop-down letting you switch between the global and the local frame. Also notice that you can click on the items in the callstack to have the \"local\" variables be displayed for that active frame.\n", + "\n", + "Use the debugger with the code in the cell below to step through the execution of the code. Watch as each of the local frames are created and use the callstack switch between these local frames to see the variable x in each of those frames." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "253366ee-3eab-49f4-a137-e78885124ad9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n" + ] + } + ], + "source": [ + "def f():\n", + " x = 1\n", + " print(x)\n", + " g()\n", + "\n", + "def g():\n", + " x = 2\n", + " print(x)\n", + " h()\n", + "\n", + "def h():\n", + " x = 3\n", + " print(x)\n", + "\n", + "f()" + ] + }, + { + "cell_type": "markdown", + "id": "96c7c201-3635-46c8-a227-cedbbb6722b7", + "metadata": {}, + "source": [ + "## Using Python Tutor\n", + "\n", + "Now use the [Python Tutor](https://cs220.cs.wisc.edu/s23/materials/lec-07.html) to watch and execute the code for each of the lessons. You can also execute the code using the debugger. Make sure you understand each of the lessons or concepts being taught.\n", + "\n", + "**Lesson 1: Functions don't execute unless they are called**" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c6932120-b5dd-48e2-836c-a889a7b27a9d", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'x' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_314983/2438601094.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'x' is not defined" + ] + } + ], + "source": [ + "def set_x():\n", + " x = 100\n", + "\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "id": "54aabfd7-3572-40bc-bb25-286947f9b14a", + "metadata": {}, + "source": [ + "**Lesson 2: Variables created in a function die after function returns**" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "8b24429f-972d-4957-9c8a-39b182157ae7", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'x' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_314983/1921672716.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mset_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'x' is not defined" + ] + } + ], + "source": [ + "def set_x():\n", + " x = 100\n", + "\n", + "set_x()\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "id": "7b3bccbb-1eba-4490-a4b4-441ce937a3ab", + "metadata": {}, + "source": [ + "**Lesson 3: Variables start fresh every time a function is called again**" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "244882dd-818f-419c-98d3-4cafa60310ff", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n", + "2\n", + "2\n" + ] + } + ], + "source": [ + "def count():\n", + " x = 1\n", + " x += 1\n", + " print(x)\n", + "\n", + "count()\n", + "count()\n", + "count()" + ] + }, + { + "cell_type": "markdown", + "id": "1ceeba4d-e2c6-45d6-80b6-ad90733723a4", + "metadata": {}, + "source": [ + "**Lesson 4: you can't see the variables of other function invocations, even those that call you**" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "ca7b26b0-6518-4061-972d-d5caec39a298", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'x' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_314983/1405022800.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mdisplay_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/tmp/ipykernel_314983/1405022800.py\u001b[0m in \u001b[0;36mmain\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mdisplay_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_314983/1405022800.py\u001b[0m in \u001b[0;36mdisplay_x\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdisplay_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'x' is not defined" + ] + } + ], + "source": [ + "def display_x():\n", + " print(x)\n", + "\n", + "def main():\n", + " x = 100\n", + " display_x()\n", + "\n", + "main()" + ] + }, + { + "cell_type": "markdown", + "id": "62f3a27f-3db3-4492-ae0d-d1ca295e66e9", + "metadata": {}, + "source": [ + "**Lesson 5: you can generally just use global variables inside a function**" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "67257372-92a2-46e7-81c2-8746004cacc5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "before: hello\n", + "hello\n", + "after: hello\n" + ] + } + ], + "source": [ + "msg = 'hello' # global, outside any func\n", + "\n", + "def greeting():\n", + " print(msg)\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "0964c63c-6e0c-4234-b347-eda94c5f3b73", + "metadata": {}, + "source": [ + "**Lesson 6: if you do an assignment to a variable in a function, Python assumes you want it local**" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "124ba158-7ee0-49ac-85ad-8dcb767d9c9c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "before: hello\n", + "greeting: welcome!\n", + "after: hello\n" + ] + } + ], + "source": [ + "msg = 'hello'\n", + "\n", + "def greeting():\n", + " msg = 'welcome!'\n", + " print('greeting: ' + msg)\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "a7df0197-9e2a-42a6-a7b9-fd062436783d", + "metadata": {}, + "source": [ + "**Lesson 7: assignment to a variable should be before its use in a function, even if there's a a global variable with the same name**" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "f516f74e-dfe0-4726-9203-5082b81c123a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "before: hello\n" + ] + }, + { + "ename": "UnboundLocalError", + "evalue": "local variable 'msg' referenced before assignment", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mUnboundLocalError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_314983/1214842779.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'before: '\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mgreeting\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'after: '\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_314983/1214842779.py\u001b[0m in \u001b[0;36mgreeting\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgreeting\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'greeting: '\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mmsg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'welcome!'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mUnboundLocalError\u001b[0m: local variable 'msg' referenced before assignment" + ] + } + ], + "source": [ + "msg = 'hello'\n", + "\n", + "def greeting():\n", + " print('greeting: ' + msg)\n", + " msg = 'welcome!'\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "a1f6e7e9-e48e-4de9-8b01-6308a1a91f04", + "metadata": {}, + "source": [ + "**Lesson 8: use a global declaration to prevent Python from creating a local variable when you want a global variable**" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "04962da5-4178-4361-929b-f068703c2998", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "before: hello\n", + "greeting: hello\n", + "after: welcome!\n" + ] + } + ], + "source": [ + "msg = 'hello'\n", + "\n", + "def greeting():\n", + " global msg\n", + " print('greeting: ' + msg)\n", + " msg = 'welcome!'\n", + "\n", + "print('before: ' + msg)\n", + "greeting()\n", + "print('after: ' + msg)" + ] + }, + { + "cell_type": "markdown", + "id": "205e3043-afd2-4c5f-b37a-3bc8067f2f31", + "metadata": {}, + "source": [ + "**Lesson 9: in Python, arguments are \"passed by value\", meaning reassignments to a parameter don't change the argument outside**" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "4c2188eb-eb00-4023-92a0-8be153cef28e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "before: A\n", + "inside: B\n", + "after: A\n" + ] + } + ], + "source": [ + "def f(x):\n", + " x = 'B'\n", + " print('inside: ' + x)\n", + "\n", + "val = 'A'\n", + "print('before: ' + val)\n", + "f(val)\n", + "print('after: ' + val)" + ] + }, + { + "cell_type": "markdown", + "id": "4633aafe-0cdc-4ded-a867-ad232e16c7b4", + "metadata": {}, + "source": [ + "**Lesson 10: it's irrelevant whether the argument (outside) and parameter (inside) have the same variable name**" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "733ba7d9-6aa9-42c2-bbbd-97d55a86c191", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "before: A\n", + "inside: B\n", + "after: A\n" + ] + } + ], + "source": [ + "x = 'A'\n", + "\n", + "def f(x):\n", + " x = 'B'\n", + " print('inside: ' + x)\n", + "\n", + "print('before: ' + x)\n", + "f(x)\n", + "print('after: ' + x)" + ] + }, + { + "cell_type": "markdown", + "id": "066458da", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "You have learned about variable **scope**, specifically **local** and **global** scope. You have watched as **frames** are created and placed on the **callstack**. These frames are used for storing local variables. And you have learned about the rules for what variables you can access from within a function." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} -- GitLab