Examen Python 16

EXAMEN EN PYTHON SUJET 16

EXAMEN : GESTION DE STOCKS ET ANALYSE DE VENTES

Exercice 1 : Questions de cours – Généralités (4pts)

  1. Expliquez la différence entre mutabilité et immutabilité en Python avec un exemple.

  2. Quel est le rôle du paramètre key dans les fonctions sorted(), max() et min() ? Donnez un exemple.

  3. Quelle est la différence entre return et print dans une fonction Python ?

  4. Expliquez ce qu'est une compréhension de liste et donnez un exemple.

  5. Que sont les arguments par défaut dans les fonctions ? Donnez un exemple.


Exercice 2 : Analyse des stocks (3pts)

Une boutique dispose d'un inventaire représenté par une liste de tuples (produit, quantité, prix_unitaire).

Écrire une fonction analyse_stock(inventaire, seuil=5) qui retourne :

  1. La valeur totale du stock
  2. Les produits dont la quantité est inférieure au seuil (sous forme de liste de tuples (produit, quantité))
  3. Le produit ayant la plus grande valeur en stock (quantité × prix) sous forme de tuple (nom, valeur)

Exercice 3 : Compression de données clients (3pts)

Une entreprise possède une liste de commandes clients sous forme [client, produit, prix].

Écrire deux fonctions :

  1. compresser_commandes(liste) qui regroupe par client et retourne un dictionnaire {client: [liste des prix]}
  2. statistiques_client(dictionnaire_compressé, client) qui retourne pour un client donné :
    • nombre de commandes
    • prix total
    • prix moyen

Exercice 4 : Filtrage et transformation avec lambda (2pts)

À partir d'une liste de dictionnaires représentant des produits [{"nom": "A", "prix": 10, "stock": 5}, ...], utiliser des fonctions lambda avec filter() et map() pour :

  1. Filtrer les produits en rupture de stock (stock = 0)
  2. Créer une liste des noms des produits dont le prix est supérieur à un seuil donné
  3. Appliquez une réduction de 10% sur tous les produits dont le stock est > 10

Problème : Gestion d'une bibliothèque (8pts)

Partie A : Gestion des livres (4pts)

Données :

bibliotheque = [
    ("1984", "George Orwell", 1949, 8.99, 3),
    ("Le Petit Prince", "Antoine de Saint-Exupéry", 1943, 7.50, 5),
    ("Dune", "Frank Herbert", 1965, 12.99, 2),
    ("Fondation", "Isaac Asimov", 1951, 11.50, 4),
    ("Harry Potter", "J.K. Rowling", 1997, 15.99, 1)
]
# Format: (titre, auteur, année, prix, exemplaires)
    

Questions :

  1. Afficher le nom de chaque livre suivi de son auteur, son année, son prix et son nombre d'exemplaires.

  2. Créer une liste des livres publiés après 1950 et l'afficher.

  3. Trouver et afficher :

    • Le livre le plus cher
    • Le livre le moins cher
    • Le prix moyen pondéré par le nombre d'exemplaires
  4. Trier les livres par année de publication (du plus ancien au plus récent) et afficher le résultat.

Partie B : Gestion des emprunts (4pts)

Données :

emprunts = {
    "Alice": [("1984", "2024-01-15"), ("Dune", "2024-01-20")],
    "Bob": [("Fondation", "2024-01-10")],
    "Charlie": [("Harry Potter", "2024-01-05"), ("1984", "2024-01-12"), ("Le Petit Prince", "2024-01-18")],
    "Diane": []
}
    

Questions :

  1. Écrire une fonction total_emprunts(dictionnaire_emprunts) qui retourne le nombre total d'emprunts.

  2. Écrire une fonction livre_plus_emprunte(dictionnaire_emprunts) qui retourne le livre le plus emprunté et son nombre d'emprunts.

  3. Écrire une fonction utilisateur_plus_actif(dictionnaire_emprunts) qui retourne l'utilisateur ayant emprunté le plus de livres et son nombre d'emprunts.

  4. Écrire une fonction suggerer_livres(utilisateur, dictionnaire_emprunts, catalogue) qui suggère à un utilisateur des livres du même auteur que ceux qu'il a déjà empruntés (sans suggérer ceux déjà empruntés).

  5. Écrire une fonction valeur_emprunts_utilisateur(utilisateur, dictionnaire_emprunts, catalogue) qui calcule la valeur totale des livres empruntés par un utilisateur.


