Introduction to Biostatistical Computing PHC 6937

functions and modules

Zhiguang Huo (Caleb)

Monday Oct 24th, 2022

Outlines

Writing Basic Python functions

def hello():
    print('Hello World!')

hello()
## Hello World!
def hello(name):
    print('Hello, ' + name + "!")

hello("Lucas")
## Hello, Lucas!

Function Descriptions and Helps

def inc(x): 
  """Increase by one
  
  Keyword arguments:
  x -- the base number to be increased
  """
  return x + 1

inc(3)
## 4
inc.__doc__ ## check docstring
## 'Increase by one\n  \n  Keyword arguments:\n  x -- the base number to be increased\n  '
?inc
help(inc)

Function structure

Recursive function

def factorial(n):
    result = n
    for i in range(1,n):
        result *= i
    return result

factorial(5)
## 120
def factorial(n):
    if n==1: return 1
    return n*factorial(n-1)

factorial(5)
## 120

In class exercise

def fibonacci(n):
    if(n<=1):
        return(1)
    else:
        return(fibonacci(n-1) + fibonacci(n-2))

fibonacci(4)
## 5
fibonacci(5)
## 8

Some built-in Python functions

abs(-4)
## 4
pow(2,3)
## 8
round(3.14)
## 3
max(6,9)
## 9
min([1,2,3,7])
## 1
sum(range(10))
## 45
help(sum)
## Help on built-in function sum in module builtins:
## 
## sum(iterable, /, start=0)
##     Return the sum of a 'start' value (default: 0) plus an iterable of numbers
##     
##     When the iterable is empty, return the start value.
##     This function is intended specifically for use with numeric values and may
##     reject non-numeric types.
?sum ## this way only works for Jupyter Notebook

Module

def hello(name):
    print('Hello ' + name + '!')
def myadd(a, b):
    return(a + b)
import mymod

mymod.hello("Lucas")
## Hello Lucas!
mymod.myadd(1, 10)
## 11

Module

Student1 = {
  "name": "Amy",
  "age": "23",
  "country": "Canada"
}
import mymod

astudent = mymod.Student1
print(astudent)
## {'name': 'Amy', 'age': '23', 'country': 'Canada'}
for akey in astudent:
        print(akey + ": " + astudent[akey])
## name: Amy
## age: 23
## country: Canada

math modules

After import module, all the objects in the module are available via module.object

import math

math.sqrt(3)
## 1.7320508075688772
math.floor(10.4)
## 10
math.ceil(10.4)
## 11
math.log(16,2)
## 4.0
math.log2(16)
## 4.0
math.pi
## 3.141592653589793

math modules

import math as m
m.pi
## 3.141592653589793
from math import pi
pi
## 3.141592653589793
from math import pi, log2
log2(pi)
## 1.6514961294723187

os module

import os
cwd = os.getcwd() ## get current working directory
print("Current working directory is " + cwd)
## Current working directory is /Users/zhuo/Dropbox (UFL)/teaching/2022FALL/lectures/Week10_functions/functions
os.listdir() 
## os.listdir(cwd)  same as this one
## ['.Rhistory', 'functions.py', 'functions.rmd', 'my_file.txt', 'new_file.txt', 'functions.html', '__pycache__', 'foo', 'functions', '.ipynb_checkpoints', 'mymod.py', 'tmp']
os.chdir('..') ## go back one folder
os.getcwd()
## '/Users/zhuo/Dropbox (UFL)/teaching/2022FALL/lectures/Week10_functions'
os.chdir(cwd) ## go back to cwd
os.getcwd()
## '/Users/zhuo/Dropbox (UFL)/teaching/2022FALL/lectures/Week10_functions/functions'
os.mkdir("tmp") ## create a single folder
os.makedirs("foo/bar")  ## create a recursive folder
os.remove(afile) ## remove afile
os.rmdir(afolder) ## remove a folder
file = 'Untitled.ipynb'
      
