## Proposition de corrigé

Code:
from typing import List, Optional
from dataclasses import dataclass

# Exercise 3 (a)
def count_divisors_of(n: int) -> int:
num_divisors = 1
for m in range(2, n + 1):
if n % m == 0:
num_divisors += 1
return num_divisors

# Exercise 3 (b)
def divisors_of(n: int) -> List[int]:
divisors = [1]
for m in range(2, n + 1):
if n % m == 0:
divisors.append(m)
return divisors

# Exercise 3 (c)
def sum_of(ints: List[int]) -> int:
sum = 0
for i in ints:
sum += i
return sum

# Exercise 3 (d)
def is_perfect(n: int) -> bool:
return sum_of(divisors_of(n)) - n == n

# Exercise 3 (e)
def show_perfect_numbers_up_to(max: int) -> None:
num_found = 0
candidate = 1
while candidate <= max:
if is_perfect(candidate):
num_found += 1
print(f"Nombre parfait numéro {num_found}: {candidate}")
candidate += 1
print(f"{num_found} nombres parfaits plus petits que {max} ont été trouvés")

print("--------------------")
print("---- Exercice 3 ----")
print("--------------------\n")

print(f"24 a {count_divisors_of(24)} diviseurs")
divisors_of_24 = divisors_of(24)
print(f"Les diviseurs de 24 sont {divisors_of_24}")
print(f"Leur somme est {sum_of(divisors_of_24)}")

show_perfect_numbers_up_to(1000)

print("\n")
print("--------------------")
print("---- Exercice 4 ----")
print("--------------------\n")

@dataclass
class Person:
id: int
name: str
age: int
best_friend: Optional['Person'] = None
worst_enemy: Optional['Person'] = None

luke = Person(0, "Luke", 19)
han = Person(1, "Han", 29)
chewie = Person(2, "Chewbacca", 200)
anakin = Person(3, "Anakin", 42)
yoda = Person(4, "Yoda", 896)
jabba = Person(5, "Jabba", 600)

han.best_friend = chewie
han.worst_enemy = jabba
chewie.best_friend = han
luke.worst_enemy = anakin
anakin.worst_enemy = anakin
jabba.worst_enemy = han

# Exercise 4 (c)
people = [ luke, han, chewie, anakin, yoda, jabba ]

for p in people:
print(p)

# Exercise 4 (d)
for p in people:
if p.best_friend is not None and p.worst_enemy is not None:
print(f"{p.name} a aussi bien un meilleur ami ({p.best_friend.name}) qu'un pire ennemi ({p.worst_enemy.name})")

# Exercise 4 (e)
for p in people:
if p.worst_enemy == p:
print(f"{p.name} est son propre pire ennemi")

# Exercise 4 (f)
for p in people:
if p.best_friend is None and p.worst_enemy is None:
print(f"{p.name} est-il apathique?")

# Exercise 4 (g)
for p in people:
if p.best_friend is not None and p.best_friend.best_friend == p and p.id < p.best_friend.id:
print(f"{p.name} et {p.best_friend.name} sont meilleurs amis symétriquement")

# Exercise 4 (h)
num_without_best_friend = 0
age_sum_witout_best_friend = 0
for p in people:
if p.best_friend is None:
num_without_best_friend += 1
age_sum_witout_best_friend += p.age

age_avg_without_best_friend = age_sum_witout_best_friend / num_without_best_friend
print(f"La moyenne d'âge des personnages sans meilleur ami est de {age_avg_without_best_friend} ans")

# Exercise 4 (i)
num_below_avg = 0
num_above_avg = 0
for p in people:
if p.best_friend is None:
if p.age > age_avg_without_best_friend:
num_above_avg += 1
elif p.age < age_avg_without_best_friend:
num_below_avg += 1

if num_below_avg == num_above_avg:
print("La moyenne est valable comme médiane")
else:
print("La moyenne n'est pas valable comme médiane")