Fin de l'examen réaliser par Mr joel yankam

Correction :

correction examen


Exercice 1 : Questions de cours – Généralités (4pts)

1. Différence entre mutabilité et immutabilité en Python

Correction :
En Python, un objet mutable peut être modifié après sa création, tandis qu'un objet immutable ne le peut pas.

Exemple :

# Liste (mutable)
ma_liste = [1, 2, 3]
ma_liste[0] = 10  # Modification possible
print(ma_liste)  # [10, 2, 3]

# Tuple (immutable)
mon_tuple = (1, 2, 3)
# mon_tuple[0] = 10  # Erreur ! TypeError
print(mon_tuple)  # (1, 2, 3) - inchangé

Explication : Les listes sont mutables car on peut modifier leur contenu sans changer leur identité. Les tuples sont immutables car toute tentative de modification crée un nouvel objet.


2. Le paramètre key dans les fonctions sorted(), max(), min()

Correction :
Le paramètre key permet de spécifier une fonction qui sera appliquée à chaque élément pour déterminer la valeur de comparaison.

Exemple :

etudiants = [("Alice", 15), ("Bob", 12), ("Charlie", 18)]
# Trier par note (deuxième élément)
tries = sorted(etudiants, key=lambda x: x[1])
print(tries)  # [('Bob', 12), ('Alice', 15), ('Charlie', 18)]

# Trouver l'étudiant avec la note max
meilleur = max(etudiants, key=lambda x: x[1])
print(meilleur)  # ('Charlie', 18)

Explication : La fonction lambda lambda x: x[1] extrait la note de chaque tuple, et c'est sur cette valeur que se fait la comparaison.


3. Différence entre return et print dans une fonction

Correction :
- return renvoie une valeur qui peut être utilisée dans le programme
- print affiche une valeur mais ne la renvoie pas

Exemple :

def fonction_avec_return(x):
    return x * 2

def fonction_avec_print(x):
    print(x * 2)

resultat1 = fonction_avec_return(5)  # resultat1 = 10
resultat2 = fonction_avec_print(5)   # Affiche 10, mais resultat2 = None

print(f"Résultat avec return: {resultat1}")  # Résultat avec return: 10
print(f"Résultat avec print: {resultat2}")   # Résultat avec print: None

Explication : return permet de récupérer une valeur pour une utilisation ultérieure, print sert uniquement à l'affichage.


4. Les compréhensions de listes

Correction :
Une compréhension de liste est une syntaxe concise pour créer des listes à partir d'autres séquences.

Exemple :

# Créer une liste des carrés de 0 à 9
carres = [x**2 for x in range(10)]
print(carres)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# Avec condition (nombres pairs)
pairs = [x for x in range(10) if x % 2 == 0]
print(pairs)  # [0, 2, 4, 6, 8]

# Sans compréhension (équivalent)
carres_sans_comp = []
for x in range(10):
    carres_sans_comp.append(x**2)

Explication : La syntaxe [expression for élément in séquence if condition] est plus concise et souvent plus lisible que les boucles traditionnelles.


5. Les arguments par défaut dans les fonctions

Correction :
Les arguments par défaut permettent de donner une valeur par défaut à un paramètre si l'appelant ne fournit pas d'argument.

Exemple :

def saluer(nom, message="Bonjour"):
    return f"{message}, {nom}!"

print(saluer("Alice"))           # Bonjour, Alice!
print(saluer("Bob", "Salut"))    # Salut, Bob!
print(saluer(nom="Charlie", message="Bienvenue"))  # Bienvenue, Charlie!

Explication : Les paramètres avec valeurs par défaut doivent être placés après les paramètres sans valeur par défaut.


Exercice 2 : Analyse des stocks (3pts)

Énoncé :
Une boutique dispose d'un inventaire représenté par une liste de tuples (produit, quantité, prix_unitaire). Écrire une fonction qui retourne :

  1. La valeur totale du stock
  2. Les produits dont la quantité est inférieure à un seuil donné (paramètre optionnel avec valeur par défaut de 5)
  3. Le produit ayant la plus grande valeur en stock (quantité × prix)

