{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Functions\n", "\n", "- defining a function\n", " - `def`\n", " - `return`\n", " - default values\n", " - keyword vs. positional arguments\n", "- executing a function\n", " - parameters\n", " - separate namespace" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Vocab\n", "\n", "- **Define/create/make** a function: To set up and write the instructions for a function.\n", "- **Execute/call/use** a function: To actually use the pre-defined function.\n", "\n", "- **Input/parameter/argument**: A variable defined by the user that is put/passed in between the parantheses `()` that comes after the function name. \n", "- **Output**: The variable that is `return`ed to the user after the function is executed." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Functions\n", "\n", "
\n", "A function is a re-usable piece of code that performs operations on a specified set of variables, and returns the result.\n", "
" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "![cheeseburger](img/cheeseburger.png)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Modular Programming\n", "\n", "
\n", "Modular programming is an approach to programming that focuses on building programs from independent modules ('pieces'). \n", "
" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Copy + Pasting the same/similar bit of code is to be avoided.\n", "\n", "**Functions** are one way to avoid this.\n", "\n", "**Loops** are another! (we'll get to these soon...)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Functions for Modular Programming" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Functions allow us to flexibly re-use pieces of code\n", "- Each function is independent of every other function, and other pieces of code\n", "- Functions are the building blocks of programs, and can be flexibly combined and executed in specified orders\n", " - This allows us to build up arbitrarily complex, well-organized programs" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# you've seen functions before\n", "# here we use the type() function\n", "my_var = 3\n", "type(my_var)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# the function print() doesn't depend on type()\n", "# but they can both be used on the same variable\n", "print(my_var)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Function Example I\n", "\n", "When you use `def`, **you are defining a function**.\n", "You are metaphorically writing the instructions for how to make the cheeseburger." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# define a function: double_value\n", "# Notice that the parameter `num` is not explicitly defined with an = \n", "# This is because it will be defined later by the user when they execute the function.\n", "def double_value(num):\n", "\n", " # do some operation\n", " doubled = num + num\n", " \n", " # return output from function\n", " return doubled " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# excecute a function by calling the function's name\n", "# and defining the parameter within the parentheses\n", "double_value(num = 2) " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# equivalent function call\n", "# Here the parameter `num` is defined without \n", "# explicitly specifying the name of the parameter\n", "double_value(2) " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Function Example II\n", "\n", "Here we are defining a function with multiple parameters" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def add_two_numbers(num1, num2):\n", " \n", " # Do some operations with the parameters\n", " answer = num1 + num2\n", " \n", " # Return the variable answer\n", " return answer" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "add_two_numbers(5, 14)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Execute our function again on some other inputs to double check \n", "# that our function is working how we think it should\n", "output = add_two_numbers(-1, 4)\n", "print(output)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Function Properties" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Functions are defined using `def` followed by the name of the function, parentheses `()`, parameters within the parentheses, and then `:` after the parentheses, which opens a code-block that comprises the function\n", " - Running code with a `def` block *defines* the function (but does not *execute* it)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Functions are *executed* with the name of the function and parentheses - `()` without `def` and `:`\n", " - This is when the code inside a function is actually run" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Inside a function, there is code that performs operations on the available variables" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Functions use the special operator `return` to exit the function, passing out any specified variables" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- When you use a function, you can assign the output (whatever is `return`ed) to a variable" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true }, "slideshow": { "slide_type": "slide" } }, "source": [ "#### Clicker Question #1\n", "Given the function defined below, what will the second code cell below return?\n", "\n", "A) 0  B) 2  C) 4  D) '2r.2 + 1'  E) ¯\\\\\\_(ツ)\\_/¯" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def remainder(number, divider):\n", " \n", " r = number % divider\n", " \n", " return r" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "ans_1 = remainder(12, 5)\n", "ans_2 = remainder(2, 2)\n", "\n", "print(ans_1 + ans_2)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true }, "slideshow": { "slide_type": "slide" } }, "source": [ "#### Clicker Question #2\n", "\n", "Write a function `greet` that takes the parameter `name`. Inside the function, concatenate 'Hello', the person's name, and 'Good morning!\". Assign this to `output` and return `output`.\n", "\n", "A) I did it!  B) I think I did it.  C) I tried but I am stuck.  D) Super duper lost." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "## YOUR CODE HERE " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# TEST YOUR FUNCTION HERE" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Default Values" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "
\n", "Function parameters can also take default values. This makes some parameters optional, as they take a default value if not otherwise specified.\n", "
" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Default Value Functions\n", "\n", "Specify a default value in a function by doing an assignment within the function definition." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Create a function, that has a default values for a parameter\n", "def exponentiate(number, exponent=2): \n", " return number ** exponent" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Use the function, using default value\n", "exponentiate(3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Call the function, over-riding default value with something else\n", "# python assumes values are in order of parameters specified in definition\n", "exponentiate(2, 3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# you can always state this explicitly\n", "exponentiate(number=2, exponent=3)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Positional vs. Keyword Arguments" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "
\n", "Arguments to a function can be indicated by either position or keyword.\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Positional arguments use the position to infer which argument each value relates to\n", "exponentiate(2, 3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Keyword arguments are explicitly named as to which argument each value relates to\n", "exponentiate(number=2, exponent=3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exponentiate(exponent=3, number=2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Note: once you have a keyword argument, you can't have other positional arguments afterwards\n", "# this cell will produce an error\n", "exponentiate(number=2, 3)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Reminder, setting a default value for parameters is allowed during function *definition*.\n", "\n", "(This may look like what we did above, but here we are including a default value for one parameter during function definition. During function *execution*, you can't mix and match using positional vs. keywords)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def exponentiate(number, exponent=2): \n", " return number ** exponent" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Clicker Question #3\n", "\n", "What will the following code snippet print?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def exponentiate(number, exponent=2): \n", " return number ** exponent\n", "\n", "exponentiate(exponent=3, number=2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- A) 8\n", "- B) 9\n", "- C) SyntaxError\n", "- D) None\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Note: when using Keyword arguments position/order no longer matters" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Code Style: Functions\n", "\n", "- Function names should be snake_case \n", "- Function names should describe task accomplished by function\n", "- Separate out logical sections within a function with new lines\n", "- Arguments should be separated by a comma and a space\n", "- Default values do NOT need a space around the `=`" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Functions: Good Code Style" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "def remainder(number, divider=2):\n", " \n", " r = number % divider\n", " \n", " return r" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Functions: Code Style to Avoid" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "# could be improved by adding empty lines to separate out logical chunks\n", "def remainder(number,divider=2): # needs space after comma\n", " r=number%divider # needs spacing around operators\n", " return r" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Function Namespace " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Each function has its own namespace\n", "- Functions only have access to:\n", " - variables explicitly passed into them\n", " - variables defined inside the function" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# You can check variables defined in the global namespace with `%whos`\n", "%whos" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Variables defined inside a function only exist within that function." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Names used inside a function are independent of those used outside\n", "# variables defined outside of functions are global variables\n", "# global variables are always available\n", "my_var = 'I am a variable'\n", "\n", "print(my_var)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# define a function that uses my_var inside the function\n", "def concat_self(my_var):\n", " \n", " my_var = my_var + ' ' + my_var\n", " \n", " return my_var\n", "\n", "print(concat_self(my_var))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# see that my_var in global name space remains unchanged\n", "print(my_var)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# only way to change my_var in global namespace\n", "# is to assign to variable my_var in global namespace\n", "my_var = concat_self(my_var)\n", "print(my_var)" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "slide" }, "tags": [] }, "source": [ "#### Clicker Question #4\n", "\n", "Write a function `convert_to_f` that will convert a temperature in Celsius to Farenheit, returning the temperature in Farenheit. \n", "\n", "Note: A temperature in Celsius will be multipled by 9/5 and then 32 will be added to that quantity to convert to Farenheit\n", "\n", "A) I did it!  B) I think I did it.  C) I tried but I am stuck.  D) Super duper lost." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "## YOUR CODE HERE " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# TEST YOUR FUNCTION HERE" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Summary\n", "- how to define a function\n", "- how to execute a function\n", "- default values\n", "- position vs. keyword arguments\n", "- global namespace vs. local namespace\n", "- code style" ] } ], "metadata": { "celltoolbar": "Slideshow", "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.11.8" }, "rise": { "scroll": true } }, "nbformat": 4, "nbformat_minor": 4 }