{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7979a0a2",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Scope\n",
    "#### CS 65/STEM 280: Introduction to Computer Science I"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "438dc517",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Scope of a variable\n",
    "\n",
    "A variable's __scope__ is the part of the program that the variable is visible to.\n",
    "\n",
    "In Python, a scope can be __local__ to a function or __global__ (visible everywhere).\n",
    "\n",
    "Furthermore, scope may also be limited within a function - e.g., you can't use a variable before you've assigned something to it\n",
    "\n",
    "Parameters are local to the function they're defined in."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0594f709",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter your hourly wage: 10\n",
      "Enter your number of hours worked: 20\n",
      "Your total pay is 200.0\n"
     ]
    }
   ],
   "source": [
    "import csv\n",
    "\n",
    "def calculate_pay(wage,hours):\n",
    "    if hours <= 40:\n",
    "        pay = wage*hours\n",
    "    else:\n",
    "        overtime_hours = hours-40\n",
    "        pay = (wage*40) + (wage*1.5*overtime_hours)\n",
    "\n",
    "    return pay\n",
    "\n",
    "\n",
    "def user_pay_calculator():\n",
    "    hourly_wage = float(input(\"Enter your hourly wage: \"))\n",
    "    num_hours = float(input(\"Enter your number of hours worked: \"))\n",
    "    #calculate_pay(hourly_wage,num_hours)\n",
    "    #print(pay) #won't work\n",
    "    print(\"Your total pay is\",calculate_pay(hourly_wage,num_hours))\n",
    "    \n",
    "user_pay_calculator()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c0314a2",
   "metadata": {},
   "source": [
    "`wage`, `hours`, `overtime_hours`, `pay` are all local to the `calculate_pay()` function\n",
    "\n",
    "You can't use `pay` inside user_pay_calculator()\n",
    "\n",
    "Similarly, `hourly_wage` couldn't be used in `calculate_pay()`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8eb80a27",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Global variables\n",
    "\n",
    "Global variables are weird"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "81a5bc13",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "350\n",
      "350\n"
     ]
    }
   ],
   "source": [
    "num_students = 350 #this variable is global because it is defined outside of a function\n",
    "\n",
    "def first_grade_classroom():\n",
    "    print(num_students)\n",
    "    \n",
    "def second_grade_classroom():\n",
    "    print(num_students)\n",
    "    \n",
    "first_grade_classroom()\n",
    "second_grade_classroom()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "68d0f8d9",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "30\n",
      "350\n"
     ]
    }
   ],
   "source": [
    "num_students = 350 #this variable is global because it is defined outside of a function\n",
    "\n",
    "def first_grade_classroom():\n",
    "    num_students = 30  #this is actually now a local variable with the same name as the global variable!\n",
    "    print(num_students)\n",
    "    \n",
    "def second_grade_classroom():\n",
    "    print(num_students)\n",
    "    \n",
    "first_grade_classroom()\n",
    "second_grade_classroom()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "913e4417",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "If you really want to change a global variable inside a function, you have to use the `global` keyword."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "aa39028f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "30\n",
      "30\n"
     ]
    }
   ],
   "source": [
    "num_students = 350 #this variable is global because it is defined outside of a function\n",
    "\n",
    "def first_grade_classroom():\n",
    "    global num_students #here, we tell it to really use the global variable\n",
    "    num_students = 30\n",
    "    print(num_students)\n",
    "    \n",
    "def second_grade_classroom():\n",
    "    print(num_students)\n",
    "    \n",
    "first_grade_classroom()\n",
    "second_grade_classroom()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ec95743",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "But, you really _shouldn't_ do this. Changing global variables inside of functions makes programs _extremely difficult_ to debug.\n",
    "\n",
    "If you need the same variable in multiple functions, it is better to pass it as an argument or return it."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d8b46a7",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Constants\n",
    "\n",
    "It's best to have all your code be in functions, except\n",
    "* Constant values you might need that never change (by convention, use all caps for names)\n",
    "* Maybe a single function call to launch the program."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9a9963b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import csv\n",
    "\n",
    "OVERTIME_THRESHOLD = 40\n",
    "\n",
    "def calculate_pay(wage,hours):\n",
    "    if hours <= OVERTIME_THRESHOLD:\n",
    "        pay = wage*hours\n",
    "    else:\n",
    "        overtime_hours = hours-OVERTIME_THRESHOLD\n",
    "        pay = (wage*OVERTIME_THRESHOLD) + (wage*1.5*overtime_hours)\n",
    "\n",
    "    return pay\n",
    "\n",
    "\n",
    "def user_pay_calculator():\n",
    "    hourly_wage = float(input(\"Enter your hourly wage: \"))\n",
    "    num_hours = float(input(\"Enter your number of hours worked: \"))\n",
    "    print(\"Your total pay is\",calculate_pay(hourly_wage,num_hours))\n",
    "    \n",
    "user_pay_calculator()"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "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.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