Correction :

def analyse_stock(inventaire, seuil=5):
    if not inventaire:
        return 0, [], None
    
    # 1. Valeur totale du stock
    valeur_totale = sum(quantite * prix for _, quantite, prix in inventaire)
    
    # 2. Produits avec stock faible
    stock_faible = [(produit, quantite) for produit, quantite, prix in inventaire 
                    if quantite < seuil]
    
    # 3. Produit avec plus grande valeur
    produit_max = max(inventaire, key=lambda x: x[1] * x[2])
    nom_max, quantite_max, prix_max = produit_max
    valeur_max = quantite_max * prix_max
    
    return valeur_totale, stock_faible, (nom_max, valeur_max)

# Test
stock = [
    ("Stylo", 10, 1.5),
    ("Cahier", 3, 2.0),
    ("Gomme", 8, 0.8),
    ("Règle", 2, 1.2)
]

total, faible, meilleur = analyse_stock(stock)
print(f"Valeur totale du stock: {total:.2f} €")
print(f"Produits en stock faible: {faible}")
print(f"Produit de plus grande valeur: {meilleur[0]} ({meilleur[1]:.2f} €)")

# Avec seuil personnalisé
total, faible, meilleur = analyse_stock(stock, seuil=4)
print(f"\nAvec seuil=4 - Produits faibles: {faible}")

Exercice 3 : Compression de données clients (3pts)

Énoncé :
Une entreprise possède une liste de commandes clients sous forme [client, produit, prix]. Écrire deux fonctions :

  1. compresser_commandes(liste) qui regroupe par client et retourne un dictionnaire {client: [liste des prix]}
  2. statistiques_client(dictionnaire_compressé, client) qui retourne pour un client donné : nombre de commandes, prix total, prix moyen

Correction :

def compresser_commandes(commandes):
    """Compresse la liste de commandes en dictionnaire par client"""
    resultat = {}
    
    for client, produit, prix in commandes:
        if client not in resultat:
            resultat[client] = []
        resultat[client].append(prix)
    
    return resultat

def statistiques_client(dictionnaire, client):
    """Retourne les statistiques pour un client donné"""
    if client not in dictionnaire:
        return 0, 0, 0
    
    prix = dictionnaire[client]
    nb_commandes = len(prix)
    prix_total = sum(prix)
    prix_moyen = prix_total / nb_commandes if nb_commandes > 0 else 0
    
    return nb_commandes, prix_total, prix_moyen

# Test
commandes = [
    ("Alice", "Stylo", 2.5),
    ("Bob", "Cahier", 3.0),
    ("Alice", "Gomme", 1.2),
    ("Charlie", "Règle", 1.8),
    ("Alice", "Cahier", 3.0),
    ("Bob", "Stylo", 2.5)
]

# Compression
compresse = compresser_commandes(commandes)
print("Commandes compressées par client:")
for client, prix in compresse.items():
    print(f"  {client}: {prix}")

# Statistiques pour Alice
nb, total, moyen = statistiques_client(compresse, "Alice")
print(f"\nStatistiques pour Alice:")
print(f"  Nombre de commandes: {nb}")
print(f"  Total des achats: {total:.2f} €")
print(f"  Prix moyen: {moyen:.2f} €")

# Statistiques pour un client inexistant
nb, total, moyen = statistiques_client(compresse, "David")
print(f"\nStatistiques pour David: {nb} commandes, {total} €")

Exercice 4 : Filtrage et transformation avec lambda (2pts)

Énoncé :
À partir d'une liste de dictionnaires représentant des produits [{"nom": "A", "prix": 10, "stock": 5}, ...], utiliser des fonctions lambda avec filter() et map() pour :

  1. Filtrer les produits en rupture de stock (stock = 0)
  2. Créer une liste des noms des produits dont le prix est supérieur à un seuil
  3. Appliquer une réduction de 10% sur tous les produits dont le stock est > 10

Correction :

