Section #5 Solutions

May 10th, 2020

Written by Brahm Capoor, Juliette Woodrow, Peter Maldonado, Kara Eng, Tori Qiu and Parth Sarin

Lists Review: Compatibility Calculations

def in_common(l1, l2):
	num_in_common = 0
	total_elem = len(l1) + len(l2)
	for i in range(len(l1)):
		if l1[i] in l2:
			num_in_common += 1

	return num_in_common / total_elem

def calc_score(netflix_history1, netflix_history2, fav_books1, fav_books2):
	netflix_score = in_common(netflix_history1, netflix_history2)
	book_score = in_common(fav_books1, fav_books2)
	return netflix_score + book_score

def new_friend(name_list, compatability_scores):
	best_score = -1
	best_friend = None 

	for i in range(len(compatability_scores)):
		compatability_score = compatability_scores[i]
		if compatability_score > best_score: # we could make this >= as well
			best_score = compatability_score
			best_friend = name_list[i]

Nested Lists & Grids

Enumerating a list

def enumerate(lst):
    enum_lst = []
    for i in range(len(lst)):
        enum_lst.append([i, lst[i]])
    return enum_lst

Matrix Math

def matrix_constant_multiply(c, m):
    prod_matrix = []

    for row in m:
        new_row = []
        for elem in row:
            new_row.append(elem * c)
    return prod_matrix

def matrix_add(m1, m2):
    sum_matrix = []

    for row_idx in range(len(m1)):
        new_sum_row = []

        row = m1[row]
        for col_idx in range(len(row)):
            sum_elem = m1[row_idx][col_idx] + m2[row_idx][col_idx]
    return sum_matrix

Times Table

def make_times_table(m, n):
    times_table = []

    for i in range(m):
        row_num = i + 1
        new_row = []
        for j in range(n):
            col_num = j + 1
            new_row.append(row_num * col_num)

    return times_table


String Slicing

  1. s[1:6]
  2. s[:2] or s[0:2]
  3. s[6:9]
  4. s[6:] or s[6:10]
  5. s[6] or s[6:7]
  6. s[:] or s[0:10] (or just s)

String Construction

def only_one_first_char(s):
	if s == "":
		return ""

	first_char = s[0]
	output = first_char
	for i in range(1, len(s)):
		if(s[i] != first_char):
			output += s[i]

	return output

def make_gerund(s):

	#if it already ends in ing, add an 'ly' instead 
	if len(s) >= 3 and s[len(s)-3:] == 'ing':
		s = s[0:len(s)-3] + 'ly'
		s = s + 'ing'

	return s

def put_in_middle(outer, inner):
	middle = len(outer) // 2
	return outer[0:middle] + inner + outer[middle:]


Word Puzzles

def is_tridrome(word):
    Returns whether or not word is a tridrome, i.e., the first three letters
    are the same as the last three letters.

        word -- The word to check

    >>> is_tridrome('ENTERTAINMENT')
    >>> is_tridrome('UNDERGROUND')
    >>> is_tridrome('DEFENESTRATION')
    >>> is_tridrome('PYTHON')
    >>> is_tridrome('')

    We need to check that
    1. the word is at least six letters, and
    2. the first three letters of the word are the same as the last three 

    To check the first condition, we check if
        len(word) >= 6

    For the second condition, we can extract the first three letters of the 
    word with word[:3] and the last three with word[-3:]. If negative indexing
    isn't comfortable, the last three letters of the word can also be sliced
    with word[len(word)-3:]!

    In Python, we can combine these two conditions using the `and` keyword,
    which short-circuits (i.e., if the first condition is false, it doesn't
    check the second condition).

    This leads to the rather nice one-line solution:
    return len(word) >= 6 and word[:3] == word[-3:]


def is_peaceful(word):
    Returns whether a word is peaceful, i.e., whether its letters appear in
    sorted order.

        word -- The word to check
    >>> is_peaceful('ABORT')
    >>> is_peaceful('FIRST')
    >>> is_peaceful('')
    >>> is_peaceful('PYTHON')
    >>> is_peaceful('CHOCOLATE')

    Python provides a really nice `sorted` function that can sort collections.
    It returns a list, and you can turn a list into a string by joining together
    its elements with a string:

    We can, therefore, get a nice one-line solution with:
    # return word == ''.join(sorted(word))

    Or, you might prefer the iterative solution, using string comparisons to 
    check if a character is >= the next character (Python lets you compare 
    strings alphabetically!):
    # for i in range(len(word) - 1): # don't check the last letter
    #     if word[i] >= word[i+1]:
    #         return False
    # return True

    And finally, we can use a creative application of the `.find` function to 
    obtain a character's position in the alphabet:
    for i in range(len(word) - 1): # don't check the last letter
        We search for the character in ALPHABET. 
        curr_letter_index = ALPHABET.find(word[i])
        next_letter_index = ALPHABET.find(word[i+1])
        if curr_letter_index >= next_letter_index:
            return False
    return True

def is_stacatto(word):
    Returns whether a word is a stacatto word, i.e., whether the letters in
    even positions are vowels.

        word -- The word to check

    >>> is_stacatto('AUTOMATIC')
    >>> is_stacatto('POPULATE')
    >>> is_stacatto('')
    >>> is_stacatto('PYTHON')
    >>> is_stacatto('SPAGHETTI')

    for i in range(len(word)):
        if i % 2 == 1:
            even_letter = word[i]
            if not even_letter in VOWELS:
                return False # we've found an even letter that isn't a vowel,
                             # so we can return immediately.

    return True

def count_tridromes(filename):
    Return the number of tridromes in the file
    count = 0
    with open(filename, 'r') as f:
        for line in f:
            word = line.strip().upper()
            if is_tridrome(word):
                count += 1
    return count

def count_peaceful(filename):
    Return the number of peaceful words in the file
    count = 0
    with open(filename, 'r') as f:
        for line in f:
            word = line.strip().upper()
            if is_peaceful(word):
                count += 1
    return count

def count_stacatto(filename):
    Return the number of stacatto words in the file
    count = 0
    with open(filename, 'r') as f:
        for line in f:
            word = line.strip().upper()
            if is_stacatto(word):
                count += 1
    return count