## 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)

search = end

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)
```
```