# data[].attributes.headline
Module : Culture et Techniques Avancées du Numérique

# data[].attributes.subject
Module : Culture et Techniques Avancées du Numérique

# data[].attributes.body
Groupes DEV 101 => https://docs.google.com/spreadsheets/d/1NJ2CQtnh9CBocI9p1lnzdie5jC4jX8RVBW4EmSN221w/edit?usp=sharing

===============================

Groupes DEV 102 =>

https://docs.google.com/spreadsheets/d/1eKRCkewt4LjL0SglRKa-DvKhXMrgLM9KMdUwFAL5fgE/edit?usp=sharing

# data[].attributes.attachment_link.description
Organize anything, together. Trello is a collaboration tool that organizes your projects into boards. In one glance, know what’s being worked on, who’s working on what, and where something is in a process.

# data[].attributes.headline
SSI (Sécurité des Systèmes d'Information): Sujets des présentations et Prise en charge

# data[].attributes.subject
SSI (Sécurité des Systèmes d'Information): Sujets des présentations et Prise en charge

# data[].attributes.body
Répartition par Groupes :

DEV102 : https://docs.google.com/spreadsheets/d/1Cn88QrJ8NdVGhgjs34m8T4rAq_sLacHoz-GgUrfdiZs/edit?usp=sharing

DEV101 :

https://docs.google.com/spreadsheets/d/1r-cLrgDNQglWNkI8jBiIPcwFZzyRw4EpKYQO-7XH4qk/edit?usp=sharing

# data[].attributes.attachment_link.description
Organize anything, together. Trello is a collaboration tool that organizes your projects into boards. In one glance, know what’s being worked on, who’s working on what, and where something is in a process.

# data[].attributes.headline
SWD: Forms - Accès BD - Sessions - Cookies - Constantes magiques - Importation de fichiers

# data[].attributes.subject
SWD: Forms - Accès BD - Sessions - Cookies - Constantes magiques - Importation de fichiers

# data[].attributes.body
DEV101 => YN

DEV102 => YN

===============================

Démo de l'app (sans utilisation de 'design arena ai'): https://drive.google.com/file/d/19TVBSz66UpW8K7yQMFhWfe6d89JCBQrQ/view?usp=sharing

===============================

Travail à faire:

Etape 1:

Analyser l'application afin de:

Assimiler comment implémenter un CRUD MySQL (Ajout, Suppression, Extraction) MySQL à partir des formulaires.

Assimiler comment interagir avec les sessions:

Ouverture/Fermeture

Manipulation des variables de session en lecture/écriture

Assimiler comment manipuler les cookies:

Création/Remplissage/Modification

Suppression

Lecture

Découvrir les constantes magiques

Découvrir différentes méthodes d'importation

Etape 2:

[N.B: Utiliser la plateforme 'design arena ai' pour redéfinir de design de l'application d'une manière plus professionnelle]

Travail à faire:

Implémenter une Inscription/authentification professionnelle, à travers:

L'ajout d'une page d'inscription qui permet d'inscrire des utilisateurs en fournissant leurs nom d'utilisateur, email, et mot de passe;

Pour des mesures de sécurité:

On impose de resaisir le mot de passe et on s'assure que les deux saisies sont identiques;

On stocke le haché du mot de passe, au lieu de le stocker en clair

Lors de la pase d'authentification, la vérification de l'existence de l'utilsateur et la corespondance du mot de passe; On veillera à ce que des feedbacks adéquats soient renvoyés à l'utilisateur

Modifier la page index.php de manière à exporter les différentes fonctionnalités dans des pages séparées;

Pour ce faire, on développera les pages suivantes:

index_cli.php : affiche la liste des clients, avec pour chaque client le bouton 'Supprimer' qui permer de supprimer le client après confirmation, et le bouton 'Editer' qui mène vers la page modifier_cli.php qui affiche un formulaire pré-rempli des données du client avec le bouton 'Modifier' et le bouton 'Retour';

De même, au dessus de la liste, à gauche on a le bouton 'Ajouter' qui mène vers la page ajouter_cli.php qui affiche un formulaire avec le bouton 'Ajouter' et le bouton 'Retour';

modifier_theme.php : mène vers le formulaire qui permet de changer le thème de l'application; le thème doit être appliqué à toute les pages

On ajouter un menu qui permet d'accéder aux deux fonctionnalités : 'Gérer Clients' et 'Personnaliser Thème'

Ajouter une page d'accueil accueil.php

Toutes les pages possèdent le même 'header' et 'footer'

N.B : Utiliser la plateforme 'design arena ai' pour redéfinir le design de l'application

====================

Takeaway => https://trello.com/c/F25Emohs

# data[].attributes.body
DEV101 => NN

DEV102 => NN

===============================

Ref: Exercice : Navigation intelligente avec redirections

==============================

Partie D — Personnalisation avec Cookies

Ajouter au menu principal une nouvelle rubrique :

Personnalisation

Cette partie permettra à l’utilisateur de :

choisir une couleur d’arrière-plan

mémoriser son nom

afficher la date/heure de la dernière visite

Modification de la Partie A — Menu principal

Ajouter dans la page d'accueil :

Nouvelle rubrique

Personnalisation
- Personnaliser mon espace

Redirection vers :

personnalisation.php

Partie D.1 — Page personnalisation.php

Créer un formulaire permettant de :

Activer (set/get) la fonctionnalité de la date/heure de la dernière visite

Saisir le nom d'utilisateur

Selectionner la couleur préférée :

bleu
vert
rouge
jaune

Bouton :

Enregistrer mes préférences

Traitement demandé

Quand l’utilisateur valide :

Créer / modifier les cookies :

nom
couleur

Durée :

1 heure

Puis rediriger vers :

personnalisation.php?msg=saved

Partie D.2 — Exploitation de la couleur

Dans toutes les pages du site :

blue → bleu clair

green → vert clair

red → rouge clair

yellow → jaune clair

sinon → gris clair par défaut

Partie D.3 — Affichage du nom

Si cookie nom existe, afficher en haut des pages :

Bienvenue NOM

Partie D.4 — Dernière visite

Créer un cookie :

derniere_visite

À chaque chargement de page :

Si le cookie existe :

Afficher :

Dernière visite : 29/04/2026 à 18:45:10

Ensuite mettre à jour le cookie avec la date/heure actuelle

Partie D.5 — Réinitialisation

Ajouter le bouton :

Supprimer mes préférences

pour supprimer :

nom
couleur
derniere_visite

Puis rediriger vers la page d'accueil avec msg=reset

# data[].attributes.body
DEV101 => YN

DEV102 => YN

=========================================

Exercice : Navigation intelligente avec redirections

Partie A — Menu principal

Créer une page index.php contenant :

Espace étudiant:

- Déposer mon devoir

- Consulter ma note

- Télécharger ma correction

Espace professeur

- Télécharger Devoirs

- Charger Corrections

Liens utiles

- Ouvrir les plateforme OFPPT et w3schools dans de nouvels onglets (JavaScript)

Partie B : Espace étudiants

Après avoir saisi son cne, l'étudiant est redirigé vers une page qui présente un menu lui permettant de

1. Déposer son devoir

2. Consulter sa note

3. Télécharger sa correction

Partie B : Espace professeurs

Le professeur est directement redirigé vers une page qui présente un menu lui permettant de

1. Télécharger les devoirs des étudiants

2. Charger les corrections des étudiants

Partie C: Liens utiles

L'utilisateur est directement redirigé vers une page qui présente un menu lui montarant

1. Le bouton 'Visiter OFPPT' qui ouvre le lien https://www.ofppt.ma/ dans un nouvel onglet

2. Le bouton 'Visiter W3schools' qui ouvre le lien https://www.w3schools.com/ dans un nouvel onglet

# data[].attributes.headline
SWD: Download des fichiers à partir du serveur Web + Exercice

# data[].attributes.subject
SWD: Download des fichiers à partir du serveur Web + Exercice

# data[].attributes.body
DEV101 => YN

DEV102 => Y(Y)

===============================

Ref: Exercice : Dépôt de devoir et consultation de la note

Travail à faire:

Modifier l'application de façon à:

-Permettre au professeurs de télécharger les travaux des étudiants

-Permettre aux étudiants de télécharger les fichiers de correction

# data[].attributes.headline
SWD: Upload des fichiers dans le serveur Web + Exercice

# data[].attributes.subject
SWD: Upload des fichiers dans le serveur Web + Exercice

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Exercice : Dépôt de devoir et consultation de la note

Contexte

On veut développer une petite application PHP permettant :

1. à l’étudiant de déposer son devoir ;

2. au professeur de renseigner la note dans un fichier séparé ;

3. à l’étudiant de consulter sa note plus tard.

Le devoir original ne doit pas être modifié.
La note sera enregistrée dans un fichier texte séparé associé au devoir.

Principe de fonctionnement

Exemple

L’étudiant envoie un fichier :

devoirs/devoir_cne-10000.txt

Le professeur crée ensuite un fichier séparé :

corrections/devoir_cne-10000_note.txt

Contenu possible :

note: 19.25/20
commentaire: Bon travail, devoir clair et bien structuré.

Ensuite, l’application doit pouvoir lire ce fichier de correction et afficher la note à l’étudiant.

Travail demandé

Partie 1 : Dépôt du devoir

Créer un formulaire permettant à l’étudiant de :

saisir son nom ;

choisir son fichier ;

envoyer son devoir.

Contraintes :

fichiers autorisés : pdf, docx, txt

taille maximale : 5 Mo

enregistrement dans le dossier devoirs/

Partie 2 : Consultation de la note

Créer un deuxième formulaire permettant à l’étudiant de :

saisir son cne ;

cliquer sur un bouton Consulter ma note

Le script doit alors :

1. construire le nom du fichier de correction correspondant ;

2. vérifier si ce fichier existe dans corrections/, sinon afficher le message: "correction non pas encore faite" ;

3. afficher la note et le commentaire

Partie 3 : Menu

Ajouter une page d'accueil au site avec un menu adéquat

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

🎯 Exercice : Gestion des inscriptions à un événement tech

🧩 Contexte

Tu développes une petite application web pour gérer les inscriptions à un bootcamp de développement web.

Chaque participant doit remplir un formulaire d’inscription en ligne.

L’application devra utiliser la méthode POST et manipuler un fichier texte pour enregistrer et rechercher les participants.

📝 Partie 1 — Page de menu

Créer une page menu.php qui servira de page d’accueil de l’application.

Cette page doit afficher un titre, par exemple :

Gestion des inscriptions au bootcamp

et proposer au moins deux liens ou boutons :

Ajouter un participant

Rechercher un participant

👉 Le lien Ajouter un participant doit mener vers la page contenant le formulaire d’inscription.
👉 Le lien Rechercher un participant doit mener vers une page permettant de rechercher un participant à partir de son identifiant.

📝 Partie 2 — Formulaire HTML

Créer une page ajoutParticipant.php contenant un formulaire de type POST permettant de collecter les informations d’un participant.

🔧 Champs à prévoir

Tu dois créer un formulaire contenant :

🔹 Informations personnelles

Identifiant (text)

Nom complet (text)

Date d’inscription (date)

🔹 Choix du niveau

Débutant

Intermédiaire

Avancé

👉 (radio buttons)

🔹 Technologies à apprendre

HTML/CSS

JavaScript

PHP

👉 (checkboxes)

🔹 Ville

👉 (select avec au moins 4 villes)

🔹 Motivation

👉 (textarea)

🔹 Bouton d’envoi

👉 (submit)

🧠 Partie 3 — Traitement PHP

Créer une page traitement.php qui permet de récupérer les données envoyées par le formulaire avec $_POST, puis de les transférer dans le fichier participants_bootcamp.txt.

Exemple attendu d'une ligne du fichier participants_bootcamp.txt

ID : 101, Nom : KARIMI FARID, Date : 2026-04-20, Niveau : Intermédiaire, Technologies : HTML/CSS & JavaScript, Ville : Meknès, Motivation : Je veux devenir développeur full stack

📂 Partie 4 — Manipulations sur les fichiers

Compléter l’application avec les manipulations suivantes :

1) Création du fichier

Si le fichier participants_bootcamp.txt n’existe pas, il faut le créer.

2) Ajout sans écrasement

À chaque nouvelle inscription, les données doivent être ajoutées à la fin du fichier sans supprimer les anciennes.

3) Séparation des enregistrements

Ajouter une ligne de séparation entre les participants pour rendre le fichier plus lisible.

Exemple :

==================================================

4) Date et heure d’enregistrement

Ajouter automatiquement la date et l’heure de sauvegarde de l’inscription dans le fichier.

5) Lecture du fichier

Créer une page listeParticipants.php qui permet d’afficher le contenu du fichier participants_bootcamp.txt.

6) Nombre total des participants

Dans listeParticipants.php, afficher le nombre total des participants enregistrés.

7) Validation simple

Avant l’enregistrement, vérifier que les champs principaux ne sont pas vides :

Identifiant

Nom complet

Date d’inscription

Niveau

Ville

Si un champ obligatoire est vide, afficher un message d’erreur et ne pas enregistrer.

🔎 Partie 5 — Recherche d’un participant

Créer une page rechercheParticipant.php contenant un formulaire qui permet de saisir un identifiant.

Après validation, cette page doit :

lire le fichier participants_bootcamp.txt

rechercher le participant correspondant à l’identifiant saisi

afficher ses informations s’il existe