# File location 
location = "/Users/zhuo/Desktop/" ## change this to your own directory
os.listdir(location)
      
# Path 
## ['.Rhistory', 's41592-021-01252-x.pdf', '.DS_Store', '.localized', 'sellingPoints.txt', 'shiny-examples', 'others', 'circadianWebsite', 'reference.pdf', 'env', 'bbaa257.pdf', 'test2022', 'update_20220401.txt']
path = os.path.join(location, file) 
print(path)
## /Users/zhuo/Desktop/Untitled.ipynb
os.path.exists(location) 
## True
os.path.exists(path) 
## False
os.path.isfile(path) 
## False
os.path.isdir(location) 
## True

random module

import random

print(random.random())
## 0.5228940589963078
random.seed(10)
print(random.random())
## 0.5714025946899135
random.seed(10)
print(random.random())
## 0.5714025946899135

random integer

print(random.randint(1, 3))
## 2
print(random.randrange(1, 3))
## 2

random choices and shuffle

mylist = ["apple", "banana", "cherry"]
random.choice(mylist)
## 'cherry'
random.choices(mylist, k = 2)
## ['apple', 'banana']
random.shuffle(mylist)
mylist
## ['apple', 'cherry', 'banana']

Default arguments

def add(arg1 = 1, arg2 = 2):   
    return(arg1 + arg2)

add(arg1 = 3, arg2 = 4)
## 7
add(arg1 = 3)
## 5
add()
## 3

Function arguments matching rule

def parrot(voltage, state='a stiff', action='voom'):
    print("-- This parrot wouldn't", action, end=' ') ## end will switch from a new line to a whitespace
    print("if you put", voltage, "volts through it.")
    print("-- It's", state, "!")
parrot(1000)                                          # 1 positional argument
## -- This parrot wouldn't voom if you put 1000 volts through it.
## -- It's a stiff !
parrot(voltage=1000)                                  # 1 keyword argument
## -- This parrot wouldn't voom if you put 1000 volts through it.
## -- It's a stiff !
parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
## -- This parrot wouldn't VOOOOOM if you put 1000000 volts through it.
## -- It's a stiff !

additional matching rules

def parrot(voltage, state='a stiff', action='voom'):
    print("-- This parrot wouldn't", action, end=' ') ## end will switch from a new line to a whitespace
    print("if you put", voltage, "volts through it.")
    print("-- It's", state, "!")
parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
## -- This parrot wouldn't VOOOOOM if you put 1000000 volts through it.
## -- It's a stiff !
parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
## -- This parrot wouldn't jump if you put a million volts through it.
## -- It's bereft of life !
parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword
## -- This parrot wouldn't voom if you put a thousand volts through it.
## -- It's pushing up the daisies !

Extra arguments

def add(a,b):
  return(a + b)
def add(a,b,c,d):
  return(a + b + c + d)

Extra arguments

def print_args(*args):
    print(args)

print_args('Testing') ## tuple of length 1
## ('Testing',)
print_args(1,2,3)
## (1, 2, 3)
def print_args_2(title, *args):
    print(title)
    print(args)

print_args_2("Args:", 1,2,3)
## Args:
## (1, 2, 3)
print_args_2("Nothing:")
## Nothing:
## ()

In class exercise

add(1,2,3,4,5) # 15
add(1,2,3,4,5,6,7,8,9,10) # 55
def add(*args):
    print(type(args)) ## the input args forms a tuple
    sum = 0
    for n in args:
        sum += n
    return sum

add(1,2,3,4,5) # 15
## <class 'tuple'>
## 15
add(1,2,3,4,5,6,7,8,9,10) # 55
## <class 'tuple'>
## 55

Extra keywords

def print_keywords_3(**keywords):
    print(keywords)

print_keywords_3(x=1,y=2,z=3)
## {'x': 1, 'y': 2, 'z': 3}
def print_keywords_4(**keywords):
    for kw in keywords:
        print(kw, ":", keywords[kw])