def gerer_produits(produits, seuil_prix=15):
    # 1. Produits en rupture de stock
    rupture = list(filter(lambda p: p["stock"] == 0, produits))
    
    # 2. Noms des produits avec prix > seuil
    noms_chers = list(map(lambda p: p["nom"], 
                         filter(lambda p: p["prix"] > seuil_prix, produits)))
    
    # 3. Appliquer réduction de 10% sur stock > 10
    produits_avec_reduction = list(map(
        lambda p: {**p, "prix": round(p["prix"] * 0.9, 2)} if p["stock"] > 10 else p,
        produits
    ))
    
    return rupture, noms_chers, produits_avec_reduction

# Test
catalogue = [
    {"nom": "Stylo", "prix": 2.5, "stock": 15},
    {"nom": "Cahier", "prix": 4.0, "stock": 0},
    {"nom": "Sac", "prix": 25.0, "stock": 3},
    {"nom": "Trousse", "prix": 8.5, "stock": 12},
    {"nom": "Agenda", "prix": 12.0, "stock": 0}
]

rupture, chers, nouveau_catalogue = gerer_produits(catalogue, seuil_prix=10)

print("1. Produits en rupture:")
for p in rupture:
    print(f"   {p['nom']}")

print(f"\n2. Produits avec prix > 10€: {chers}")

print("\n3. Catalogue après réduction:")
for p in nouveau_catalogue:
    print(f"   {p['nom']}: {p['prix']}€ (stock: {p['stock']})")

Problème : Gestion d'une bibliothèque (8pts)

Partie A : Gestion des livres (4pts)

Données :

bibliotheque = [
    ("1984", "George Orwell", 1949, 8.99, 3),
    ("Le Petit Prince", "Antoine de Saint-Exupéry", 1943, 7.50, 5),
    ("Dune", "Frank Herbert", 1965, 12.99, 2),
    ("Fondation", "Isaac Asimov", 1951, 11.50, 4),
    ("Harry Potter", "J.K. Rowling", 1997, 15.99, 1)
]
# Format: (titre, auteur, année, prix, exemplaires)

1. Afficher les informations de chaque livre

print("=== INVENTAIRE DE LA BIBLIOTHÈQUE ===\n")

for livre in bibliotheque:
    titre, auteur, annee, prix, exemplaires = livre
    print(f"? {titre}")
    print(f"   Auteur: {auteur}")
    print(f"   Année: {annee}")
    print(f"   Prix: {prix:.2f} €")
    print(f"   Exemplaires: {exemplaires}")
    print()

2. Créer une liste des livres récents (après 1950)

print("=== LIVRES PUBLIÉS APRÈS 1950 ===\n")

livres_recents = [livre for livre in bibliotheque if livre[2] > 1950]

for livre in livres_recents:
    titre, auteur, annee, prix, exemplaires = livre
    print(f"• {titre} ({annee}) - {auteur}")

3. Trouver le livre le plus cher et le moins cher

print("\n=== PRIX DES LIVRES ===\n")

# Livre le plus cher
livre_cher = max(bibliotheque, key=lambda x: x[3])
titre_cher, auteur_cher, annee_cher, prix_cher, ex_cher = livre_cher
print(f" Livre le plus cher: {titre_cher} - {prix_cher:.2f} €")

# Livre le moins cher
livre_pas_cher = min(bibliotheque, key=lambda x: x[3])
titre_pc, auteur_pc, annee_pc, prix_pc, ex_pc = livre_pas_cher
print(f"? Livre le moins cher: {titre_pc} - {prix_pc:.2f} €")

# Prix moyen
prix_moyen = sum(livre[3] * livre[4] for livre in bibliotheque) / sum(livre[4] for livre in bibliotheque)
print(f"? Prix moyen pondéré par stock: {prix_moyen:.2f} €")

4. Trier les livres par année de publication (du plus ancien au plus récent)

print("\n=== LIVRES TRIÉS PAR ANNÉE (ANCIEN → RÉCENT) ===\n")

livres_tries = sorted(bibliotheque, key=lambda x: x[2])

for livre in livres_tries:
    titre, auteur, annee, prix, exemplaires = livre
    print(f"{annee} - {titre} ({auteur})")

Partie B : Gestion des emprunts (4pts)

Données :

emprunts = {
    "Alice": [("1984", "2024-01-15"), ("Dune", "2024-01-20")],
    "Bob": [("Fondation", "2024-01-10")],
    "Charlie": [("Harry Potter", "2024-01-05"), ("1984", "2024-01-12"), ("Le Petit Prince", "2024-01-18")],
    "Diane": []
}

