## Question 1: Introduction to Dictionaries¶

A dictionary contains keys that map to values. For example, we have a dictionary that maps a country (keys) to its capital (values):

countryCapitals = {
'Iran': 'Tehran',
'Turkey': 'Ankara'
}


### 1.1¶

What will countryCapitals.keys() output?

In [2]:
# YOUR ANSWER HERE


In [ ]:
countryCapitals = {
'Iran': 'Tehran',
'Turkey': 'Ankara'
}

print('countryCapitals.keys(): ', countryCapitals.keys())


### 1.2¶

What will countryCapitals.values() output?

In [12]:
# YOUR ANSWER HERE


In [ ]:
print('countryCapitals.values(): ', countryCapitals.values())


### 1.3¶

What will len(countryCapitals) output?

In [14]:
# YOUR ANSWER HERE


In [ ]:
print('len(countryCapitals): ', len(countryCapitals))


### 1.4¶

What will 'Iran' in countryCapitals output?

In [ ]:
# YOUR ANSWER HERE


In [ ]:
print("'Iran' in countryCapitals: ", 'Iran' in countryCapitals)


### 1.5¶

What will 'Iraq' in countryCapitals output?

In [20]:
# YOUR ANSWER HERE


In [ ]:
print("'Iraq' in countryCapitals: ", 'Iraq' in countryCapitals)


## Question 2: Using and Changing Dictionaries¶

### 2.1¶

Write a dictionary friendsAge mapping the names of five of your friends to their ages. We want a dictionary with students names as keys and ages as values.

In [25]:
friendsAge =  {
}


### 2.2¶

Write a function averageFriendsAge(d) that returns the average age of all the friends in a dictionary.

• The input is d is a dictionary mapping the names of friends to their ages.
• Return the average age of all the friends in the dictionary d.

For example:

d = { 'dan': 10,
'sahaana': 15,
'corina': 20 }

averageFriendsAge(d) ==  15

In [115]:
def averageFriendsAge(d):
return

# After you finish, this should print True
testDictionary = {
'isabelle': 15,
'jelani': 16,
'will': 14,
'heather': 16,
'rupal': 16
}

print(averageFriendsAge(testDictionary) == 15.4)

False


Try running this on your friendsAge dictionary:

In [ ]:
print(averageFriendsAge(friendsAge))


### 2.3¶

Now, write a function addFriend(d, name, age) that adds a new friend to a dictionary

• The inputs are:
• d, a dictionary mapping the names of friends to their ages.
• name, a string that represents your new friend's name.
• age, an integer that represents your new friend's age.
• Returns the dictionary after adding the new friend.

Note: Do not add a key if you already have a friend with the name given in name.

For example:

d = { 'dan' : 10,
'sahaana' : 15,
'jelani' : 20 }

addFriend(d, 'isabelle', 25) ==  { 'dan' : 10,
'sahaana' : 15,
'jelani' : 20,
'isabelle' : 25 }

# 'sahaana' is already in the dictionary, so nothing should be changed.
# sahaana's age should remain at 15 -- it should NOT be changed to 22.
addFriend(d, 'sahaana', 22) ==  { 'dan': 10,
'sahaana': 15,
'jelani': 20,
'isabelle': 25 }

In [14]:
def addFriend(d, name, age):
return

# After you finish, these should all print True
inputDictionary = {
'friendA' : 15,
'friendB' : 16,
'friendC' : 14,
'friendD' : 16,
'friendE' : 16
}

outputDictionaryA = {
'friendA' : 15,
'friendB' : 16,
'friendC' : 14,
'friendD' : 16,
'friendE' : 16,
'friendF' : 19
}

outputDictionaryB = {
'friendA' : 15,
'friendB' : 16,
'friendC' : 14,
'friendD' : 16,
'friendE' : 16,
'friendF' : 19,
'friendG' : 15
}


False
False
False


### 2.4¶

Write a function changeAge(d, name, age) to change a friend's age.

