INF3135_H2021

Construction et maintenance de logiciels (langage C)

View project on GitHub

Travail pratique 2

L’objectif est de continuer notre initiation à la programmation avec le langage C. Cette fois nous allons un peu plus loin dans notre processus de création et de réflexion. Vous devez dans ce travail livrer un programme de qualité irréprochable qui tient compte de critères déjà vus. Spécifiquement vous devez lire et produire des données sur l’entrée et la sortie standard respectivement.

De plus, vos sources seront maintenues dans un gestionnaire de version/source de type git.

La compréhension et la prise de décision sont aussi des objectifs à atteindre durant la mise en oeuvre, la réalisation, de vos travaux.

  Le travail est à réaliser individuellement. 
  Ce qui veut dire seul, pas de travail d'équipe.

Sujet (rappel)

Chaque session nous avons un sujet unique que nous traînons pendant plusieurs semaines. Cette fois encore, je continue avec cette bonne habitude. L’avantage est que nous n’avons pas à apprendre des sujets différents pour chaque travail pratique. Ainsi nous pouvons vraiment concentrer l’effort sur ce qui est important, c’est-à-dire la construction et la maintenance de logiciels. Pour nous c’est avec le langage C. Un langage de programmation important qui produit des logiciels dits performants, mais il n’en serait rien sans des programmeurs qui savent ce qu’ils font.

TSX-C est un projet qui concerne la bourse de Toronto. Nous allons manipuler des indices boursiers et les données qui s’y rattachent.

Description du travail

Vous devez dans ce travail apporter des modifications au code existant. Vous ajouterez une fonction de gestion des arguments (options) de la ligne de commande. Vous devez créer un programme juste et robuste. Des fichiers (modules) seront utilisés pour garder un code propre et lisible. L’utilisation de toutes les notions vues cette session seront utile. Finalement, le langage dans les mains de programmeur tel que vous peut produire, doit produire, un exécutable performant.

Ce que vous devez faire :

  • modulariser le code du travail pratique précédent.

Ce travail est une modification du tp1 vous devez donc modifier ce que vous avez déjà. Vous allez donc produire le tp2.c à partir des sources du tp1.c. Lorsque vous serez prêt, compilez les sources afin de produire un exécutable nommé tp2.

Le programme exécutable peut être lancé en ligne de commande avec différentes syntaxes :

# sans option
$ ./tp2
$ cat file.dat | ./tp2
$ head -n 100 file.txt| tail -n 25 | ./tp2

# avec option(s) de la ligne de commande (-c 1 -d 1 -t -s)
$ cat indices.txt | ./tp2 -c 1 -d 3
$ ./tp2 -s -d 0
$ ./tp2 -c 3
$ ./tp2 -s -t
...

Vous devez réaliser le travail selon les contraintes (directives formelles) suivantes:

Ce que nous devons retrouver dans le fichier tp2.c :

  • uniquement le code de la fonction int main(int argc, char *argv[]).
  • ne doit pas contenir plus de 35 lignes, une instruction par ligne.

Ce que vous devez retrouver dans le fichier outil3.h et outil3.c:

  • Ce module est indépendant;
    • Aucune dépendance sur des librairies personnelles ou non standard au langage C;
  • Le code source de la fonction int cmd(...);
    • La fonction gère les arguments de la ligne de commande;
  • La MACRO _OUTIL3_H_ doit exister pour la détection des inclusions multiple;
  • Limiter le code source de outil3.c à 250 lignes ou moins, une instruction par ligne.
  • Limiter le code source de outil3.h à 35 lignes ou moins, une instruction par ligne.

Nouvelles directives afin de rendre la réalisation plus facile:

  • Votre code doit IMPÉRATIVEMENT être formaté
    • aucune tabulation (2 espaces) selon le format Java;
    • Ne faites pas le formatage à la main; (pensez utiliser l’utilitaire astyle)
  • Ceux qui veulent faire une librairie ab (arbre binaire) ajouter:
    • ab.c et ab.h afin de produire un .a et un .so;
    • une cible ab.o, ab.so, ab.a;
  • Ceux qui veulent prendre mon vector.c ajouter:
    • vector.c et vector.h afin de produire un .a et un .so;
    • une cible vector.o vector.so, vector.a;
  • Ceux qui veulent faire une librairie abr (arbre binaire de recherche) ajouter :
    • abr.c et abr.h afin de produire un .a et un .so;
    • une cible abr.o, abr.a, abr.so;
      • Je vais compiler avec make tp2 afin de produire un executable shared.
      • Je vais compiler avec make tp2s afin de produire un executable static.
      • Je vais utiliser valgrind.
      • Assurez-vous de bien tout prévoir dans votre Makefile avec des dépendances.
      • Les librairies sont indépendantes (autonome) couplage nul avant usage.
  • Merci aux étudiants pour les bonnes idées.. Ah oui jq n’est pas utile, pour ce travail.