sinon afficher le message :

Participant introuvable

🧭 Partie 6 — Navigation entre les pages

L’application doit permettre à l’utilisateur de circuler facilement entre les différentes pages.

La page menu.php doit permettre d’accéder à :

ajoutParticipant.php

rechercheParticipant.php

Aajouter aussi des liens de retour vers le menu dans :

ajoutParticipant.php

rechercheParticipant.php

listeParticipants.php

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

🎯 Exercice : Gestion des inscriptions à un événement tech

🧩 Contexte

Tu développes une petite application web pour gérer les inscriptions à un bootcamp de développement web.

Chaque participant doit remplir un formulaire d’inscription en ligne.

📝 Partie 1 — Formulaire HTML

Créer un formulaire de type GET permettant de collecter les informations d’un participant.

🔧 Champs à prévoir

Tu dois créer un formulaire contenant :

🔹 Informations personnelles

Identifiant (text)

Nom complet (text)

Date d’inscription (date)

🔹 Choix du niveau

Débutant

Intermédiaire

Avancé
👉 (radio buttons)

🔹 Technologies à apprendre

HTML/CSS

JavaScript

PHP
👉 (checkboxes)

🔹 Ville

👉 (select avec au moins 4 villes)

🔹 Motivation

👉 (textarea)

🔹 Bouton d’envoi

👉 submit

🧠 Partie 2 — Traitement PHP

Créer une page traitement.php qui permet de récupérer les données, puis les transférer dans le fichier participants_bootcamp.txt

Exemple attendu d'une ligne du fihier participants_bootcamp.txt:

ID : 101, Nom : KARIMI FARID, Date : 2026-04-20, Niveau : Intermédiaire, Technologies : HTML/CSS & JavaScript, Ville : Meknès, Motivation : Je veux devenir développeur full stack

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Lien du guide pédagogique:

https://docs.google.com/document/d/1ykh4bn1VWJGyXef4kzdGPw-gaSrMu4dwWh1K1JaJUfI/edit?usp=sharing

===============================

Exercice : Gestion d’un appareil intelligent

On veut modéliser un système simple d’appareils intelligents en utilisant les traits.

Partie 1 : premier trait

Créez un trait TraitAlimentation qui contient :

Une propriété publique etat

Une méthode allumer() qui affiche : "Appareil allumé"

Une méthode eteindre() qui affiche : "Appareil éteint"

Partie 2 : deuxième trait

Créez un trait TraitConnexion qui contient :

Une propriété publique wifi

Une méthode connecter() qui affiche :
"Connexion WiFi établie"

Une méthode abstraite, publique et void afficherTypeConnexion()

Partie 3 : classe principale

Créez une classe Appareil qui utilise :

TraitAlimentation

TraitConnexion

Puis :

Implémentez la méthode afficherTypeConnexion() qui

affiche : "Type de connexion : WiFi"

Partie 4 : classe fille

Créez une classe SmartTV qui hérite de Appareil.

Dans cette classe :

Redéfinir afficherTypeConnexion() pour afficher : "Type de connexion : WiFi + Ethernet"

Ajouter une méthode changerChaine() qui affiche :
"Chaîne changée"

Partie 5 : utilisation

Dans le programme principal :

1. Créez un Appareil, puis :

Allumez-le

Connectez-le

Affichez son type de connexion

2. Créez un Smart TV

Puis :

Allumez-le

Connectez-le

Affichez son type de connexion

Changez la chaine

Eteignez-le

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Lien du guide pédagogique:

https://docs.google.com/document/d/1d20270qqd1j5yhwcc_W3nNkBLCGb2qtcrVI3N1NRiX0/edit?usp=sharing

===============================

Exercice : Gestion d’appareils connectés

Objectif

Mettre en pratique :

les interfaces

l’implémentation

l’héritage de classes

l’utilisation des objets

Énoncé

On veut modéliser un petit système d’appareils connectés.

1) Créer deux interfaces

Interface 1 : IAllumable

Elle doit contenir les méthodes suivantes :

allumer()

eteindre()

Interface 2 : IConnectable

Elle doit contenir les méthodes suivantes :

connecterWifi()

deconnecterWifi()

2) Créer une classe Lampe

Cette classe doit :

implémenter l’interface IAllumable

contenir un attribut marque

avoir un constructeur pour initialiser la marque

définir toutes les méthodes imposées par IAllumable

Les méthodes doivent simplement afficher des messages comme :

"Lampe allumée"

"Lampe éteinte"

Ajouter aussi une méthode :

afficherMarque()

3) Créer une classe SmartLampe

Cette classe doit :

hériter de la classe Lampe

implémenter l’interface IConnectable

Les méthodes doivent afficher des messages comme :

"SmartLampe connectée au WiFi"

"SmartLampe déconnectée du WiFi"

Ajouter aussi une méthode :

changerCouleur()

qui affiche par exemple :

"Couleur changée"

4) Utilisation des classes

Dans le programme principal :

a) Créer un objet Lampe

Par exemple :

marque : Philips

Puis :

afficher sa marque

l’allumer

l’éteindre

b) Créer un objet SmartLampe

Par exemple :

marque : Xiaomi

Puis :

afficher sa marque

l’allumer

connecter au WiFi

changer la couleur

déconnecter le WiFi

éteindre

# data[].attributes.headline
SWD: Fonctions isset() - empty() - is_null()

# data[].attributes.subject
SWD: Fonctions isset() - empty() - is_null()

# data[].attributes.headline
SWD: Abstract Classes & Methods + Exercice

# data[].attributes.subject
SWD: Abstract Classes & Methods + Exercice

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Exercice : Système de Gestion des Appareils (Trackers)

Le Scénario

Dans l'application Gest-BTP , on gère différents types d'appareils de tracking. Bien que chaque modèle soit différent, tous doivent obligatoirement être capables de s'allumer et de rapporter leur niveau de batterie.

1. La Classe Abstraite : AppareilGps

Créez une classe abstraite AppareilGps :

Propriété publique : $identifiant (IMEI ou nom).

Constructeur : Initialise l'identifiant.

Méthode Abstraite Protégée : activerSignal(). Elle doit retourner un string.

Méthode Abstraite Publique : consommerEnergie($heures). Elle doit retourner un float.

2. La Classe Fille : TrackerTeltonika

Elle hérite de AppareilGps.

Propriété spécifique : $capaciteBatterie (ex: 500 mAh).

Implémentation de activerSignal() : Doit retourner "Signal Teltonika activé via protocole UDP".

Implémentation de consommerEnergie($heures) : Retourne le résultat: $heures * 0.5.

Ajout d'argument optionnel : Modifie consommerEnergie pour ajouter un paramètre optionnel $modeEco = false. Si $modeEco est vrai, la consommation est divisée par 2.

3. La Classe Fille : TrackerSolaire

Elle hérite de AppareilGps.

Implémentation de activerSignal() : Doit retourner "Signal Solaire activé via protocole LoRa".

Implémentation de consommerEnergie($heures) : Retourne toujours 0 (car il se recharge au soleil).

4. Test

1. Instanciez un TrackerTeltonika ("TELT-001", 500).

2. Instanciez un TrackerSolaire ("SOLAR-99").

3. Affichez le signal et la consommation (pour 10 heures) de chaque appareil.

4. Testez la consommation du Teltonika avec le mode Eco activé.

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Exercice : Système de Livraison Sécurisé

Le Scénario

Vous développez un logiciel pour une entreprise de transport. Toutes les livraisons doivent être scellées de la même manière pour éviter le vol, mais chaque type de véhicule (Camion ou Drone) a sa propre façon de se déplacer.

1. La Classe Mère : Livraison

Créez une classe abstraite (ou normale) Livraison :

Méthode Normale : seDeplacer(). Elle affiche "Le colis est en route...".

Méthode FINALE : scellerColis(). Elle affiche "Application du sceau de sécurité DEV-2026. Interdiction de modifier ce processus !".

2. La Première Fille : LivraisonCamion

Elle hérite de Livraison.

Elle réécrit (override) la méthode seDeplacer() pour afficher : "Le camion roule sur l'autoroute."