• The inputs are:
• d, a dictionary mapping the names of friends (the keys) to their ages (the values).
• name, a string that represents your friend's name.
• age, an integer that represents your friend's new age.
• Return the dictionary after changing the friend's age.

Note: Do not change the dictionary if you do not have a friend with the name given in name.

For example:

d = { 'dan': 10,
'sahaana': 15,
'isabelle': 20 }

changeAge(d, 'isabelle', 25) ==  { 'dan': 10,
'sahaana': 15,
'isabelle': 25 }

# 'bob' is not in the dictionary, so nothing should be changed.
# 'bob' should NOT be added to the dictionary.
changeAge(d, 'bob', 58) == { 'dan': 10,
'sahaana': 15,
'isabelle': 25 }

In [18]:
def changeAge(d, name, age):
return

# After you finish, these should return True
inputDictionary = {
'friendA' : 15,
'friendB' : 16,
'friendC' : 14,
'friendD' : 16,
'friendE' : 16
}

outputDictionaryA = {
'friendA' : 16,
'friendB' : 16,
'friendC' : 14,
'friendD' : 16,
'friendE' : 16
}

outputDictionaryB = {
'friendA' : 16,
'friendB' : 13,
'friendC' : 14,
'friendD' : 16,
'friendE' : 16
}

print(changeAge(inputDictionary, 'friendA', 16) == outputDictionaryA)
print(changeAge(inputDictionary, 'friendB', 13) == outputDictionaryB)
print(changeAge(inputDictionary, 'friendF', 17) == outputDictionaryB)

False
False
False


### 2.5¶

Write a function getFriendAge(d, name) that returns the age of your friend.

• The inputs are:
• d, a dictionary mapping the names of friends (string keys) to their ages (integer values).
• name, your friend's name (a string).
• Return the age of your friend (integer). If your friend is not in the dictionary, return None.

For example:

d = { 'dan' : 10,
'sahaana' : 15,
'isabelle' : 20 }

getFriendAge(d, 'sahaana') == 15
getFriendAge(d, 'bob') == None

In [22]:
def getFriendAge(d,name):
return

# After you finish, these should all print True
inputDictionary = {
'friendA' : 15,
'friendB' : 16,
'friendC' : 14,
'friendD' : 16,
'friendE' : 16
}

print(getFriendAge(inputDictionary,'friendA') == 15)
print(getFriendAge(inputDictionary, 'friendD') == 16)
print(getFriendAge(inputDictionary, 'friendX') == None)

False
False
True


## Question 3: Find the Smallest Key¶

Write a function minKey(d) that:

• Takes a dictionary argument, d, that has integer keys.
• Returns the smallest (minimum) key in d.

For example:

minKey({77: 'foo', 28: 'bar', 32: 'baz'}) == 28

d = {
9: 2,
8: 1,
3: 7,
7: 8,
4: 3
}
minKey(d) == 3


Hints:

• d.keys() returns the list of keys in a dictionary d. For example {1: 'a', 2: 'b'}.keys() == [1, 2]
• min(lst) finds the minimum value in a list. For example min([3,2,4]) == 2
In [23]:
# When you are done, these should all print True
def minKey(d):
return

print(minKey({77: 'foo', 28: 'bar', 32: 'baz'}) == 28)

d = {
9: 2,
8: 1,
3: 7,
7: 8,
4: 3
}

print(minKey(d) == 3)
print(minKey({88: 99}) == 88)

False
False
False


## Question 4: Find the Largest Value¶

Write a function maxValue(d) that:

• Takes a dictionary argument, d, that has integer values.
• Returns the largest (maximum) value in d.

For example:

maxValue({'dog': 33, 'cat': 92, 'ferret': 34}) == 92

d = {
9: 2,
8: 1,
3: 7,
7: 8,
4: 3
}

maxValue(d) == 8


Hints:

• d.values() returns the list of values in a dictionary d. For example {1: 'a', 2: 'b'}.values() == ['a', 'b']
• max(lst) finds the maximum value in a list. For example max([3,2,4]) == 4
In [24]:
def maxValue(d):
return

# When you are done, these should all print True
print(maxValue({'dog': 33, 'cat': 92, 'ferret': 34}) == 92)

d = {
9: 2,
8: 1,
3: 7,
7: 8,
4: 3
}

print(maxValue(d) == 8)
print(maxValue({1: 10, 2: 10, 3: 10}) == 10)

False
False
False


## Question 5: Find the Key with the Same Value¶

Write a function sameKeyAndValue(d) that:

• Takes a dictionary arguement, d.
• Returns a key that maps to the same value, or None if there is no such key.

For example:

d = {
1: 2,
3: 3,
4: 5
}

sameKeyAndValue(d) == 3   # key 3 has the same value of 3.

sameKeyAndValue({'foo': 'foo', 'bar': 'baz'}) == 'foo'

sameKeyAndValue({'a': 1, 'b': 2}) == None   # no keys have the same value

sameKeyAndValue({}) == None


Hints:

• d.items() returns a list of [key, value] pairs in a dictionary d. For example {1: 'a', 2: 'b'}.items() == [[1, 'a'], [2, 'b']]
• Here is how to use d.items() in a loop:
d = {1: 'a', 2: 'b', 3: 'c'}
for key, value in d.items():
print(value * key)

# this loop will print:
a
bb
ccc

In [25]:
def sameKeyAndValue(d):
return

# When you are done, these should all print True
d = {
1: 2,
3: 3,
4: 5
}
print(sameKeyAndValue(d) == 3)
print(sameKeyAndValue({'foo': 'foo', 'bar': 'baz'}) == 'foo')
print(sameKeyAndValue({'a': 1, 'b': 2}) == None)
print(sameKeyAndValue({}) == None)
# if multiple keys map to the same value, it is correct to return any one of them
print(sameKeyAndValue({1: 1, 2: 3, 4: 4}) in [1, 4])

False
False
True
True
False


## Question 6: Finding Specific Keys¶

### 6.1¶

Write a function getKey(d, value) that returns a key that maps to a given value. In this problem, only one key will map to a value (no repeats or duplicates.)

• The inputs are:
• d, a dictionary
• value, the value to find a key for.
• Return a key that maps to the given value. If no key exists, return None

Hint: Go through all of the keys in d with a loop, and check to see if it maps to value

For example:

friends = { 'jelani': 10,
'timnit': 15,
'daniel': 20 }

getKey(friends, 10) == 'jelani'
getKey(friends, 20) == 'daniel'
getKey(friends, 100) == None

animals = { 'pig': 'pink',
'crow': 'black',
'donkey': 'brown',
'sheep': 'white' }

getKey(animals, 'black') == 'crow'
getKey(animals, 'pink') == 'pig'
getKey(animals, 'purple') == None

In [38]:
def getKey(d, value):
return

# After you finish, these should return True
friends = { 'jelani': 10,
'timnit': 15,
'daniel': 20 }

print(getKey(friends, 10) == 'jelani')
print(getKey(friends, 20) == 'daniel')
print(getKey(friends, 100) == None)

animals = { 'pig': 'pink',
'crow': 'black',
'donkey': 'brown',
'sheep': 'white' }

print(getKey(animals, 'black') == 'crow')
print(getKey(animals, 'pink') == 'pig')
print(getKey(animals, 'purple') == None)

False
False
True
False
False
True


### 6.2¶

In the previous question, we found a single key with a specific value. Now, write a function getKeys(d, value) that returns a list of keys that map to a given value. We may have repeat values for each key, so return them all in a list.

• The inputs are:
• d, a dictionary.
• value, the value to find keys for.
• Return a list of keys that map to the given value (return the keys in any order). If no key exists, return an empty list [].

Hint: Go through all of the keys in d with a loop, and check to see if it maps to value, and add it to a list

For example:

friends = { 'arash': 10,
'mike': 15,
'corina': 20,
'jessica': 10,
'basi': 10,
'timnit': 20}

getKeys(friends, 10) has the same elements as ['arash', 'jessica', 'basi']
getKeys(friends, 20) has the same elements as ['corina', 'timnit']
getKeys(friends, 15) has the same elements as ['mike']
getKeys(friends, 999) == []

checkForSameKeys(getKeys(friends, 15), ['mike'])

animals = { 'pig' : 'pink',
'crow' : 'black',
'donkey' : 'brown',
'sheep' : 'white',
'mouse' : 'brown',
'monkey' : 'brown'}

getKeys(animals, 'black') has the same elements as ['crow']
getKeys(animals, 'brown') has the same elements as  ['donkey', 'mouse', 'monkey']
getKeys(animals, 'purple') == None


Note: Because you can return the lists in any order, we created a function for you to check if two lists have the same elements. You can use it to check your work, like we do in the tests!

# This function sorts the two lists, and checked if they are the same
def checkForSameKeys(lst1, lst2):
return sorted(lst1) == sorted(lst2)

In [71]:
def getKeys(d, value):
return

# After you finish, each print statement below should print True
friends = {
'arash': 10,
'mike': 15,
'corina': 20,
'jessica': 10,
'basi': 10,
'timnit': 20
}

# This function sorts the two lists, and checked if they are the same
def checkForSameKeys(lst1, lst2):
if lst1 is None or lst2 is None:
return False
return sorted(lst1) == sorted(lst2)

print(checkForSameKeys(getKeys(friends, 10), ['arash', 'jessica', 'basi']))
print(checkForSameKeys(getKeys(friends, 20), ['corina', 'timnit']))
print(checkForSameKeys(getKeys(friends, 15), ['mike']))
print(getKeys(friends, 999) == [])

animals = { 'pig' : 'pink',
'crow' : 'black',
'donkey' : 'brown',
'sheep' : 'white',
'mouse' : 'brown',
'monkey' : 'brown'}

print(checkForSameKeys(getKeys(animals, 'black'), ['crow']))
print(checkForSameKeys(getKeys(animals, 'brown'), ['donkey', 'mouse', 'monkey']))
print(getKeys(animals, 'purple') == [])

False
False
False
False
False
False
False


## Question 7: Students and Grades¶

### 7.1¶

Write a function mergeNamesAndGrades(names, grades) that takes two lists (the student names and their grades) as inputs and returns a dictionary with the names of the students as keys and their grades as values.

• The inputs are:
• names, a list of strings with names of students
• grades, a list of strings with grades of each students ('A' - 'F')
• Return a dictionary with the names of the sudents as keys and the grades as values

For example:

mergeListsAsDict(['Daniel', 'Rupal', 'Rajiv'], ['D', 'A', 'B']) == {
'Daniel': 'D',
'Rupal': 'A',
'Rajiv': 'B'
}

In [72]:
def mergeListsAsDict(names, grades):
return

names = ['Daniel', 'Basi', 'Rupal', 'Dim', 'Leello', 'Mike']
grades = ['D', 'B', 'A', 'C', 'A', 'B']

dictResult = {
'Daniel': 'D',
'Basi': 'B',
'Rupal': 'A',
'Dim': 'C',
'Leello': 'A',
'Mike': 'B'
}
print(mergeListsAsDict(['bob'], ['F']) == {'bob': 'F'})
print(mergeListsAsDict([], []) == {})

False
False
False


### 7.2¶

Write a function getStudentsWithGrade(d, grade) that returns a list of students with a given grade.

• The inputs are:
• d, a dictionary mapping student names to their grades
• grade, a string corresponding to a grade from 'A' to 'F'
• Return the list of students with the given grade, for instance:
getStudentsWithGrade({'Daniel': 'F', 'Rupal': 'A', 'George': 'B'}, 'A') == ['Rupal']
getStudentsWithGrade({'Bob': 'F', 'Dim': 'F', 'Jelani': 'A'}, 'F') == ['Bob', 'Dim']


Hint: to complete this exercise in one line of code, try using one of the functions that you have already written!

In [74]:
def getStudentsWithGrade(d, grade):
return {}

print(set(getStudentsWithGrade({'Daniel': 'A', 'Rupal': 'A', 'George': 'B'}, 'A')) == set(['Daniel', 'Rupal']))
print(getStudentsWithGrade({'Bob': 'F', 'Dim': 'F', 'Jelani': 'A'}, 'F') == ['Bob', 'Dim'])
print(getStudentsWithGrade({'Daniel': 'F', 'Rupal': 'A'}, 'D') == [])

False
False
False


# Good job so far! The problems below are all optional.¶

## Question 8: Finding Duplicates¶

Write a function findDuplicates(lst) that:

• Takes a list argument, lst.
• Returns a dictionary showing each duplicate item in lst. Specifically:
• keys of the dictionary should be the repeated items in lst.
• each value of the dictionary should be a list of the repeated item's indices — all the places where the repeated item appears.

Some examples will help:

findDuplicates([1, 5, 1, 0, 8, 1, 8]) == {
1: [0, 2, 5],  # 1 appears in the list at positions 0, 2 and 5.
8: [4, 6]      # 8 appears at positions 4 and 6.
}

findDuplicates([1, 5, 'Jelani', 'Timnit', 'Timnit', 'Jelani', 5]) == {
5: [1, 6],
'Jelani': [2, 5],
'Timnit': [3, 4]
}

findDuplicates([False, True, False]) == {False: [0, 2]}

findDuplicates([0, 1, 2, 3]) == {}  # there are no repeats, so, return an empty dictionary.
findDuplicates([]) == {}            # an empty list also results in an empty dictionary.
In [44]:
def findDuplicates(lst):
return

# When you are done, these should all print True
print(findDuplicates([1, 5, 1, 0, 8, 1, 8]) == {
1: [0, 2, 5],
8: [4, 6]
})

print(findDuplicates([1, 5, 'Jelani', 'Timnit', 'Timnit', 5, 'Jelani']) == {
5: [1, 5],
'Jelani': [2, 6],
'Timnit': [3, 4]
})

print(findDuplicates([False, True, False]) == {False: [0, 2]})
print(findDuplicates([0, 1, 2, 3]) == {})
print(findDuplicates([]) == {})
print(findDuplicates([8, 8, 8, 8, 8, 8]) == {8: [0, 1, 2, 3, 4, 5]})

False
False
False
False
False
False


## Question 9: Counting Unique Words¶

Write a function countWords(s) that:

• Takes a string of words, s.
• Returns a dictionary showing how many times each word appears in s. Specifically:
• Each key should be a word in s.
• Each value should be an integer — how many times that word appears in s.

For example:

countWords('hello word hello ethiopia hello addis ababa') == {
'hello': 3,    # hello appears three times
'world': 1,    # everything else appears once
'ethiopia': 1,
'ababa': 1
}

countWords('. . @ # . # . . @ @ @@') == {
'.': 5,
'@': 3,
'#': 2,
'@@': 1
}

countWords('aaa aa aa a a a') == {
'aaa': 1,
'aa': 2,
'a: 3
}

Important Note: In Python, use the split method to break strings into lists of words. For example:

'some words 1 2 3'.split() == ['some', 'words', '1', '2', '3']

s = '. . @ # . # . . @ @ @@'
s.split() == ['.', '.', '@', '#', '.', '#', '.', '.', '@', '@', '@@']
In [45]:
def countWords(s):
return

# When you are done, these should all print True
print(countWords('hello world hello ethiopia hello addis ababa') == {
'hello': 3,
'world': 1,
'ethiopia': 1,
'ababa': 1
})

print(countWords('. . @ # . # . . @ @ @@') == {
'.': 5,
'@': 3,
'#': 2,
'@@': 1
})

print(countWords('aaa aa aa a a a') == {
'aaa': 1,
'aa': 2,
'a': 3
})

print(countWords('a b c') == {
'a': 1,
'b': 1,
'c': 1
})

print(countWords('') == {})

False
False
False
False
False


## Question 10: Lab Visitors¶

Write a function countUniqueVisitors(d) that counts how many different people enter a lab on each day.

• The input d is a dictionary mapping the days of the week to a list of names of people who entered the lab on that day, for instance:
d = {
'Segno': ['rupal', 'arash', 'dim'],
'Maksegno': ['leello', 'leelo', 'leelo', 'dim'],
'Erob': ['dim', 'dim'],
'Hamus': ['arash', 'corina'],
'Arb': ['leello', 'leello', 'isa']
}

• Return another dictionary that maps the days of the week to the number of distinct people who have entered the lab on that day, for example:
getDistinctEntriesCount(d) == {
'Segno': 3,    # the distinct people are 'rupal', 'arash' and 'dim'.
'Maksegno': 2, # the distinct people are 'leelo' and 'dim'.
'Erob': 1,     # only person who entered is 'dim'.
'Hamus': 2,
'Arb': 2
}

In [106]:
def countUniqueVisitors(d):
return {}

# When you finish, the code below should print True
input1 = {
'Segno': ['arash', 'arash', 'isa', 'rupal', 'arash', 'leello'],
'Maksegno': ['leello', 'dim', 'arash', 'arash', 'isa', 'rupal', 'nati', 'arash', 'nati', 'basi'],
'Erob': ['leello', 'dim', 'dim', 'dim', 'arash'],
'Hamus': ['arash', 'arash', 'rupal', 'arash'],
'Arb': ['leello', 'leello', 'isa', 'dim', 'rupal', 'corina', 'basi', 'nati']
}

input2 = {
'Segno': ['arash', 'arash', 'isa', 'rupal', 'arash', 'leello'],
'Maksegno': ['leello', 'dim', 'arash', 'arash', 'isa', 'rupal', 'nati', 'arash', 'nati', 'basi'],
'Erob': ['leello', 'dim', 'dim', 'dim', 'arash'],
'Hamus': [],
'Arb': ['leello', 'leello', 'isa', 'dim', 'rupal', 'corina', 'basi', 'nati']
}

output1 = {
'Segno': 4,
'Maksegno': 7,
'Erob': 3,
'Hamus': 2,
'Arb': 7
}

output2 = {
'Segno': 4,
'Maksegno': 7,
'Erob': 3,
'Hamus': 0,
'Arb': 7
}

print(countUniqueVisitors(input1) == output1)
print(countUniqueVisitors(input2) == output2)

False
False


## Question 11: Kitchen Ingredients¶

Write a function getIngredients(dishesDict, ingredientsDict) that maps people to the list of ingredients they need to cook their favorite dishes.

• The arguments are:
• dishesDict, a dictionary mapping people to a list of dishes, for example:
dishesDict = {
'corina': ['pizza', 'soup'],
}

• ingredientsDict, a dictionary mapping dishes to a list of its ingredients, for example:
ingredientsDict = {
'pizza': ['sauce', 'dough', 'cheese'],
'pasta': ['spaghetti', 'sauce'],
'soup': ['carrots', 'stock']
}

• Return a dictionary mapping the same keys of people to the ingredients they need to buy, for example:
getIngredients(dishesDict, ingredientsDict) ==  {
'sahaana': ['tomatoes', 'cucumber', 'spinach', 'spaghetti', 'sauce'],
'corina': ['salami', 'dough', 'cheese', 'carrots', 'stock'],
'dan': ['tomatoes', 'cucumber', 'spinach']
}


Important Note: If two or more of a person's favorite dishes require the same ingredient, include it in their ingredient list only once. For example:

dishesDict = {
'will': ['icecream', 'butter']
}
ingredientsDict = {
'icecream': ['milk', 'sugar'],
'butter': ['milk', 'salt']
}
getIngredients(dishesDict, ingredientsDict) == {
'will': ['milk', 'sugar', 'salt']  ### milk appears only once!
}

In [99]:
def getIngredients(dishesDict, ingredientsDict):
return {}

# When you are finished, these messages should all show 'True' at the end.
dishesDict = {
'corina': ['pizza', 'soup'],
}
ingredientsDict = {
'pizza': ['salami', 'dough', 'cheese'],
'pasta': ['spaghetti', 'sauce'],
'soup': ['carrots', 'stock']
}
expected = {
'sahaana': ['spaghetti', 'sauce', 'tomatoes', 'cucumber', 'spinach'],
'corina': ['carrots', 'stock', 'salami', 'dough', 'cheese'],
'dan': ['tomatoes', 'cucumber', 'spinach']
}
actual = getIngredients(dishesDict, ingredientsDict)

print('Example answer has the right number of keys:', len(actual) == len(expected))
for person, ingredientsList in actual.items():
print(person, 'is one of the keys we expect in the example:', person in expected)
print('ingredients list for', person, 'is correct:', sorted(ingredientsList) == sorted(expected[person]))

dishesDict = {
'will': ['icecream', 'butter']
}
ingredientsDict = {
'icecream': ['milk', 'sugar'],
'butter': ['milk', 'salt']
}
actual = getIngredients(dishesDict, ingredientsDict)
expected = {'will': ['milk', 'sugar', 'salt']}
print("There is only one key in Will's dictionary:", len(actual) == 1)
print("There are three ingredients in Will's list:", 'will' in actual and len(actual['will']) == 3)
print("Will's list has milk, sugar and salt:", 'will' in actual and sorted(actual['will']) == ['milk', 'salt', 'sugar'])

Example answer has the right number of keys: False
There is only one key in Will's dictionary: False
There are three ingredients in Will's list: False
Will's list has milk, sugar and salt: False


## Question 12: Number Theory¶

In mathematics, the $n^{th}$ Taxicab number, typically denoted Ta(n) or Taxicab(n), also called the $n^{th}$ Hardy–Ramanujan number, is defined as the smallest number that can be expressed as a sum of two positive cubes in $n$ distinct ways.

$Taxicab(1) = 2$, because 2 is the smallest number that can be written (in one distinct way) as the sum of two positive cubes:

$Taxicab(1) = 2 = 1^3 + 1^3$

The most famous taxicab number is 1729. It can be written as two distinct sums of positive cubes:

$Taxicab(2) = 1729 = 1^3 + 12^3 = 9^3 + 10^3$

The name is derived from a conversation in ~1919 involving mathematicians G. H. Hardy and Srinivasa Ramanujan. As told by Hardy:

I remember once going to see Ramanujan when he was lying ill at Putney. I had ridden in taxi-cab No. 1729, and remarked that the number seemed to be rather a dull one, and that I hoped it was not an unfavourable omen. "No", he replied, "it is a very interesting number; it is the smallest number expressible as the sum of two positive cubes in two different ways.

### 12.1¶

Write some Python code to find $Taxicab(3)$.

Hint: $958595904$ can be written as the sum of two positive cubes in three distinct ways. (You can use Python to check for yourself.)

$958595904 = 856^3 + 692^3$

$958595904 = 984^3 + 180^3$

$958595904 = 986^3 + 22^3$

However, $Taxicab(3) \neq 958595904$ because it is not the smallest such number.

In [ ]:
# YOUR CODE HERE: how can you use python to find Taxicab(3)?


#### What is $Taxicab(3)$?¶

In [113]:
# YOUR NUMBER HERE


### 12.2¶

Write some Python code to prove that there is no number smaller than 1729 that can be written as a sum of two positive cubes in two distinct ways.

In [ ]:
# YOUR CODE HERE