Vous devez ajouter ceci dans votre Makefile pour avoir du succès avec la librairie shared :

-Wl,-rpath=./

Directives générales:

  • Profitez de la période de questions en classe pour vos questions;
  • Votre travail sera réalisé et livré dans le dépôt distant toujours privé;
  • Les fichiers d’entête :
    • standard sont tous permis;
    • <unistd.h>, <windows.h> ne sont pas autorisé;
  • Branche git :
    • Les fichiers seront maintenus dans la branche nommée tp2;
    • Aucun fichier dans la branche nommé main (branche par défaut);
    • La branche main est pour les rétroactions et commentaires de l’enseignant;
  • Ne garder que les fichiers essentiels dans votre projet (dépôt distant);
  • La gestion des répertoires :
    • votre répertoire de travail étant : ./;
    • doit se faire de façon explicite à partir de votre répertoire de travail;
  • La note zéro est attribuée si :
    • vous utilisez ~ ou ~/;
    • vous utilisez .. avec la commande cd;
    • vous utilisez .. ou * avec la commande rm;
    • vous descendez, dans la structure, en deçà de votre répertoire de travail;
    • Vous ne pouvez pas utiliser les commandes suivantes dans le Makefile ou dans vos scripts bash :
      • cd, mv
      • rm uniquement pour la cible clean;
  • Idéalement :
    • réaliser un code simple facile à travailler;
    • vous devez produire du code juste, donc faites ce que vous connaissez;
    • vous devez produire du code robuste, donc débarrassez-vous du code instable;
    • vous devez produire un Makefile qui n’a pas d’effet de bord ou :
      • qui est sans effet secondaire;
      • qui n’a pas un comportement hasardeux;
      • qui n’appelle pas des scripts (exception getQuote.sh);
    • n’attendez pas à la dernière minute, cela risque de devenir stressant.

Rôle de votre programme

Le rôle de votre programme est de lire les indices (déjà fait durant le tp1). Le tp2 ajoute une fonctionnalité qui compte de nombre d’indices lus et selon le cas affichera les informations recueillies. Les options suivantes doivent être gérées :

Voici les cas et les traitements en fonction des options :

  • option -c [0-4] est un filtre
    • 0 affiche tous les classements;
    • [1-4] affiche uniquement le classement demandé;
  • option -d [0-3] est un filtre
    • 0 affiche toutes les classes de dividendes;
    • [1-3] affiche uniquement le la classe de dividende demandé;
  • option -s
    • Le nombre total d’indices filtrés sur total;
  • option -t
    • Le mode tranquille n’affiche pas les indices en sortie;

Quelques exemples visuels (le rendu est important)

Ici vous avez un exemple visuel seulement, les données ne sont pas validées ou vérifiables. Les indices sont sortis dans l’ordre qui’ils sont lus.

exemple avec les options -t -s -d 0 -c 0

information de classement des indices
  C-1 : 1
  C-2 : 0
  C-3 : 3
  C-4 : 0
information par classe de dividende
  D-1 : 1
  D-2 : 1
  D-3 : 2
information sommaire
  nbr indice : 4 sur 4

exemple avec les options -s

K   C-1 DIV-1   9.35  0.00%
BCE C-2 DIV-2  19.77  3.77%
BNS C-3 DIV-2  90.99  4.77%
BLU C-1 DIV-1  11.34  2.22%
BMO C-4 DIV-3  77.50  7.77%
GUY C-1 DIV-3 987.99 99.02%

information de classement des indices
  C-1 : 3
  C-2 : 1
  C-3 : 1
  C-4 : 1
information par classe de dividende
  D-1 : 2
  D-2 : 2
  D-3 : 2
information sommaire
  nbr indice : 6 sur 6

exemple avec les options -c 1 -s

Exemple (colonnes : indice, classement, classe-dividende, prix marché, le dividende)

K   C-1 DIV-1   9.35  0.00%
BLU C-1 DIV-1  11.34  2.22%
GUY C-1 DIV-3 987.99 99.02%

information de classement des indices
  C-1 : 3
  C-2 : 0
  C-3 : 0
  C-4 : 0
information par classe de dividende
  D-1 : 2
  D-2 : 0
  D-3 : 1
information sommaire
  nbr indice : 3 sur 6

NOTES:

  • Les colonnes : indice, classement, classe-dividende, prix marché, le dividende.
  • Une tabulation est utilisée entre les colonnes.
  • il n’y a pas de caractères accentués. Le format de sortie est important cette fois.
  • il y a un petit changement dans la façon d’afficher (format) le résultat versus le tp1
    • alignement à droite
    • le prix marché (formaté 999.99)
    • le dividende (formaté 99.99%)

Makefile

