Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Functions

Built in Functions

print(type(len))

import numpy as np
print(type(np.linspace))
<class 'builtin_function_or_method'>
<class 'numpy._ArrayFunctionDispatcher'>

Custom Function

def greet(name):
    return f"Hello, {name}!"

print(greet("Alice"))
Hello, Alice!
n = 42

def func():
    global n
    print(f'Within function: n is {n}')
    n = 3
    print(f'Within function: change n to {n}')

func()
print(f'Outside function: Value of n is {n}')
Within function: n is 42
Within function: change n to 3
Outside function: Value of n is 3

Nested Functions

import math

def my_dist_xyz(x, y, z):
    """
    x, y, z are 2D coordinates contained in a tuple
    output:
    d - list, where
        d[0] is the distance between x and y
        d[1] is the distance between x and z
        d[2] is the distance between y and z
    """
    
    def my_dist(x, y):
        """
        subfunction for my_dist_xyz
        Output is the distance between x and y, 
        computed using the distance formula
        """
        out = math.sqrt((x[0]-y[0])**2+(x[1]-y[1])**2)
        return out
    
    d0 = my_dist(x, y)
    d1 = my_dist(x, z)
    d2 = my_dist(y, z)
    
    return [d0, d1, d2]
d = my_dist_xyz((0, 0), (0, 1), (1, 1))
print(d)
d = my_dist((0, 0), (0, 1)) 
[1.0, 1.4142135623730951, 1.0]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[10], line 3
      1 d = my_dist_xyz((0, 0), (0, 1), (1, 1))
      2 print(d)
----> 3 d = my_dist((0, 0), (0, 1)) 

NameError: name 'my_dist' is not defined

Here my_dist is a nested function, and so it’s not defined outside of my_dist_xyz.

Lambda Functions

The syntax for a lambda function is:

lambda arguments: expression
square = lambda x: x**2

print(square(2))
print(square(5))
4
25

EXAMPLE: Sort [(1, 2), (2, 0), (4, 1)] based on the 2nd item in the tuple.

sorted([(1, 2), (2, 0), (4, 1)], key=lambda x: x[1])
[(2, 0), (4, 1), (1, 2)]
# Lambda functions
square = lambda x: x**2
print(square(5))

# Using lambda with map, filter, sort
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)

# Filter even numbers
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)

# Sort by custom key
students = [("Alice", 85), ("Bob", 90), ("Charlie", 78)]
students.sort(key=lambda x: x[1])  # Sort by grade
print(students)
25
[1, 4, 9, 16, 25]
[2, 4]
[('Charlie', 78), ('Alice', 85), ('Bob', 90)]

Recursion

def fibonacci_display(n):
    """Computes and returns the Fibonacci of n, 
    a postive integer.
    """
    if n == 1: # first base case
        out = 1
        print(out)
        return out
    elif n == 2: # second base case
        out = 1
        print(out)
        return out
    else: # Recursive step
        out = fibonacci_display(n-1)+fibonacci_display(n-2)
        print(out)
        return out # Recursive call 
    
fibonacci_display(5)
1
1
2
1
3
1
1
2
5
5

Divide and conquer (Bonus)

Check the next section, “Condition & Loops”, if you don’t know about their syntax. For now, let’s focus on the function itself.

Tower of Hanoi

def my_towers(N, from_tower, to_tower, alt_tower):
    """
    Displays the moves required to move a tower of size N from the
    'from_tower' to the 'to_tower'. 
    
    'from_tower', 'to_tower' and 'alt_tower' are uniquely either 
    1, 2, or 3 referring to tower 1, tower 2, and tower 3. 
    """
    
    if N != 0:
        # recursive call that moves N-1 stack from starting tower
        # to alternate tower
        my_towers(N-1, from_tower, alt_tower, to_tower)
        
        # display to screen movement of bottom disk from starting
        # tower to final tower
        print("Move disk %d from tower %d to tower %d."\
                  %(N, from_tower, to_tower))
        
        # recursive call that moves N-1 stack from alternate tower
        # to final tower
        my_towers(N-1, alt_tower, to_tower, from_tower)

my_towers(3, 1, 3, 2)  # Move a tower of size 3 from tower 1 to tower 3 using tower 2 as an auxiliary
Move disk 1 from tower 1 to tower 3.
Move disk 2 from tower 1 to tower 2.
Move disk 1 from tower 3 to tower 2.
Move disk 3 from tower 1 to tower 3.
Move disk 1 from tower 2 to tower 1.
Move disk 2 from tower 2 to tower 3.
Move disk 1 from tower 1 to tower 3.

Quick Sort

def my_quicksort(lst):
    
    if len(lst) <= 1:
        # list of length 1 is easiest to sort 
        # because it is already sorted
        
        sorted_list = lst    
    else:
        
        # select pivot as teh first element of the list
        pivot = lst[0]
        
        # initialize lists for bigger and smaller elements 
        # as well those equal to the pivot
        bigger = []
        smaller = []
        same = []
        
        # loop through list and put elements into appropriate array
        
        for item in lst:
            if item > pivot:
                bigger.append(item)
            elif item < pivot:
                smaller.append(item)
            else:
                same.append(item)
        
        sorted_list = my_quicksort(smaller) + same + my_quicksort(bigger)
        
    return sorted_list

# Example usage
unsorted_list = [3, 6, 8, 10, 1, 2, 1]
sorted_list = my_quicksort(unsorted_list)
print(sorted_list)  # Output: [1, 1, 2, 3, 6, 8, 10]
[1, 1, 2, 3, 6, 8, 10]