#Exercice 1
def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b


# Test
for x in fibonacci(10):
    print(x, end=" ")

###########################################################
#Exercice 2
from collections import deque

# Classe Pile (LIFO)
class Pile:
    def __init__(self):
        self.data = []

    def append(self, element):
        self.data.append(element)

    def pop(self):
        if not self.data:
            raise IndexError("Pile vide")
        return self.data.pop()


# Classe File (FIFO)
class File:
    def __init__(self):
        self.data = deque()

    def append(self, element):
        self.data.append(element)

    def pop(self):
        if not self.data:
            raise IndexError("File vide")
        return self.data.popleft()


# Tests
p = Pile()
p.append(1)
p.append(2)
print(p.pop())  # 2

f = File()
f.append(1)
f.append(2)
print(f.pop())  # 1

###########################################################
#Exercice 3
def filtre_positifs():
    print("Coroutine démarrée...")
    while True:
        nombre = yield
        if nombre > 0:
            print("Positif :", nombre)


# Utilisation
c = filtre_positifs()
next(c)  # Initialisation

c.send(5)
c.send(-3)
c.send(10)

###########################################################
#Exercice 4
from collections import Counter

phrase = "python est puissant et python est simple"
mots = phrase.split()

compteur = Counter(mots)
print(compteur)
###########################################################
#Exercice 5
from collections import defaultdict

etudiants = [
    ("Alice", "Informatique"),
    ("Bob", "Maths"),
    ("Charlie", "Informatique"),
]

groupes = defaultdict(list)

for nom, filiere in etudiants:
    groupes[filiere].append(nom)

print(dict(groupes))


###########################################################
#Exercice 6

from collections import namedtuple
import math

Point = namedtuple("Point", ["x", "y"])

p = Point(3, 4)

distance = math.sqrt(p.x**2 + p.y**2)
print("Distance :", distance)

###########################################################
#Exercice 7
from functools import reduce

nombres = [1, 2, 3, 4, 5, 6]

# Doubler les nombres
doubles = list(map(lambda x: x * 2, nombres))

# Garder les nombres pairs
pairs = list(filter(lambda x: x % 2 == 0, nombres))

# Somme des éléments
somme = reduce(lambda x, y: x + y, nombres)

print("Doubles :", doubles)
print("Pairs :", pairs)
print("Somme :", somme)











