From c39d1d340dcb16ba43aee6dd62440c30a75b2c6a Mon Sep 17 00:00:00 2001
From: "iliya.saroukha" <iliya.saroukhanian@etu.hesge.ch>
Date: Fri, 18 Apr 2025 19:38:24 +0200
Subject: [PATCH] feat: report finished

---
 report/report.qmd | 174 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 173 insertions(+), 1 deletion(-)

diff --git a/report/report.qmd b/report/report.qmd
index 82a8050..0d4ecc7 100644
--- a/report/report.qmd
+++ b/report/report.qmd
@@ -420,4 +420,176 @@ Node(weight=9,
  
 Pour le décodage, nous allons appliquer l'algorithme présenté dans le cours
 n°5. Celui-ci stripule qu'il est nécessaire de parcourir l'arbre au fur et à
-mésure jusqu'à retrouver la feuille NYT. À ce moment il est 
+mésure jusqu'à retrouver la feuille NYT. À ce moment, il est nécessaire de
+lire les $e$ bits suivants. Si la valeur de ceux-ci en base 10 est inférieur
+à $r$, alors pour obtenir le symbole correspondant il est nécessaire de lire
+les $(e + 1)$, de les convertir en base 10 et d'y ajouter 1. La valeur numérique
+résultante sera la position dans du symbole dans l'alphabet. Si la valeur de
+$e$ est inférieur ou égale à $r$, il faut convertir ces bits en base 10 et d'y
+ajouter la valeur $r + 1$.
+
+Plus concrètement, nous allons en premier lieu nous débarasser des éventuels
+espaces dans la chaîne de caractères codées, puis nous allons lire cette chaîne
+jusqu'à l'épuisement des bits dans celles-ci. À l'intérieur de la boucle, nous
+commencerons par parcourir l'arbre jusqu'à la feuille NYT. Si la valeur du bit
+actuel est 0, nous allons bifurquer à gauche, sinon à droite. Ayant recontré
+la feuille NYT, nous appliquerons l'algorithme énoncé précédemment pour
+déterminer le caractère rencontré. Celui-ci, sera rajouté à la chaîne de
+caractère finale et sera aussi insérer dans un `set` afin d'indiquer que ce
+caractère fut recontré. Ceci est important du fait que lorsque ce caractère
+sera à nouveau rencontré, le parcours de l'arbre ne se fera plus jusqu'à une
+feuille NYT et par conséquent le code NYT ne sera plus présent dans la chaîne
+décodée. Ce cas est présenté par le branchement conditionnel à la ligne 43.
+L'implémentation de cette fonction se trouve ci-dessous :
+
+```python
+def decode(encoded: str) -> (str, str):
+    bits = encoded.replace(' ', '')
+    tree = Node()
+    result = ''
+    seen = set()
+    i = 0
+
+    message_with_nyt: list[str] = []
+    message_without_nyt: list[str] = []
+
+    while i < len(bits):
+        node = tree
+
+        while node.left or node.right:
+            if bits[i] == '0':
+                node = node.left
+            else:
+                node = node.right
+            i += 1
+
+        if node.value == 'NYT':
+            e, r = compute_vitter_params(len(LIST_ALPHABET))
+            prefix_bits = bits[i:i+e]
+            val = int(prefix_bits, 2)
+
+            if val < r:
+                code_bits = bits[i:i+e+1]
+                k = int(code_bits, 2) + 1
+                i += e + 1
+            else:
+                k = val + r + 1
+                i += e
+
+            char = LIST_ALPHABET[k - 1]
+            result += char
+            seen.add(char)
+            insert_char(tree, char)
+
+            message_with_nyt.append('NYT')
+            message_with_nyt.append(char)
+            message_without_nyt.append(char)
+
+        else:
+            char = node.value
+            result += char
+            insert_char(tree, char)
+
+            message_with_nyt.append(char)
+            message_without_nyt.append(char)
+        pprint.pp(tree)
+
+    pprint.pp(tree)
+
+    return ' '.join(message_with_nyt[1:]), ''.join(message_without_nyt)
+```
+
+### Résultat du décodage
+
+Pour la chaîne de caractères encodées `Code final: 000011 0 000000 00 01101 100
+00110 1100 10001 10 0 11100 01010 110`, nous allons à nouveau obtenir la
+chaîne initiale "darkvador" tout en reconstruisant l'arbre au fur et à mesure
+du décodage.
+
+```bash
+Message initial avec NYT : d NYT a NYT r NYT k NYT v a d NYT o r
+Message initial sans NYT : darkvador
+```
+
+L'arbre résultant de ce décodage sera donc le même que celui construit au moment
+de l'encodage :
+
+```bash
+Node(weight=9,
+     nyt_code=None,
+     value='NYT',
+     left=Node(weight=2, nyt_code='', value='d', left=None, right=None),
+     right=Node(weight=7,
+                nyt_code=None,
+                value='NYT',
+                left=Node(weight=2,
+                          nyt_code='0',
+                          value='a',
+                          left=None,
+                          right=None),
+                right=Node(weight=5,
+                           nyt_code=None,
+                           value='NYT',
+                           left=Node(weight=2,
+                                     nyt_code='00',
+                                     value='r',
+                                     left=None,
+                                     right=None),
+                           right=Node(weight=3,
+                                      nyt_code=None,
+                                      value='NYT',
+                                      left=Node(weight=1,
+                                                nyt_code='100',
+                                                value='k',
+                                                left=None,
+                                                right=None),
+                                      right=Node(weight=2,
+                                                 nyt_code=None,
+                                                 value='NYT',
+                                                 left=Node(weight=1,
+                                                           nyt_code=None,
+                                                           value='NYT',
+                                                           left=Node(weight=0,
+                                                                     nyt_code=None,
+                                                                     value='NYT',
+                                                                     left=None,
+                                                                     right=None),
+                                                           right=Node(weight=1,
+                                                                      nyt_code='11100',
+                                                                      value='o',
+                                                                      left=None,
+                                                                      right=None)),
+                                                 right=Node(weight=1,
+                                                            nyt_code='1100',
+                                                            value='v',
+                                                            left=None,
+                                                            right=None))))))
+```
+
+\newpage
+
+## Utilisation du programme
+
+Le programme `dyn_huffman.py` est utilisé de la manière suivante :
+
+- Si l'on souhaite encoder une chaîne de caractère, il est nécessaire de
+la préfixer du flag `-e` (pour _encode_) avant de la fournir à la ligne de
+commande comme ceci :
+```bash
+python3 dyn_huffman.py -e "darkvador"
+```
+- Inversement, si l'on souhaite décoder une chaîne binaire il est nécessaire
+de spécifier le _flag_ `-d``(pour _decode_)
+```bash
+python3 dyn_huffman.py -d "000011 0 000000 00 01101 100 00110 1100 10001 10 0 \
+11100 01010 110"
+```
+
+## Résumé du travail
+
+Ce travail pratique nous a permis de mettre en œuvre l'algorithme d'Huffman
+adaptatif pour la compression optimale de chaîne de caractères. C'est avec un
+franc succès que nous avons réussi à encoder correctement une chaîne de
+caractères fournies en argument au programme grâce à la construction itérative
+de l'arbre binaire, puis implémenter le décodage associé afin de retrouver la
+chaîne de caractère initiale.
-- 
GitLab