Hi everyone! Here is a list of practice questions to help you review dicts and their uses. This is also a great review for your upcoming quiz. The answer key will be released later this week - be sure to try them first before looking at the answers!

# Basketball Team

You have been hired as the coach of a basketball team. As the new coach, you have several tasks ahead of you and you are tring to figure out how to proceed. Luckily, you know Python and have access to historical team data that can help you make the right choices!

## Tasks to Complete:

### Average Scores of Players

Given a `Dict`

with it’s key as players’ names and a corresponding `List`

containing their scores over several games (`Dict[str, List[int]]`

), find the average score of each player and return it as a dictionary. Expected function signature:

Example usage:

```
>>> find_avg_score({"kate": [10, 20, 30]})
{"kate": 20}
```

Explanation:

Kate’s scores over 3 games = `[10, 20, 30]`

; the average of that list is `20`

.

### Joining Salary Data

Given two dictionaries: one containing the id and name of each player (`Dict[int, str]`

) and the other containing their id and salary (`Dict[int, int]`

), return a `Dict`

containing the player’s name matched with their salary. Expected function signature:

Example usage:

```
>>>join_salary_data({30: "armando"}, {30: 10000})
"armando: 10000"}
```

Explanation:

As given by first `Dict`

, player with `id = 30`

is `"armando"`

. The second `Dict`

tells us that player with `id = 30`

makes `10000`

dollars. Therefore, `"armando"`

makes `10000`

dollars.

Note:

If you cannot find a player’s salary from the first dictionary with `{id: name}`

, mark their salary in the output `Dict`

as `-1`

.

```
>>>join_salary_data({30: "armando", 20: "kate"}, {30: 10000})
{"armando": 10000, "kate": -1}
```

### Highest and Lowest Scores

Given the player names and average scores for all players on your team (`Dict[str, int]`

), find the players with the highest and lowest scores. Return your result as a `Dict`

containing the names of both players. Expected function signature:

Example Usage:

```
>>> highest_and_lowest({"kate": 20, "mary": 40, "john": 10})
{"max": "mary", "min": "john"}
```

### Compare Scores

As one of the best coaches in the game, you value consistency over one-time achievement! Given a `Dict`

containing a players name and their corresponding scores for games in the season (`Dict[str, List[int]]`

), find the player who consistenly had the highest score on the team. Expected function signature:

Example usage:

```
>>> compare_scores({"kate": [10, 20, 20], "john": [5, 7, 60]}, 3)
"kate"
```

Explanation:

Despite the fact that John’s total score (`5 + 7 + 60 = 72`

) was higher than Kate’s total score (`10 + 20 + 20 = 50`

), Kate scored higher in game 1 with a score of `10`

vs. John’s `5`

and in game 2 with a score of `20`

vs. John’s `7`

. Thus, Kate had the highest score for `2`

games while John had the highest score for only `1`

game and `"kate"`

is returned by the function.

Note: the parameter `num_games`

tells you the number of games played by the team. Thus, the size of each `List[int]`

in the dictionary will be equal to `num_games`

.

## Tests for Each of these Functions to Try Out!

### Average Scores of Players

```
def test_1_find_avg_score() -> None:
"""find_avg_score(data) --> {"tom": 40, "jack": 50}.
where data: Dict[str, List[int]] = {
"tom": [10, 30, 80],
"jack": [20, 50, 100, 30]
}
"""
data: Dict[str, List[int]] = {
"tom": [10, 30, 80],
"jack": [20, 50, 100, 30]
}
assert find_avg_score(data) == {"tom": 40, "jack": 50}
def test_2_find_avg_score() -> None:
"""find_avg_score(data) --> {"rick": 0, "selena": 40}.
where data: Dict[str, List[int]] = {
"rick": [],
"selena": [20, 50, 100, 30, 40]
}
"""
data: Dict[str, List[int]] = {
"rick": [],
"selena": [20, 50, 100, 30, 40]
}
assert find_avg_score(data) == {"rick": 0, "selena": 48}
```

### Joining Salary Data

