Code:
from dataclasses import dataclass
from typing import List, Set, Dict

# 1
@dataclass
class Contact:
    first_name: str
    last_name: str
    gender: bool
    age: int
    height: float


# 2
all_contacts = [
    Contact("Josh", "Lyman", False, 42, 1.86),
    Contact("Toby", "Ziegler", False, 51, 1.78),
    Contact("Donna", "Moss", True, 25, 1.72),
    Contact("Jed", "Bartlet", False, 56, 1.75),
    Contact("Zoey", "Bartlet", True, 19, 1.69),
    Contact("Leo", "McGarry", False, 62, 1.77),
    Contact("C. J.", "Cregg", True, 43, 1.82),
    Contact("Sam", "Seaborn", False, 39, 1.71),
]

# 3
for c in all_contacts:
    print(c)
print("--")

# 4
def reverse(contacts: List[Contact]) -> List[Contact]:
    reversed: List[Contact] = []
    for i in range(len(contacts) - 1, -1, -1):
        reversed.append(contacts[i])
    return reversed


def reverse2(contacts: List[Contact]) -> List[Contact]:
    return contacts[::-1]


for c in reverse(all_contacts):
    print(c)
print("--")


# 5
def filter_by_gender(
    contacts: List[Contact], wanted_gender_as_bool: bool
) -> List[Contact]:
    filtered: List[Contact] = []
    for c in contacts:
        if c.gender == wanted_gender_as_bool:
            filtered.append(c)
    return filtered


def filter_by_gender2(
    contacts: List[Contact], wanted_gender_as_bool: bool
) -> List[Contact]:
    return [c for c in contacts if c.gender == wanted_gender_as_bool]


only_women = filter_by_gender(all_contacts, True)
only_men = filter_by_gender(all_contacts, False)

# 6
def calculate_average_age(contacts: List[Contact]) -> float:
    sum_age = 0
    for c in contacts:
        sum_age += c.age
    return sum_age / len(contacts)


def calculate_average_age2(contacts: List[Contact]) -> float:
    return sum([c.age for c in contacts]) / len(contacts)


print(calculate_average_age(all_contacts))
print(calculate_average_age(only_women))
print(calculate_average_age(only_men))


# 7
def calculate_maximum_height(contacts: List[Contact]) -> float:
    max_height = 0.0
    for c in contacts:
        if c.height > max_height:
            max_height = c.height
    return max_height


def calculate_maximum_height2(contacts: List[Contact]) -> float:
    return max([c.height for c in contacts])


print(calculate_maximum_height(all_contacts))
print(calculate_maximum_height(only_women))
print(calculate_maximum_height(only_men))


# 8
def count_first_names_of_length(l: int, contacts: List[Contact]) -> int:
    num = 0
    for c in contacts:
        if len(c.first_name) == l:
            num += 1
    return num


for l in 3, 4, 5:
    n = count_first_names_of_length(l, all_contacts)
    print(f"Il y a {n} contacts avec un prénom de taille {l}")
print("--")

# 9
def gather_first_names_alphabetically(contacts: List[Contact]) -> List[str]:
    first_names: Set[str] = set()
    for c in contacts:
        first_names.add(c.first_name)
    first_names_as_list = list(first_names)
    first_names_as_list.sort()
    return first_names_as_list


for fn in gather_first_names_alphabetically(all_contacts):
    print(fn)
print("--")

# 10
def build_letter_frequency_dict(contacts: List[Contact]) -> Dict[str, int]:
    letter_counts: Dict[str, int] = {}
    for c in contacts:
        for name in c.first_name, c.last_name:
            for char in name:
                char = char.lower()
                if char in letter_counts:
                    letter_counts[char] += 1
                else:
                    letter_counts[char] = 1
    return letter_counts


all_letter_counts = build_letter_frequency_dict(all_contacts)

# 11
def find_most_often_used_character(letter_counts: Dict[str, int]) -> str:
    num_max = 0
    char_max = ""
    for c, n in letter_counts.items():
        if n > num_max:
            num_max = n
            char_max = c
    return char_max


print(find_most_often_used_character(all_letter_counts))

# 12
def group_by_last_name(contacts: List[Contact]) -> Dict[str, Set[str]]:
    groups: Dict[str, Set[str]] = {}
    for c in contacts:
        if c.last_name in groups:
            groups[c.last_name].add(c.first_name)
        else:
            groups[c.last_name] = {c.first_name}
    return groups


print(group_by_last_name(all_contacts))
Last modified: Friday, 18 December 2020, 10:16