{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# More on functions\n", "In this lecture, we also various important features of designing functions in Python\n", "\n", "**Created and edited by:** John C.S. Lui on August 10th, 2020.\n", "\n", "**Important note**: If you want to use and modify this notebook file, please acknowledge the author." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Let's define a display function\n", "\n", "def display_func(name):\n", " print (\"To \" + name + \", \", end='')\n", " print (\"welcome to CSCI2040.\")\n", " \n", "display_func('John')\n", "display_func('Dr. S.H. Or')\n", "\n", "# calling the function below will create a problem\n", "# display_func()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting default values for argument to a function\n", "We can avoid the above problem if we have some default values. Let's see." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Let's define a display function with default value\n", "\n", "#def display_func(name):\n", "def display_func(name='Mr. Big Nose'):\n", " print (\"To \" + name + \", \", end='')\n", " print (\"welcome to CSCI2040.\")\n", " \n", "display_func('John')\n", "display_func('Jack')\n", "display_func()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Positional arguments in function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This function takes in a person's first and last name, his/her age and prints this information out\n", "\n", "def describe_person(first_name, last_name, age):\n", "\n", " print(\"First name: %s\" % first_name.title())\n", " print(\"Last name: %s\" % last_name.title())\n", " print(\"Age: %d\\n\" % age)\n", "\n", "describe_person('brian', 'kernighan', 71)\n", "describe_person('ken', 'thompson', 70)\n", "describe_person('john c.s.', 'lui', 28)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Comment for the above program\n", "For the above program, *first_name*, *last_name*, and *age*. These are called **positional arguments**,
\n", "Python knows which value to assign to each by the order in which you give the function values.\n", "\n", "What if we want to pass these arguments in whatever order? Let's illustrate\n", "the concept of **keyword argument**.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def describe_person(first_name, last_name, age):\n", " print(\"First name: %s\" % first_name.title())\n", " print(\"Last name: %s\" % last_name.title())\n", " print(\"Age: %d\\n\" % age)\n", "\n", "describe_person(age=71, first_name='brian', last_name='kernighan') # using keyword argument format\n", "describe_person(age=70, first_name='ken', last_name='thompson')\n", "describe_person(first_name='John C.S.', age=28, last_name='Lui')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Mixing positional and keyword arguments and default values\n", "Let's see." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def describe_person(first_name, last_name, age=None, favorite_language=None, died=None):\n", " # Required information:\n", " print(\"First name: %s\" % first_name.title())\n", " print(\"Last name: %s\" % last_name.title())\n", " # Also initialize some arguemnts with default values\n", " \n", " # Optional information:\n", " if age:\n", " print(\"Age: %d\" % age)\n", " if favorite_language:\n", " print(\"Favorite language: %s\" % favorite_language)\n", " if died:\n", " print(\"Died at: %d\" % died)\n", " \n", " # Blank line at end.\n", " print(\"\\n\")\n", " \n", "describe_person('brian', 'kernighan', favorite_language='C')\n", "describe_person('ken', 'thompson', age=70)\n", "describe_person('adele', 'goldberg', age=68, favorite_language='Smalltalk')\n", "describe_person('dennis', 'ritchie', favorite_language='C', died=2011)\n", "describe_person('guido', 'van rossum', favorite_language='Python')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Function which takes on an arbitrary number of arguments\n", "\n", "We have now seen that using *keyword arguments* can allow for much more flexible calling statements.\n", "\n", "* This benefits you in your own programs, because you can write one function that can handle many different situations you might encounter.\n", "* This benefits you if other programmers use your programs, because your functions can apply to a wide range of situations.\n", "* This benefits you when you use other programmers' functions, because their functions can apply to many situations you will care about.\n", "\n", "There is another issue that we can address, though. Let's consider a function that takes two number in, and prints out the sum of the two numbers:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This function adds two numbers together, and prints the sum\n", "def adder(num_1, num_2):\n", " sum = num_1 + num_2\n", " print(\"The sum of your numbers is %d.\" % sum)\n", " \n", "# Let's add some numbers.\n", "adder(1, 2)\n", "adder(-1, 2)\n", "adder(1, -2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function appears to work well. But what if we pass it three numbers, which is a perfectly reasonable thing to do mathematically?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def adder(num_1, num_2):\n", " sum = num_1 + num_2\n", " print(\"The sum of your numbers is %d.\" % sum)\n", " \n", "# Let's add some numbers.\n", "adder(1, 2)\n", "adder(1, 2, 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try to fix this problem. If we place an argument at the end of the list of arguments,
\n", "with an asterisk in front of it, that argument will collect any remaining values from the calling
\n", "statement into a tuple. Here is an example demonstrating how this works:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# define a new function and let's pay attention at the argument values.\n", "\n", "def example_function(arg_1, arg_2, *arg_3): # see the *arg_3 ?\n", " print('\\narg_1:', arg_1)\n", " print('arg_2:', arg_2)\n", " print('arg_3:', arg_3)\n", " \n", "example_function(1, 2)\n", "example_function(1, 2, 3)\n", "example_function(1, 2, 3, 4)\n", "example_function(1, 2, 3, 4, 5)\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use a *loop* to process these other arguments." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def example_function(arg_1, arg_2, *arg_3):\n", " print('\\narg_1:', arg_1)\n", " print('arg_2:', arg_2)\n", " for value in arg_3:\n", " print('arg_3 value:', value)\n", "\n", "example_function(1, 2)\n", "example_function(1, 2, 3)\n", "example_function(1, 2, 3, 4)\n", "example_function(1, 2, 3, 4, 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's rewrite our *adder()* function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This function adds the given numbers together, and prints the sum.\n", "\n", "def adder(num_1, num_2, *nums): \n", "\n", " sum = num_1 + num_2 # Start by adding the first two numbers, which will always be present.\n", " \n", " for num in nums: # Then add any other numbers that were sent.\n", " sum = sum + num\n", " \n", " print(\"The sum of your numbers is %d.\" % sum) # Print the results.\n", " \n", "# Let's add some numbers.\n", "adder(3,4)\n", "adder(1, 2, 3)\n", "adder(1,2,3,4,5)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Accepting an arbitrary number of keyword arguments\n", "\n", "Python also provides a syntax for accepting an arbitrary number of keyword arguments. The syntax looks like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Let's look at the argument values.\n", "def example_function(arg_1, arg_2, **kwargs):\n", " print('\\narg_1:', arg_1)\n", " print('arg_2:', arg_2)\n", " print('arg_3:', kwargs)\n", " \n", "example_function('a', 'b')\n", "example_function('a', 'b', value_3='c')\n", "example_function('a', 'b', value_3='c', value_4='d')\n", "example_function('a', 'b', value_3='c', value_4='d', value_5='e')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The third argument has two asterisks in front of it, which tells Python to collect all remaining key-value
arguments in the calling statement. This argument is commonly named **kwargs**. We see in the output
\n", "that these key-values are stored in a dictionary. We can **loop** through this dictionary to work with
\n", "all of the values that are passed into the function:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def example_function(arg_1, arg_2, **kwargs):\n", " print('\\narg_1:', arg_1)\n", " print('arg_2:', arg_2)\n", " for key, value in kwargs.items():\n", " print('arg_3 value:', value)\n", " \n", "example_function('a', 'b')\n", "example_function('a', 'b', value_3='c')\n", "example_function('a', 'b', value_3='c', value_4='d')\n", "example_function('a', 'b', value_3='c', value_4='d', value_5='e')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Final example" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This function takes in a person's first and last name, and an arbitrary number of keyword arguments.\n", "def describe_person(first_name, last_name, **kwargs):\n", " \n", " # Required information:\n", " print(\"First name: %s\" % first_name.title())\n", " print(\"Last name: %s\" % last_name.title())\n", " \n", " # Optional information:\n", " for key in kwargs:\n", " print(\"%s: %s\" % (key.title(), kwargs[key]))\n", " \n", " # Blank line at end.\n", " print(\"\\n\")\n", "\n", "describe_person('brian', 'kernighan', favorite_language='C', famous_book='The C Programming Language')\n", "describe_person('ken', 'thompson', age=70, alma_mater='UC Berkeley')\n", "describe_person('adele', 'goldberg', age=68, favorite_language='Smalltalk')\n", "describe_person('dennis', 'ritchie', favorite_language='C', died=2011, famous_book='The C Programming Language')\n", "describe_person('guido', 'van rossum', favorite_language='Python', company='Dropbox')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.3" } }, "nbformat": 4, "nbformat_minor": 2 }