Section #6 Solutions

May 17th, 2020


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


Counting by Consonants

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

def count_by_consonants(filename):
    counts = {}

    with open(filename, 'r') as f:
        for word in f:
            word = word.strip()
            word = remove_consonants(word)
            if word not in counts:
                counts[word] = 0
            counts[word] += 1
            
    return counts
      
    

Drawing Friend Graphs

      
def draw_friend_graph(canvas, friends_file, coordinates_file):
    network = create_friend_dict(friends_file)
    coord_list = create_coord_dict(coordinates_file)
    draw_first_coords(canvas, coord_list)
    draw_connections(canvas, network, coord_list)


def create_friend_dict(filename):
    """
    This function creates a dictionary from a given file containing the names of each person in the network
    along with a list of people that they follow. The key is the name of a person in the
    network. The value is a list of people that they follow. 
    """
    network = {}
    with open(filename) as f:
        for line in f:
            line = line.strip()
            first_split = line.split(": ")
            key = first_split[0]
            friends = first_split[1].split(", ")

            # add each name to the network
            network[key] = friends

    return network


def create_coord_dict(filename):
    """
    This function creates a dictionary from a given file with each name containing a name and a list 
    of corresponding x and y coordinates. Each key in the dictionary is the name of a person in the network, 
    and the value is a list where the first item is the x coordinate for this person's node and the second 
    item is the y coordinate. This fuction returns the dictionary created. 
    """
    coord_list = {}
    with open(filename) as f:
        for line in f:
            first_split = line.split(": ")
            key = first_split[0]
            coords = first_split[1].split(", ")

            # convert from string to int
            coords[0] = int(coords[0])
            # trim the trailing whitespace and convert from string to int
            coords[1] = int(coords[1].strip())
            # update the dictionary to include this key value pair
            coord_list[key] = coords

    return coord_list


def draw_first_coords(canvas, coord_list):
    """
    This function draws a single circle for each friend in the network at it's given starting coordinate. 
    It also adds a string of text with the name of the person that the circle represents in the network. 
    """
    for name in coord_list:
        x_val = coord_list[name][0]
        y_val = coord_list[name][1]
        canvas.create_oval(x_val, y_val, x_val+10-1, y_val+10-1, fill='green')
        canvas.create_text(x_val, y_val, text=name)


def draw_connections(canvas, network, coord_list):
    """
    This function draws the lines betweens friends in the network based on the given dictionary. 
    network is a the dictionary of relationships created in create_dict
    coord_list is the dict of names and coordinates given
    """
    for name in network:
        start_x = coord_list[name][0]
        start_y = coord_list[name][1]
        for friend in network[name]:
            end_x = coord_list[friend][0]
            end_y = coord_list[friend][1]
            canvas.create_line(start_x, start_y, end_x, end_y)
      
    

First Letter Index

      
def first_list(strs):
	uniq_ltrs = {}
	for s in str:
		first_c = s[0]
		if first_c not in uniq_ltrs:
			uniq_ltrs[first_c] = []
		uniq_ltrs[first_c].append(s)
	return uniq_ltrs
      
    

Cryptography

      
def encrypt(plaintext):
    output = ""

    for ch in text:
        if ch in ENCRYPTION_DICT:
            output += ENCRYPTION_DICT[ch]
        else:
            output += ch

    return output

def reverse_encryption_dict():
    decryption_dict = {}

    for plaintext_char in ENCRYPTION_DICT:
        encrypted_char = ENCRYPTION_DICT[plaintext_char]
        decryption_dict[encrypted_char] = plaintext_char 

    return decryption_dict

def decrypt(ciphertext):
    decryption_dict = reverse_encryption_dict()
    output = ""
    
    for ch in text:
      if ch in decryption_dict:
          output += decryption_dict[ch] 
      else:
          output += ch
    
    return output

      
    

Recipes

      
def read_dict_from_file(filename):
    d = {}
    with open(filename) as f:
        for s in f:
            key_val = s.split(":: ")
            d[key_val[0]] = float(key_val[1])
    return d

def can_make(recipe, pantry)
    for ingredient in recipe:
        if pantry.get(ingredient, 0) < recipe[ingredient]:
            return False
    return True

def make_recipe(recipe, pantry):
      for ingredient in recipe:
          pantry[ingredient] -= recipe[ingredient]
      return pantry

def main():
    pantry = read_dict_from_file(PANTRY_FILENAME)
    while True:
        recipe_filename = input(
            "What recipe should we bake next (Press enter to quit.)? ")
        if recipe_filename == "":
            break
        recipe = read_dict_from_file(recipe_filename)
        if can_make(recipe, pantry):
          make_recipe(recipe, pantry)
          print("You can make that recipe! Your pantry now looks like this:")
          print(pantry)
        else:
          print("You can't make that recipe.")
      
    

Anagrams

      
LEXICON = 'dictionary.txt'

def get_sorted_word(word):
  return "".join(sorted(word))

def load_anagram_dict():
    anagram_dict = {}

    with open(LEXICON) as f:
        for line in f:
            word = line.strip()
            sorted_word = get_sorted_word(word)
            if sorted_word not in anagram_dict:
                anagram_dict[sorted_word] = []
            anagram_dict[sorted_word].append(word)
    
    return anagram_dict

def main():
    anagram_dict = load_anagram_dict()
    while True:
        word = input("Word: ")
        if word == "":
            break
        sorted_word = get_sorted_word(word)
        if sorted_word in anagram_dict:
            print(anagram_dict[sorted_word])
        else:
            print(word + " is not in the dictionary")
      
    

Big Tweet Data

      
def add_tweet(user_tags, tweet):
    user = parse_user(tweet)
    if user == '':
        return user_tags

    # if user is not in there, put them in with empty counts
    if user not in user_tags:
        user_tags[user] = {}

    # counts is the nested tag -> count dict
    # go through all the tags and modify it
    counts = user_tags[user]
    parsed_tags = parse_tags(tweet)
    for tag in parsed_tags:
        if tag not in counts:
            counts[tag] = 0
        counts[tag] += 1

    return user_tags

def parse_tweets(filename):
    user_tags = {}
    # here we specify encoding 'utf-8' which is how this text file is encoded
    # python technically does this by default, but it's better to be explicit
    with open(filename, encoding='utf-8') as f:
        for line in f:
            add_tweet(user_tags, line)
    return user_tags

def user_total(user_tags, user):
    """
    Optional. Given a user_tags dict and a user, figure out the total count
    of all their tags and return that number.
    If the user is not in the user_tags, return 0.
    """
    if user not in user_tags:
        return 0
    counts = user_tags[user]
    total = 0
    for tag in counts.keys():
        total += counts[tag]
    return total

def flat_counts(user_tags):
    """
    Given a user_tags dicts, sum up the tag counts across all users,
    return a "flat" counts dict with a key for each tag,
    and its value is the sum of that tag's count across users.
    """
    counts = {}
    for user in user_tags.keys():
        tags = user_tags[user]
        for tag in tags:
            if tag not in counts:
                counts[tag] = 0
            counts[tag] += tags[tag]
    return counts