420-KBK-LG – Veille technologique

Quelques raccourcis :

Ceci est un petit site de support pour le cours 420-KBK-LG – Veille technologique. Ce cours est donné par plusieurs enseignant(e)s, et comporte plusieurs volets. Le volet qui nous concerne ici est celui de « programmation avancée ».

Vous trouverez aussi des liens sur divers langages (dont C#, notre outil de prédilection dans ce cours) un peu partout dans http://h-deb.clg.qc.ca/

Les diverses sections de cette page (en fonction desquelles vous trouverez quelques liens dans l'encadré à droite) vous mèneront elles-aussi sur des pistes qui vous permettront d'explorer un peu plus par vous-mêmes, de valider vos acquis et d'enrichir votre apprentissage

Cliquez sur cette cible pour le plan de cours, sous forme électronique

Pratiques de correction

Je corrige les programmes en appliquant des codes de correction. Vous trouverez ici la liste des codes les plus fréquents.

Ma stratégie de correction en tant que telle (pour le code, à tout le moins) est résumée ici.

Cliquez sur cette cible pour un résumé des principales règles de programmatique en vigueur dans ce cours.

Détail des séances en classe

Pour le groupe 01, les séances sont de 8 h à 11 h 35 par Zoom. Pour le groupe 02, les séances sont de 12 h 35 à 16 h 10 par Zoom.

Date gr. 1 Date gr. 2 Séance Détails

9 avril

30 avril

S00

Au menu :

  • Présentation du cours et du plan de cours, du moins le volet qui nous concerne
  • Nos thèmes pour ces trois séances seront (dans le désordre!) :
    • Gestion d'exceptions
    • Gestion de ressources
    • Algorithmique
    • Programmation générique
    • Programmation fonctionnelle
    • Conception logicielle
  • Petit exercice de remise en forme
  • Rappel sur :
  • Présentation de l'activité pour cette semaine. Attention : les activités sont cumulatives, alors ne prenez pas de retard!

Pour un exemple d'énumérateurs sur des entiers pairs, voir https://dotnetfiddle.net/KyScon

Pour l'exemple de Liste<T> avec énumérateur :

class ListeVideException : Exception { }
class Liste<T> : IEnumerable<T>
{
   public IEnumerator<T> GetEnumerator() =>
      new Énumérateur(Tête);
   IEnumerator IEnumerable.GetEnumerator() =>
      throw new NotImplementedException();
   // un énumérateur de C# / un itérateur de Java, modélise
   // une séquence à demi ouverte (debut, fin]
   class Énumérateur : IEnumerator<T>
   {
      Noeud Cur { get; set; }
      public Énumérateur(Noeud tête)
      {
         Cur = new Noeud(default);
         Cur.Succ = tête;
      }
      public bool MoveNext()
      {
         if (Cur.Succ == null)
            return false;
         Cur = Cur.Succ;
         return true;
      }
      public void Reset() => throw new NotImplementedException();
      public void Dispose() { }
      public T Current => Cur.Valeur;
      object IEnumerator.Current => throw new NotImplementedException();
   }
   class Noeud
   {
      public T Valeur { get; init; }
      public Noeud Succ { get; set; } = null;
      public Noeud(T val)
      {
         Valeur = val;
      }
   }
   Noeud Tête { get; set; } = null;
   Noeud Queue { get; set; } = null;
   public Liste()
   {
   }
   public bool EstVide => Tête == null;
   public void AjouterDébut(T val)
   {
      var noeud = new Noeud(val);
      if (EstVide)
         Tête = Queue = noeud;
      else
      {
         noeud.Succ = Tête;
         Tête = noeud;
      }
   }
   public void AjouterFin(T val)
   {
      var noeud = new Noeud(val);
      if (EstVide)
         Tête = Queue = noeud;
      else
      {
         Queue.Succ = noeud;
         Queue = noeud;
      }
   }
   public void SupprimerDébut()
   {
      if (EstVide)
         throw new ListeVideException();
      Tête = Tête.Succ;
      if (Tête == null)
         Queue = null;
   }
}
static void Main()
{
   var lst = new Liste<string>();
   lst.AjouterFin("J'aime");
   lst.AjouterFin("mon");
   lst.AjouterFin("prof");
   foreach (var s in lst)
      Console.Write($"{s} ");
}

16 avril

7 mai

S01

Au menu :

  • Schéma de conception Fabrique
  • Schéma de conception Visiteur
  • Présentation de l'activité pour cette semaine. Attention : les activités sont cumulatives, alors ne prenez pas de retard!

À titre de rappel :

  • Avec le schéma de conception Fabrique, une classe ou une fonction est responsable de créer des objets
  • Pourquoi? Plusieurs raisons sont possibles :
    • Parfois, c'est qu'on a besoin d'une construction en deux temps (p.ex.: var th = new Thread(...); puis th.Start())
    • Parfois, c'est pour une question de gestion d'erreurs (p.ex.: un constructeur n'a pas de type de retour, donc sa capacité à signaler un problème est limitée, typiquement aux levées d'exceptions)
    • Parfois, on ne veut pas révéler le type d'objet construit, on veut juste exposer une interface, ou encore on veut choisir le type en fonction des circonstances
    • Parfois, les paramètres suppléés ne sont pas appropriés pour un constructeur
    • etc.

Pour le schéma de conception Visiteur, nous avons fait un bref exemple (un peu simpliste), soit :

using System;
using System.Collections.Generic;

class Program
{
   class ListeVideException : Exception { }
   // modélise une liste simplement chaînée dont chaque noeud
   // "contient" un T
   class Liste<T>  where T : IComparable<T>
   {
      class Noeud
      {
         public Noeud Succ { get; set; } = null;
         public T Valeur { get; private init; }
         public Noeud(T valeur)
         {
            Valeur = valeur;
         }
      }
      Noeud Tête { get; set; }
      Noeud Queue { get; set; } // optimisation pour connaître le dernier noeud
                                // coût : grossit un peu chaque Liste<T>
      public Liste() // modélise une liste vide
      {
         Tête = null;
         Queue = null;
         Count = 0;
      }
      public bool EstVide => Tête == null; // ou Count == 0
      public void AjouterDébut(T valeur)
      {
         var p = new Noeud(valeur);
         if (EstVide)
            Queue = p;
         p.Succ = Tête;
         Tête = p;
         ++Count;
      }
      public void AjouterFin(T valeur)
      {
         if (EstVide)
            AjouterDébut(valeur);
         else
         {
            Queue.Succ = new Noeud(valeur);
            Queue = Queue.Succ;
            ++Count;
         }
      }
      public void SupprimerDébut()
      {
         if (EstVide)
            throw new ListeVideException();
         Tête = Tête.Succ;
         if (Tête == null)
            Queue = null;
         --Count;
      }
      public int Count
      {
         get; private set;
      }
      public Liste(Liste<T> autre) : this() // appelle d'abord le ctor par défaut
      {
         for (var p = autre.Tête; p != null; p = p.Succ)
            AjouterFin(p.Valeur);
      }
      public T ConsulterDébut()
      {
         if (EstVide)
            throw new ListeVideException();
         return Tête.Valeur;
      }
      public Liste(IEnumerable<T> objs) : this()
      {
         foreach (T x in objs)
            AjouterFin(x);
      }
      public void Accepter(Action<T> f)
      {
         for (var p = Tête; p != null; p = p.Succ)
            f(p.Valeur);
      }
   }

   public static void Main()
   {
      var lst = new Liste<string>();
      foreach (var s in new[] { "J'aime", "mon", "prof" })
         lst.AjouterFin(s);
      lst.Accepter(s => Console.Write($"{s} "));
      string plusseLongue = null;
      lst.Accepter(s =>
      {
         if (plusseLongue == null || s.Length > plusseLongue.Length)
            plusseLongue = s;
      });
      Console.WriteLine($"Chaîne la plusse longue : {plusseLongue}");
      string plusseCourte = null;
      lst.Accepter(s =>
      {
         if (plusseCourte == null || s.Length < plusseCourte.Length)
            plusseCourte = s;
      });
      Console.WriteLine($"Chaîne la plusse courte : {plusseCourte}");
   }
}

Portez évidemment attention à la méthode Accepter...

23 avril

14 mai

S02

Au menu :

Nous allons discuter remise 🙂 Pour chaque équipe de travail, voici ce que je vais ramasser :

  • Une archive .zip portant le nom des équipières et des équipiers, p. ex. : nguyen-bob-tremblay-joanne.zip pour l'équipe de Bob Nguyen et Joanne Tremblay. J'utiliserai le nom de l'archive pour l'attribution des points alors respectez la consigne rigoureusement!
    • Cette archive devra contenir tous vos fichiers .cs à l'exception de celui contenant votre programme principal. Assurez-vous donc que, dans votre solution, la classe Program et sa fonction Main soient seules dans un fichier .cs et que tout le reste soit dans d'autres fichiers sources
      • Cette contrainte est dûe au fait que je vais utiliser mon propre code de test!
    • Je vais présumer que votre code se trouve dans un namespace nommé Boites. Si vous ne respectez pas cette consigne, votre code ne passera pas les tests et vous perdrez des points
    • Je vais présumer que votre code respecte les noms de classes utilisés dans les énoncés boites-v0.html et boites-v1.html, et que le code de test proposé pour ces deux parties de l'énoncé compilera intégralement si pris tel quel; je parle des classes Boite, ComboVertical, ComboHorizontal, FabriqueBoites (incluant le format des string passées à Créer), IVisiteur<T> et IVisitable<T>. Si vous ne respectez pas cette consigne, votre code ne passera pas les tests et vous perdrez des points
  • Vous devrez aussi livrer un fichier texte portant le nom de votre équipe, avec l'extension .test, p. ex. : nguyen-bob-tremblay-joanne.test pour l'équipe de Bob Nguyen et Joanne Tremblay. J'utiliserai le nom du fichier pour l'attribution des points alors respectez la consigne rigoureusement!
    • Le fichier .test devra contenir une séquence de lignes qui seront consommées par FabriqueBoites.Créer, à l'aide d'un programme comme celui-ci (mais plus sophistiqué) :
static string LireBoite(StreamReader sr)
{
   string s = sr.ReadLine();
   while(s != null && s.Trim().Length == 0)
      s = sr.ReadLine();
   if(s != null)
   {
      for(string ligne = sr.ReadLine(); ligne != null && ligne.Trim().Length != 0; ligne = sr.ReadLine())
         s += $"\n{ligne}";
   }
   return s;
}
static void Tester(IBoite b, params IVisiteur<IBoite>[] viz)
{
   Console.WriteLine(b);
   foreach (var v in viz)
      b.Accepter(v);
}
static void Main(string []args) // on passera votre fichier .test en paramètre à l'appel de Main
{
   var fab = new FabriqueBoites();
   var coul = new Couleureur();
   var mes = new Mesureur();
   using(var sr = new StreamReader(args[0]))
      for(var s = LireBoite(sr); s != null; s = LireBoite(sr))
         Tester(new Boite(fab.Créer(s)), coul, mes);
}
  • Enfin, vous devrez livrer un fichier texte portant le nom de votre équipe, avec l'extension .res, p. ex. : nguyen-bob-tremblay-joanne.res pour l'équipe de Bob Nguyen et Joanne Tremblay. J'utiliserai le nom du fichier pour l'attribution des points alors respectez la consigne rigoureusement!
    • Le fichier .res devra contenir le texte qui devrait s'afficher à l'écran si on utilise le fichier .test de la même équipe. Par exemple (je n'ai pas mis la couleur dans l'affichage) :
nguyen-bob-tremblay-joanne.test nguyen-bob-tremblay-joanne.res
mono J'aime mon "prof"

cv
mono J'aime mon "prof"
mono moi itou

ch
mono J'aime mon "prof"
mono moi itou

ch
cv
mono J'aime mon "prof"
mono moi itou
mono eh ben

ch
cv
mc
mono J'aime mon "prof"
mono moi itou
mono eh ben
+-----------------+
|J'aime mon "prof"|
+-----------------+
Boite
  Mono 1 x 17
+-----------------+
|J'aime mon "prof"|
|-----------------|
|moi itou         |
+-----------------+
Boite
  ComboVertical
    Boite
      Mono 1 x 17
    Boite
      Mono 1 x 17
+--------------------------+
|J'aime mon "prof"|moi itou|
+--------------------------+
Boite
  ComboHorizontal
    Boite
      Mono 1 x 17
    Boite
      Mono 1 x 8
+------------------------+
|J'aime mon "prof"|eh ben|
|-----------------|      |
|moi itou         |      |
+------------------------+
Boite
  ComboHorizontal
    Boite
      ComboVertical
        Boite
          Mono 1 x 17
        Boite
          Mono 1 x 17
    Boite
      Mono 3 x 6
+--------------------------+
|+-----------------+|eh ben|
||J'aime mon "prof"||      |
|+-----------------+|      |
|-------------------|      |
|moi itou           |      |
+--------------------------+
Boite
  ComboHorizontal
    Boite
      ComboVertical
        Boite
          MonoCombo
            Boite
              Mono 1 x 17
        Boite
          Mono 1 x 19
    Boite
      Mono 5 x 6

Notez que les MonoCombo (préfixe mc dans le fichier) sont optionnels. Si vous ne les supportez pas, dans FabriqueBoites.Créer, levez une exception de type BonusNonSupportéException

Ce que je ferai avec ça :

  • Je vais valider votre correspondance entre .test et .res à partir de mes propres classes, pour voir si votre code de test est bon!
    • Si votre code de test est incorrect, il sera exclu du processus et votre note sera impactée. Prudence!
  • Assurez-vous que votre code de test ne se limite pas à plagier le mien au texte près, et assurez-vous qu'il soit pertinent; je serai sévère si je constate de la négligence
  • Les paires .test,.res retenues seront ensuite appliquées, mécaniquement, au code source de toutes les équipes, et je produirai une note d'exécution sur la base des résultats
    • J'ajouterai mes propres tests au lot

Pour le groupe 1 : remettez-moi le tout au plus tard le vendredi 7 mai 2021 en pièce jointe d'un message Colnet

Pour les groupes 2 et 3 : remettez-moi le tout au plus tard le vendredi 21 mai 2021 en pièce jointe d'un message Colnet

Petits coups de pouces

Vous trouverez ici quelques documents, la plupart petits, qui peuvent vous donner un petit coup de pouce occasionnel.

Vous trouverez aussi des exemples de code C# dans la section Divers – C# du site, mais notez que je n'ai pas nécessairement harmonisé ces exemples (écrits pour des cours plus avancés, sous forme de survols) aux standards de programmation appliqués dans le présent cours. À lire avec prudence et discrimination, donc.

Solutionnaires et exemples

Quelques solutionnaires suivent. En espérant que ça vous aide à organiser vos idées!

ExempleSéance

À venir

 

À venir

 


Valid XHTML 1.0 Transitional

CSS Valide !