""" 
A module with just the functions for insertion sort.

You can run this by typing "python insertion_sort.py" on the command line.

Author: Walker M. White (wmw2), Anne Bracy (awb93)
Date:   May 3, 2018
"""

# HELPER FUNCTIONS
def swap(b, h, k):
    """
    Procedure swaps b[h] and b[k]
    
    Parameter b: The list to rearrange
    Precondition: b is a mutable sequence (e.g. a list).
    
    Parameter h: The first position to swap
    Precondition: h is an int and a valid position in b
    
    Parameter k: The second position to swap
    Precondition: k is an int and a valid position in b
    """
    # We typically do not enforce preconditions on hidden helpers
    temp = b[h]
    b[h] = b[k]
    b[k] = temp

def push_down(b, k):
    """
    Moves the value at position k into its sorted position in b[0.k-1].
    
    Parameter b: The list to rearrange
    Precondition: b is a list, with b[0..k-1] sorted
    
    Parameter k: The position to push down into b[0..k-1]
    Precondition: k is an int and a valid position in b
    """
    # We typically do not enforce preconditions on hidden helpers

    # Start from position k
    j = k

    # inv: b[j..k] is sorted
    while j > 0:
        if b[j-1] > b[j]:
            swap(b,j-1,j)
        j = j - 1
    # post: b[0..k] is sorted     

def insertion_sort(b):
    """
    Insertion Sort: Sorts the array b in n^2 time
    
    Parameter b: The sequence to sort
    Precondition: b is a mutable sequence (e.g. a list).
    """
    assert type(b) == list, repr(b)+' is not a list'
    
    # Start from beginning of list
    i = 0
    
    # inv: b[0..i-1] sorted    
    while i  < len(b):
        push_down(b,i)
        i = i + 1
    
    # post: b[0..len(b)-1] sorted

my_list = [2,4,6,2,6,9,8,2,3]
print("list before:")
print(my_list)
insertion_sort(my_list)
print("list after insertion-sorting:")
print(my_list)