Tentative interdite : Essayez de réécrire scellerColis() pour afficher "On ferme juste la porte". (Commentez ce code pour éviter l'erreur fatale après avoir testé).

3. La Deuxième Fille : LivraisonDrone

Elle hérite de Livraison.

Elle réécrit (override) la méthode seDeplacer() pour afficher : "Le drone survole la ville."

Elle utilise la méthode scellerColis() telle qu'elle est définie chez la mère.

4. Travail à faire (Test)

1. Instanciez un objet LivraisonCamion.

2. Instanciez un objet LivraisonDrone.

3. Pour chaque objet, appelez scellerColis() puis seDeplacer().

4. Vérifiez que le message de scellage est identique pour les deux, car personne n'a pu le modifier !

# data[].attributes.body
DEV101 => Y

DEV102 => Y

===============================

# data[].attributes.headline
SWD: Héritage en POO PHP (2) - Override + Exercice

# data[].attributes.subject
SWD: Héritage en POO PHP (2) - Override + Exercice

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Exercice : Gestion des Employés du Chantier

1. La Classe Mère : Salarie

Créez une classe Salarie avec les caractéristiques suivantes :

Propriétés privées : $nom et $salaire.

Constructeur : Initialise le nom et le salaire.

Accesseurs (Getters) : Pour récupérer le nom et le salaire.

Mutateur (Setter) : Pour modifier le salaire.

Méthode afficher() : Affiche "Employé : [nom] | Salaire : [salaire] DH".

2. La Classe Fille : ChefChantier

Créez une classe ChefChantier qui hérite de Salarie :

Propriété privée supplémentaire : $prime (ex: 1000 DH).

Réécrivez (Override) le Getter du salaire : Il doit retourner le salaire de base + la prime.

Réécrivez (Override) la méthode afficher() : Elle doit afficher "CHEF : [nom] | Total avec prime : [salaire_total] DH".

3. Travail à faire (Test)

1. Instanciez un Salarie ("Samir", 4000).

2. Instanciez un ChefChantier ("Yassine", 7000).

3. Affichez les informations des deux.

4. Modifiez le salaire du chef via le setter et vérifiez que le nouveau total (avec prime) est correct.

# data[].attributes.headline
SWD: Héritage en POO PHP (1) - Principe + Exercice

# data[].attributes.subject
SWD: Héritage en POO PHP (1) - Principe + Exercice

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

🏗️ Exercice : Sécurité et Visibilité sur le Chantier "Errachidia BTP"

Le Script de Base

class Vehicule {

    public $modele;

    protected $matricule;

    private $codeMoteur;

    public function __construct($modele, $matricule, $codeMoteur) {

        $this->modele = $modele;

        $this->matricule = $matricule;

        $this->codeMoteur = $codeMoteur;

    }

   protected function get_codeMoteur() {

       return $this->codeMoteur;

    }

    public function afficherInfos() {

        echo "Modèle : $this->modele | Matricule : $this->matricule\n";

    }

}

📝 Travail à faire

Créez une classe Utilitaire qui hérite de Vehicule

Ajoutez une méthode externaliser_codeMoteur() qui renvoie le code du moteur à l'extérieur

Ajoutez une méthode afficher_Utilitaire () qui affiche toutes les informations d'un Utilitaire

Test: ajoutez une méthode tenterAccesMoteur() qui tente d'afficher $this->codeMoteur; Que se passe-t-il à l'exécution ? Expliquez ?

Créez une classe Camion qui hérite de Vehicule

Ajoutez une propriété publique $chargeUtile

Ajoutez une méthode afficher_camion() publique qui affiche toues les informations du camion

Réécrivez le constructeur pour accepter 4 paramètres : $modele, $matricule, $codeMoteur et $chargeUtile

Indice : Utilisez parent::__construct() pour initialiser les 3 premières valeurs

Créer un utilitaire

Afficher son code moteur

Afficher toutes ses informations

Créez un camion

Afficher toutes ses informations

Test: Tentez de modifier les trois propriétés directement depuis l'extérieur:

$monCamion->modele = "Volvo FMX";     // Cas A

$monCamion->matricule = "1234-A-40";  // Cas B

$monCamion->codeMoteur = "V8-TURBO";  // Cas C

=> Lesquels de ces changements vont provoquer une erreur fatale ? Pourquoi ?

# data[].attributes.headline
SWD: Manipulation des membres partagés: 'static' - POO PHP (Tuto + Exercice)

# data[].attributes.subject
SWD: Manipulation des membres partagés: 'static' - POO PHP (Tuto + Exercice)

# data[].attributes.body
DEV101 => FAD

DEV102 => FAD

===============================

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Exercice:

Modifer le script réalisé dans le cadre de l'exercice du padlet "SWD: Accesseurs/Mutateurs et Constantes" pour:

Rendre possible l'initialisation des données des stagiaires au moment de l'instanciation des objets

Procéder à l'initialisation des données des stagiaires au moment de l'instanciation des objets

Rendre le cne, le nom, et le prénom en lecture seule

# data[].attributes.body
DEV101 => YY

DEV102 => YY

===============================

Exercice:

Reprendre la classe du padlet 'SWD: Bases POO - 1 + Exercice' et procéder aux amendements suivants:

Rendre toutes les propriétés privées

Ajouter des accesseurs et des mutateurs

Ajouter une constante privée, nommée ISTA, positionnée à la valeur 'ISTA Errachidia'

Ajouter la méthode afficher() qui affiche toutes les informations du stagiaire

Créer un tableau de 10 stagiaires

Afficher les informations des stagiaires agés de plus de 19 ans; Utiliser la fonction array_filter() pour filtrer

Afficher les ages de tous les stagiaires; Utiliser la fonction array_map()

# data[].attributes.headline
SWD: Opérations sur les tableaux (FAD) - Modifié + Exercice

# data[].attributes.subject
SWD: Opérations sur les tableaux (FAD) - Modifié + Exercice

# data[].attributes.body
DEV101 => FAD

DEV102 => FAD

===============================

Modification du 31/03/2026

=> Ajout des opérations:

foreach

in_array()

array_filter()

array_values()

array_map()

==========================================

Exercice — API de gestion des commandes

On développe une API PHP qui traite des commandes clients.

On dispose des données suivantes :

$commandes = [
  ["client"=>"Ali", "montant"=>1200, "statut"=>"valide"],
  ["client"=>"Sara", "montant"=>800, "statut"=>"en_attente"],
  ["client"=>"Yassine", "montant"=>1500, "statut"=>"valide"],
  ["client"=>"Lina", "montant"=>400, "statut"=>"annule"]
];

1. Ajouter une nouvelle commande pour "Omar" avec un montant de 950 et statut "valide".

2. Créer un tableau contenant uniquement les commandes validées.

3. À partir des commandes validées, créer un tableau contenant uniquement les noms des clients.

4. On reçoit une nouvelle liste :

$nouvelles = [
  ["client"=>"Imane", "montant"=>2000, "statut"=>"valide"]
];

Fusionner les deux listes.

5. Vérifier si un client nommé "Sara" existe dans la liste des clients (toutes commandes confondues).

6. À partir du tableau des commandes validées, réindexer correctement le tableau.

7. Créer un tableau contenant uniquement les montants des commandes validées.

# data[].attributes.headline
SWD: Manipulation des fichiers en PHP (FAD) + Exercice

# data[].attributes.subject
SWD: Manipulation des fichiers en PHP (FAD) + Exercice

# data[].attributes.body
DEV101 => FAD

DEV102 => FAD

===============================

Tuto =>

https://docs.google.com/document/d/1tyvIakmpu_LF2mihCXnx771rw9zzTJr1rquX35FDMOk/edit?usp=sharing

Exercice:

On considère la classe Stagiaire du padlet 'SWD: Bases POO - 1 + Exercice';

On veut sauvegarder les données des stagiaires dans un fichier texte, pour cela on implémente ce qui suit:

1. Ajouter dans la classe Stagiaire:

une méthode toLigneFichier() qui renvoie les données du stagiaire sous la forme :
cne;nom;prenom;date_naissance

2. Créer une classe BDStagiaire qui contient la propriété $chemin qui représente le chemin d’un fichier texte.

3. Ajouter dans BDStagiaire les méthodes suivantes :

sauvegarder($stagiaires) : enregistre un tableau de stagiaires dans le fichier

charger() : lit le fichier et reconstitue les objets Stagiaire

positionActuelle($f) : renvoie la position actuelle dans le fichier

allerPosition($f, $position) : place le curseur à une position exacte

lireStagiaireA($position) : lit un stagiaire à partir d’une position donnée dans le fichier

4. Créer un tableau de 5 stagiaires.

5. Sauvegarder tous les stagiaires dans un fichier texte nommé stagiaires.txt.

6. Recharger les stagiaires depuis le fichier et afficher leurs noms complets.

7. Lire un stagiaire à partir d’une position donnée dans le fichier, puis afficher ses informations.

# data[].attributes.body
DEV101 => 30/03/2026

DEV102 => 31/03/2026 Corrigé le 31/03/2026

===============================

Exercice:

1 -Créer la classe Stagiaire avec les données: CNE, nom, prenom, et date_naissance, ainsi que les méthodes nom_complet() qui affiche le nom et prénom du stagiaire, renvoyer_age() qui renvoie l'age du stagiaire

2 -Créer un tableau de 10 stagiaires.

3 -Affciher les nom complets de tous les stagiaires.

4 -Afficher les données des stagiaires les plus agés.

# data[].attributes.headline
SWD: Complément Exercice Structures de contrôle (Calcul age)

# data[].attributes.subject
SWD: Complément Exercice Structures de contrôle (Calcul age)

# data[].attributes.body
Intégrer puis supprimer

# data[].attributes.headline
SWD: Bases Programmation PHP (Modifié Le 26/03/2026)

# data[].attributes.subject
SWD: Bases Programmation PHP (Modifié Le 26/03/2026)

# data[].attributes.body
Modifications du 26/03/2026:

-> Ajout de nouvels éléments aux tableaux

-> Affichage des tableaux avec print_r()

==========================================

Contenu de base

-variables

-affichages

-concaténation

-constantes

-tableaux

# data[].attributes.headline
SWD: Structures de contrôle dans PHP (Script Pédagogique +   Exercices)

# data[].attributes.subject
SWD: Structures de contrôle dans PHP (Script Pédagogique +   Exercices)

# data[].attributes.body
Exercice 1:

1-Afficher les éléments pairs d'un tableau d'entiers.
2-Claculer et afficher le maximum des éléments d'un tableau de rééls.
3-Effectuer le tri croissant d'un tableau d'entiers.

N.B: Corrigé pour DEV102

Exercice 2:

1-Créer un tableau qui contient les notes des élèves; Chaque élève possède 3 notes.
2-Afficher la note maximale du dernier élève.
3-Afficher les moyennes générales de tous les élèves.

4-Créer un tableau qui associe à chaque étudiant défini par son CNE un tableau qui contient son nom, prénom, date de naissance, et moyenne de BAC, définis respectivement par les clés "nom", "prenom", "date_naissance", et "moyenne_bac".
5-Afficher la moyenne de l'étudiant ayant le CNE 25000.
6-Trier les étudiants par ordre de mérite (moyenne de BAC).

N.B: Corrigé pour DEV102

Exercice 3:

1-Afficher les étudiants dont le nom dépasse 3 lettres
2-Afficher les étudiants sous format CNE-X-Y avec X qui représnete les 3 premières lettres du nom, et Y qui représente les 3 premières lettres du prénomno
3-Afficher les noms et prénoms des étudiants avec le Nom en majuscules et la première lettre des prénoms en majuscule et le reste en miniscule.

N.B: Corrigé pour DEV102

Complément:

1-Afficher les étudiants nés durant le premier semèstre de l'année.
2-Afficher les cne, noms, prénoms et ages des étudiants.

# data[].attributes.headline
SWD: Réctificatif Exercice Gestion Etudiants

# data[].attributes.subject
SWD: Réctificatif Exercice Gestion Etudiants

# data[].attributes.body
<?php

$etu = [
    "98262" => ["nom" => "Karimi", "moyenne_bac" => 16.5],
    "25000" => ["nom" => "Nabili", "moyenne_bac" => 15.8],
    "12987" => ["nom" => "Hafidi", "moyenne_bac" => 17.1],
    "55432" => ["nom" => "Zahidi", "moyenne_bac" => 14.2],
    "88120" => ["nom" => "Bennani", "moyenne_bac" => 18.45],
    "44001" => ["nom" => "Tazi", "moyenne_bac" => 12.0],
    "33988" => ["nom" => "Mansouri", "moyenne_bac" => 15.75],
    "11223" => ["nom" => "Idrissi", "moyenne_bac" => 16.5],
    "77654" => ["nom" => "Amrani", "moyenne_bac" => 10.5],
    "66543" => ["nom" => "Alaoui", "moyenne_bac" => 19.1]
];

$etu2 = [];

while (count($etu) > 0) {
    $max_key = null;

    foreach ($etu as $key => $details) {
        // Si c'est le premier de la liste ou s'il est plus grand que le max actuel
        if ($max_key === null || $details["moyenne_bac"] > $etu[$max_key]["moyenne_bac"]) {
            $max_key = $key;
        }
    }

    // On a trouvé le VRAI plus grand de ce tour
    $etu2[$max_key] = $etu[$max_key];

    // On le retire pour ne plus le comparer au prochain tour
    unset($etu[$max_key]);
}

$etu = $etu2;

print_r($etu);
?>

# data[].attributes.headline
SWD  (Sites Web Dynamiques (avec PHP)): Doc

# data[].attributes.subject
SWD  (Sites Web Dynamiques (avec PHP)): Doc

# data[].attributes.body
Travail à Faire (TAF):

LISTE DES CONCEPTS À RECHERCHER

Groupe 1 : Architecture Web

1. Architecture Client / Serveur

2. Client dans une application web

3. Serveur informatique

4. Middleware

5. Communication requête / réponse

Groupe 2 : Réseaux et Internet

6. Adresse IP

7. DNS

8. Ports réseau

9. Nom de domaine

Groupe 3 : Architectures logicielles

11. Architecture 1-tiers

12. Architecture 2-tiers

13. Architecture 3-tiers

14. Architecture n-tiers

15. Application distribuée

Groupe 4 : Architecture des applications

16. Couche Présentation (IHM)

17. Couche Traitement (Logique métier)

18. Couche Données

19. SGBD

Groupe 5 : Web et HTTP

21. Serveur Web

22. Serveur Web statique

23. Serveur Web dynamique

24. HTTP

25. URL

Groupe 6 : Technologies Web

26. Navigateur Web

27. Codes HTTP (200, 404, 500)

28. Page web statique

29. Page web dynamique

30. Serveur d’application

Groupe 7 : Introduction à PHP

31. Langage interprété

32. Langage de script

33. Histoire du PHP

34. Avantages de PHP

# data[].attributes.headline
BD: Fonctions de manipulation des chaines de caractères

# data[].attributes.subject
BD: Fonctions de manipulation des chaines de caractères

# data[].attributes.attachment_link.readable_text
select length("je suis excellent") as 'longueur'; select upper("je suis excellent") as "majuscule", lower("Je suis excellent") as "minuscule";
select concat("bonjour,", ltrim("  je suis excellent"), rtrim(",je suis fantastic   "), trim("     ,et confiant     "), "."); 
select ascii("?");
select char(63 USING utf8mb4);
select reverse("bonjour");
select left("bonjour", 2) as 'gauche', right("bonjour", 3) as droite;
select insert("je suis bien.", 9, 200, "excellent"); #INSERT(str,pos,len,newstr); => 'newstr' est positionn��e �� partir de 'pos' en rempla��ant 'len' caract��res de la chaine m��re �� partir de 'pos' 
select replace("je suis bien, tr��s bien !", "bien", "excellent"); #remplace toutes les occurrences
select substring("je suis formidable �� tous les ��gards !", 9, 10); #SUBSTRING(str,pos,len)
#################################
#select 1 as "col"; select numero, 2*numero as "double numero" from filiere;
select nom, length(nom) as 'longueur nom' from filiere;
select nom, length(nom) as 'longueur nom', upper(nom) as 'maj', lower(nom) as 'min' from filiere;
select nom, left(nom, 3) as '3premchar', substring(nom, 1, 3) as '3premchar' from filiere;

#somme des longueurs des noms des fil��res
select sum(length(nom)) from filiere;
select * from filiere;

#somme des longueurs des secteurs par premier caract��re du nom de la fili��re
select left(nom, 1), sum(length(secteur)) from filiere
	group by left(nom, 1);
    
#fili��res dans l'ordre croissant des longueurs de leurs noms
select * from filiere order by length(nom);

# data[].attributes.attachment_link.readable_text
/* ============================================================
   LES FONCTIONS MATH��MATIQUES
   Objectif : Manipuler les nombres, arrondir et calculer
   ============================================================ */

-- 1) LES FONCTIONS DE BASE & SIGNES
SELECT ABS(-15.5);           -- Retourne 15.5 (Valeur absolue, utile pour les ��carts)
SELECT SIGN(-45), SIGN(0), SIGN(45); -- Retourne -1, 0 ou 1 selon le signe

-- 2) LES ARRONDIS (Tr��s important pour les prix/factures)
SELECT CEIL(12.1);           -- Retourne 13 (Plafond : entier sup��rieur le plus proche)
SELECT FLOOR(12.9);          -- Retourne 12 (Plancher : entier inf��rieur le plus proche)

-- ROUND vs TRUNCATE
SELECT ROUND(15.678, 2);     -- Retourne 15.68 (Arrondit au plus proche)
SELECT ROUND(15.675, 2);     -- Retourne 15.68
SELECT TRUNCATE(15.678, 2);  -- Retourne 15.67 (Coupe brutalement apr��s la virgule)

-- 3) DIVISION ET PUISSANCE
SELECT MOD(10, 3);           -- Retourne 1 (Le reste de 10/3, utile pour les nombres pairs/impairs)
SELECT 10 % 3;               -- Alias de MOD
SELECT POW(2, 3);            -- Retourne 8 (2 �� la puissance 3)
SELECT SQRT(16);             -- Retourne 4 (Racine carr��e)

-- 4) G��N��RER DE L'AL��ATOIRE
SELECT RAND();               -- Retourne un nombre entre 0 (inclu) et 1 (exclu) (ex: 0.4523...)
-- G��n��rer un entier entre 1 et 100
SELECT FLOOR(1 + (RAND() * 100)) AS nombre_aleatoire;

###########################
-- APPLICATION SUR LES TABLES
###########################

DROP DATABASE IF EXISTS shop_math_db;
CREATE DATABASE shop_math_db;
USE shop_math_db;

