diff --git a/code dynamic b/code dynamic
new file mode 100644
index 0000000000000000000000000000000000000000..d4d287f86918cf62e678b66fc3380a7d95661d90
--- /dev/null
+++ b/code dynamic	
@@ -0,0 +1,204 @@
+from typing import Any
+
+import gffutils
+import pandas as pd
+import matplotlib.pyplot as plt
+from collections import Counter
+from io import StringIO
+
+#STAT
+def avg_lenght(db):
+    """
+    Calcule la longueur moyenne de chaque chaque features
+    :param db: base de données
+    :return: la moyenne de chaque chaque features
+    """
+    avg = Counter()
+    for feature in db.featuretypes():
+        longueurs = [feature.end - feature.start + 1 for feature in db.features_of_type(feature)]
+        avg[feature] = sum(longueurs) / len(longueurs) if longueurs else 0
+    return avg
+
+def count(db):
+    """
+    comptage de chaque features
+    :param db: base de données
+    :return: dict avec feature : nombre de ce feature dans le fichier GFF
+    """
+    stats = Counter()
+    for feature in db.all_features(): #methode gffutils
+        stats[feature.featuretype] += 1
+    return stats
+
+def fusions_stat(count, avg):
+    """
+    Combinaisons de plusieurs dictionnaires stat dans 1 tableau
+    :param count: Un dictionnaire avec le nombre de chaque type de feature.
+    :param avg: Un dictionnaire avec la longueur moyenne de chaque type de feature.
+    :return: Un tableau
+    """
+    # Transformer les dict en tableau
+    count_df = pd.DataFrame(count.items(), columns=["Feature Type", "Count"])
+    avg_df = pd.DataFrame(avg.items(), columns=["Feature Type", "Average Length"])
+
+    # Fusion les tableaux sur la colonne "Feature Type"
+    combined_df = pd.merge(count_df, avg_df, on="Feature Type", how="left") #faut que klé des deux dict soit les memes
+
+    return combined_df
+
+
+#LIEN
+
+def liens(feature):
+    """
+    LIEN NCBI
+    :param feature: Un objet représentant une feature du fichier GFF.
+    :return: lien vers site NCBI du feature
+    """
+    return "NA"
+
+def graphe(stats, output_plot):
+    """
+     Génère un graph de la distribution des features du GFF.
+     :param stats:  Dictionnaire contenant le nombre de chaque type de feature.
+     :return: image qu'on utilisera plus tard
+    """
+    fig, ax = plt.subplots()
+    ax.pie(stats.values(), labels=stats.keys(), autopct='%1.1f%%', startangle=140)
+    ax.axis('equal')  # Cercle parfait
+
+    img_buffer = StringIO()
+    plt.savefig(img_buffer, format='svg')
+    plt.savefig(output_plot)
+    plt.close()
+
+def extraire_attributs(db):
+    """
+    recup tout les attributes present dans notres GFF
+    :param db: base de donnees
+    :return: set d'attribut
+    """
+    attributs = set()
+    for feature in db.all_features():
+        attributs.update(feature.attributes.keys())
+    return sorted(attributs)
+
+def gff_a_html(gff_file, output_html, output_plot="feature_distribution.png"):
+    """
+    Analyse un fichier GFF et génère un tableau HTML avec les informations des gènes extraites
+    :param gff_file: chemin de ou est enregistré le fichier GFF
+    :param output_html: chemin de ou on veux que le fichier HTML s'enregistre
+    :return: enregistre un fichier HTML avec un tableau de donnée la ou on lui a demandé
+    """
+    # base de données temporaire du fichier
+    db = gffutils.create_db(gff_file, dbfn=":memory:", force=True, keep_order=True, merge_strategy="create_unique", sort_attribute_values=True)
+            # memory : pour pas stocker sur disque (RAM)
+            #force = true : recrée base si elle existe déja
+            #merge_strategy="create_unique" : pour que les valeurs fusionnée reste unique
+            #sort_attribute_values=True : tri valeurs
+    data = []  # Liste stock infos
+    attributs = extraire_attributs(db)
+
+    # création data
+    for feature in db.all_features():
+        entry = {"Feature Type": feature.featuretype, "ID": feature.id, "Start": feature.start, "End": feature.end,
+                 "Strand": feature.strand, "External Link": liens(feature)}
+        for attr in attributs:
+            entry[attr] = ", ".join(feature.attributes.get(attr, ["N/A"]))
+        data.append(entry)
+
+    # DATA
+    df = pd.DataFrame(data)
+    df_html = df.to_html(index=False, escape=False) #html
+
+    # STAT
+    cnt = count(db)
+    avg = avg_lenght(db)
+    stats_df = fusions_stat(cnt, avg)
+    stats_html = stats_df.to_html(index=False) #html
+
+    graphe(avg, output_plot)
+
+    html_template = f"""
+       <!DOCTYPE html>
+       <html lang="en">
+       <head>
+           <meta charset="UTF-8"> 
+           <meta name="viewport" content="width=device-width, initial-scale=1.0">
+           <title>GFF Report</title>
+           <link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
+           <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
+           <script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
+           <style>
+               body {{
+                   font-family: Arial, sans-serif;
+                   margin: 20px;
+               }}
+               table {{
+                   width: 100%;
+                   border-collapse: collapse;
+                   margin-bottom: 20px;
+               }}
+               th, td {{
+                   border: 1px solid #ddd;
+                   padding: 8px;
+                   text-align: left;
+               }}
+               th {{
+                   background-color: #f2f2f2;
+               }}
+               img {{
+                   max-width: 100%;
+                   height: auto;
+               }}
+           </style>
+           <script>
+               $(document).ready(function() {{
+                   $('table').DataTable({{
+                       "paging": true,
+                       "searching": true,
+                       "ordering": true
+                   }});
+               }});
+           </script>
+       </head>
+       <body>
+           <h1>Feature Data</h1>
+           {df_html}
+
+           <h1>Statistics</h1>
+           {stats_html}
+
+           <h1>Distribution celon les longueurs</h1>
+           <img src="{output_plot}" alt="Feature Distribution">
+       </body>
+       </html>
+       """
+
+    with open(output_html, "w", encoding="utf-8") as f:
+        f.write(html_template)
+
+    print(f"HTML report saved as {output_html}")
+
+# UTF8 permet les encodages spéciaux
+# viewport permet de lire le documents sur un format téléphone
+# les trucs apres c'est pour charger CSS, jQuery (librairy JS) et DataTables.js (permet tri et recherche)
+# mise en page avec police Arial, margin c'est pour mettre des espaces entre les elements
+# th, td c'est tous le tableau entete et reste
+# th c'est l'entete et j'ai mis un fond gris pour meuilleur visu
+# max-width: 100% permet d'adapter la taille de l'image a la taille de la fenetre du moteur de recherche
+# dans scrit : permet pagination quand tableau est trop long, rechercher dans les colonnes et trier
+
+
+if __name__ == "__main__":
+
+        #chemin des fichiers de Clara :
+    #gff_file = "/Users/claramoreno/PycharmProjects/PythonProjectPaster/wormbase_gff2_alt.txt"
+    gff_file = "/Users/claramoreno/PycharmProjects/PythonProjectPaster/PROKKA_REF_ONTillumina.gff"
+    output_html = "/Users/claramoreno/PycharmProjects/PythonProjectPaster/output.html"
+
+        #chemin des fichiers :
+    #gff_file =
+    #output_html =
+
+    print(gff_a_html(gff_file,output_html))
\ No newline at end of file