{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Procedural programming in Python: Functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For loops let you repeat some code for every item in a list. Functions are similar in that they run the same lines of code for new values of some variable. They are different in that functions are not limited to looping over items.\n", "\n", "Functions are a critical part of writing easy to read, reusable code.\n", "\n", "Create a function like:\n", "```\n", "def function_name (parameters):\n", " \"\"\"\n", " optional docstring\n", " \"\"\"\n", " function expressions\n", " return [variable]\n", "```\n", "\n", "_Note:_ Sometimes I use the word argument in place of parameter. Technically \"parameter\" refers to the abstract variable used in the function definition, while \"argument\" refers to the concrete value that is actually used when a function call is made. But that distinction isn't very important so you'll often hear both words interchangeably.\n", "\n", "Here is a simple example. It prints a string that was passed in and returns nothing." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def print_string(str):\n", " \"\"\"This prints out a string passed as the parameter.\"\"\"\n", " print(str)\n", " return" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "To call the function, use:\n", "```\n", "print_string(\"You're awesome!\")\n", "```\n", "\n", "_Note:_ The function has to be defined before you can call it!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you don't provide an argument or too many, you get an error." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Parameters (or arguments) in Python are all passed by reference. This means that if you modify the parameters in the function, they are modified outside of the function.\n", "\n", "See the following example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def change_list(my_list):\n", " \"\"\"This changes a passed list into this function\"\"\"\n", " my_list.append('four');\n", " print('list inside the function: ', my_list)\n", " return" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_list = [1, 2, 3];\n", "print('list before the function: ', my_list)\n", "change_list(my_list);\n", "print('list after the function: ', my_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Scope\n", "\n", "Variables have scope: `global` and `local`\n", "\n", "In a function, new variables that you create are not saved when the function returns - these are `local` variables. Variables defined outside of the function can be accessed but not changed - these are `global` variables, _Note_ there is a way to do this with the `global` keyword. Generally, the use of `global` variables is not encouraged, instead use parameters.\n", "\n", "Try:\n", "\n", " * declaring a local variable inside a function and using it outside the function\n", " * declaring a global variable and using it inside a function\n", " * modifying a global variable inside a function\n", " * declaring an existing variable `global` inside a function, and modifying it\n", " * declaring a new variable `global` inside a function, and using it oustide the function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Try some things with globals here!\n", "\n", "my_global_1 = 'bad global 1'\n", "my_global_2 = 'bad global 2'\n", "my_global_3 = 'bad global 3'\n", "\n", "def my_function():\n", " return\n", " \n", "my_function()\n", "print(my_global_1)\n", "print(my_global_2)\n", "print(my_global_3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Rules for how global variables work:\n", "\n", "* When we create a variable inside a function, it is local by default.\n", "* When we define a variable outside of a function, it is global by default. You don't have to use the global keyword.\n", "* We use the global keyword to read and write a global variable inside a function.\n", "* Use of the global keyword outside a function has no effect." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In general, though, you want to use parameters to provide data to a function and return a result with the `return`. E.g.\n", "\n", "```\n", "def sum(x, y):\n", " my_sum = x + y\n", " return my_sum\n", "```\n", "\n", "If you are going to return multiple objects, what data structure that we talked about can be used? Give an example below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Parameters have three different types:\n", "\n", "| type | behavior |\n", "|------|----------|\n", "| required | positional, must be present or error, e.g. `my_func(first_name, last_name)` |\n", "| keyword | position independent, e.g. `my_func(first_name, last_name)` can be called `my_func(first_name='Dave', last_name='Beck')` or `my_func(last_name='Beck', first_name='Dave')` |\n", "| default | keyword params that default to a value if not provided |\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def print_name(first, last='the Clown'):\n", " print(f'Your name is {first} {last}')\n", " return" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Play around with the above function." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Functions can contain any code that you put anywhere else including:\n", "* if...elif...else\n", "* for...else\n", "* while\n", "* other function calls" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def print_name_age(first, last, age):\n", " print_name(first, last)\n", " print('Your age is %d' % (age))\n", " if age > 35:\n", " print('You are really old.')\n", " return" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print_name_age(age=76, last='Winstanley', first='Melissa')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Breakout\n", "\n", "After writing each function, call your function several times with examples to make sure it works like you expect it to.\n", "\n", "1. Write a function to provide a summary of a list of numbers - it should return the sum, the average, the minimum, and the maximum. (What kind of data type might be useful to return multiple summary values?)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2. Write a Python function that checks whether a passed string is palindrome or not. A palindrome is a word, phrase, or sequence that reads the same backward as forward, e.g., madam or nurses run." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3. Write a function that computes a histogram of values from a dictionary. In other words, it takes a dictionary as input and returns a dictionary that contains the original values mapped to how often they appear.\n", "\n", " If the original dictionary is:\n", " ```\n", " {'V': 10, 'VI': 10, 'VII': 40, 'VIII': 20, 'IX': 70, 'X': 80, 'XI': 40, 'XII': 20}\n", " ```\n", " Then the resulting histogram would be:\n", " ```\n", " {10: 2, 40: 2, 20: 2, 70: 1, 80: 1}\n", " ```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.9.6 (default, Oct 18 2022, 12:41:40) \n[Clang 14.0.0 (clang-1400.0.29.202)]" }, "vscode": { "interpreter": { "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" } } }, "nbformat": 4, "nbformat_minor": 1 }