-- Cr��ation de la table avec tous les champs n��cessaires pour les tests
CREATE TABLE produits (
    idP INT PRIMARY KEY AUTO_INCREMENT,
    designation VARCHAR(100),
    categorie VARCHAR(50),
    prix_achat DECIMAL(10,2),
    prix_vente DECIMAL(10,2),
    prix_unitaire DECIMAL(10,2), -- Champ sp��cifique pour le test TRUNCATE
    stock INT
);

-- Insertion de donn��es cibl��es
INSERT INTO produits (designation, categorie, prix_achat, prix_vente, prix_unitaire, stock) VALUES
-- Cas pour TRUNCATE = 10 et stocks pour CEIL
('Cl�� USB 32Go', 'Accessoire', 5.50, 12.99, 10.95, 1250),   -- idP 1 (Impair)
('C��ble HDMI', 'Accessoire', 3.20, 8.50, 10.15, 800),      -- idP 2 (Pair)
('Adaptateur USB-C', 'Accessoire', 4.10, 9.90, 10.80, 250), -- idP 3 (Impair)

-- Cas pour tester la marge et les cat��gories
('Souris Optique', 'P��riph��rique', 8.00, 19.90, 20.50, 2100),   -- idP 4 (Pair)
('Clavier M��canique', 'P��riph��rique', 35.00, 79.99, 85.00, 450), -- idP 5 (Impair)

-- Cas pour gros stocks (CEIL) et prix ronds
('��cran 24 pouces', '��cran', 110.00, 185.55, 199.90, 120),       -- idP 6 (Pair)
('Support ��cran', '��cran', 25.00, 45.00, 49.99, 1950);           -- idP 7 (Impair)

/* ============================================================
   V��RIFICATION DES TESTS DU SCRIPT
   ============================================================ */

-- Test 1 : La marge arrondie (ROUND)
-- On verra des r��sultats comme 7.49, 5.30, etc.
SELECT designation, prix_vente, prix_achat, 
       ROUND(prix_vente - prix_achat, 2) AS marge 
FROM produits;

-- Test 2 : Nombre de "milliers" n��cessaires (Paliers de 1000)
-- Accessoire (2300)    -> affichera 3 (paliers)
-- P��riph��rique (2550) -> affichera 3 (paliers)
-- ��cran (2070)       -> affichera 3 (paliers)
SELECT categorie, 
       SUM(stock) AS stock_reel,
       CEIL(SUM(stock) / 1000) AS nb_paliers_mille
FROM produits
GROUP BY categorie;

-- Test 3 : Alternance de lignes (MOD)
-- V��rifie bien que l'idP 1 est 'Impair', 2 est 'Pair', etc.
SELECT idP, designation, 
       IF(MOD(idP, 2) = 0, 'Ligne Paire', 'Ligne Impaire') AS position
FROM produits;

-- Test 4 : Tronquer le prix (TRUNCATE)
-- Ne doit retourner que les 3 premiers articles (prix_unitaire entre 10.00 et 10.99)
SELECT designation, prix_unitaire 
FROM produits 
WHERE TRUNCATE(prix_unitaire, 0) = 10;

# data[].attributes.headline
BD: Sauvegarde/Restauration BD MySQL - Vidéo 2

# data[].attributes.subject
BD: Sauvegarde/Restauration BD MySQL - Vidéo 2

# data[].attributes.headline
BD: Sauvegarde/Restauration BD MySQL - Vidéo 1

# data[].attributes.subject
BD: Sauvegarde/Restauration BD MySQL - Vidéo 1

# data[].attributes.headline
BD : Sauvegarde et Restauration des BD MySQL

# data[].attributes.subject
BD : Sauvegarde et Restauration des BD MySQL

# data[].attributes.body
NEW

# data[].attributes.headline
BD : Tutoriel - Gestion de la sécurité (utilisateurs/privilèges) dans MySQL

# data[].attributes.subject
BD : Tutoriel - Gestion de la sécurité (utilisateurs/privilèges) dans MySQL

# data[].attributes.body
NEW

# data[].attributes.headline
BD: Gestion d'utilisateurs et privilèges (sujet de la vidéo)

# data[].attributes.subject
BD: Gestion d'utilisateurs et privilèges (sujet de la vidéo)

# data[].attributes.attachment_link.readable_text
/********************************************************** Gestion des utilisateurs*********************************************************/
#cr��ation des utilisateurs sans et avec mot de passe
drop user if exists 'karim'@'localhost';

#'karimi' peut se connecter �� partir de la machine 'localhost'
create user 'karim'@'localhost';

#v��rifier que l'utilisateur a ��t�� cr����
select * from mysql.user;
#[#select database() #=> current database]

drop user if exists 'samir'@'localhost';
create user 'samir'@'localhost' identified by 'samir2025';

drop user if exists 'nabil'@'127.0.0.1';
CREATE USER 'nabil'@'127.0.0.1' IDENTIFIED BY 'nabil2025';

#Said peut se connecter �� partir de n���importe quel h��te dont l���adresse IP commence par 127.0.0
drop user 'Said'@'127.0.0.%';
CREATE USER 'Said'@'127.0.0.%' IDENTIFIED BY 'said2025';

#Hanane peut se connecter �� partir de n���importe quel h��te
drop user 'Hanane'@'%';
CREATE USER 'Hanane'@'%' IDENTIFIED BY 'hanane2025';

# afficher les utilisateurs
select user from mysql.user order by user;

# afficher l'utilisateur connect��
select session_user();


#renommer un utilisateur
rename user 'karim'@'localhost' to 'karim3'@'localhost';

#modifier le mot de passe d'un utilisateur; PASSWORD() est utilis��e pour hacher le MP
set password for 'samir'@'localhost' = PASSWORD('samir25');

set password for 'karim3'@'localhost' = password('karim2025'); # on a ajout�� un mot de passe �� 'karimi2'
set password for 'Hanane'@'%' = ''; # on a supprim�� le mot de passe pour 'karim2'

/********************************************************** Gestion des droits d'acc��s*********************************************************/
					    ######################## octroi de privil��ges
use bdcommerce;
grant select, insert, update, delete on clients to 'Hanane'@'%' ;

grant update(nom, prenom), delete on clients to 'samir'@'localhost';

grant select(idcli) on clients to 'samir'@'localhost';

create user 'achraf'@'localhost';
grant select on *.* to 'achraf'@'localhost';

create user 'salim'@'localhost';

#accorder tous les privil��ges sur toutes les bases de donn��es et toutes les tables �� l'utilisateur 'salim' lorsqu'il se connecte depuis 'localhost'.
#create database, drop database, create table, insert, update, ...
grant ALL PRIVILEGES on *.* to 'salim'@'localhost'; 

# privil��ges sur toutes les tables de la bd bdformation
grant insert, delete on bdformation.* to 'samir'@'localhost'; 

 #privil��ge de faire des requ��tes SELECT uniquement sur la colonne numero de la table filiere dans la base de donn��es bdformation
grant select(numero) on bdformation.filiere to 'samir'@'localhost'; 

#privil��ges SELECT, UPDATE, DELETE et INSERT sur toutes les tables de toutes les bases de donn��es
grant select, update, delete, insert on *.* to 'nabil'@'127.0.0.1';

#privil��ges avec le droit de donner ces m��mes privil��ges
create user 'kamal'@'localhost';
create user 'farid'@'localhost';
create user 'nadir'@'localhost';
create user 'rachid'@'localhost';

grant select, insert on bdcommerce.clients to 'kamal'@'localhost';
grant select, insert on bdcommerce.clients to 'farid'@'localhost' with grant option;

/*tests �� faire : 
-se connecter �� la session de kamal et essayer de donner les privil��ges 'select, insert on bdcommerce.clients' �� rachid
-se connecter �� la session de farid et essayer de donner les privil��ges 'select, insert on bdcommerce.clients' �� rachid
*/

# retirer des privil��ges des utilisateurs apr��s l'octroi
grant insert, update, delete, select on *.* to 'nabil'@'127.0.0.1'; #octroi
revoke insert on *.* from 'nabil'@'127.0.0.1'; #ok, rq : on doit pr��ciser '*.*'
revoke update, delete on *.* from 'nabil'@'127.0.0.1'; #ok

#Lorsqu'un utilisateur dispose de privil��ges larges, il n'est pas possible de r��voquer une partie sp��cifique de ces privil��ges
revoke select on bdcommerce.clients from 'nabil'@'127.0.0.1'; #nok

# gestion des r��les
drop role if exists monRole;
#cr��er un role
create role monRole;

#octroyer des privil��ges un role
grant select on bdcommerce.* to monRole;
grant insert on bdcommerce.clients to monRole;
grant delete on bdcommerce.produit to monRole;
grant update on bdcommerce.commande to monRole;

#affecter des utilisateurs �� un role
drop user if exists 'halima'@'localhost';
create user 'halima'@'localhost';
create user 'saida'@'localhost' identified by 'saida2025';
grant monRole to 'halima'@'localhost';
grant monRole to 'saida'@'localhost';

#retirer des utilisateurs d'un role
revoke monRole from 'saida'@'localhost';


############################
show grants;
show grants for 'root'@'localhost';
show grants for current_user();
show grants for 'nabil'@'127.0.0.1';
show grants for monRole;

#######theoretical summary of managing users and privileges in MySQL 
/*
Managing Users and Privileges in MySQL
MySQL provides powerful tools for user management and privilege control to ensure database security and proper access control. Below are the key concepts and operations:

1. Users
Creation: Users are identified by a username and host, and can optionally have a password.
Connection Restrictions: Users can be restricted to connect from specific hosts or IP ranges.
Viewing Users: The mysql.user table stores user information.
2. Passwords
Passwords can be added, updated, or removed for user accounts to enhance security.
3. Privileges
Privileges define the actions a user can perform on database objects:

Types: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, etc.
Granularity:
Global: Affect all databases (*.*).
Database-level: Affect a specific database (dbname.*).
Table-level: Affect a specific table (dbname.tablename).
Column-level: Restrict to specific columns (tablename(column)).
4. Granting Privileges
The GRANT statement is used to assign privileges to users.
With the WITH GRANT OPTION clause, users can further delegate their privileges.
5. Revoking Privileges
The REVOKE statement removes specific privileges from a user.
6. Roles
Roles are named collections of privileges that simplify privilege management.
Creation: Roles are created and assigned privileges.
Assignment: Users can be assigned to one or more roles.
Revocation: Users can be removed from roles.
7. Viewing Privileges
The SHOW GRANTS statement provides details on the privileges assigned to a user or role.
8. Best Practices
Follow the principle of least privilege: Assign only the minimum privileges required for a user's tasks.
Regularly audit user accounts and their privileges.
Use roles to simplify privilege management for groups of users with similar responsibilities.
*/

# data[].attributes.headline
BD: Vidéo - Gestion d'utilisateurs et privilèges (droits d'accès) dans MySQL

# data[].attributes.subject
BD: Vidéo - Gestion d'utilisateurs et privilèges (droits d'accès) dans MySQL

# data[].attributes.headline
BD: Exercice Manipulation des date/time en MySQL

# data[].attributes.subject
BD: Exercice Manipulation des date/time en MySQL

# data[].attributes.body
Pour DEV101 (02/03/2026)

Pour DEV102 (03/03/2026)

===============================

Gestion d'un Parc Automobile (Location de voitures).

===============================

Soit le MLD suivant :

Vehicule (id, immatriculation, modele, date_achat)

