Code:
from dataclasses import dataclass

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

xs: list[float] = [0.0, 5.0, 6.0, 9.0, 10.0]
ys: list[float] = [0.0, 5.0, 1.0, 1.0, 8.0]

### 3 (a)

# Ajout d'une erreur dans les données:
# ceci ajoute une valeur à ys sans ajouter une valeur
# correspondante dans xs et crée ainsi une incohérence
ys.append(1000)

p = len(xs)
if p == len(ys):
    print("Data OK")
else:
    print("Correcting length mismatch")
    p = min(p, len(ys))
    xs = xs[:p]
    ys = ys[:p]


### 3 (b)

print("Considered points: ", end="")
for i in range(p - 1):
    print(f"({xs[i]}, {ys[i]})", end=", ")
print(f"({xs[p - 1]}, {ys[p - 1]})")


### 3 (c)


def is_monotonic_increasing(values: list[float]) -> bool:
    for i in range(1, len(values)):
        if values[i] <= values[i - 1]:
            return False
    return True


print(f"xs is monotonic inscreasing: {is_monotonic_increasing(xs)}")
print(f"ys is monotonic inscreasing: {is_monotonic_increasing(ys)}")


### 3 (d)


def interpolated_y(x: float) -> float:
    for i in range(1, p):
        if xs[i - 1] <= x <= xs[i]:
            y = ys[i - 1] + (ys[i] - ys[i - 1]) * (x - xs[i - 1]) / (xs[i] - xs[i - 1])
            return y
    return float("nan")


### 3 (e)

for i in range(100 + 1):
    x = i / 10
    y = interpolated_y(x)
    print(f"x={x} -> y={y}")


### 3 (f)

num_mismatch = 0
for i in range(p):
    x, y = xs[i], ys[i]
    y_int = interpolated_y(x)
    if y != y_int:
        print(f"Mismatch for x={x}: should be {y}, but computed {y_int}")
        num_mismatch += 1

if num_mismatch == 0:
    print("No mismatch found")


### 3 (g)


def areas_under_curve(xs: list[float], ys: list[float]) -> list[float]:
    areas: list[float] = []
    for i in range(1, p):
        mean_height = (ys[i] + ys[i - 1]) / 2
        width = xs[i] - xs[i - 1]
        local_area = mean_height * width
        areas.append(local_area)
    return areas


areas = areas_under_curve(xs, ys)
print(areas)

sum_areas = 0.0
for a in areas:
    sum_areas += a
print(f"Total area: {sum_areas}")


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


### 4 (a) & (b)


@dataclass
class Task:
    person: str
    title: str
    start_day: int
    duration: int
    difficulty: float


tasks = [
    Task("Bernard", "Overview", 0, 2, 0.5),
    Task("Heidi", "Frontend", 1, 4, 0.9),
    Task("Gabriel", "Kickoff", 0, 1, 0.2),
    Task("Morgane", "Backend", 0, 3, 0.8),
    Task("Bernard", "Demos", 3, 2, 0.7),
    Task("Gabriel", "Database", 1, 3, 0.8),
    Task("Morgane", "Tests", 3, 2, 0.65),
]

for task in tasks:
    print(task)


### 4 (c)

occupations: dict[str, list[str]] = {}

for task in tasks:
    if task.person not in occupations:
        occupations[task.person] = ["", "", "", "", ""]
    for day in range(task.start_day, task.start_day + task.duration):
        occupations[task.person][day] = task.title

for person, occupation in occupations.items():
    print(f"{person}'s occupation: {occupation}")


### 4 (d)

for person, occupation in occupations.items():
    for i, title in enumerate(occupation):
        if len(title) == 0:
            print(f"{person} has nothing to do on day {i}")


### 4 (e)

days_booked: dict[str, set[int]] = {}

num_conflicts = 0
for task in tasks:
    if task.person not in days_booked:
        days_booked[task.person] = set()
    persons_days = days_booked[task.person]
    for day in range(task.start_day, task.start_day + task.duration):
        if day in persons_days:
            print(f"{task.person} should work on “{task.title}” on day {day} but is already busy")
            num_conflicts += 1
        else:
            persons_days.add(day)

if num_conflicts == 0:
    print(f"No conflicts detected")


### 4 (f)

difficulties: dict[str, float] = {}
for task in tasks:
    if task.person not in difficulties:
        difficulties[task.person] = 0
    difficulties[task.person] += task.difficulty * task.duration

max_diff = 0.0
max_person = ""
for person, total_difficulty in difficulties.items():
    if total_difficulty > max_diff:
        max_diff = total_difficulty
        max_person = person

print(f"{max_person} has the largest sum of difficulties: {max_diff}")
Last modified: Saturday, 23 March 2024, 14:22