```
def test_1_join_salary_data() -> None:
"""join_salary_data(data, salary) --> {"rick": 500, "selena": 1000}.
data: Dict[int, str] = {
30: "rick",
20: "selena"
}
salary: Dict[int, int] = {
20: 1000,
30: 500,
40: 10000
}
"""
data: Dict[int, str] = {
30: "rick",
20: "selena"
}
salary: Dict[int, int] = {
20: 1000,
30: 500,
40: 10000
}
assert join_salary_data(data, salary) == {"rick": 500, "selena": 1000}
def test_2_join_salary_data() -> None:
"""join_salary_data(data, salary) --> {"rick": 500, "selena": 1000, "tom": -1}.
data: Dict[int, str] = {
30: "rick",
20: "selena",
50: "tom"
}
salary: Dict[int, int] = {
20: 1000,
30: 500,
40: 10000
}
"""
data: Dict[int, str] = {
30: "rick",
20: "selena",
50: "tom"
}
salary: Dict[int, int] = {
20: 1000,
30: 500,
40: 10000
}
assert join_salary_data(data, salary) == {"rick": 500, "selena": 1000, "tom": -1}
```

### Highest and Lowest Scores

```
def test_1_highest_and_lowest() -> None:
"""highest_and_lowest(data) --> {"max": "mary", "min": "Amanda"}.
data: Dict[str, int] = {"mary": 1000, "katherine": 350, "amanda": 400}
"""
data: Dict[str, int] = {"mary": 1000, "katherine": 350, "amanda": 400}
assert highest_and_lowest(data) == {"max": "mary", "min": "katherine"}
```

### Comparing Scores

```
def test_1_compare_scores() -> None:
"""compare_scores(data, 3) --> "mary".
where data = {
"mary": [30, 40, 60],
"john": [10, 10, 200],
"kate": [20, 5, 5]
}
"""
data: Dict[str, List[int]] = {
"mary": [30, 40, 60],
"john": [10, 10, 200],
"kate": [20, 5, 5]
}
assert compare_scores(data, 3) == "mary"
```

## Solutions to Each Problem

### Average Scores of Players

```
def find_avg_score(players: Dict[str, List[int]]) -> Dict[str, int]:
"""Finds the average score for players on the team."""
# Create a blank result to start with
avg_scores: Dict[str, int] = {}
# Iterates through all player keys
for p in players:
if(len(players[p]) > 0):
# Use bracket notation to extract the list from each player in the dictionary, then sum and divide by length.
# Then, assign this to a new key (using the same value p for the player name) in the result dict
avg_scores[p] = int(sum(players[p]) / len(players[p]))
else:
# No division by zero
avg_scores[p] = 0
return avg_scores
```

### Joining Salary Data

```
def join_salary_data(players: Dict[int, str], salaries: Dict[int, int]) -> Dict[str, int]:
"""Joins two dicts together based on common key values."""
# Start with a blank result
result: Dict[str, int] = {}
# Iterate through all the keys of the players, using that same key to extract the salary
for key in players:
if key in salaries:
# Update the result by using the value of the players as the new key, then assign the salary
# Ultimately, the original keys which were integers will not show up in the result.
result[players[key]] = salaries[key]
else:
# If the player did not have a key in salaries, assign -1
result[players[key]] = -1
return result
```

### Highest and Lowest Scores

```
def highest_and_lowest(items: Dict[str, int]) -> Dict[str, str]:
"""Finds the keys with the highest and lowest salaries."""
# Use -1 as a dummy max since scores cannot be negative. The idea is to compare to see if each value is greater than this.
max: int = -1
max_key: str = ""
# Use a high number as dummy min as scores will not be greater than this. T
min: int = 50000
min_key: str = ""
# Compare each item in the dictionary to see to find its max and min, updating not only the values but the keys
for key in items:
# The max and min variables are used as comparisons for each subsequent item
# The max_key and min_key needs to be tracked too since that's what we want to return at the end.
if max < items[key]:
max = items[key]
max_key = key
if items[key] < min:
min = items[key]
min_key = key
return {"max": max_key, "min": min_key}
```

### Comparing Scores

```
def compare_scores(player: Dict[str, List[int]], num_games: int) -> str:
"""Finds the player with the most consistently high score."""
tracker: Dict[str, int] = {}
max: int = -1
max_player: str = ""
i: int = 0
# num_games represents the number of games played by all players
while i < num_games:
# Go through each player
for key in player:
# Compare the ith item in the scores for each player, updating the max along the way
if player[key][i] > max:
max = player[key][i]
max_player = key
# Update the tracker dictionary by who got the highest score in that game (represented by max_player)
if max_player not in tracker:
# Initialize by 1 to represent that the player 'won' the highest score that game already
tracker[max_player] = 1
else:
# If already in the dictionary, update by 1
tracker[max_player] += 1
# Reset values for the next game
max = -1
max_player = ""
i += 1
# Use the highest and lowest function we already made to find who had the max number of highest scoring games
return highest_and_lowest(tracker)["max"]
```