Il est obligatoire d’inclure un fichier Makefile dans votre projet pour faciliter la compilation et les autres actions requises. Celui-ci doit minimalement offrir les services suivants :

  • Le Makefile
    • La commande make tp2 est commande pour construire l’exécutable tp2;
    • La commande make employée seule devra exécuter la cible default qui est dépendante de tp2;
    • La commande make librairie produira deux librairies liboutil3.so et liboutil3.a;
  • Lorsqu’on entre make clean, le projet revient dans son état d’origine, c’est-à-dire son état lors de la récupération initiale. Vous devez avoir le strict minimum;

  • Les programmes seront compilés et évalués avec les options suivant -Wall -Werror=vla -pedantic -std=c11;

Complément

  • -std=c11 indique au compilateur de traiter le code selon le standard C11 (2011) (et donc de rejeter certaines extensions comme celles de GNU par exemple);
  • -pedantic permet de signaler les avertissements, ou warnings, selon la norme ISO;
  • -Wall permet de signaler un grand nombre d’autres warnings décrit dans le man gcc;
  • -Werror=vla indique au compilateur que la déclaration de tableaux de longueur variable n’est pas permise.

En effet, la grande permissivité de C réduit l’aide du compilateur (lorsqu’il n’y a pas d’option) pour traquer certaines erreurs et les mauvaises pratiques de programmation.

.gitignore

  • Votre projet (dépôt distant) doit contenir uniquement les fichiers strictement nécessaires;
  • Votre projet ne doit pas contenir de fichiers objet ou binaire par exemple.
  • Votre projet ne doit pas contenir de fichiers *.guy;

README.md

Votre projet doit contenir un fichier nommé README.md qui décrit le contenu et qui respecte le format Markdown. Il doit minimalement contenir les informations ci-bas :

Les badges ajoutés à votre README.md seront en mis à jour par votre fichier YAML;

   # Travail pratique X

   badge tpXc.yml
   badge tpXt.yml
   
   ## Auteur

   Un tableau de deux colonnes `nom colonne` et la `valeur`
   
   Identité  Prénom Nom
   CodeMS  ab123456
   CP  ABCD12345678

   ## Votre fierté

   <expliquez brièvement comment faire fonctionner votre projet>

   ## Difficultés rencontrées
   
   <décrire les difficultés>

   ## Références

   <citez vos sources ici>

   ## Listes Exigences
   
   <une liste `check list` de toutes les fonctionnalités réalisées>
   
   ## Statut et auto-évaluation

   <indiquez si le projet est complété ou s'il y a des bogues>

Remise

La totalité de votre travail doit être remise au plus tard le 9 mai 2021 23h59 ET (heure du Québec). Après cette date, une pénalité de 10 points par jour de retard sera appliquée.

La remise se fait obligatoirement par l’intermédiaire de la plateforme Github https://github.com/

Aucune remise par courriel ne sera acceptée (le travail sera considéré comme non remis).

Le nom de votre dépôt doit être le même que dans le travail pratique précédent. L’utilisateur guyfrancoeur toujours comme collaborateur. Vous n’avez pas à refaire la demande de collaboration.

Votre projet devrait minimalement contenir, à la racine du dépôt, les fichiers de type Unix/Linux et ascii suivants :

  • Un fichier tp2.c contenant votre fonction main;
  • Les fichiers outil3.h et outil3.c (ajout pour bien modulariser);
  • Le fichier getQuote.sh corrigé (si correction sont nécessaire);
  • Un fichier README.md selon le format proposé;
  • Un fichier nommé Makefile complet et optimal;
  • Un fichier nommé cp.txt avec votre code permanent en majuscule;
  • Un fichier .gitignore;
  • Les fichiers compilation.md et execution.md seront aussi présents dans votre dépôt.

Aussi dans la structure de répertoire approprié :

  • Un fichier YAML nommé tp2c.yml qui valide la compilation;
  • Un fichier YAML nommé tp2t.yml qui effectue un test fonctionnel en fonction de indices.txt;

Optionnel

  • le .h et .c pour : l’arbre, l’arbre binaire et le vector : ab.h/c | abr.h/c | vector.h/c

L’usage de la commande rm dans votre travail est permise. Avec de grands pouvoirs viennent de grandes responsabilités.

Les travaux seront corrigés sur le serveur Java. Vous devez donc vous assurer que votre programme fonctionne tel que livré, sans modification sur celui-ci.

Barème de correction

Critère Sous-critère Points
Exigences voir exigences 4.0
Compilation exécutable, .so, .a 3.0
Makefile plusieurs critères seront évalués 3.0
tp2c.yml produire le résultat dans compilation.md 1.0
tp2t.yml test fonctionnel execution.md avec indices.txt 1.0
badges yaml mettre les badges dans README.md 2.0
Fonctionnabilité tests et résultats (comparaison binaire) 6.0
Optimal (git) aucun leak 1.0
Total   21/20

Les points extra seront ajoutés au dossier de l’étudiant.

FIN.

Guy Francoeur :copyright: édition H2021