Functions
- A named chunk of coded that can be used multiple times.
    - Avoids need to repeatedly re-write the same code over and over
- Helps organize code into manageable abstractions.
        - Think “Engine” as opposed to “block, pistons, rods, etc.”
 
 
- Python supplies many useful functions
    - max
- min
- abs
- round
- input
- int
- float
 
- Remember parentheses when calling function, otherwise nothing happens
    - Because a function without parentheses is a value.
- print(min(44, 15))
- print(min)
 
- This is usually a problem with functions that take zero parameters, like exit- Show exitvs.exit()in REPL.
 
- Show 
Libraries and import statements
- Python provides a lot of functions. To help with organization and avoid name collisions, these
functions are organized into different packages.
    - If all built-in functions were global, then you might have trouble picking function names that weren’t already “taken”.
- Putting functions in packages also helps you know where to look.
 
- Consider the mathpackage: https://docs.python.org/3/library/math.html- If you are browsing for the name of a particular function, it is easier to browse through this shorter list.
 
- Two steps to using a library function:
    - import math
- Use “full name” of function (e.g., math.sqrt(14))
- (There are short-cuts that I’ll show later).
 
- This page https://docs.python.org/3/library/functions.html provides
    - List of functions in the “global” namespace.
- List of packages you can browse.
 
Writing your own functions
- Basic format:
def name(parameters)
  statements
- Use indentation to show what is part of the function.
- Docstring: Describe what the function does and what each parameter is for.
def fahrenheit_to_celsius(f):
  """ Converts a temperature in Fahrenheit to Celsius """
  c = 5/9*(f-32)
  return c
- Formal vs. actual parameters.
    - The writer of a function and the user of a function are typically two different people. We don’t want to require that they use the same variable names. (In fact, doing so would create a lot of name collisions)
- Use a subtractmethod as a running example.
 
- actual parameters mapped to formal parameters in order.
    - show difference between subtract(5, 4)andsubtract(4, 5)
- repeat above using variables.
- Use an example where formal and actual parameters have the same names.
- switch to show that it is the order that matters
 
- show difference between 
- Variables have scope
    - The ainside a function is different from theaoutside of it.
- (Mostly.)
 
- The 
- noneis not 0.
- returnis the always the last line executed.- Lines after a returnnever run.
- Add a printafter thereturninsubtract.
 
- Lines after a 
- Demonstrate that variables have local scope.
- Global variables can be seen inside of functions.
    - Don’t do this: It leads to confusing code.
 
- Do problem 1 in In-Class 3
Type annotations
- Type annotations
    - Used to show the user what data type is expected.
- Makes code easier to read.
- The annotations are for readability only, they do not affect how the program is run. (i.e., they are not used at runtime.)
 
def duplicate(msg):
    """Returns a string containing two copies of `msg`"""
    return msg + msg
def duplicate(msg: str) -> str:
    """Returns a string containing two copies of `msg`"""
    return msg + msg
- Look at apothem example from Section 4.10
    - https://runestone.academy/ns/books/published/gvsu_cis500_w24/functions_functions-can-call-other-functions-composition.html
 
- printvs.- return
- Don’t repeat yourself.