9  Functions

9.1 Define a Function

def greet():
  """Greeeting"""
  print("Hello World")
greet()
#> Hello World

9.2 Arguments

Terminology: key = value

  • Parameters are like key
  • Arguments are like value that supply to the parameters
def greet(first, last):
  """Greeeting someone"""
  print(f"Hello {first} {last}")
  print("Welcome aboard!")

Parameters = first, last

greet("Ada", "Lovelace")
#> Hello Ada Lovelace
#> Welcome aboard!
# Using Keyword args
greet(first = "Mary",last="John")
#> Hello Mary John
#> Welcome aboard!

Default parameter must come after required parameter

def increment(x, by = 1):
  return x + by
increment(2)
#> 3
increment(2, 2)
#> 4

Arguments = “Ada”, “Lovelace”

9.2.1 Args Type Hint

For Python 3.9 and earlier:

from typing import Union, List

def num_or_list(x: Union[float, List[float]]) -> None:
    if isinstance(x, float):
        print("x is float")
    elif isinstance(x, list):
        print("x is list")

For Python 3.10 and later:

def num_or_list(x: float | list[float]) -> None:
    if isinstance(x, float):
        print("x is float")
    elif isinstance(x, list):
        print("x is list")

9.3 Return

return a value with return statement

def get_greet(name):
  return f"Hello {name}"
print(get_greet("mom"))
#> Hello mom

By default function return None, if not provide return value.

def myfun():
  print("Hi")
print(myfun())
#> Hi
#> None

9.4 Scoping

Note

Variables are scoped at the function level

This is similar to R.

# Global Var
name, age = "Joy", 10
def greet(name = "mark"):
  age = 20
  return {"name": name, "age": age}
greet()
#> {'name': 'mark', 'age': 20}
name
#> 'Joy'
age
#> 10

9.5 xargs

use *args to receives any number of arguments to the function.

Ref: official doc

def multi(*numbers):
  return numbers

 
a = multi(1, 3)
a
#> (1, 3)
type(a)
#> <class 'tuple'>

xargs is a tuple. Let’s iterate over “tuple”

def multi(*numbers):
  for number in numbers:
    print(number)

    

Must be positional argument only

multi(1, 2, 3)
#> 1
#> 2
#> 3

keyword args is not allowed

multi(a = 1)
#> TypeError: multi() got an unexpected keyword argument 'a'

9.5.1 Exercise

Let’s multiply any input of numbers.

def multiply(*numbers):
  total = 1
  for number in numbers:
    total *= number
  return(total)
multiply(2, 3, 4)
#> 24

Same logic using R

multiply_r1 <- function(...) {
  
  numbers <- list(...)
  total <- 1
  for (number in numbers) {
    total <- total * number
  }
  total
}

multiply_r1(1, 2, 3)
#> [1] 6

Or using R functional programming by base::Reduce() or purrr::reduce()

multiply_r2 <- function(...) Reduce(`*`, list(...))

multiply_r2(1, 2, 3)
#> [1] 6

9.6 xxargs

Use **args to capture any number of keyword arguments as dictionary.

def save_user(**user):
  return user
usr = save_user(id = 1, name = "mike")
usr
#> {'id': 1, 'name': 'mike'}
type(usr)
#> <class 'dict'>
usr["id"]
#> 1
usr["name"]
#> 'mike'

If supply positional arg will fail.

save_user("mike")
#> TypeError: save_user() takes 0 positional arguments but 1 was given