{ "cells": [ { "cell_type": "markdown", "id": "0af955cc", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Python Functions and Modules\n", "\n", "Feng Li\n", "\n", "School of Statistics and Mathematics\n", "\n", "Central University of Finance and Economics\n", "\n", "[feng.li@cufe.edu.cn](mailto:feng.li@cufe.edu.cn)\n", "\n", "[https://feng.li/python](https://feng.li/python)" ] }, { "cell_type": "markdown", "id": "775c1af6", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Build-in Functions\n", "\n", "- The Python interpreter has a number of functions built into it that are always available. They are listed here in alphabetical order. Use e.g. `help(abs)` to see the function help.\n", "\n", "\n", "```py\n", "abs() aiter() all() any() anext() ascii() bin() bool() breakpoint() bytearray() bytes() callable() chr() classmethod() compile() complex() delattr() dict() dir() divmod() enumerate() eval() exec() filter() float() format() frozenset() getattr() globals() hasattr() hash() help() hex() id() input() int() isinstance() issubclass() iter() len() list() locals() map() max() memoryview() min() next() object() oct() open() ord() pow() print() property() range() repr() reversed() round() set() setattr() slice() sorted() staticmethod() str() sum() super() tuple() type() vars() zip() __import__()\n", "```\n", "\n", "- See https://docs.python.org/3/library/functions.html for a complete description of those functions.\n" ] }, { "cell_type": "markdown", "id": "f6904adb", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Import modules\n", "\n", "To import a module (like `math`) that is not in Python's default module, use" ] }, { "cell_type": "code", "execution_count": 43, "id": "07f678d3", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import math" ] }, { "cell_type": "markdown", "id": "9be4c800", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Then you can use all the mathematical functions inside `math` module as:" ] }, { "cell_type": "code", "execution_count": 44, "id": "fd1b30c0", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.exp(0)" ] }, { "cell_type": "markdown", "id": "1ac8d5b9", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "- Alternatively, you can do the following module renaming when importing" ] }, { "cell_type": "code", "execution_count": 45, "id": "d9920725", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "2.718281828459045" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import math as mt\n", "mt.exp(1)" ] }, { "cell_type": "markdown", "id": "cef8aea0", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- If you just want to import one or two functions from a module" ] }, { "cell_type": "code", "execution_count": 46, "id": "1e31ec02", "metadata": { "scrolled": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "20.085536923187668" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import exp\n", "exp(3)" ] }, { "cell_type": "code", "execution_count": 47, "id": "546b74b1", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "2.718281828459045" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import exp as myexp\n", "myexp(1)" ] }, { "cell_type": "markdown", "id": "48e4b9ea", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Install third-party modules\n", "\n", "### through terminal\n", "\n", "- Use `pip` in a **terminal** to install a Python module from PyPi (https://pypi.org) on your user directory.\n", "```sh\n", "pip install numpy --user\n", "```\n", "- You could also specify a faster mirror close to you\n", "```sh\n", "pip install numpy --user -i https://pypi.tuna.tsinghua.edu.cn/simple\n", "```\n", "- Update a Python module\n", "```sh\n", "pip install pandas -U\n", "```\n", "- Remove a Python module\n", "```sh\n", "pip uninstall numpy \n", "```" ] }, { "cell_type": "markdown", "id": "7a19460e", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### trhough Jupyter notebook\n", "\n", "You could issue the above commands within the Jupyter notebook. Just place the `!` in front of the command " ] }, { "cell_type": "code", "execution_count": 2, "id": "cee4ead2", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Looking in indexes: https://mirrors.163.com/pypi/simple/\n", "Requirement already satisfied: pandas in /usr/local/lib/python3.9/dist-packages (1.3.4)\n", "Collecting pandas\n", " Using cached https://mirrors.163.com/pypi/packages/48/b4/1081d66b71c4dfc1bc1e19d6f2abbf93ed42f69df7703eb323742d45423e/pandas-1.3.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.5 MB)\n", " Using cached https://mirrors.163.com/pypi/packages/03/ea/98d488a4047b3fd8075b5c1e00469ad42d715e2c1e4fd15fa1ffaef8d635/pandas-1.3.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.5 MB)\n", "Requirement already satisfied: python-dateutil>=2.7.3 in /usr/lib/python3/dist-packages (from pandas) (2.8.1)\n", "Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.9/dist-packages (from pandas) (1.21.2)\n", "Requirement already satisfied: pytz>=2017.3 in /usr/lib/python3/dist-packages (from pandas) (2021.3)\n" ] } ], "source": [ "! pip3 install pandas -U" ] }, { "cell_type": "markdown", "id": "c46b603d", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Control Flow Tools\n", "\n", "### The `if` statements\n", "Perhaps the most well-known statement type is the if statement. For example:" ] }, { "cell_type": "code", "execution_count": 4, "id": "c2abe7a9", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Zero\n" ] } ], "source": [ "x = 0\n", "\n", "if x < 0:\n", " x = 0\n", " print('Negative changed to zero')\n", "elif x == 0:\n", " print('Zero')\n", "elif x == 1:\n", " print('Single')\n", "else:\n", " print('More')" ] }, { "cell_type": "markdown", "id": "2c6e2c2e", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "**Note** \n", "\n", "- the comma/colon sign(:) should be right after `if`, `elif` and `else` statement.\n", "- the `indentation` is very important. The first non-blank line after the first line of the string determines the amount of indentation for the entire documentation string." ] }, { "cell_type": "markdown", "id": "b20ae42e", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### The `for` Statements" ] }, { "cell_type": "code", "execution_count": 49, "id": "f0fab355", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cat 3\n", "window 6\n", "defenestrate 12\n" ] } ], "source": [ "words = ['cat', 'window', 'defenestrate']\n", "for w in words:\n", " print(w, len(w))" ] }, { "cell_type": "code", "execution_count": 5, "id": "921cf8d2", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1900 is not a leap year\n", "2000 is a leap year\n", "2004 is a leap year\n", "2011 is not a leap year\n", "2022 is not a leap year\n" ] } ], "source": [ "x = [1900, 2000, 2004, 2011, 2022]\n", "\n", "for year in x:\n", " if (year % 400 == 0) or (year % 100 != 0 and year % 4 == 0):\n", " print(year, \"is a leap year\")\n", " else:\n", " print(year, \"is not a leap year\")" ] }, { "cell_type": "markdown", "id": "308c1141", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Defining Functions\n", "\n", "\n", "- We can create a function that writes the Fibonacci series to an arbitrary boundary.\n", "\n", "- The function should also include a proper help with the `docstring`\n", "\n", " - The first line should always be a short, concise summary of the object's purpose. \n", "\n", " - If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description. \n", " \n", " - The following lines should be one or more paragraphs describing the object's calling conventions, its side effects, etc." ] }, { "cell_type": "code", "execution_count": 9, "id": "be87e07a", "metadata": { "scrolled": true, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "# 0, 1, 1, 2, 3, 5,\n", "def fib(n): # write Fibonacci series up to n\n", " \"\"\"Print a Fibonacci series up to n.\n", " \n", " par n: integer\n", " out : list\n", " \"\"\" # the function help\n", " a, b = 0, 1\n", " while a < n:\n", " print(a, end=' ')\n", " # better than print(a), why?\n", " a, b = b, a+b" ] }, { "cell_type": "code", "execution_count": 10, "id": "fff7c7f6", "metadata": { "scrolled": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function fib in module __main__:\n", "\n", "fib(n)\n", " Print a Fibonacci series up to n.\n", " \n", " par n: integer\n", " out : list\n", "\n" ] } ], "source": [ "help(fib)" ] }, { "cell_type": "code", "execution_count": 11, "id": "82eddb11", "metadata": { "scrolled": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 " ] } ], "source": [ "fib(20000)" ] }, { "cell_type": "markdown", "id": "212d0198", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "- **Function could also have default values**. The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow. For example:" ] }, { "cell_type": "code", "execution_count": 40, "id": "98a86d98", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):\n", " while True:\n", " ok = input(prompt)\n", " if ok in ('y', 'ye', 'yes'):\n", " return True\n", " if ok in ('n', 'no', 'nop', 'nope'):\n", " return False\n", " retries = retries - 1\n", " if retries < 0:\n", " raise IOError('too many tries')\n", " print(complaint)" ] }, { "cell_type": "code", "execution_count": 41, "id": "a8eb6a91", "metadata": { "scrolled": true, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Do you really want to go, dear?a\n", "Yes or no, please!\n", "Do you really want to go, dear?b\n", "Yes or no, please!\n", "Do you really want to go, dear?c\n" ] }, { "ename": "OSError", "evalue": "too many tries", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mOSError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/tmp/ipykernel_332089/131326152.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mask_ok\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Do you really want to go, dear?\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretries\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/tmp/ipykernel_332089/2101535446.py\u001b[0m in \u001b[0;36mask_ok\u001b[0;34m(prompt, retries, complaint)\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mretries\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mretries\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mretries\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mIOError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'too many tries'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcomplaint\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mOSError\u001b[0m: too many tries" ] } ], "source": [ "ask_ok(\"Do you really want to go, dear?\", retries=2)" ] }, { "cell_type": "markdown", "id": "2419a1e9", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "- **Anonymous functions** Small anonymous functions can be created with the `lambda` keyword. \n", "\n", "Lambda functions can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda functions can reference variables from the containing scope. The example uses a lambda expression to return a function" ] }, { "cell_type": "code", "execution_count": 32, "id": "ce432d1d", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "def make_incrementor(n):\n", " return lambda x: x + n\n", "f = make_incrementor(42)" ] }, { "cell_type": "code", "execution_count": 56, "id": "e4ec8c01", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "42" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(0)" ] }, { "cell_type": "code", "execution_count": 57, "id": "15b8ab10", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "43" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1)" ] }, { "cell_type": "markdown", "id": "aa37d302", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "The anonymous function is very useful in manipulating the `list` and Python DataFrame (`pandas`) " ] }, { "cell_type": "markdown", "id": "2daef8c0", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "- If we save the function to a file named `mycollections.py`, we could import the function as follows\n", "```python\n", ">>> import mycollections\n", ">>> mycollections.fib(2000)\n", "0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597\n", ">>> from mycollections import fib\n", ">>> fib(2000)\n", "```" ] }, { "cell_type": "code", "execution_count": 3, "id": "daffe267", "metadata": {}, "outputs": [], "source": [ "import mycollections" ] }, { "cell_type": "code", "execution_count": 4, "id": "ec90694f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mycollections.fib" ] }, { "cell_type": "code", "execution_count": 5, "id": "77fefda2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 1 2 3 5 8 13 21 34 55 89 " ] } ], "source": [ "mycollections.fib(100)" ] }, { "cell_type": "code", "execution_count": 6, "id": "40db07d2", "metadata": {}, "outputs": [], "source": [ "from mycollections import fib" ] }, { "cell_type": "code", "execution_count": 7, "id": "b0e20576", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 1 2 3 5 8 13 21 34 55 89 144 " ] } ], "source": [ "fib(200)" ] }, { "cell_type": "code", "execution_count": 8, "id": "e6fe87b6", "metadata": {}, "outputs": [], "source": [ "def fib(n): # write Fibonacci series up to n\n", " \"\"\"Print a Fibonacci series up to n.\n", "\n", " argument\n", " n: numeric number\n", "\n", " vaule\n", " return Fibonacci series\n", " \"\"\"\n", " a, b = 0, 1\n", " while a < n:\n", " print(a, end=' ')\n", " # better than print(a), why?\n", " a, b = b, a+b" ] }, { "cell_type": "code", "execution_count": 9, "id": "6ab7067f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 1 2 3 5 8 " ] } ], "source": [ "fib(10)" ] }, { "cell_type": "code", "execution_count": 10, "id": "ecb0a1c0", "metadata": {}, "outputs": [], "source": [ "import feng" ] }, { "cell_type": "code", "execution_count": 11, "id": "53d9b21d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 1 2 3 5 8 13 21 34 55 89 " ] } ], "source": [ "feng.fib(100)" ] } ], "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.10.8" }, "rise": { "auto_select": "first", "autolaunch": false, "enable_chalkboard": true, "start_slideshow_at": "selected", "theme": "black" } }, "nbformat": 4, "nbformat_minor": 5 }