Location (id, #id_vehicule, date_debut, date_fin_prevue, date_retour_reelle, montant_journalier)

Écrire les requêtes SQL pour répondre aux besoins suivants :

1. Afficher la date et l'heure actuelle au format français : Lundi 02 Mars 2026 - 14:30.

2. Calculer combien de jours se sont écoulés depuis le 1er janvier de cette année.

3. Afficher l'immatriculation de chaque véhicule et son âge en années.

4. Lister les années d'achat des véhicules, sans doublons, triées de la plus récente à la plus ancienne.

5. Pour chaque location terminée (où date_retour_reelle n'est pas nulle), calculer le nombre de jours réels de location (datediff).

6. Afficher par véhicule (id_vehicule) la somme totale des revenus perçus, mais uniquement pour les véhicules dont la première location a eu lieu après 2023.

7. Afficher les véhicules dont toutes les locations ont été effectuées durant un week-end (Samedi ou Dimanche).

# data[].attributes.headline
BD: Accès à MySQL via la ligne de commande de Windows (cmd)

# data[].attributes.subject
BD: Accès à MySQL via la ligne de commande de Windows (cmd)

# data[].attributes.body
+ Bonus à propos de l'opérateur 'DISTINCT':

#autre exemple de distinct

select distinct nom, prenom from stagiaire;

# data[].attributes.attachment_link.readable_text
Microsoft Windows [version 10.0.19045.6466]
(c) Microsoft Corporation. Tous droits rÃ©servÃ©s.

C:\Users\hp-pc>mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.4.32-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------------+
| Database                 |
+--------------------------+
| bd1                      |
| bd3                      |
| bd_ayoub                 |
| bd_controllers_effective |
| bd_ecole                 |
| bd_employes              |
| bd_formation             |
| bd_location              |
| bd_location2             |
| bd_test                  |
| bdtest                   |
| commentsdb               |
| cors_api                 |
| data-access_db           |
| db_table_handling        |
| dbdev102                 |
| eloquentdb               |
| gimmob                   |
| hotel_db                 |
| hotel_db2                |
| hotel_db_2               |
| information_schema       |
| librax_evolution         |
| ma_bd                    |
| mabasedonnees            |
| mysql                    |
| navarco_db               |
| performance_schema       |
| phpmyadmin               |
| request_db               |
| requests_db_4            |
| response_db              |
| shop_db                  |
| shop_math_db             |
| sitedb                   |
| sitedb2                  |
| sitedb3                  |
| student_management       |
| test                     |
| training_demo            |
| usersdb                  |
+--------------------------+
41 rows in set (0.002 sec)

MariaDB [(none)]> use bd_formation;
Database changed
MariaDB [bd_formation]> show tables;
+------------------------+
| Tables_in_bd_formation |
+------------------------+
| filiere                |
| stagiaire              |
+------------------------+
2 rows in set (0.001 sec)

MariaDB [bd_formation]> describe stagiaire;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| cne          | int(11)     | NO   | PRI | NULL    |       |
| nom_complet  | varchar(50) | YES  |     | NULL    |       |
| code_filiere | int(11)     | NO   | MUL | NULL    |       |
| daten        | date        | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
4 rows in set (0.018 sec)

MariaDB [bd_formation]> select * from stagiaire;
+-----+-------------+--------------+------------+
| cne | nom_complet | code_filiere | daten      |
+-----+-------------+--------------+------------+
|   1 | NULL        |            1 | 2000-04-22 |
|   2 | NULL        |            1 | 1999-05-13 |
|   3 | NULL        |            1 | 2000-02-09 |
+-----+-------------+--------------+------------+
3 rows in set (0.075 sec)

MariaDB [bd_formation]> alter table stagiaire drop column nom_complet;
Query OK, 0 rows affected (0.015 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [bd_formation]> describe stagiaire;
+--------------+---------+------+-----+---------+-------+
| Field        | Type    | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+-------+
| cne          | int(11) | NO   | PRI | NULL    |       |
| code_filiere | int(11) | NO   | MUL | NULL    |       |
| daten        | date    | YES  |     | NULL    |       |
+--------------+---------+------+-----+---------+-------+
3 rows in set (0.019 sec)

MariaDB [bd_formation]> alter table stagiaire add column nom varchar(50);
Query OK, 0 rows affected (0.012 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [bd_formation]> alter table stagiaire add column prenom varchar(50);
Query OK, 0 rows affected (0.011 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [bd_formation]> describe stagiaire;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| cne          | int(11)     | NO   | PRI | NULL    |       |
| code_filiere | int(11)     | NO   | MUL | NULL    |       |
| daten        | date        | YES  |     | NULL    |       |
| nom          | varchar(50) | YES  |     | NULL    |       |
| prenom       | varchar(50) | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
5 rows in set (0.016 sec)

MariaDB [bd_formation]> select * from stagiaire;
+-----+--------------+------------+------+--------+
| cne | code_filiere | daten      | nom  | prenom |
+-----+--------------+------------+------+--------+
|   1 |            1 | 2000-04-22 | NULL | NULL   |
|   2 |            1 | 1999-05-13 | NULL | NULL   |
|   3 |            1 | 2000-02-09 | NULL | NULL   |
+-----+--------------+------------+------+--------+
3 rows in set (0.000 sec)

MariaDB [bd_formation]> update stagiaire set nom='karimi', prenom='karim' where cne=1;
Query OK, 1 row affected (0.007 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [bd_formation]> update stagiaire set nom='faridi', prenom='farid' where cne=2;
Query OK, 1 row affected (0.012 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [bd_formation]> update stagiaire set nom='karimi', prenom='karim' where cne=3;
Query OK, 1 row affected (0.005 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [bd_formation]> select * from stagiaire;
+-----+--------------+------------+--------+--------+
| cne | code_filiere | daten      | nom    | prenom |
+-----+--------------+------------+--------+--------+
|   1 |            1 | 2000-04-22 | karimi | karim  |
|   2 |            1 | 1999-05-13 | faridi | farid  |
|   3 |            1 | 2000-02-09 | karimi | karim  |
+-----+--------------+------------+--------+--------+
3 rows in set (0.000 sec)

MariaDB [bd_formation]>

# data[].attributes.attachment_link.title
Accès à MySQL via la ligne de commande de Windows (cmd)

# data[].attributes.headline
BD: Fonctions de manipulation de date/time dans MSQL

# data[].attributes.subject
BD: Fonctions de manipulation de date/time dans MSQL

# data[].attributes.body
dev102 (25/02/2026) - partie 1

# data[].attributes.attachment_link.readable_text
select current_date();  
select current_time();
select now(), current_timestamp(); #datetime
select utc_date(), utc_time, utc_timestamp(); #universel
select date(now()); #date part of datetime
select time(now());
select year(now()), month(now()), day(now()), hour(now()), minute(now()), second(now()), week(now());
select datediff(now(), '2022-12-15'); #'now() - 2022-12-15', exprim�� en 'day'
select date_add(now(), interval 2 minute);
select date_format(now(), "%d/%m/%Y-%H:%i:%s");
select weekday('2005-8-8'); #jour de la semaine, lundi : 0
select concat(dayname(now()), " ", monthname(now()), " ", year(now())) as 'date nomm��e';
###########################
select curdate();
#select datediff(now(), '2022-12-15');
select TIMESTAMPDIFF(WEEK , '2026-02-24' , CURDATE());
###########################
select * from stagiaire;

select cne, year(daten) from stagiaire; #(Arr��t Dev102 25/02/2026)

# Liste de toutes les ann��es de naissance pr��sentes (sans doublons)
select distinct year(daten) from stagiaire;

#somme des cne par ann��e de naissance
select year(daten), sum(cne) from stagiaire
	group by year(daten);
    
#ann��e de naissance minimale par nom et pr��nom de stagiaire
select nom, prenom, min(year(daten)) from stagiaire
	group by nom, prenom;
    
#ann��e de naissance minimale par nom et pr��nom de stagiaire pour les groupes dont tous les stagiaires
#sont n��s dans les 10 premiers jours des mois
select nom, prenom, min(year(daten)) from stagiaire
	group by nom, prenom
    having(max(day(daten)) <= 10)
    

# data[].attributes.headline
BD: Exercice Opérateurs ensemblistes MSQL

# data[].attributes.subject
BD: Exercice Opérateurs ensemblistes MSQL

# data[].attributes.body
--------------------------------------------------------------

1. Le Setup (Création et Données)

CREATE DATABASE IF NOT EXISTS labo_recherche;

USE labo_recherche;

-- 1) Création des tables

CREATE OR REPLACE TABLE enseignants (

id_ens INT PRIMARY KEY AUTO_INCREMENT,

nom VARCHAR(50),

grade INT, -- 3: PES, 2: PH, 1: PA

departement VARCHAR(20),

date_embauche DATE

);

CREATE OR REPLACE TABLE chercheurs (

id_cher INT PRIMARY KEY AUTO_INCREMENT,

nom_complet VARCHAR(50),

grade INT, -- 3: PES, 2: PH, 1: PA

specialite VARCHAR(20),

date_embauche DATE

);

-- 2) Insertion des données (Valeurs entières pour les grades)

INSERT INTO enseignants (nom, grade, departement, date_embauche) VALUES

('Alami Ahmed', 3, 'Informatique', '2010-03-15'),

('Bennani Salma', 2, 'Maths', '2015-06-20'),

('Rami Omar', 1, 'Physique', '2020-01-10'),

('Chakiri Hanae', 2, 'Informatique', '2018-11-05');

INSERT INTO chercheurs (nom_complet, grade, specialite, date_embauche) VALUES

('Alami Ahmed', 3, 'IA', '2010-03-15'),

('Drissi Khalid', 1, 'Bio-tech', '2021-09-12'),

('Chakiri Hanae', 2, 'Réseaux', '2018-11-05');

--------------------------------------------------------------

2. Énoncé

Question 1 : Affichez la liste unique de tous les noms de personnes travaillant dans le laboratoire (qu'ils soient enseignants ou chercheurs).

Question 2 : Trouvez les noms des personnes qui ont la double casquette : ils sont à la fois enseignants et chercheurs.

Question 3 : Affichez les enseignants qui ne font pas de recherche .

Question 4 : Trouvez les enseignants dont le grade est "supérieur" aux grades de quelques  chercheurs.

Question 5 : Trouvez les enseignants qui ont été embauchés après tous les chercheurs.

Question 6 : Affichez tous les chercheurs uniquement s'il existe au moins un enseignant dans le département 'Maths'.

# data[].attributes.attachment_link.readable_text
use bd1;
create table client(id int, nom varchar(50));
insert into client values(2222,"sadiki"), (333,"soubhi");

drop temporary table cli;
create temporary table cli(id int, nom varchar(50));
insert into cli select id, nom from client limit 3;
select * from cli;

#union => supported since mariad 10.3.
#intersect => supported since mariad 10.3.
#except => supported since mariad 10.3.
#IN
#EXISTS
#ALL/ANY
###########################################################################
use test;

#create table personnes(id int auto_increment primary key, nom_prenom varchar(50));
create or replace table personnes(id int primary key auto_increment, nom_prenom char(20));
describe personnes;
create or replace table etudiants(numero int auto_increment primary key, nom_complet varchar(50));

insert into personnes(nom_prenom) values('karimi farid'), 
            ('sadiki rachid'), ('rabh israe'), ('nassiri farid');
insert into etudiants(nom_complet) values('chakiri hanae'), ('kamali sanae'), 
                 ('rabh israe'); 

#union
(select * from personnes) union (select * from etudiants); #elimination de doublons; SELECTs doivent avoir m��me nombre colonnes; noms des colonnes de 'personnes'
select id as identifiant, nom_prenom as nom_et_prenom from personnes union select * from etudiants; 
select id as identifiant from personnes union select numero from etudiants; 

#except
(select * from personnes) except (select * from etudiants); #ok
select id as identifiant, nom_prenom as nom_et_prenom from personnes except select * from etudiants; 

#intersect
(select * from personnes) intersect (select * from etudiants); #ok
select id as identifiant, nom_prenom as nom_et_prenom from personnes intersect select * from etudiants; 

#ALL
select * from personnes 
        where id >= ALL(select numero from etudiants where nom_complet like 'a%');

#ANY/SOME
select * from personnes where id > ANY(select numero from etudiants);
select * from personnes where id > SOME(select numero from etudiants);

#IN
select * from personnes where id in (select numero from etudiants);
#utilisation aussi de l'op��rateur not (s'utilise aussi avec exsits, between)
select * from personnes where id not in (select numero from etudiants); 

#EXISTS
select * from personnes where EXISTS(select * from personnes where id > 3);
select * from personnes where not EXISTS(select * from personnes where id > 3);

# data[].attributes.body
Exercice SQL : Gestion de Maintenance "Auto-Tech"

Énoncé

Vous gérez la base de données d'un garage. Vous devez suivre les véhicules, les mécaniciens et les interventions réalisées.

1. Préparation des données

Créez les trois tables suivantes :

1. vehicules : idV (PK), matricule, modele, annee.

2. mecaniciens : idM (PK), nom, specialite.

3. interventions : idI (PK), date_inter, id_vehicule, id_mecanicien, cout.

Insérez ce jeu de test :

Véhicules : Une 'Dacia Sandero', une 'Golf 8', et une 'Tesla Model 3' (qui n'a aucune intervention).

Mécaniciens : 'Ahmed' (Expert Moteur), 'Said' (Électricien), et 'Karim' (Carrossier - qui n'a aucune intervention assignée).

Interventions : Ahmed a réparé la Dacia (500 DH). Said a réparé la Golf (1200 DH).

2. Requêtes à réaliser

A. INNER JOIN (Les liens actifs)

1. Fiche d'atelier : Afficher le matricule du véhicule, le nom du mécanicien et la date de l'intervention pour tous les travaux en cours.

2. Détail financier : Afficher le modèle du véhicule et le coût de son intervention.

3. Expertise : Afficher le nom du mécanicien et la spécialité utilisée pour chaque intervention enregistrée.

B. LEFT JOIN

4. Suivi de parc : Lister tous les véhicules avec la date de leur dernière intervention; NULL si aucune date.

5. Véhicules neufs : Trouver les matricules des véhicules qui n'ont encore subi aucune intervention.

C. RIGHT JOIN

6. Activité du staff : Lister tous les mécaniciens et le montant des interventions qu'ils ont réalisées. (Le mécanicien 'Karim' doit apparaître même s'il n'a rien fait).

7. Productivité : Trouver les mécaniciens (nom et spécialité) qui n'ont pas d'interventions.

D. JOINTURES MULTIPLES ET AGRÉGATIONS

8. Rapport Global : Afficher le nom du mécanicien, le modèle du véhicule et le coût pour chaque ligne.

9. Chiffre d'affaires par mécano : Afficher le nom de chaque mécanicien et la somme totale d'argent qu'il a rapportée au garage.

10. Statistiques par année : Afficher l'année du véhicule et le coût moyen des réparations, uniquement pour les véhicules sortis après 2020.

# data[].attributes.attachment_link.readable_text
/* ============================================================
   SCRIPT P��DAGOGIQUE ��� LES JOINTURES (INNER, LEFT, RIGHT)
   Th��me : Suivi des Commandes Clients
   ============================================================

   OBJECTIFS (ce que les ��tudiants vont apprendre / faire) :
   1) Comprendre la notion de correspondance de cl��s (PK / FK).
   2) R��cup��rer des donn��es de deux tables (INNER JOIN).
   3) G��rer les donn��es sans correspondance (LEFT JOIN / RIGHT JOIN).
   4) Effectuer une jointure multiple (Lier 3 tables ou plus).
   5) Combiner Jointures + Agr��gats (Calculs complexes).
   ============================================================ */


/* ============================================================
   1) PR��PARATION DE LA BASE (Relier les tables)
   ============================================================ */

USE shop_db; -- On continue sur la m��me base

/*
CREATE TABLE produits (
    idP INT PRIMARY KEY AUTO_INCREMENT,
    designation VARCHAR(100) NOT NULL,
    categorie VARCHAR(50),
    prix_unitaire DECIMAL(10,2),
    stock INT DEFAULT 0
);
*/

CREATE TABLE acheteurs (
    idA INT PRIMARY KEY AUTO_INCREMENT,
    nom VARCHAR(50) NOT NULL,
    ville VARCHAR(50)
);

CREATE TABLE commandes (
    idC INT PRIMARY KEY AUTO_INCREMENT,
    date_cmd DATE,
    id_acheteur INT,
    id_produit INT,
    quantite INT,
    FOREIGN KEY (id_acheteur) REFERENCES acheteurs(idA),
    FOREIGN KEY (id_produit) REFERENCES produits(idP)
);

-- Insertion des acheteurs
INSERT INTO acheteurs (nom, ville) VALUES
('Salma Bennani', 'Casablanca'),
('Yassine Farih', 'Rabat'),
('Amine Touzani', 'Tanger'),
('Samiha Drissi', 'Marrakech'); -- Cet acheteur n'a pas encore command��

-- Insertion des commandes
INSERT INTO commandes (date_cmd, id_acheteur, id_produit, quantite) VALUES
('2026-02-01', 1, 1, 1), -- Salma ach��te un iPhone
('2026-02-02', 1, 5, 2), -- Salma ach��te 2 AirPods
('2026-02-03', 2, 3, 1), -- Yassine ach��te un MacBook
('2026-02-04', 3, 2, 1); -- Amine ach��te un Samsung


/* ============================================================
   2) LA JOINTURE INTERNE (INNER JOIN)
   Objectif : Uniquement ce qui correspond dans les deux tables.
   ============================================================ */

-- 2.1) Qui a command�� quoi ?
-- On lie l'acheteur �� sa commande
SELECT acheteurs.nom, commandes.date_cmd, commandes.quantite
FROM acheteurs
INNER JOIN commandes ON acheteurs.idA = commandes.id_acheteur;

-- 2.2) Avec des ALIAS de tables (Plus propre)
SELECT a.nom, c.date_cmd, p.designation, p.prix_unitaire
FROM acheteurs a
INNER JOIN commandes c ON a.idA = c.id_acheteur
INNER JOIN produits p  ON c.id_produit = p.idP;


/* ============================================================
   3) LES JOINTURES EXTERNES (LEFT / RIGHT JOIN)
   Objectif : Ne perdre personne, m��me ceux qui n'ont pas de lien.
   ============================================================ */

-- 3.1) LEFT JOIN : Tous les acheteurs, m��me ceux sans commandes
-- Utile pour identifier les clients inactifs.
SELECT a.nom, c.idC AS 'Num��ro Commande'
FROM acheteurs a
LEFT JOIN commandes c ON a.idA = c.id_acheteur;

-- 3.2) Trouver sp��cifiquement les clients qui n'ont JAMAIS command��
SELECT a.nom
FROM acheteurs a
LEFT JOIN commandes c ON a.idA = c.id_acheteur
WHERE c.idC IS NULL;

-- 3.3) RIGHT JOIN : Tous les produits, m��me ceux jamais vendus
-- Utile pour voir les produits qui ne sortent pas du stock.
SELECT p.designation, c.idC
FROM commandes c
RIGHT JOIN produits p ON c.id_produit = p.idP
WHERE c.idC IS NULL;


/* ============================================================
   4) PUISSANCE MAX : JOINTURES + AGR��GATS
   ============================================================ */

-- 4.1) Chiffre d'affaires total par client
SELECT a.nom, SUM(c.quantite * p.prix_unitaire) AS CA_Total
FROM acheteurs a
INNER JOIN commandes c ON a.idA = c.id_acheteur
INNER JOIN produits p  ON c.id_produit = p.idP
GROUP BY a.nom
ORDER BY CA_Total DESC;

-- 4.2) Rapport d��taill�� par ville
SELECT a.ville, COUNT(c.idC) AS 'Nombre de ventes', SUM(c.quantite) AS 'Articles vendus'
FROM acheteurs a
INNER JOIN commandes c ON a.idA = c.id_acheteur
GROUP BY a.ville
HAVING COUNT(c.idC) > 0;

# data[].attributes.body
dqsdqsddd

# data[].attributes.attachment_link.readable_text
show databases;
use navarco_db;
show tables;



update sous_traitants set adresse = 'Meknes' where id=4;

#ne respecter pas la casse
select * from sous_traitants 
where adresse like 'm%';

#respecter la casse
select * from sous_traitants 
where adresse like binary 'm%';

ALTER TABLE sous_traitants 
MODIFY adresse VARCHAR(50) 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_bin;   #par defaut: utf8mb4_general_ci 

select * from information_schema.schemata;

#utiliser l'op��rateur regexp

#dans mysql l'op��rateur LIKE supporte 2 m��tacat��res: %, _
#solution pour des formats plus souples => utiliser l'op��rateur: regexp
select * from employes
where nom regexp '^[B-E]';

select * from employes
where user_id regexp '^[1-2]';

select * from employes
where nom regexp '^(B|E)';

select * from employes
where nom regexp 'Benali(.)+';
############## metacaract��res#############
/*
^ : D��but de cha��ne.

[] : Classe de caract��res.

[a-z] : Intervalle (m��me si [b-b] est techniquement juste la lettre 'b').

. : N'importe quel caract��re.

*, +, ? : Quantificateurs.

| : L'alternative (OR).
         -----------------------------------------------
nouveaut�� de MySQL 8.0 => supporter la biblioth��que ICU plus large: \d, \w, etc.

*/

# data[].attributes.headline
BD: Exercice SQL - 3 (SELECT-Clauses-Agrégats)

# data[].attributes.subject
BD: Exercice SQL - 3 (SELECT-Clauses-Agrégats)

# data[].attributes.body
--------------------------------------------------------------

Exercice SQL : Gestion de la "Grande Bibliothèque"

Énoncé

Vous venez d'être recruté pour gérer la base de données d'une bibliothèque. Vous devez créer la table et répondre aux besoins de la directrice en utilisant les concepts SELECT, WHERE, GROUP BY, HAVING et ORDER BY.

1. Préparation des données

a. Créez une table nommée livres avec les colonnes suivantes : idL (clé primaire), titre, auteur, genre, prix_achat, et nombre_exemplaires.

b. Insérez un jeu d'au moins 3 enregistrements par table

2. Requêtes d'extraction de données à écrire

A. SÉLECTION ET FILTRAGE SIMPLE

1. Afficher tous les titres et leurs auteurs renommés en 'Écrivain'.

2. Lister les livres dont le prix d'achat est strictement supérieur à 15 DH.

3. Afficher les livres dont le genre est soit 'Roman' soit 'Science-Fiction'.

4. Trouver tous les livres dont le titre contient le mot 'Le'.

B. AGRÉGATIONS ET CALCULS

5. Quel est le prix moyen d'un livre dans cette bibliothèque ?

6. Quelle est la valeur totale financière de tous les exemplaires possédés (Prix * Nombre d'exemplaires) ?

7. Afficher le prix du livre le moins cher de la catégorie 'BD'.

C. GROUPEMENT ET FILTRAGE AVANCÉ

8. Afficher le nombre de titres par genre.

9. Afficher la somme des exemplaires par genre, mais uniquement pour les genres qui ont plus de 10 exemplaires au total.

10. Afficher le genre et le prix moyen des livres, uniquement pour les livres qui ne sont pas en rupture de stock (nombre_exemplaires > 0), et trier par prix moyen décroissant.

# data[].attributes.body
Travail à Faire:

Projet : "Librax-Evolution" (Gestion de Bibliothèque)

Scénario : L'université a commencé à gérer ses livres sur un simple fichier Excel. Vous devez créer la base de données. Au début, la structure est "bancale" (sans contraintes), puis vous devrez la transformer en une base de données professionnelle en utilisant uniquement des commandes ALTER TABLE.

1. Phase de départ : Création "Brute"

Vous devez d'abord créer les tables sans aucune clé primaire ni contrainte.

LIVRE (codeL, titre, auteur)

ETUDIANT (idE, nom, email)

EMPRUNT (codeL, idE, dateSortie)

2. Phase de "professionnalisation" de la base:

Vous devez suivre cette série de modifications pour "professionnaliser" la base :

DÉFI A : Identité et Unicité

1. Ajouter une clé primaire sur codeL pour la table livres.

2. Ajouter une clé primaire sur idE pour la table etudiants, puis la rendre AUTO_INCREMENT.

3. L'université exige que chaque étudiant ait un email unique. Ajoutez la contrainte.

DÉFI B : Évolution des colonnes

1. Ajouter une colonne nbPages (INT) dans la table livres. Elle doit être placée APRÈS le titre.

2. Ajouter une colonne dateRetour dans la table emprunts.

3. Modifier la colonne titre pour qu'elle puisse accepter jusqu'à 255 caractères et qu'elle soit NOT NULL.

DÉFI C : Règles de gestion (CHECK & DEFAULT)

1. Ajouter une contrainte CHECK pour vérifier que nbPages est toujours supérieur à 0.

2. Par défaut, si la dateSortie n'est pas saisie dans la table emprunts, elle doit prendre la date du jour (CURRENT_DATE).

3. Ajouter une colonne statut dans la table livres ('Disponible', 'Emprunté', 'Perdu') avec 'Disponible' par défaut.

DÉFI D : Relations (Foreign Keys)

1. Lier emprunts à livres. Si un livre change de code, le changement doit être automatique dans les emprunts (CASCADE).

2. Lier emprunts à etudiants. On interdit la suppression d'un étudiant s'il a encore un emprunt en cours (RESTRICT).

DÉFI E : Nettoyage (DROP)

1. Finalement, l'université décide de ne plus collecter les auteurs pour les livres. Supprimez la colonne auteur.

2. Supprimez la contrainte CHECK sur les pages.

# data[].attributes.attachment_link.readable_text
/* ============================================================
   SCRIPT P��DAGOGIQUE ��� ALTER TABLE (Contraintes + Colonnes)
   Th��me : h��tel (suites, clients, r��servations)
   ============================================================

   OBJECTIFS (ce que les ��tudiants vont apprendre / faire) :
   1) Cr��er une base de donn��es et s��lectionner la BD de travail (CREATE / USE).
   2) Cr��er des tables SANS contraintes au d��part (pour comprendre ALTER TABLE).
   3) Ajouter des contraintes APR��S la cr��ation :
      - PRIMARY KEY (PK)
      - AUTO_INCREMENT
      - UNIQUE
      - CHECK
      - FOREIGN KEY + ON DELETE / ON UPDATE
   4) Ins��rer des donn��es de test (INSERT) et valider que les contraintes fonctionnent.
   5) Modifier une colonne pour autoriser/interdire NULL :
      - passer de NULL -> NOT NULL (et g��rer les valeurs NULL existantes)
      - passer de NOT NULL -> NULL
   6) Ajouter / supprimer / modifier des colonnes :
      - ADD COLUMN (+ position FIRST / AFTER)
      - DROP COLUMN
      - MODIFY (type, taille, NULL/NOT NULL, etc.)
      - RENAME COLUMN (si MySQL >= 8)
   7) Comprendre et manipuler DEFAULT :
      - ajouter un DEFAULT
      - modifier un DEFAULT
      - supprimer un DEFAULT
   8) Supprimer des contraintes :
      - DROP FOREIGN KEY
      - DROP INDEX (pour UNIQUE)
      - DROP PRIMARY KEY
      - DROP CHECK
   9) Retrouver les noms des contraintes/index :
      - SHOW CREATE TABLE
      - INFORMATION_SCHEMA
      - SHOW INDEX
  10) Supprimer les tables et la base (DROP TABLE / DROP DATABASE)
   ============================================================ */


/* ============================================================
   1) CR��ER / UTILISER LA BASE
   ============================================================ */

DROP DATABASE IF EXISTS hotel_db2;   -- Supprime la BD si elle existe d��j�� (repartir propre)

CREATE DATABASE hotel_db2;           -- Cr��e la nouvelle BD
-- (optionnel mais recommand�� en vrai projet : charset/collation)

USE hotel_db2;                       -- On se place dans la BD hotel_db2


/* ============================================================
   2) CR��ER LES TABLES SANS CONTRAINTES (au d��but)
   Objectif: ajouter ensuite PK/FK/UNIQUE/CHECK par ALTER TABLE
   ============================================================ */

/* Table SUITES (pas de PK, pas de CHECK pour l���instant) */
CREATE TABLE suites (
  codeS     VARCHAR(10) NOT NULL,
  etage     INT NOT NULL,
  nbPieces  INT NOT NULL
) ENGINE=InnoDB;

/* Table CLIENTS (pas de PK, pas de UNIQUE pour l���instant) */
CREATE TABLE clients (
  numeroC     INT NOT NULL,
  nomComplet  VARCHAR(100) NOT NULL,
  email       VARCHAR(150) NOT NULL,
  telephone   VARCHAR(30) NULL
) ENGINE=InnoDB;

/* Table RESERVATIONS (pas de PK, pas de FK pour l���instant) */
CREATE TABLE reservations (
  numeroR   INT NOT NULL,
  dateR     DATE NOT NULL,
  suite     VARCHAR(10) NOT NULL,
  client    INT NOT NULL
) ENGINE=InnoDB;


/* ============================================================
   3) AJOUTER DES CONTRAINTES APR��S COUP (ALTER TABLE)
   ============================================================ */

-- 3.1) Ajouter une cl�� primaire sur suites(codeS)
ALTER TABLE suites
  ADD CONSTRAINT pk_suites PRIMARY KEY (codeS);

-- 3.2) Ajouter une cl�� primaire sur clients(numeroC)
ALTER TABLE clients
  ADD CONSTRAINT pk_clients PRIMARY KEY (numeroC);

-- 3.3) Ajouter une cl�� primaire sur reservations(numeroR)
ALTER TABLE reservations
  ADD CONSTRAINT pk_reservations PRIMARY KEY (numeroR);