1. Fonction pour compter le nombre total d'emprunts

def total_emprunts(dictionnaire_emprunts):
    total = 0
    for emprunts_utilisateur in dictionnaire_emprunts.values():
        total += len(emprunts_utilisateur)
    return total

print("=== STATISTIQUES DES EMPRUNTS ===\n")
print(f"Nombre total d'emprunts: {total_emprunts(emprunts)}")

2. Fonction pour trouver le livre le plus emprunté

def livre_plus_emprunte(dictionnaire_emprunts):
    compteur = {}
    
    for emprunts_utilisateur in dictionnaire_emprunts.values():
        for livre, date in emprunts_utilisateur:
            if livre in compteur:
                compteur[livre] += 1
            else:
                compteur[livre] = 1
    
    if not compteur:
        return None, 0
    
    livre_max = max(compteur.items(), key=lambda x: x[1])
    return livre_max

livre_pop, nb_emprunts = livre_plus_emprunte(emprunts)
print(f"Livre le plus emprunté: '{livre_pop}' ({nb_emprunts} fois)")

3. Fonction pour trouver l'utilisateur le plus actif

def utilisateur_plus_actif(dictionnaire_emprunts):
    if not dictionnaire_emprunts:
        return None, 0
    
    utilisateur_max = max(dictionnaire_emprunts.items(), 
                         key=lambda x: len(x[1]))
    return utilisateur_max[0], len(utilisateur_max[1])

user_actif, nb_emprunts_user = utilisateur_plus_actif(emprunts)
print(f"Utilisateur le plus actif: {user_actif} ({nb_emprunts_user} emprunts)")

4. Fonction pour suggérer des livres à un utilisateur

def suggerer_livres(utilisateur, dictionnaire_emprunts, catalogue):
    """
    Suggère des livres du même auteur que ceux déjà empruntés
    """
    if utilisateur not in dictionnaire_emprunts:
        return []
    
    # Livres déjà empruntés par l'utilisateur
    livres_empruntes = [livre for livre, date in dictionnaire_emprunts[utilisateur]]
    
    if not livres_empruntes:
        return []
    
    # Trouver les auteurs des livres empruntés
    auteurs_interets = set()
    for livre in livres_empruntes:
        for livre_catalogue in catalogue:
            if livre_catalogue[0] == livre:  # Si titre correspond
                auteurs_interets.add(livre_catalogue[1])  # Ajouter l'auteur
                break
    
    # Suggérer d'autres livres de ces auteurs
    suggestions = []
    for livre in catalogue:
        titre, auteur, annee, prix, exemplaires = livre
        if auteur in auteurs_interets and titre not in livres_empruntes:
            suggestions.append((titre, auteur, annee))
    
    return suggestions

print("\n=== SUGGESTIONS DE LIVRES ===\n")
suggestions = suggerer_livres("Charlie", emprunts, bibliotheque)
print("Suggestions pour Charlie (aime Orwell et Herbet):")
for titre, auteur, annee in suggestions:
    print(f"  • {titre} ({auteur}, {annee})")

5. Fonction pour calculer la valeur totale des livres empruntés

def valeur_emprunts_utilisateur(utilisateur, dictionnaire_emprunts, catalogue):
    """
    Calcule la valeur totale des livres empruntés par un utilisateur
    """
    if utilisateur not in dictionnaire_emprunts:
        return 0
    
    # Créer un dictionnaire des prix des livres
    prix_livres = {livre[0]: livre[3] for livre in catalogue}
    
    valeur_totale = 0
    for livre, date in dictionnaire_emprunts[utilisateur]:
        if livre in prix_livres:
            valeur_totale += prix_livres[livre]
    
    return valeur_totale

print("\n=== VALEUR DES EMPRUNTS ===\n")
for utilisateur in emprunts.keys():
    valeur = valeur_emprunts_utilisateur(utilisateur, emprunts, bibliotheque)
    print(f"{utilisateur}: {valeur:.2f} € de livres empruntés")

Fin de l'examen

 

Questions / Réponses

Aucune question. Soyez le premier à poser une question.
Aucune note. Soyez le premier à attribuer une note !

Ajouter un commentaire

Anti-spam