DS2000 (Spring 2019, NCH) :: Lecture 4b

0. Administrivia

  1. Due today @ 9pm: HW3 (submit via Blackboard)
  2. Due before Monday's lecture: pre-class quiz (via Blackboard; feel free to use book/notes/Python)
  3. Due next Friday @ 9pm: HW4 (submit via Blackboard)

1. Problem: Normalize Data

Given a list of numbers, return L1-normalized data (each data point divided by the sum of the absolute value of all the data points: $ \frac{x_i}{\sum_j |x_j|} $) and the normalization factor.

In [2]:
def l1_norm(nums):
    sum = 0
    
    for num in nums:
        sum += abs(num) # note: NOT allowed in HW!
        
    return sum

def l1_normalize(nums):
    norm = l1_norm(nums)
    result = []
    
    for num in nums:
        result.append(num / norm)
        
    return result, norm

print(l1_normalize([60, 20, 20]))
print(l1_normalize([1, 2, 3, 4, 5]))
([0.6, 0.2, 0.2], 100)
([0.06666666666666667, 0.13333333333333333, 0.2, 0.26666666666666666, 0.3333333333333333], 15)

2. Problem: Keep-If

Given a list and a function, return the subset of the input list for which the function returns true (i.e. filter).

In [3]:
def is_vowel(c):
    return c in ('a', 'e', 'i', 'o', 'u')

def is_even(num):
    return num % 2 == 0

def keep_if(pred, l):
    result = []
    for element in l:
        if pred(element):
            result.append(element)
    return result

print(keep_if(is_even, [1, 2, 3, 4, 5]))
print(keep_if(is_vowel, 'hello there!'))
[2, 4]
['e', 'o', 'e', 'e']

2a. Challenge: Invert Predicate

Given a function, return a function that does the opposite!

In [4]:
def invert_pred(p):
    def f(x):
        return not p(x)
    
    return f

print(keep_if(invert_pred(is_even), [1, 2, 3, 4, 5]))
print(keep_if(invert_pred(is_vowel), 'hello there!'))
[1, 3, 5]
['h', 'l', 'l', ' ', 't', 'h', 'r', '!']

3. Problem: Longest

Given a list of strings, return a list of those strings that have the most characters (i.e. max).

In [5]:
def longest(words):
    if len(words) == 0:
        return []
    
    first_word = words[0]
    big_len = len(first_word)
    result = [first_word]
    
    for i in range(1, len(words)):
        word = words[i]
        word_len = len(word)
        
        if word_len == big_len:
            result.append(word)
        elif word_len > big_len:
            result = [word]
            big_len = word_len
    
    return result

print(longest(['a', 'b', '']))
print(longest(['hello', 'howdy', 'hi', 'yo']))
['a', 'b']
['hello', 'howdy']

4. Problem: Number -> Grade

Given a numeric grade and a rubric (sorted list, from smallest to greatest grade), output resulting grade.

In [6]:
PF = (
    (0, 'Fail'),
    (60, 'Pass')
)

ABCDF = (
    (0, 'F'),
    (60, 'D'),
    (70, 'C'),
    (80, 'B'),
    (90, 'A'),
)

def number_to_grade(rubric, numeric):
    grade = rubric[0][1]
    
    for i in range(1, len(rubric)):
        if numeric >= rubric[i][0]:
            grade = rubric[i][1]
    
    return grade

print(number_to_grade(PF, 50))
print(number_to_grade(ABCDF, 50))

print(number_to_grade(PF, 60))
print(number_to_grade(ABCDF, 60))

print(number_to_grade(PF, 75))
print(number_to_grade(ABCDF, 75))

print(number_to_grade(PF, 93))
print(number_to_grade(ABCDF, 93))
Fail
F
Pass
D
Pass
C
Pass
A