diff --git "a/TD2  Qualit\303\251 de d\303\251veloppement" "b/TD2  Qualit\303\251 de d\303\251veloppement"
new file mode 160000
index 0000000000000000000000000000000000000000..e43d48160bf1d9aa01ecba7f77a7dd28db9c60a3
--- /dev/null
+++ "b/TD2  Qualit\303\251 de d\303\251veloppement"	
@@ -0,0 +1 @@
+Subproject commit e43d48160bf1d9aa01ecba7f77a7dd28db9c60a3
diff --git a/TD3 Exceptions/Exercice.ts b/TD3 Exceptions/Exercice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..41321d460564beeb0a05e9fd754369b8662260e8
--- /dev/null
+++ b/TD3 Exceptions/Exercice.ts	
@@ -0,0 +1,239 @@
+
+function creeInitiales(nom, prenom) {
+    return nom[0].toUpperCase() + prenom[0].toUpperCase();
+  }
+  
+  console.log(creeInitiales('Corona', 'Nikola')); 
+ 
+  function creeInitialesSecurise(nom, prenom) {
+    if (!nom || !prenom) {
+      throw new Error('Le nom et le prénom ne doivent pas être vides.');
+    }
+    return nom[0].toUpperCase() + prenom[0].toUpperCase();
+  }
+  
+
+  class NomVideError extends Error {
+    constructor(message) {
+      super(message);
+      this.name = 'NomVideError';
+    }
+  }
+  
+  class PrenomVideError extends Error {
+    constructor(message) {
+      super(message);
+      this.name = 'PrenomVideError';
+    }
+  }
+  
+  class NomEtPrenomVideError extends Error {
+    constructor(message) {
+      super(message);
+      this.name = 'NomEtPrenomVideError';
+    }
+  }
+  
+
+  function creeInitialesAvecExceptions(nom, prenom) {
+    if (!nom && !prenom) {
+      throw new NomEtPrenomVideError('Le nom et le prénom sont vides.');
+    }
+    if (!nom) {
+      throw new NomVideError('Le nom est vide.');
+    }
+    if (!prenom) {
+      throw new PrenomVideError('Le prénom est vide.');
+    }
+    return nom[0].toUpperCase() + prenom[0].toUpperCase();
+  }
+  
+
+  try {
+    console.log(creeInitialesAvecExceptions('Corona', 'Nikola'));
+  } catch (error) {
+    if (error instanceof NomEtPrenomVideError || error instanceof NomVideError || error instanceof PrenomVideError) {
+      console.error(error.message);
+    } else {
+      throw error;
+    }
+  } finally {
+    console.log('Fin du programme');
+  }
+  
+
+  class InitialesError extends Error {
+    constructor(message) {
+      super(message);
+      this.name = 'InitialesError';
+    }
+  }
+  
+  function creeInitialesSimplifie(nom, prenom) {
+    if (!nom && !prenom) {
+      throw new InitialesError('Le nom et le prénom sont vides.');
+    }
+    if (!nom) {
+      throw new InitialesError('Le nom est vide.');
+    }
+    if (!prenom) {
+      throw new InitialesError('Le prénom est vide.');
+    }
+    return nom[0].toUpperCase() + prenom[0].toUpperCase();
+  }
+  
+
+
+  class INEError extends Error {
+    constructor(message: string) {
+        super(message);
+        this.name = "INEError";
+    }
+}
+
+class Etudiant {
+    private INE: string;
+    private nom: string;
+    private prenom: string;
+
+    constructor(nom: string, prenom: string) {
+        this.nom = nom;
+        this.prenom = prenom;
+        this.INE = "";
+    }
+
+    isLetter(c: string): boolean {
+        return (c >= "a" && c <= "z") || (c >= "A" && c <= "Z");
+    }
+
+    setINE(ine: string): void {
+        const regex1 = /^\d{10}[A-Za-z]$/;
+        const regex2 = /^\d{9}[A-Za-z]{2}$/;
+        
+        if (!regex1.test(ine) && !regex2.test(ine)) {
+            throw new INEError("Format incorrect");
+        }
+        
+        this.INE = ine;
+    }
+
+    getINE(): string {
+        return this.INE;
+    }
+}
+
+function demanderINE(etudiant: Etudiant) {
+    let valide = false;
+    while (!valide) {
+      try {
+          const ine = prompt("Entrez le code INE :") || "";
+          etudiant.setINE(ine);
+          console.log("INE enregistré :", etudiant.getINE());
+          valide = true;
+      } catch (error) {
+          if (error instanceof INEError) {
+              console.log(error.message);
+          } else {
+              console.log("Une erreur inattendue s'est produite.");
+              break ; 
+          }
+      }
+  }
+  
+}
+
+class FormatDateError extends Error {
+  constructor(message: string) {
+      super(message);
+      this.name = "FormatDateError";
+  }
+}
+
+class ValeurDateError extends Error {
+  constructor(message: string) {
+      super(message);
+      this.name = "ValeurDateError";
+  }
+}
+
+function parseDate(dateStr: string): number[] {
+  const parts = dateStr.split("/");
+  
+  if (parts.length !== 3) {
+      throw new FormatDateError("Format de date incorrect. Utilisez JJ/MM/AAAA.");
+  }
+
+  const jour = parseInt(parts[0], 10);
+  const mois = parseInt(parts[1], 10);
+  const annee = parseInt(parts[2], 10);
+
+  if (isNaN(jour) || isNaN(mois) || isNaN(annee)) {
+      throw new FormatDateError("La date contient des valeurs non numériques.");
+  }
+
+  if (jour < 1 || jour > 31) {
+      throw new ValeurDateError("Le jour doit être compris entre 1 et 31.");
+  }
+
+  if (mois < 1 || mois > 12) {
+      throw new ValeurDateError("Le mois doit être compris entre 1 et 12.");
+  }
+
+  return [jour, mois, annee];
+}
+
+class ErreurOperandeNull extends Error {
+  constructor(message: string) {
+      super(message);
+      this.name = "ErreurOperandeNull";
+  }
+}
+
+class ErreurOpeInva extends Error {
+  constructor(message : string){
+    super(message);
+    this.name = "ErreurOpeInva";
+  }
+}
+
+class ErreurHorsTab extends Error {
+  constructor(message : string){
+    super(message);
+    this.name = "ErreurHorsTab";
+  }
+}
+
+function calcule(
+  tableau: Array<number>,
+  indice: number,
+  operateur: string,
+  operande: number
+ ): number {
+  if (indice < 0 || indice > tableau.length-1){
+    throw new ErreurHorsTab("Indice trop grand")
+  }
+  switch (operateur) {
+  case "+":
+  return tableau[indice] + operande;
+  case "-":
+  return tableau[indice] - operande;
+  case "*":
+  return tableau[indice] * operande;
+  case "/":
+    if (operande === 0){
+      throw new ErreurOperandeNull("Division Null")
+    }
+    else {
+      return tableau[indice] / operande;
+    }
+  }
+  return 0;
+ }
+try {
+  console.log(calcule([10, 20, 30, 40], 2, "/", 0))
+}
+catch(error){
+    if (error instanceof ErreurOperandeNull){
+      console.log("Erreur de division denominateur null" + error.message)   }
+}
+
diff --git a/TD3 Exceptions/exceptions.pdf b/TD3 Exceptions/exceptions.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..879c8775a530b37b6f66a7bc7fa472834d16a32b
Binary files /dev/null and b/TD3 Exceptions/exceptions.pdf differ
diff --git a/TD3 Exceptions/td_exceptions.pdf b/TD3 Exceptions/td_exceptions.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..b45f63b6b373b0c780882f09ca1f996e0318d06d
Binary files /dev/null and b/TD3 Exceptions/td_exceptions.pdf differ
diff --git a/TD3 Exceptions/tsconfig.json b/TD3 Exceptions/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..d9bde0733bcf45b616755763d237f50adef46f4e
--- /dev/null
+++ b/TD3 Exceptions/tsconfig.json	
@@ -0,0 +1,25 @@
+{
+  // Use IntelliSense to learn about possible attributes.
+  // Hover to view descriptions of existing attributes.
+  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+
+      {
+          "request": "launch",
+          "name": "Launch Program",
+          "type": "node",
+          "program": "${workspaceFolder}/test.ts",
+          "cwd": "${workspaceFolder}",
+          "env": {},
+          "runtimeExecutable": "/home/laroche5/.deno/bin/deno",
+          "runtimeArgs": [
+              "run",
+              "--unstable",
+              "--inspect-wait",
+              "--allow-all"
+          ],
+          "attachSimplePort": 9229
+      }
+  ]
+}
\ No newline at end of file