{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from __future__ import print_function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So far, our scripts have been simple, single-use code blocks.\n", "One way to organize our Python code and to make it more readable and reusable is to factor-out useful pieces into reusable *functions*.\n", "Here we'll cover two ways of creating functions: the ``def`` statement, useful for any type of function, and the ``lambda`` statement, useful for creating short anonymous functions.\n", "\n", "Functions are used to organize program flow, especially to allow us to easily do commonly needed tasks over and over again. We've already used a lot of functions, such as those that work on lists (`append()` and `pop()`) or strings (like `replace()`). Here we see how to write our own functions. If you are familiar will matlab you will find functions very similar." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A function takes arguments, listed in the `()` and returns a value. Even if you don't explictly give a return value, one will be return (e.g., `None`). \n", "\n", "Here's a simple example of a function that takes a single argument, `i`" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello\n" ] } ], "source": [ "a = print(\"Hello\")\n", "a\n", "# print(type(a))\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Defining Functions\n", "Functions become even more useful when we begin to define our own, organizing functionality to be used in multiple places.\n", "In Python, functions are defined with the ``def`` statement." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "in the function, i = 10\n", "in the function, i = 5\n", "Help on function my_fun in module __main__:\n", "\n", "my_fun(i)\n", " input:\n", " i integer\n", " output:\n", " None\n", " Use:\n", "\n", "in the function, i = 10\n" ] } ], "source": [ "def my_fun(i):\n", " \"\"\" input:\n", " i integer\n", " output:\n", " None\n", " Use: \"\"\"\n", " print(\"in the function, i = {}\".format(i))\n", " \n", "my_fun(10)\n", "my_fun(5)\n", "help(my_fun)\n", "a = my_fun(10)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = my_fun(0)\n", "print(a)\n", "print(type(a))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "functions are one place where _scope_ comes into play. A function has its own _namespace_. If a variable is not defined in that function, then it will look to the namespace from where it was called to see if that variable exists there. \n", "\n", "However, you should avoid this as much as possible (variables that persist across namespaces are called global variables).\n", "\n", "We already saw one instance of namespaces when we imported from the `math` module." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-----\n", "----------\n" ] } ], "source": [ "global_var = 10\n", "\n", "def print_fun(string, n):\n", " \"\"\" \"\"\"\n", " if n < global_var:\n", " print(string*n)\n", " else:\n", " print(string*global_var)\n", "\n", "print_fun(\"-\", 5)\n", "print_fun(\"-\", 20)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "global_var = 100" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] } ], "source": [ "print_fun(\"-\",50)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default, python will let you read from a global, but not update it." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "in function outer = -100.0\n", "outside, outer = 1.0\n" ] } ], "source": [ "outer = 1.0\n", "\n", "def update():\n", " # uncomment this to allow us to access outer in the calling namespace\n", " # global outer\n", " outer = -100.0\n", " print(\"in function outer = {}\".format(outer))\n", " \n", "update()\n", "print(\"outside, outer = {}\".format(outer))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "functions always return a value—if one is not explicitly given, then they return None, otherwise, they can return values (even multiple values) of any type" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "in the function, i = 10\n", "None\n" ] } ], "source": [ "a = my_fun(10)\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's a simple function that takes two numbers and returns their product." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12\n" ] } ], "source": [ "def multiply(a, b):\n", " return a*b\n", "\n", "c = multiply(3, 4)\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "