This site is from a past semester! The current version will be here when the new semester starts.

Week 7 [Mon, Feb 20th] - Programming Topics

Guidance for the item(s) below:

So far, we have learned how to use Python lists to store sequences of objects. This week we move onto another slightly more complex data structure called dictionary which can store a collection of key-value pairs.

Dictionaries

The Dictionary Data Structure

A dictionary (python type: dict) is a collection of many values that can be indexed by any object type, unlike lists that are automatically indexed by integers. Indexes for dictionaries are called keys, and a key with its associated value is called a key-value pair. Python dictionaries use the curly braces notation { key1: value1, key2: value2, ...}.

A list containing names of animals ['cat', 'dog', 'hen', 'fish']

Index Value
0 'cat'
1 'dog'
2 'hen'
3 'fish'

A dictionary containing ages of three people {'john': 12, 'sara': 14.5, 'colin': 13}. john-12 is a key-value pair.

Key Value
'john' 12
'sara' 14.5
'colin' 13

A dictionary containing details of a person {'name': 'john', 'age': 14.5, 'sex': 'F', 'citizen': True}

Key Value
'name' 'john'
'age' 14.5
'gender' 'F'
'citizen' True

Some examples of defining dictionaries.

friends = {} # empty dictionary
grades = {'TEE3201': 'A'}
numbers = {1: 'one', 2: 'two', 3: 'three'}
is_nice = {'jane': False, 'hakim': True, 'ravi': True}
prices = {'bread': 3.5, 'butter': 5.0, 'banana': 0.15}

Unlike lists, you cannot force a key-value pair in a dictionary to be at a specific position. The order of insertion will be the order of items in a dict.

Exercise: Get Subject Info

Exercise: Get Subject Info

Complete the get_subject_info function below to return a dictionary such that the code produces the given output.

def get_subject_info(code, name, level, is_core):
  return {} # UPDATE THIS LINE
  
print(get_subject_info('TEE3201', 'Software Engineering', 3, False))
print(get_subject_info('CS1101', 'Programming Basics', 1, True))

{'code': 'TEE3201', 'name': 'Software Engineering', 'level': 3, 'core?': False}
{'code': 'CS1101', 'name': 'Programming Basics', 'level': 1, 'core?': True}

Partial solution



Working with Dictionaries

You can use keys to access values in a dictionary.

Some examples of retrieving values based on the key:

numbers = {1: 'one', 2: 'two', 3: 'three'}
prices = {'bread': 3.5, 'butter': 5.0, 'banana': 0.15}
print(type(numbers))
print(numbers[1])
print(prices['butter'])
 → 

<class 'dict'>
one
5.0

Examples of adding, updating, and deleting dictionary entries:

grades = {'TEE3201': 'A'}
grades['CS2103'] = 'B'
print('After adding:',grades)
grades['TEE3201'] = 'A+'
print('After updating:',grades)
del grades['CS2103']
print('After deleting:', grades)

After adding: {'TEE3201': 'A', 'CS2103': 'B'}
After updating: {'TEE3201': 'A+', 'CS2103': 'B'}
After deleting: {'TEE3201': 'A+'}

Exercise: Get Set Delete Score

Exercise: Get, Set, Delete Score

Complete the three function below such that the code produces the given output.

Given the parameterscores is a dictionary of the format {'amy': 35, 'betty': 36, 'charlie': 30} which contains scores of a bunch of players,

  • get_score(scores, player): returns the value of the key player
  • set_score(scores, player, new_score): sets the value of the key player to the new_score
  • delete_score(scores, player): deletes the value for key player
def get_score(scores, player):
  return # UPDATE HERE!
    
def set_score(scores, player, new_score):
  pass # REPLACE THIS WITH YOUR CODE!
  
def delete_score(scores, player):
  pass # REPLACE THIS WITH YOUR CODE!
  
game1_scores = {'amy': 35, 'betty': 36, 'charlie': 30}
print(get_score(game1_scores, 'betty'))
print(get_score(game1_scores, 'amy'))
set_score(game1_scores, 'charlie', 5)
set_score(game1_scores, 'dan', 0)
print(game1_scores)
delete_score(game1_scores, 'dan')
print(game1_scores)

36
35
{'amy': 35, 'betty': 36, 'charlie': 5, 'dan': 0}
{'amy': 35, 'betty': 36, 'charlie': 5}

Partial solution



Trying to access a value for a non-existent key raises a KeyError exception.

This example raises an exception because the key 'santa' does not exist in the dictionary is_nice:

is_nice = {'jane': False, 'hakim': True}
print(is_nice['santa'])
 → 

Traceback (most recent call last):
  File "python", line 9, in <module>
KeyError: 'santa'

Exercise: Get Score with Error Handling

Exercise: Get Score with Error Handling

Update the get_score1(scores, player) function to handle error situations, as described below.

Given the parameterscores is a dictionary of the format {'amy': 35, 'betty': 36, 'charlie': 30} which contains scores of a bunch of players,

  • get_score1(scores, player): returns the value of the key player. Returns an error message if the player is not in scores.
def get_score1(scores, player):
  return scores[player] # UPDATE HERE!
    
game1_scores = {'amy': 35, 'betty': 36, 'charlie': 30}
print(get_score1(game1_scores, 'charlie'))
print(get_score1(game1_scores, 'brown'))

30
brown is not in the game!

Partial solution



You can use keys() and values() methods to iterate through keys and values of a dictionary, respectively.

The code below shows how to iterate through keys/values of a dictionary.

prices = {'bread': 3.5, 'butter': 5.0, 'banana': 0.15}
for k in prices.keys():
  print(k, '->', prices[k])
 → 

bread -> 3.5
butter -> 5.0
banana -> 0.15
prices = {'bread': 3.5, 'butter': 5.0, 'banana': 0.15}
for v in prices.values():
  print(v)
 → 

3.5
5.0
0.15

You can use the sorted() function to sort the keys/values before iterating through them.

The code below shows how to iterate through keys/values of a dictionary.

prices = {'bread': 3.5, 'butter': 5.0, 'banana': 0.15}
for k in sorted(prices.keys()):
  print(k, '->', prices[k])
 → 

banana -> 0.15
bread -> 3.5
butter -> 5.0

Exercise: Print Scorecard

Exercise: Print Scorecard

Update the functions in the code to behave as described below such that the code produces the output given below the code.

Given the parameterscores is a dictionary of the format {'amy': 35, 'betty': 36, 'charlie': 30} which contains scores of a bunch of players,

  • get_team_score(scores): returns the total of all scores of all players in scores.
  • print_scorecard(scores): prints scores of each player in the format given, in the alphabetical order of player names.
def get_team_score(scores):
  total = 0
  #ADD YOUR CODE HERE!
  return total
  
def print_scorecard(scores):
  #pass #REPLACE WITH YOUR CODE!

game2_scores = {'zac': 35, 'betty': 30, 'aaron': 10}
print_scorecard(game2_scores)
print('total =', get_team_score(game2_scores))

aaron = 10
betty = 30
zac = 35
total = 75

Partial solution



As usual, you can use in and not in to check whether a key or a value is in a dictionary.

The code below shows how to check if a certain key or a value exists in a dictionary.

prices = {'bread': 3.5, 'butter': 5.0, 'banana': 0.15}
print('bread' in prices.keys())
print('sugar' not in prices.keys())
 → 

True
True
prices = {'bread': 3.5, 'butter': 5.0, 'banana': 0.15}
print(3.5 in prices.values())
print(6.0 in prices.values())
 → 

True
False

Exercise: Add Bonus

Exercise: Add Bonus

Update the functions in the code to behave as described below such that the code produces the output given below the code.

Given the parameterscores is a dictionary of the format {'amy': 35, 'betty': 36, 'charlie': 30} which contains scores of a bunch of players,

  • add_bonus(scores, player, bonus): adds the bonus to the value of the player if player already exists in scores. Otherwise, adds the player to scores with the value bonus.
def add_bonus(scores, player, bonus):
  pass #REPLACE WITH YOUR CODE!


game3_scores = {'amy': 35, 'betty': 36, 'charlie': 30}    
add_bonus(game3_scores, 'amy', 5)
add_bonus(game3_scores, 'dan', 10)
print(game3_scores)

{'amy': 40, 'betty': 36, 'charlie': 30, 'dan': 10}

Partial solution



Nested Dictionaries

Dictionaries and lists can be nested in each other to create more complicated data structures.

This dictionary keeps track of assignments of each subject. Note how the value is a list rather than a simple value such as an int or a string.

assignments = {'TEE3201': ['do exercises', 'submit project'],
               'CS2103': [],
               'CS3281': ['do presentation']}

Python ignores line breaks and indentations in the middle of a dictionary/list definition which allows you to structure the code into a more readable format (e.g., one key-value pair per line).

As the values in this dictionary are lists, you can do list operations on them, e.g., append(), len()

print('CS3281 assignments:', assignments['CS3281'])

assignments['CS3281'].append('study for exams')
print(assignments['CS3281'])

print('How many things to do in TEE3201?', len(assignments['TEE3201']))

# calculate total assignments
total = 0
for a in assignments.values():
  total = total + len(a)
print('total tasks to do:', total)

CS3281 assignments: ['do presentation']
['do presentation', 'study for exams']
How many things to do in TEE3201? 2
total tasks to do: 4

Exercise: Inning-Scores

Exercise: Inning-Scores

Assume the game has three innings and a player can play in 0-3 innings. For each inning, a player will have a inning-score which is an integer e.g., player amy scored 5, 5, and 10 for the three innings (in order).

Update the get_detailed_scores functions in the code below such that it returns a dictionary that stores inning scores of each player as a list of integers for each player. Inning-scores of each player is given below.

Player Scores in different innings
amy 5, 5, 10
betty 10
charile (did not play any innings)
def get_detailed_scores():
  return {'amy': 20, 'betty': 30, 'charlie': 30} #REPLACE WITH YOUR CODE! 

print(get_detailed_scores())

{'amy': [5, 5, 10], 'betty': [10], 'charlie': []}

Partial solution



This dictionary uses dictionaries as values (i.e., nesting dictionaries inside dictionaries). It stores details of a group of persons.

friends = {'john': {'name': 'John Doe', 'birthday': 'Jan 12'},
           'sara': {'name': 'Sara Parker', 'birthday': 'Jun 30'},
           'betty': {'name': 'Betsy Sims', 'birthday': 'Jan 12'}}
           
print(friends['john']['birthday'])

# print friends whose birthday is Jan 12

for f in friends.keys():
  details = friends[f]
  if details['birthday'] == 'Jan 12':
    print(details['name'])

Jan 12
John Doe
Betsy Sims

As friends['john'] evaluates to a dictionary, you can use the ['birthday'] notation to find the birthday of that person.
friends['john']['birthday']
{'name': 'John Doe', 'birthday': 'Jan 12'}['birthday']
'Jan 12'

Exercise: Player Stats

Exercise: Player Stats

Assume in each inning a player gets to bat a number of times and each hit can score 0, 1, 4, or 6, which are known as hit sizes. There is a need to keep track of how many times a player achieved each hit size in an inning.

Note how the player_stats dictionary in the code below uses lists which contain dictionaries to store, for each player, how many times the player scored a certain hit size, for each inning. For example, the player amy scored hit size of 0 x 0 times; hit size of 1 x 1 times; hit size of 4 x 1 times; hit size of 6 x 0 time in the first inning (which adds up to a score of 0*0 + 1*1 + 4*1 + 6*0 = 5 for her first inning).

player_stats = {'amy': [{0:0, 1:1, 4:1, 6:0},  # amy's first inning stats
                        {0:2, 1:5, 4:0, 6:0},  # amy's second inning stats
                        {0:0, 1:0, 4:1, 6:1}], # amy's third inning stats
                'betty': [{0:2, 1:2, 4:2, 6:0}],
                'charlie': []}

Update the get_player_hit_count(player_stats, player, inning, hit_size) functions in the code such that it uses the player_stats dictionary to return the hit count for the player in the inning for the given hit_size.
e.g., get_player_hit_count(player_stats, 'amy', 2, 6) should return how many times amy's hits in her second inning (i.e., inning = 2) scored 6s; the return value should be 0.

def get_player_hit_count(stats, player, inning, hit_size):
  return 0 #REPLACE WITH YOUR CODE!
  
print(get_player_hit_count(player_stats, 'amy', 2, 1))
print(get_player_hit_count(player_stats, 'betty', 1, 4))

5
2

Partial solution



Exercise: Grade Report

Exercise: Grade Report

Write a program that reads student grades one entry at a time and print a consolidated grade report at the end. Follow the sample output given below.

-----------------------------------------------------
     ~ Welcome to Grade Report System ~
* Enter one entry at a time in the format NAME GRADE
* NAME should be one word
* Enter an empty line to proceed to printing report
-----------------------------------------------------
Student name and grade?amy A
Student name and grade?ben B
Student name and grade?ben
Invalid input! Entry rejected.
Student name and grade?ben C D
Invalid input! Entry rejected.
Student name and grade?ben A
Student name and grade?charlie F
Student name and grade?amy A+
Student name and grade?amy D
Student name and grade?
============ Grade Report ===============
amy : A A+ D
ben : B A
charlie : F

The program should be able to accept any name (but you can assume each name is only one word e.g., Jane but not Jane Doe), not just the three names mentioned in the example above.

💡 Python hints



Exercise: Inventory Report

Exercise : Inventory Report

Write a function that prints an inventory report like the examples given below, when the report title (a string), print-width (an int), and list of items (as a suitable data structure, e.g., dictionary) is given to the function.

Kitchen Inventory Report:

  • Title: Kitchen
  • Width: 15
Item count
pots 5
eggs 100
 → 

###############
### KITCHEN ###
###############
eggs.......:100
pots.......:  5
            ---
total......:105
            ===

Bookshop Inventory Report:

  • Title: Book Shop
  • Width: 25
Item count
pens 85
books 3
pencils 22
 → 

#########################
####### BOOK SHOP #######
#########################
books................:  3
pencils..............: 22
pens.................: 85
                      ---
total................:110
                      ===
  • Title should be centered and in upper case.
  • Items should be in alphabetical order.
  • Width of the number column is 3. Numbers should be right-justified.

Partial solution