-- 3.4) Transformer numeroC et numeroR en AUTO_INCREMENT
-- (AUTO_INCREMENT doit ��tre index��: PK ou UNIQUE)
ALTER TABLE clients
  MODIFY numeroC INT NOT NULL AUTO_INCREMENT;

ALTER TABLE reservations
  MODIFY numeroR INT NOT NULL AUTO_INCREMENT;

-- 3.5) Ajouter UNIQUE sur email
ALTER TABLE clients
  ADD CONSTRAINT uq_clients_email UNIQUE (email);

-- 3.6) Ajouter un CHECK (MySQL 8+ l���applique ; MariaDB d��pend version)
ALTER TABLE suites
  ADD CONSTRAINT chk_suites_etage_nbPieces
  CHECK (etage >= 0 AND nbPieces >= 1);

-- 3.7) Ajouter les Foreign Keys (FK) dans reservations
ALTER TABLE reservations
  ADD CONSTRAINT fk_res_suite
    FOREIGN KEY (suite) REFERENCES suites(codeS)
    ON DELETE RESTRICT
    ON UPDATE CASCADE;

ALTER TABLE reservations
  ADD CONSTRAINT fk_res_client
    FOREIGN KEY (client) REFERENCES clients(numeroC)
    ON DELETE RESTRICT
    ON UPDATE CASCADE;


