> For the complete documentation index, see [llms.txt](https://igb.mit.edu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://igb.mit.edu/mini-courses/python/introduction-to-python-for-biologists/functions.md).

# Functions

### Functions are like machines

<figure><img src="https://498238201-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWuHhstIreJ3jFvE4gQ3y%2Fuploads%2FrElzZm4JUqrw9rVxKdsH%2Fimage.png?alt=media&amp;token=9e95eec2-278b-4b10-a18a-830af41b45b4" alt="" width="188"><figcaption></figcaption></figure>

<figure><img src="https://498238201-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWuHhstIreJ3jFvE4gQ3y%2Fuploads%2Fbliejfc0ADN6JbARUAYb%2Fimage.png?alt=media&amp;token=cd9048d8-ddbd-4408-8aa3-21d2a9bb9b7e" alt=""><figcaption></figcaption></figure>

* Learning to write your own functions will greatly increase the complexity of the programs that you can write
* A function is a black box-it takes some input,does something with it, and spits out some output
* Functions hide details away, allowing you to solve problems at a higher level without getting bogged down

### Examples

* A typical function looks like this:

```
def function_name(function_arguments)
   """optional string decribing the function"""
   statements ...
   return result
```

<br>

* A function example: sum

```
In [1]: numbers=[1,2,3,4,5]

In [2]: sum(numbers)
Out[2]: 15

```

<br>

* Anatomy of sum function

```
1.initialize the sum to zero
2.loop over each number while adding the number to the sum variable
3.return the value of sum

def sum(xs):
   """Given a sequence of numbers, return the sum."""
   s=0
   for x in xs:
      s=s+x
   return s

```

<br>

* Writing your own function

```
Open a text editor, type the following and save it as MyMathFunctions.py:
def mysum(numbers):
        """Given a sequence of numbers, return the sum"""
        s=0
        for x in range(numbers):
                s=s+x
        return s

def myproduct(numbers):
        """Given a sequence of numbers, return the product"""
        p=1
        for x in range(numbers):
                p=p*x
        return p
```

<br>

* Importing a function from a file (module)
  * Once we import `MyMathFunctions` module we just wrote, we can use the `mysum` function and `myproduct` function just like the built-in function
  * The way to call a function is to give the function name followed by parenthesis with values for the number of arguments expected

```
In [1]: import MyMathFunctions

In [2]: numbers=[1,2,3,4]

In [3]: MyMathFunctions.mysum(numbers)
Out[3]: 10

In [4]: MyMathFunctions.myproduct(numbers)
Out[4]: 24

```

```
Too many typing strokes? Try the following:

In [5]: import MyMathFunctions as f

In [6]: f.mysum(numbers)
Out[6]: 10

```

```
Still too many typing strokes? Try the following:
In [7]: import MyMathFunctions

In [8]: a=MyMathFunctions.mysum

In [9]: a(numbers)
Out[9]: 10

```

* Function arguments
  * We can define functions with more than one arguments

```
Example: restrcition.py
def finder(DNA,enzyme):
        db={}
        name=['ECOR1','BAMH1','HINDIII']
        site=['GAATTC','GGATCC','AAGCTT']
        db=dict(zip(name,site))
        DNA=DNA.upper()
        enzyme=enzyme.upper()
        index=DNA.find(db[enzyme])
        if (index>-1):
                print ("The restriction site starts at base pair %d\n" %index)
        else:
                print ("No such restriction site\n")

In [1]: import restriction
In [2]: restriction.finder('ATGGAATTCCGT','EcoR1')
The restriction site starts at base pair 3

In [3]: restriction.finder('ATGGAATTCCGT','BamH1')
No such restriction site

```

* Arguments with default values do not need to be supplied when calling a function. But if provided, will overwrite the default values

```
Example: restrcition_BamH1_default.py
def finder(DNA,enzyme='BamH1'):
        db={}
        name=['ECOR1','BAMH1','HINDIII']
        site=['GAATTC','GGATCC','AAGCTT']
        db=dict(zip(name,site))
        DNA=DNA.upper()
        enzyme=enzyme.upper()
        index=DNA.find(db[enzyme])
        if (index>-1):
                print ("The restriction site starts at base pair %d" %index)
        else:
                print ("No such restriction site\n")

In [1]: import restriction_BamH1_default

In [2]: restriction_BamH1_default.finder('ATGGAATTCCGT')
No such restriction site


In [3]: restriction_BamH1_default.finder('ATGGAATTCCGT','Ecor1')
The restriction site starts at base pair 3
```

* Some existing Python modules
  * The `os` module provides a platform independent way to work with the operating system, make or remove files and directories
  * The `csv` module provides readers and writers for comma separated value data
  * The `sys` module contains many objects and functions for dealing with how python was complied or called when executed
  * The `glob` module proves the `glob` function to perform file globbing similar to what the unix shell provides
  * The `math` module provides common algebra and trigonometric function along with several math constants
  * The `re` module provides access to powerful regular expression
  * The `datetime` module provides time and datetime objects. allowing easy comparison of times and dates
  * The `time` module provides simple estimates for how long a command takes
  * The `pickle` module provides a way to save python objects to a file that you can unpickle later in a different program
  * The `pypi` module helps package installation
  * The `numpy` module is the de facto standard for numerical computing
  * The `pandas` module is useful for tabular data managing
  * The `matplotlib` module is the most frequently used plotting package in Python
  * The `seaborn` module is a module based on `matplotlib`. It provides a high-level interface for drawing attractive graphics.