print_keywords_4(x=1,y=2,z=3)
## x : 1
## y : 2
## z : 3
def print_params_4(x,y,z=3,*pospar, **keypar):
    print(x,y,z)
    print(pospar)
    print(keypar)

print_params_4(x=1,y=2)
## 1 2 3
## ()
## {}
print_params_4(1,2,3,5,6,7,foo=1)
## 1 2 3
## (5, 6, 7)
## {'foo': 1}

Assertion

assert expression[, assertion_message]
number = 1 ## try -1 as well
assert number > 0
assert number > 0, f"number greater than 0 expected, got: {number}"

Lambda function

def f1(x):
    return(x + 10)

f1(5)
## 15
f2 = lambda x : x + 10

f2(5)
## 15
(lambda x : x + 10)(5)
## 15

Lambda function with more than 1 argument

def f3(a,b):
  return(a*b)

f3(5,6)
## 30
f4 = lambda a, b : a * b
print(f4(5, 6))
## 30

Function scopes

x = 300

def afun():
  print(x)

afun()
## 300
print(x)
## 300

Function scopes

x = 300

def afun():
  x = 200
  print(x)

afun()
## 200
print(x)
## 300

Function scopes

def bfun():
  global x
  x = 50

bfun()
print(x)
## 50
x = 50

def bfun():
  global x
  x = 60

bfun()
print(x)
## 60

Multiple return values

def f23(x):
    x_square = x**2
    x_cubic = x**3
    res_tuple = (x_square, x_cubic)
    return(res_tuple)

f23(3)
## (9, 27)
a, b = f23(5)
print(a)
## 25
print(b)
## 125

Other looping technique

d = ["a", "b", "c"]
e = [1, 2, 3]

zip(d,e)
## <zip object at 0x110958980>
list(zip(d,e))
## [('a', 1), ('b', 2), ('c', 3)]
for i, j in zip(d,e):
    print(i + str(j))
## a1
## b2
## c3
for index, string in enumerate(d):
    print(string + str(index))
## a0
## b1
## c2

list comprehension

squares = []
for x in range(10):
    squares.append(x**2)

squares
## [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[x**2 for x in range(10)]
## [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

list comprehension

[(i,j) for i in range(3) for j in range(3)]
## [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
[i for i in range(10) if i%2==0 ]
## [0, 2, 4, 6, 8]
names = ["Amy", "Beth", "Carl"]
[aname[0] for aname in names]
## ['A', 'B', 'C']

list comprehension for dictionary

names = ["Amy", "Beth", "Carl", "Dan", "Emily", "Frank"]

import random

students_scores = {name: random.randint(0, 100) for name in names}

students_scores
## {'Amy': 83, 'Beth': 20, 'Carl': 4, 'Dan': 66, 'Emily': 62, 'Frank': 41}

Install new packages

pip install packages

python -m pip install numpy
>>> import numpy as np ## test if the package has been installed in python
python3 -m pip install numpy==1.23 ## specifying a package version
python3.9 -m pip install --upgrade numpy ## upgrade a package
pip install numpy --user ## if you are not a admin
py -3 -m pip install numpy
>>> import numpy as np ## test if the package has been installed in python
py -3 -m pip install numpy==1.23 ## specifying a package version
py -3 -m pip install --upgrade numpy ## upgrade a package
py -3 -m pip install numpy --user ## if you are not a admin

conda install packages

conda install numpy
conda install numpy=1.16
conda list --name numpy conda ## check current installed version
conda update numpy

Python environment (using conda)

conda create -n myenv
## conda create -n myenv python=3.9 ## create an environment with a specific Python version.
conda activate myenv ## activate the environment
conda info --envs ## list all environment
conda install -n myenv scipy=0.17.3
python ## open python with this environment
conda deactivate

Python environment (using pip)

Reference