/* ============================================================
   4) DONN��ES DE TEST (INSERT)
   ============================================================ */

INSERT INTO suites(codeS, etage, nbPieces) VALUES
('S101', 1, 2),
('S201', 2, 3);

INSERT INTO clients(nomComplet, email, telephone) VALUES
('Amina El Idrissi', 'amina@gmail.com', '0612345678'),
('Youssef Benali',  'youssef@gmail.com', '0698765432');

INSERT INTO reservations(dateR, suite, client) VALUES
('2026-02-02', 'S101', 1),
('2026-02-05', 'S201', 2);


/* ============================================================
   5) NULL / NOT NULL : rendre un champ optionnel ou obligatoire
   ============================================================ */

-- 5.1) Passer une colonne de NULL -> NOT NULL
-- IMPORTANT: si des NULL existent d��j��, MySQL les transforme en chaines vides.
-- Exemple p��dagogique : on met d'abord un t��l��phone �� NULL (pour cr��er la situation)
UPDATE clients SET telephone = NULL WHERE numeroC = 2;

-- ��� Si on essaie maintenant : NULL se transforme en chaine vide
-- ALTER TABLE clients MODIFY telephone VARCHAR(30) NOT NULL;

-- 5.2) Passer une colonne de NOT NULL -> NULL (on autorise l���absence de valeur)
ALTER TABLE clients
  MODIFY telephone VARCHAR(30) NULL;


/* ============================================================
   6) AJOUTER / SUPPRIMER / MODIFIER DES COLONNES
   ============================================================ */

-- 6.1) Ajouter une colonne (ADD COLUMN)
-- Ajouter "date_naissance" apr��s nomComplet (NULL autoris��)
ALTER TABLE clients
  ADD COLUMN date_naissance DATE NULL
  AFTER nomComplet;

-- Ajouter une colonne en premi��re position (FIRST)
ALTER TABLE clients
  ADD COLUMN code_client VARCHAR(20) NULL FIRST;

-- 6.2) Supprimer une colonne (DROP COLUMN)
-- ATTENTION: perte d��finitive des donn��es de cette colonne
ALTER TABLE clients
  DROP COLUMN code_client;

-- 6.3) Modifier une colonne (MODIFY)
-- Exemple : agrandir l���email (taille) + garder NOT NULL
ALTER TABLE clients
  MODIFY email VARCHAR(200) NOT NULL;

-- Exemple : changer le type (numeroR en BIGINT)
ALTER TABLE reservations
  MODIFY numeroR BIGINT NOT NULL AUTO_INCREMENT;

-- 6.4) Renommer une colonne (RENAME COLUMN)
-- (MySQL 8+)
ALTER TABLE reservations
CHANGE dateR date_reservation DATE NOT NULL;


/* ============================================================
   7) LA CONTRAINTE DEFAULT (valeur par d��faut)
   ============================================================ */

-- 7.1) Ajouter un DEFAULT
-- Exemple : si telephone est NULL, on peut lui donner un default
ALTER TABLE clients
  MODIFY telephone VARCHAR(30) NULL DEFAULT 'INCONNU';

-- 7.2) Modifier un DEFAULT (changer la valeur par d��faut)
ALTER TABLE clients
  MODIFY telephone VARCHAR(30) NULL DEFAULT 'NON RENSEIGNE';

-- 7.3) Supprimer un DEFAULT
-- (il suffit de red��finir la colonne sans DEFAULT)
ALTER TABLE clients
  MODIFY telephone VARCHAR(30) NULL;

-- 7.4) Exemple tr��s courant : DEFAULT sur une date (ou timestamp)
-- Ici, on utilise CURRENT_DATE (date du jour)
-- (Selon versions, CURRENT_DATE peut ��tre accept��; sinon on mettra la date c��t�� application)
ALTER TABLE reservations
  MODIFY date_reservation DATE NOT NULL DEFAULT (CURRENT_DATE); #select CURRENT_DATE, curdate(); # CURRENT_DATE, curdate() => jour&mois&ann��e

-- Enlever ce DEFAULT
ALTER TABLE reservations
  MODIFY date_reservation DATE NOT NULL;


/* ============================================================
   8) COMMENT SUPPRIMER (DROP) DES CONTRAINTES
   ============================================================ */

-- 8.1) Supprimer une FK (il faut conna��tre SON NOM)
-- Ici on l���a appel��e fk_res_suite et fk_res_client
ALTER TABLE reservations
  DROP FOREIGN KEY fk_res_suite;

ALTER TABLE reservations
  DROP FOREIGN KEY fk_res_client;

-- 8.2) Supprimer un UNIQUE
-- UNIQUE = index unique => DROP INDEX
ALTER TABLE clients
  DROP INDEX uq_clients_email;

-- 8.3) Supprimer une PK
#si la PK est d��finie en tant que auto-increment, if faut en premier lieu enlever cette contrainte:
ALTER TABLE reservations
MODIFY numeroR INT NOT NULL;
#puis supprimer la PK
ALTER TABLE reservations
  DROP PRIMARY KEY;

-- 8.4) Supprimer un CHECK (MySQL 8+)
-- sinon on obtient le nom de la contraite en premier lieu:
show create table suites;
-- ou
select * from information_schema.table_constraints where table_name= 'suites'; 
ALTER TABLE suites
  DROP constraint chk_suites_etage_nbPieces;


/* ============================================================
   9) RETROUVER LES NOMS DES CONTRAINTES / INDEX (tr��s utile)
   ============================================================ */

-- Voir les CREATE TABLE complets (on y voit PK, FK, CHECK, index)
SHOW CREATE TABLE reservations;
SHOW CREATE TABLE clients;
SHOW CREATE TABLE suites;

-- Lister les contraintes connues par MySQL
SELECT constraint_name, constraint_type
FROM information_schema.table_constraints
WHERE table_schema = DATABASE()
  AND table_name = 'reservations';

-- Lister les index (PK/UNIQUE) d���une table
-- SHOW INDEX FROM clients;


/* ============================================================
   10) SUPPRIMER DES TABLES ET SUPPRIMER LA BASE
   ============================================================ */

-- 10.1) Supprimer les tables (ordre important si FK existent)
DROP TABLE IF EXISTS reservations;
DROP TABLE IF EXISTS clients;
DROP TABLE IF EXISTS suites;

-- 10.2) Supprimer la base enti��re (attention: tout dispara��t)
DROP DATABASE IF EXISTS hotel_db2;

# data[].attributes.body
Sujets:

- Création de tables avec contraintes

- Opérations CRUD de base

Annexe:

#########Voir les tables de la BD

show tables;

#########Voir la structure de la table suites

describe suites;

---

Travail à Faire:

Projet : "Navarco-Stock" (Gestion de Location de Matériel BTP)

Contexte : Dans le secteur du bâtiment, une entreprise ne possède pas toujours tout son matériel. Elle doit souvent louer des engins (grues, pelleteuses) à d'autres sociétés. Tu dois créer la base de données qui gère ces locations.

1. Le MLD

Voici la structure logique imposée :

CATEGORIE (codeCat, libelle)

