Pyramid

            
def make_pyramid(image):
    pyramid_image = SimpleImage.blank(image.width, image.height)  # the new image
    for y in range(image.height):              # go through each row of the image
        range_min = image.width // 2 - y       # the x coordinate of the beginning of the row
        range_max = image.width // 2 + y + 1   # the x coordinate of the end of the row
        for x in range(range_min, range_max):
            pixel = image.get_pixel(x, y)      # the pixel we're copying from
            pixel_pyramid = pyramid_image.get_pixel(x, y) # the pixel we're copying to
            pixel_pyramid.red = pixel.red
            pixel_pyramid.green = pixel.green
            pixel_pyramid.blue = pixel.blue
    return pyramid_image
            
        

Tracing

          
$ python3 the-office.py 2 -flax
6
$ python3 the-office.py 5 -scott
1
$ python3 the-office.py 4
0
          
        

String Problems

Parsing Problems

          
def find_numbers(s):
    search = 0
    numbers = []
    while True:
        begin = search

        # we look for a digit or a period to indicate the start of a number
        while begin < len(s) and not (s[begin].isdigit() or s[begin] == '.'):
            begin += 1

        # begin is now at the end of the string or the index of the first
        # digit or period in the number. First,  let's make sure we're not
        # at the end of the string by ending the loop if we are.
        if begin >= len(s):
            break

        # start off end one character after begin, since the number will
        # be at least one character long.
        end = begin + 1
        # find the first non-number-or-period character after begin
        while end < len(s) and (s[end].isdigit() or s[end] == '.'):
            end += 1

        # slice out the number from the string
        number = s[begin:end]

        # count the number of periods in the number
        num_periods = 0
        for i in range(len(number)):
            if number[i] == '.':
                num_periods += 1

        # make sure there's a maximum of one period
        # in the number
        if num_periods <= 1:
            numbers.append(number)

        search = end + 1
    return numbers

def parse_phone_number(s):
    """
    This function uses indexing to parse a string representing a 10 digit phone number into a list of strings
    where the first string is the area code of the given phone number and the second string is the rest of 
    the phone number with the dash characters removed. 
    """
    area_code = s[:3]
    rest_of_num_with_dash = s[4:]
    dash_loc = rest_of_num_with_dash.find('-')
    rest_of_num_no_dash = rest_of_num_with_dash[0:dash_loc] + rest_of_num_with_dash[dash_loc+1:]
    output_lst = [area_code, rest_of_num_no_dash]
    print(output_lst)


def parse_phone_number(s):
    """
    This function uses a while loop accompanied with str.find() to parse a phone number into a list of strings
    where the first string is the area code of the given phone number and the second string is the rest of 
    the phone number with the dash characters removed. This function will work for all phone numbers, 
    not just 10 digit ones. 
    """
    output_lst = []
    num_split_by_dash = []
    start_search_indx = 0
    while True:
      dash_location = s.find('-', start_search_indx)
      if dash_location == -1:
        break
      else:
        num_split_by_dash.append(s[start_search_indx:dash_location])
        start_search_indx = dash_location + 1
 
    num_split_by_dash.append(s[start_search_indx:])

    area_code = num_split_by_dash[0]
    
    rest_of_num_no_dash = ''
    for part in num_split_by_dash[1:]:
      rest_of_num_no_dash += part
      
    output_lst.append(area_code)
    output_lst.append(rest_of_num_no_dash)

    return output_lst


def find_letter_runs(s):
    search = 0
    words = []
    while True:
        begin = search
        while begin < len(s) and not s[begin].isalpha():
            begin += 1

        if begin >= len(s):
            break

        end = begin + 1
        while end < len(s) and s[end] == s[begin]:
            end += 1

        word = s[begin:end]
        if len(word) > 1:
          words.append(word)
        # notice we don't increment search here, since the
        # next letter run could begin immediately

    return words

def parse_out_hashtags(s):
    start_search_indx = 0
    hashtag_lst = []
    while True:
      octothorpe_loc = s.find('#', start_search_indx)
      
      #out of hashtags, so stop searching 
      if octothorpe_loc == -1:
        break

      end = octothorpe_loc + 1

      while end < len(s) and s[end].isalnum():
        end += 1

      curr_hashtag = s[octothorpe_loc + 1:end]

      #only add a hashtag that isn't an empty string
      if curr_hashtag != '':
        hashtag_lst.append(curr_hashtag)

      start_search_indx = end  # the next character might be a hashtag
  
    return hashtag_lst

def find_quotes(s):
    quote_lst = []
    start_search_inx = 0
    while True:
      first_quotation = s.find('"', start_search_inx)
      
      if first_quotation == -1:
        break
      
      close_quotation = s.find('"', first_quotation+1)
      if close_quotation == -1:
        break
      
      curr_quote = s[first_quotation+1:close_quotation]
      quote_lst.append(curr_quote)

      start_search_inx = close_quotation + 1

    return quote_lst
          
        

Pig Latin

            
def is_vowel(char):
    """
    A useful helper function that returns True
    if char is a vowel and False otherwise
    """
    return char in ['a', 'e', 'i', 'o', 'u']

def pig_latin(word):
    if len(word) == 0:
        # we don't want to look at the first character
        # of an empty string, so we just return a blank
        # string immediately.
        return ''

    if is_vowel(word[0]):
        return word + 'yay'

    first_vowel_index = 1
    for i in range(1, len(word)):
        if not is_vowel(word[i]):
            first_vowel_index += 1
        else:
            break

    return word[first_vowel_index:] + word[:first_vowel_index] + "ay"

            
        

is_alpha_order

          
def is_in_alpha_order(s):
	prev_char = s[0]
	for ch in s[1:]:
		if ch < prev_char:
			return False
		prev_char = ch

  return True
          
        

List Problems

Collapse

          
def collapse(nums):
  result = []
  for i in range(len(nums)//2):
    # since we're going pairs at a time, we only need
    # to go as many as times as half the number of elements
    result.append(nums[i * 2] + nums[i * 2 + 1])

  # You don't need to understand the % operator for the midterm,
  # but it was covered in Monday's lecture. Essentially, we check
  # that the remainder when the length is divided by 2 is 1.
  # If so, it's odd and we need to add the last element of the original
  # result to the string
  if len(result) % 2 == 1:
    result.append(nums[-1])
  return result
          
        

Rotate

          
def right_list_right(numbers, num):
    output_list = []

    for i in range(len(numbers) - num, len(numbers)):
        output_list.append(numbers[i])

    for i in range(0, len(numbers) - num):
        output_list.append(numbers[i])

    return output_list
          
        


Word counts

          
def remove_vowels(s):
    out = ''
    for c in s:
        if c not in 'aieou':
            out += c
    return out

def remove_consonants(s):
    out = ''
    for c in s:
        if c in 'aieou':
            out += c
    return out

def count_lines(filename, keep_vowels):
    counts = {}
    with open(filename, 'r') as f:
        for word in f:
            word = word.strip()
            if keep_vowels:
                word = remove_vowels(word)
            else:
                word = remove_consonants(word)
            if word not in counts:
                counts[word] = 0
            counts[word] += 1
    for key in sorted(counts.keys()):
        print(key, '->', counts[key])

def main():
    args = sys.argv[1:]

    if len(args) == 2 and args[0] == '-vowels':
        count_lines(args[1], True)
    else:
        count_lines(args[0], False)