{"id":16287054,"url":"https://github.com/ombrelin/dut1-sda","last_synced_at":"2025-04-09T05:19:01.019Z","repository":{"id":107020159,"uuid":"292926006","full_name":"Ombrelin/dut1-sda","owner":"Ombrelin","description":"Projet Structure de Données et Algorithme : Traitements de message","archived":false,"fork":false,"pushed_at":"2020-11-24T22:36:30.000Z","size":3285,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-14T23:44:00.368Z","etag":null,"topics":["cpp","data-structures"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ombrelin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-04T19:03:06.000Z","updated_at":"2020-12-21T20:33:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"d43a8a91-cee6-440d-ae90-ca496dcd5e62","html_url":"https://github.com/Ombrelin/dut1-sda","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ombrelin%2Fdut1-sda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ombrelin%2Fdut1-sda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ombrelin%2Fdut1-sda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ombrelin%2Fdut1-sda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ombrelin","download_url":"https://codeload.github.com/Ombrelin/dut1-sda/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247981037,"owners_count":21027849,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","data-structures"],"created_at":"2024-10-10T19:44:18.852Z","updated_at":"2025-04-09T05:19:01.001Z","avatar_url":"https://github.com/Ombrelin.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Structures de Données et Algorithmique\n\nIUT Paris Descartes 2017 - 2018\nMaud GELLEE Groupe\nArsène LAPOSTOLET\n\nMémoire de Projet\n\n## Introduction\n\nInternet se fonde sur le transfert de paquets. C’est pourquoi quand on trans-\nmet des données en réseau, on divise ces données en paquets-réseau pour rendre\nleur transfert possible. A là réception des paquets, il est nécessaire de disposer\nd’un outil de messagerie pour réorganiser les données afin des les rendre intelli-\ngibles pour l’utilisateur.\n\n**Problématique :**\n\nProgrammer une application de gestion de messagerie.\n\n**Rôle fonctionnel du projet :**\n\nL’objectif de ce projet est de programmer un logiciel dont la fonction est de\nlire des paquets-réseau dans un fichier texte. Il doit ensuite rassembler les don-\nnées contenues dans ces paquets et les classer pour les rendre compréhensibles\npar l’utilisateur. Ces données sont également rangées dans des fichiers texte en\nfonction de leur destinataire par souci d’organisation. On rapporte les activités du\nlogiciel dans un fichier texte appelé log afin de voir ce qui a été effectué. Le logi-\nciel doit également gérer la perte de paquets. C’est-à-dire que si tous les paquets\nconstituant un message n’ont pas été recueillis via le réseau, on supprime ce mes-\nsage.\n\n**Les entrées et sorties :**\n\nLes entrées du programme correspondent à un fichier texte qui contient les\npaquet-réseau constitués de leurs identifiants et des données qu’ils contiennent.\n\nLe programme fait l’acquisition de ces informations par le biais d’un flot d’en-\ntrée de type _std::ifstream._ Les flots sont issus de la bibliothèque _\u003cifstream\u003e._ On\nva ensuite ouvrir ce fichier grâce à la méthode _.open._ Nous avons donc spécifié et\n\n\ncodé des fonctions de lecture pour ranger les données ainsi lues dans les compo-\nsants de notre application. Le prototype de ces fonctions est par exemple pour un\nPaquet Réseau : _void lire(std::istream\u0026 is, PaquetReseau\u0026 packRes);_.\n\nPour ce qui est des sorties nous avons, pour les mêmes composants, codés des\nfonctions d’affichage pour envoyer les contenus désirés dans un flot de sortie. Le\nprototype de ces fonctions est, par exemple, pour un Paquet Réseau : _void afficher\n(std::ostream\u0026 os, PaquetReseau\u0026 packRes);_. Nous ouvrons ensuite les flots de\nsortie dont nous avons besoin. _std::cout_ pour la trace écran, _Mailbox_ pour écrire\ndans les Mailbox, et _log_ pour écrire dans le fichier log.\n\n\n## Graphe de dépendance fonctionnelle\n\n\n\nLe projet a été mené sous forme de sprints définis par le génie logiciel. Un\nsprint est défini par une spécification, un jeu de données de test (inSp#) ainsi\nque des résultats attendus (OutSp#).\nUn test permet de valider un objectif. Il utilise donc le jeu de données de\ntest (JDT) et le résultat précis. Nous avons donc utilisé la redirection de flux\nd’entrée pour tester rapidement et efficacement nos programmes afin de vali-\nder nos sprints.\nNous avons ainsi créé un dossier contenant les fichiers requis :\nUtilisation de l’invite de commande pour la redirection :\n\n```\nMicrosoft Windows [version 10.0.16299.19]\n(c) 2017 Microsoft Corporation. Tous droits réservés.\nC:\\Users\\arsen\u003ecd Onedrive\nC:\\Users\\arsen\\OneDrive\u003ecd Documents\nC:\\Users\\arsen\\OneDrive\\Documents\u003ecd \"TEST_SDA\"\nC:\\Users\\arsen\\OneDrive\\Documents\\TEST_SDA\"\u003e\"sprint 5.exe\" \u003cinSp5.txt\u003e\nrun.txt\nC:\\Users\\arsen\\OneDrive\\Documents\\TEST_SDA\"\u003e\nOn crée ainsi un fichier run.txt qui contient les sorties de notre programme.\n```\n##  Organisation des tests\n\n\nIl s’agit ensuite de comparer ce fichier de sorties run.txt avec le fichier des sor-\nties attendues OutSp#.txt. Pour cela on utilise un outil fourni par les profes-\nseurs, diff.jar :\n\nCe programme nous montre ainsi les différences entre le fichier de sortie\nproduit par notre programme et le fichier de sortie attendu. Si des différences\napparaissent, il convient de revoir le programme, sinon, il est déclaré 0-défaut,\net on passe à la suite.\n\n\n## Bilan de validation des tests\n\nPour le bilan de la validation de tests, notre projet valide les six sprints.\n\nPour le premier sprint, il faut créer les composants BlocData, Identifica-\nteurMessage _et PaquetReseau_. Il faut également coder leurs fonctions de lecture et\nd’affichage. Les fonctions de lecture utilisent la lecture mot à mot pour Identifica-\nteurMessage et de la lecture mot à mot combinée à un appel de la mé-\nthode. _getline_. Pour PaquetReseau, on a un appel des fonctions de lecture de\nBlocData et IdentificateurMessage. Il est ensuite nécessaire dans le main de faire\nune boucle qui va lire le fichier pour stocker ses données dans les composants\npour ensuite afficher les composants. Le sprint permet de tester si nos flots fonc-\ntionnent correctement. La comparaison des fichiers obtenus par redirection nous a\nmontré que des espaces en début de ligne manquaient. Nous avons donc créé la\nfonction _NettoyerLigne_ , donnée par notre professeur, qui agit come un _ws_ en lais-\nsant l’espace en début de ligne. Nous sommes ensuite passés au sprint de niveau\nsupérieur.\n\nPour le deuxième sprint, il faut organiser les données en mémoire. C’est pour-\nquoi on utilise le composant Liste, reposant sur un conteneur en mémoire dyna-\nmique des composants tous deux fournis par l’équipe pédagogique. Il faut égale-\nment créer les composants Messagerie, MessageEnCours et spécialiser le compo-\nsant Item en MessageEnCours. Nous avons codé pour MessageEnCours des fonc-\ntions _initialiser_ et _detruire_ pour manipuler ce composant. Il faut également coder\nla fonction _estEgal_ dans IdentificateurMessage qui permet de comparer deux\nIdentificateurMessage. Enfin, dans le composant de Messagerie, nous avons codé\nla fonction _TraiterPaquetReseau_ qui permet de comparer les PaquetReseau et de\nles ranger dans la liste sous forme de MessageEnCours. Dans le main, on ajoute\nl’appel de _TraiterPaquetReseau_ dans la boucle de lecture. On fait ensuite une\nboucle d’affichage car ce qui est demandé ici c’est les IdentificateursMessage. La\ncomparaison des fichiers obtenus par redirection nous a permis de déclarer\ncesprint comme 0-défaut et de passer au sprint de niveau supérieur.\n\n\nPour le troisième sprint, il faut stocker les blocs de données en mémoire, pour\npouvoir les ranger par identifiant. Nous avons donc implémenté le composant de\nfile fourni par l’équipe pédagogique. Il faut aussi spécifier le type _Itemf_ en _BlocD_\nainsi que modifier la fonction _TraiterPaquetReseau_ et la structure _MessageEn-\nCours._ Nous avons envisagé deux cas : celui où l’identifiant est encore inconnu et\ncelui où on a déjà reçu un paquet de ce message. Etant donné que nous ne devions\npas encore trier les blocs de données en fonction de leur place dans le message, il\nnous a suffit de les implémenter en mémoire grâce à la structure _MessageEn-\nCours_. En effet, la file se trouve dans cette dernière. La comparaison des fichiers\nobtenus par redirection nous a permis de déclarer ce sprint comme 0-\ndéfaut et de passer au sprint de niveau supérieur.\n\nLe quatrième sprint n’a rien à voir avec les précédents. Il consiste à modifier\nla fonction _ecrire_ du composants de file fourni par l’équipe pédagogique. Désor-\nmais la fonction _ecrire_ devait se rapprocher de la fonction _inserer_ d’un composant\nde liste. En effet, à chaque fois que la fonction _entrer_ est appelée on parcourt toute\nla file afin de comparer le critère de l’ _item_ à insérer avec celui des _item_ déjà exis-\ntants. Pour cela on utilise la fonction _EnOrdre_ qui compare des _int_. Ainsi, la file\nobtenu est une file à priorité, c’est-à-dire que les _item_ qu’elle stocke sont stockés\npar ordre de priorité (ordre déterminé par le critère de la fonction _EnOrdre_ ). La\ncomparaison des fichiers obtenus par redirection nous a permis de déclarer c e\nsprint comme 0-défaut et de passer au sprint de niveau supérieur.\n\nPour le cinquième sprint, il faut désormais que les blocs de données soient\nrangés en fonction de leur numéro de bloc. Nous utilisons le composant de file à\npriorité développé dans le quatrième sprint à la place du composant file. Nous\nchoisissons le numéro de bloc comme critère dans la fonction _EnOrdre._ Ainsi nous\nobtenons les messages originaux. La comparaison des fichiers obtenus par redi-\nrection nous a permis de déclarer ce sprint comme 0-défaut et de passer au sprint de niveau supérieur.\n\nPour le sixième sprint, il faut créer les fichiers de Mailbox et le fichier log.\nPour chaque action telle que la réception d’un nouveau message, suppression d’un\nmessage, nous avons dû réutiliser les flots d’entrée-sortie pour créer un fichier log\nainsi que plusieurs fichiers Mailbox qui correspondent à la messagerie de chaque\ndestinataire. Nous avons donc modifié la fonction _TraiterPaquetReseau_ à cet effet.\nDe plus, nous devons désormais prendre en compte la perte de paquets réseau.\nOn ne doit afficher le message que lorsque tous les blocs de données d’un message\nont été reçus dans les temps. Nous nous sommes heurtés à trois difficultés ma-\njeures. La première concernait la suppression de paquets réseau. Au début, nous\navions pensé que pour chaque paquet réseau reçu, nous devions vérifier si son nu-\nméro de paquet réseau était inférieur ou non à _10 + lastPRecu._ Cette technique\nfonctionnait parfaitement. Cependant, lorsque nous avons commencé à remplir le\nfichier log, nous nous sommes rendus compte que cette opération était effectuée\ntrop tard par notre programme par rapport au log attendu. Nous avons donc,\naprès comparaison, dû changer la fonction. Ainsi, à chaque paquet réseau, la fonc-\ntion _TraiterPaquetReseau_ vérifie si pour tous les messages en cours, le numéro du\n_lastPRecu_ est inférieur ou non à 10 + le numéro du paquet actuel. Notre deuxième\nproblème portait sur la création des Mailbox. En effet, nous avions deux manières\nde procéder : soit en créant un fichier Mailbox dès qu’un nouveau destinataire\nétait repéré, soit en créant la Mailbox lorsque tout le message avait été reçu. La\npremière solution nous permettait d’écrire correctement le titre de cette Mailbox,\nsans doublons (exemple : Mailbox all qui recevait deux messages différents). Mais\nnous devions alors supprimer les Mailbox, dans lesquelles des messages étaient\nperdus et se retrouvaient donc vides en fin de programme (exemple : Mailbox\ngrp9a12). Or, nous ne sommes pas parvenu à supprimer un fichier, malgré nos es-\nsais avec la fonction _remove()_. Nous avons donc opté pour la deuxième solution,\nmais nous devions nous assurer que le titre n’était pas écrit deux fois en cas de\nréception de deux messages différents pour un même destinataire. Après\nquelques essais infructueux, nous sommes finalement parvenus grâce à la\n\n\nfonction _getline()_ à vérifier si nous avions déjà écrit le titre dans un fichier. Une\nfois ces deux problèmes résolus, notre sprint six était pratiquement 0-défaut, mis\nà part quelques problèmes d’espaces en trop pour les blocs de données, problème\nque nous n’avons pas réussi à résoudre.\n\n\n##  Bilan du Projet\n\nCe projet collaboratif en programmation nous a permis de découvrir le lan-\ngage C++, ses possibilités, mais aussi ses aspects difficiles à appréhender. En ef-\nfet, ce projet a constitué pour nous une introduction aux mécaniques des flots\nd’entrée-sortie, mais aussi à la compilation séparée, qui permet une meilleure or-\nganisation et un repérage plus intuitif dans le projet, augmentant ainsi la pro-\nductivité. Cela nous a aidé non seulement à parfaire notre maîtrise des outils de\nprogrammation impérative mais aussi à intégrer la rigueur de la documentation\nformatée, afin de faciliter l’implémentation de mise à jour ainsi que les modifica-\ntions ultérieures. Tout au long de ce projet, nous avons encore une fois ressenti en\nnous l’âme du développeur. En effet, le fait de créer un tel logiciel fourni un senti-\nment d’accomplissement très agréable. Nous nous sommes sentis encore plus\nproche du programmeur qui fait tout son possible pour remplir son contrat.\nChaque difficulté surmontée par la réflexion nous à motivé à avancer plus encore\net à persévérer pour parachever notre ouvrage. Quand on développe ces projets,\non se sent programmeur, et c’est vraiment une expérience unique.\n\nEnfin, l’aspect collaboratif de ce projet fait partie de ses points forts. En effet,\nla motivation mutuelle est un moteur si puissant qu’il permet de surmonter tout\ntype de désespoir. De plus, la puissance de deux esprits focalisés sur le même ob-\njectif, communicant sur un problème est une des formes les plus efficaces de ré-\nflexion. Chacun comblant les faiblesses de l’autre, nous avons pu nous tirer mu-\ntuellement vers le haut. Ayant déjà l’expérience du travail en commun, nous\navons renforcé notre niveau de collaboration et cela nous a permis d’avancer en-\ncore plus vite malgré les difficultés, chacun connaissant les spécificités de l’autre.\nEncore une fois, cette expérience nous permet d’affirmer que la collaboration sur\nun tel projet est la forme la plus productive de travail.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fombrelin%2Fdut1-sda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fombrelin%2Fdut1-sda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fombrelin%2Fdut1-sda/lists"}