ENGIN (idEngin, nom, #codeCat, etat)

LOCATION (idLoc, dateDebut, dateFin, #idEngin, nomClient)

2. Les Consignes du Projet (Le "Cahier des Charges")

Vous devez rédiger le script SQL en respectant les règles métier suivantes :

1. Table CATEGORIE :

codeCat est une chaîne de 5 caractères (ex: 'GRUE', 'PELLE'); Indication: Utiliser l'opérateur 'LIKE'.

libelle est obligatoire.

2. Table ENGIN :

idEngin est un entier auto-incrémenté.

etat doit être obligatoirement soit 'Disponible', soit 'En Maintenance', soit 'Loué' (utiliser une contrainte CHECK).

Un engin appartient à une catégorie. Si on modifie le codeCat, cela doit se répercuter sur les engins (ON UPDATE CASCADE).

3. Table LOCATION :

idLoc est auto-incrémenté.

dateFin doit être supérieure ou égale à dateDebut (utiliser une contrainte CHECK).

Si on essaie de supprimer un Engin qui a déjà été loué, le système doit l'interdire (ON DELETE RESTRICT).

3. Travail à réaliser (Questions)

Q1 : Écrire le script de création de la base de données navarco_stock.

Q2 : Insérer 2 catégories ('LEV', 'TER') et 3 engins (dont une 'Grue mobile' et un 'Bulldozer').

Q3 (Le Test) : Écrire une requête INSERT pour une location qui commence aujourd'hui et se termine hier. On doit vérifier que MySQL bloque l'insertion grâce au CHECK.

Q4 (La Requête de Gestion) : Écrire une requête qui affiche les locations en cours.

# data[].attributes.attachment_link.description
Organize anything, together. Trello is a collaboration tool that organizes your projects into boards. In one glance, know what’s being worked on, who’s working on what, and where something is in a process.

# data[].attributes.body
https://docs.google.com/spreadsheets/d/1wbXtEeMXSKA6zV5HCsi2Qyv4309ebTulXoCXGAlJxoM/edit?usp=sharing

# data[].attributes.headline
BD: Manipulations Basiques MySQL Workbench 

# data[].attributes.subject
BD: Manipulations Basiques MySQL Workbench 

# data[].attributes.attachment_link.readable_text
/*Selectionner la bd ma_bd*/
use ma_bd; 

/*extraire les donn��es de la table ma_table1 qhi existe dans la bd mabasedonnees*/
SELECT * FROM ma_bd.filiere; 

/*Voir la structure de la table filiere*/
describe filiere;

/*Ins��rer un nouvel enregistrement*/
insert into filiere values(3, 'commerce')
insert into filiere(designation,code) values('tsge', 4)
insert into filiere(code) values(5) /*designation=NULL*/
insert into filiere values(6, '')

/*Mettre �� jour (modifier) un enregistrement existant*/
update filiere set designation='aii' where code=6

/*Supprimer un enregistrement*/
delete from filiere where code=6

# data[].attributes.headline
BD: Créer des BD en utilisant MySQL Workbench

# data[].attributes.subject
BD: Créer des BD en utilisant MySQL Workbench

# data[].attributes.body
Annexe:

etape 1: demarrer le serveur mysql

etape 2: aller dans workench et créer la base de

données appelée ma_bd

->clique avec kle bouton droit de la souris

->create schema

etape 3: aller dans la BD et créer les tables

(dans l'onglet ma_bd, et sur l'oglet tables

=> clique par le bouton droit

=> create table)

PK: clé primaire

(double clique sur une colonne pour ecrire)

type_cle_etrangère = type_cle_primaire_referencée

double clique dans 'referenced table'

supprimer 'visible', car non supporté par maria db

# data[].attributes.headline
BD: Exercice 3 - Conception SI/Modélisation Merise

# data[].attributes.subject
BD: Exercice 3 - Conception SI/Modélisation Merise

# data[].attributes.body
Exercice 3 : Société de location de véhicule

Cet exercice porte la gestion de location de véhicule.
La société loue des véhicules aux entreprises comme aux particuliers grâce à un réseau d’agences. Il y a une centaine d’agence réparties sur tout le territoire. Chaque agence est considérée comme un
centre de profit autonome et gère son personnel administratif et technique.
Les petites agences possèdent un bureau de location unique. Les grandes agences, par exemple dans les aéroports et les centres-villes, sont organisées en plusieurs offices auprès desquels les clients peuvent se rendre pour louer un véhicule. Les ffices sont sous la responsabilité d’une seule agence, et disposent de tous les véhicules de l’agence. Les véhicules sont garés dans les emplacements de parking réservés par l’agence dans des parkings publics.
Lorsqu’un client loue un véhicule, un contrat est établi à l’office où il est adressé. Le Contrat possède un numéro qui rappelle l’agence qui l’a émis. Hormis la date et l’heure, le contrat indique aussi l’immatriculation du véhicule loué, le modèle, le constructeur et le kilométrage de départ. On trouve aussi, sur le contrat, la possibilité de noter des remarques sur l’état du véhicule.
Le client signe le contrat. Un exemplaire du contrat est conservé à l’agence et l’original est remis au client avec les clefs. Le client prend possession du véhicule et part.
À la fin de la location, le client a la ossibilité de rendre le véhicule à l’agence de son choix. Il le dépose directement au parking où le technicien de service note, sur le contrat, le kilométrage de retour, la consommation de carburant et éventuellement les chocs ou rayures sur la carrosserie.
Chaque agence propose à la location les véhicules qui lui sont attribués et des véhicules qui viennent d’autres agences. Quand un véhicule est déposé par un client, il est possible qu’il l’ait loué dans une autre agence. En cas de besoin, les échanges de véhicules entre agences sont possibles. Le système à mettre en place doit permettre de connaître, à chaque instant, l’état d’un véhicule (loué ou disponible) et, s’il est disponible, dans le parking de quelle agence il se trouve.
Certains véhicules sont destinés uniquement à la location avec chauffeur.
Pour une bonne gestion du parc de véhicule, il est important d’en connaître l’année de mise en circulation.
Il est possible de louer des véhicules avec chauffeur. Les chauffeurs sont des sous-traitants de l’agence. Pour être pressenti, un chauffeur doit fournir son état civil et son permis de conduire en cours de validité. Ils peuvent conduire tous les véhicules avec chauffeur disponibles à l’agence. Un contrat avec chauffeur suppose que le véhicule soit ramené obligatoirement à l’agence d’où le
véhicule est parti. Si le client désire être déposé ailleurs, le trajet de retour à l’agence est pris en compte dans le coût de la location.

# data[].attributes.headline
SWS: Positionnement avec FlexBox (Exercice)

# data[].attributes.subject
SWS: Positionnement avec FlexBox (Exercice)

# data[].attributes.body
Travail à faire:

Soit la page HTML suivante:

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <title>Exercice Flexbox – Débutant</title>

  <style>
    body {
      font-family: Arial, sans-serif;
      background: #f3f4f6;
      padding: 40px;
    }

    .container {
      background: #1f2937;
      height: 200px;
      padding: 16px;
    }

    .item {
      background: #e5e7eb;
      padding: 12px;
      width: 80px;
      text-align: center;
      border-radius: 6px;
      font-weight: bold;
    }
  </style>
</head>

<body>

  <h2>Exercice Flexbox</h2>

  <div class="container">
    <div class="item">A</div>
    <div class="item">B</div>
    <div class="item">C</div>
  </div>

</body>
</html>

CONSIGNES

1 — Activer Flexbox pour aligner les trois blocs sur une seule ligne.

2 — Centrer les blocs horizontalement dans le container.

3 — Centrer verticalement les blocs dans le container.

4 — Espacer les éléments de façon à mettre le premier bloc à gauche, le dernier à droite. L’espace est réparti entre les éléments.

5 — Faire en sorte que l’élément B prenne tout l’espace libre.

# data[].attributes.headline
SWS: Positionnement avec FlexBox (vidéo)

# data[].attributes.subject
SWS: Positionnement avec FlexBox (vidéo)

# data[].attributes.body
ref =>

https://drive.google.com/file/d/19r_fAjyFoMSG5AX94DBBUgzmduiRCvJd/view?usp=sharing

# data[].attributes.body
N.B: Source de la vidéo qui traite des flexbox

# data[].attributes.headline
BD: Exercice 2 - Conception SI/Modélisation Merise

# data[].attributes.subject
BD: Exercice 2 - Conception SI/Modélisation Merise

# data[].attributes.body
Exercice 2 : Le canard au sang

Cet exercice porte sur l’automatisation de l’édition des certificats-souvenir des plats de Canard au
Sang.
La spécialité d’un célèbre restaurant parisien est une préparation particulière du canard appelée le
Canard au Sang. Les canards destinés à ce plat sont numérotés.
Quand une table commande un Canard au Sang, un certificat-souvenir est donné à chaque client de
la table. Sur cette attestation figure l’intitulé du restaurant, le nom du client, la date, le nom du
maître d’hôtel en charge de cette table, et des informations sur le canard qui a été servi : son
numéro, son âge et le nom de l’éleveur. Un canard est servi pour quatre personnes au maximum. Il
est possible qu’une table reçoive plusieurs canards mais un canard ne peut être servi qu’à une seule
table.

Travail à faire:

Elaborer le DD, le GDF, le MCD, ainsi que le MLD correspondant

# data[].attributes.headline
BD: MCD - Exercice 1 (rectifié) - DEV102

# data[].attributes.subject
BD: MCD - Exercice 1 (rectifié) - DEV102

# data[].attributes.body
Le passage du MCD (Modèle Conceptuel de Données) au MLD (Modèle Logique de Données) consiste à transformer des objets conceptuels en structures de tables prêtes pour une base de données relationnelle.

Voici les 3 règles d'or à retenir :

1. Transformation des Entités

Chaque Entité du MCD devient automatiquement une Table dans le MLD.

L'Identifiant de l'entité devient la Clé Primaire (PK) de la table.

Les Propriétés deviennent les Colonnes (attributs) de la table.

2. Relation de type (1,n) — La "Migration"

Dans une relation binaire où les cardinalités maximales sont 1 d'un côté et n de l'autre :

La règle : La clé primaire de la table côté "n" migre comme Clé Étrangère (FK) dans la table côté "1".

Exemple : Si un Étudiant appartient à une Classe, la clé id_classe est ajoutée dans la table ETUDIANT.

3. Relation de type (n,n) — La "Création"

Dans une relation binaire où les cardinalités maximales sont n des deux côtés (ou relation porteuse de propriétés) :

La règle : L'association disparait et devient une nouvelle Table de jointure (ou table de relation).

La Clé Primaire : C'est une clé composée des identifiants des entités liées.

Les Attributs : Si l'association avait des propriétés (ex: quantité), elles deviennent des colonnes de cette nouvelle table.

Cas particulier : Relation (1,1)

Si (1,1) des deux côtés : On fusionne généralement les deux entités en une seule table (ou on choisit un sens de migration si elles doivent rester séparées).

Si (0,1) - (1,1) : De préférence, la clé migre de l'entité ayant la cardinalité (0,1) vers celle ayant la cardinalité (1,1).

# data[].attributes.body
Le passage d'un schéma de dépendances fonctionnelles (DF) au Modèle Conceptuel de Données (MCD) suit des règles de normalisation précises. Voici les trois règles fondamentales :

1. Règle des Entités (DF élémentaires simples)

Toute Dépendance Fonctionnelle de type X -> Y où X est une clé (source unique) donne naissance à une Entité.

L'identifiant : La source de la dépendance (X) devient l'identifiant de l'entité.

Les propriétés : Le but de la dépendance (Y) devient un champ de cette entité, si il n'est pas une clé.

Exemple : Matricule -> Nom, Prénom devient une entité Employé avec Matricule comme identifiant.

2. Règle des Associations (DF élémentaires composées)

Une Dépendance Fonctionnelle dont la source est composée de plusieurs champs (X, Y -> Z (Z peut ne pas être présent)) donne généralement naissance à une Association (ou relation).

Les entités liées : Les champs sources (X et Y) doivent déjà être des identifiants d'entités existantes.

La propriété de l'association : Le champ cible (Z), si il existe, devient une propriété portée par l'association elle-même.

Cardinalités : L'entité (X) aura une cardinalité maximale de n vers l'association (car à une occurrence de X correspond plusieurs occurrences de Y). L'entité (Y) aura aussi une cardinalité maximale de n vers l'association (car à une occurrence de Y correspond plusieurs occurrences de X).

Exemple : ID_Produit, ID_Commande -> Quantité devient une association Ligne_Commande entre les entités Produit et Commande, portant le champ Quantité.

3. Règle des Relations Binaires (DF entre identifiants)

Lorsqu'il existe une Dépendance Fonctionnelle entre deux identifiants d'entités différentes (Id_A -> Id_B) :

Cela se traduit par une association binaire.

Cardinalités : L'entité source (A) aura une cardinalité maximale de 1 vers l'association (car un A ne détermine qu'un seul B). L'entité cible (B) aura souvent une cardinalité maximale de n.

Exemple : Num_Employé -> Code_Département crée une relation entre Employé et Département avec une cardinalité (1,1) côté Employé.

# data[].attributes.headline
BD: Exemple Etude De Cas Merise (Gestion d’un centre de formation)

# data[].attributes.subject
BD: Exemple Etude De Cas Merise (Gestion d’un centre de formation)

# data[].attributes.body
Ref: https://docs.google.com/document/d/e/2PACX-1vRmIN_96IGRwcq4b0FdwqtmB8fMS0lqIOgL68uOyQmdDji-tMZibB6Oqq__aXMLYI-5QK_SeLzTe6fh/pub

---------------------------------------------

# data[].attributes.body
Étude de cas (EC)

Application de gestion des étudiants

Contexte

Un établissement de formation souhaite mettre en place une application pour gérer la scolarité de ses étudiants.
L’application doit permettre de suivre les étudiants, les classes, les modules enseignés et les résultats obtenus.

Objets manipulés et leur définition

Étudiant

Un étudiant est défini par :

son CNE,

son nom,

son prénom,

sa date de naissance,

son adresse e-mail,

son numéro de téléphone.

Chaque étudiant est identifié de manière unique par son CNE.

Classe

Une classe est définie par :

un code de classe,

un intitulé de classe,

un niveau (première année, deuxième année, etc.).

Une classe regroupe des étudiants au cours d’une année scolaire.

Module

Un module est défini par :

un code de module,

un intitulé de module,

un coefficient.

Un module peut être enseigné dans plusieurs classes.

Inscription

Une inscription représente le fait qu’un étudiant s’inscrit dans une classe pour une année scolaire donnée.

Une inscription est définie par :

l’année scolaire,

la date d’inscription.

Une inscription associe un étudiant et une classe.
Pour une même année scolaire, un étudiant ne peut être inscrit que dans une seule classe.

Programmation des modules

La programmation des modules représente les modules enseignés dans une classe.

Elle associe :

une classe,

un module.

Une classe peut programmer plusieurs modules, et un module peut être programmé dans plusieurs classes.

Note

Une note représente l’évaluation d’un étudiant dans un module.

Une note est définie par :

une valeur comprise entre 0 et 20,

une session (normale ou rattrapage),

une date de saisie.

Une note associe un étudiant et un module.
Pour un même étudiant et un même module, il ne peut y avoir qu’une seule note par session.

Règles de gestion

1. Un étudiant est identifié de manière unique par son CNE.

2. Une classe peut contenir plusieurs étudiants.

3. Un étudiant est inscrit dans une seule classe par année scolaire.

4. Une classe peut enseigner plusieurs modules.

5. Un module peut être enseigné dans plusieurs classes.

6. Les notes sont comprises entre 0 et 20.

7. Un étudiant peut avoir au maximum deux notes par module (session normale et rattrapage).

# data[].attributes.attachment_link.title
structure d'un cahier de charges on younes_board _ Trello

# data[].attributes.body
TAF:

Lire jusqu'à la diapositive 28

# data[].attributes.body
ref:

https://mobbin.com/

# data[].attributes.body
Ajout de:

-pseudo-classes

-pseudo-elements

-selecteurs niveau 4

-pseudo-elements des formulaires

# data[].attributes.body
N.B:

Ajout de sélecteurs relationnels

# data[].attributes.body
Travail à faire:

1- Créer une page web similaire à celle en pièce jointe.

2- Ajouter une section qui permet d'afficher le menu complet du café sous format PDF, avant la partie de réservation.

3- Ajouter une section qui permet de présenter une vidéo de présentation du café.

4- Ajouter une section qui permet de présenter un audio qui contient le mot du fondateur du café.

# data[].attributes.attachment_link.readable_text
Color-hex gives information about colors including color models (RGB,HSL,HSV and CMYK), Triadic colors, monochromatic colors and analogous colors calculated in color page. Color-hex.com also generates a simple css code for the selected color. Html element samples are also shown below the color detail page. Simply type the 6 digit color code in the box above and hit enter.

Users Latest Favorite Colors

# data[].attributes.attachment_link.description
Color hex is a easy to use tool to get the color codes information including color models (RGB,HSL,HSV and CMYK), css and html color codes.

# data[].attributes.body
dev101 => 22/09/2025