Quelques raccourcis :

420-SF1-RE – Introduction à la programmation

Ceci est un petit site de support pour le cours 420-SF1-RE – Introduction à la programmation.

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/. Portez une attention particulière à ../../../Sujets/Divers--cdiese/index.html.

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.

Cliquez sur cette cible pour les normes appliquées dans ce cours, en ce qui a trait au pseudocode

Détail des séances en classe

Note sur l'organisation des séances :

Date Séance Détails

22 août

S00

Au menu :

  • Présentation du cours et du plan de cours
  • Premiers pas avec les séquences et le pseudocode (et même une touche de code C#, pour le plaisir)
  • Présentation du laboratoire 00 : remettre un document

À faire au plus tôt :

  • Laboratoire 00 : remettre un document

25 août

S01

Au menu :

  • Structures de contrôle (première partie) : la séquence
  • Suites de nos premiers contacts avec le pseudocode
  • Introduction plus formelle du type float, pour représenter des nombres à virgule flottante
  • Première mention formelle du type int, pour représenter des nombres entiers
  • Retour sur les règles de nomenclature applicables dans le cours :
    • comment exprimer un nom de variable
    • comment exprimer un nom de constante
    • pourquoi limiter les noms en majuscules aux constantes
    • comment séparer des mots dans un nom de variable?
    • comment séparer des mots dans un nom de constante?
  • Quelques éléments de vocabulaire :
    • Mention de noms et de préfixes utilisés pour nommer des quantités, particulièrement en informatique : bit, byte, octet, de même que les préfixes kilo (considéré par certains comme valant 1000, et par la plupart des informaticien(ne)s comme valant 1024), méga, giga et téra
  • Introduction à la conception logicielle (module 01 des notes de cours)
  • Quelques éléments de culture, incluant :
    • Une très brève mention d'Alan Turing, un personnage important pour nous, et diverses considérations historiques
    • J'ai glissé un mot sur Kurt Gödel et sur David Hilbert, entre autres
  • Quelques exercices
  • Présentation du laboratoire 01 : conversion de volumes

À faire pour S02 :

  • Se familiariser avec l'introduction à la conception logicielle (module 01 des notes de cours)
  • Pour vous aider, commencer à lire le module 02 des notes de cours
  • Laboratoire 01 : conversion de volumes (analyse, pseudocode, jeux d'essai)

29 août

S02

Au menu :

  • Détail technique : le mot-clé using de C# (avec exemples dans Visual Studio et dans dotnetfiddle pour illustrer une subtilité)
  • Retour sur le laboratoire 00
  • Algorithmes et codification (module 02 des notes de cours)
  • Toute petite introduction au débogueur
    • Pas à pas détaillé
    • Points d'arrêt
    • Examen du changement d'état de certaines variables

Exercices en classe :

À remettre :

  • Laboratoire 01 : conversion de volumes (analyse, pseudocode, jeux d'essai)

Nous avons fait un petit exemple d'utilisation du type string et d'affichage, avec formatage « de base », avec formatage positionnel comme avec formatage par interpolation. Les trois sont des manières distinctes d'avoir le même effet.

Pour l'affichage « de base », le code suit :

string nom;
int âge;
Console.Write("Nom? ");
nom = Console.ReadLine();
Console.Write("Âge? ");
âge = int.Parse(Console.ReadLine());
Console.Write("Bonjour, ");
Console.Write(nom);
Console.Write(" qui a ");
Console.Write(âge);
Console.WriteLine(" ans");

Pour l'affichage avec formatage positionnel, le code suit :

string nom;
int âge;
Console.Write("Nom? ");
nom = Console.ReadLine();
Console.Write("Âge? ");
âge = int.Parse(Console.ReadLine());
Console.WriteLine("Bonjour, {0} qui a {1} ans", nom, âge);

Pour l'affichage avec formatage par interpolation, le code suit :

string nom;
int âge;
Console.Write("Nom? ");
nom = Console.ReadLine();
Console.Write("Âge? ");
âge = int.Parse(Console.ReadLine());
Console.WriteLine($"Bonjour, {nom} qui a {âge} ans");

1 sept.

S03

Au menu :

  • Discussions sur le laboratoire 01
  • Préciser ce qui constitue ou non un intrant (ou : que signifie la primitive Lire du pseudocode?)
  • Retour sur les règles de nomenclature applicables dans le cours :
    • comment exprimer un nom de variable
    • comment exprimer un nom de constante
    • pourquoi limiter les noms en majuscules aux constantes
    • comment séparer des mots dans un nom de variable?
    • comment séparer des mots dans un nom de constante?
  • Retour sur le fait que deux noms différents dénotent deux objets distincts
  • Nombres à virgule flottante : utiliser le '.' ou la ','?
  • Types string, int, float et double
  • Suites de la section Algorithmes et codification (module 02 des notes de cours)
  • Sondage SPEC
  • Présentation du laboratoire 02 : pizza! (analyse, pseudocode, code C#, jeux d'essai)

À faire pour S04 :

  • Laboratoire 02 : pizza! (analyse, pseudocode, code C#, jeux d'essai)

5 sept.

S04

Au menu :

  • Bref regard sur le transtypage, ou comment forcer le compilateur transformer une valeur d'un type vers un autre type – nous n'avons pas exploré formellement la chose, cela dit; nous l'avons mentionné et utilisé, sans plus, mais nous y reviendrons
  • Expressions arithmétiques, séquences et fonctions (module 03 des notes de cours)
  • Survol des fonctions mathématiques de C#
    • aujourd'hui, nous limiterons notre démarche à l'utilisation de fonctions; évidemment, dans quelques séances, nous rédigerons nos propres fonctions
  • Services des types de C#
    • méthode Parse
    • méthode ToString
    • certaines constantes telles que MinValue, MaxValue et (pour les nombres à virgule flottante) Epsilon
  • Survol de la structure interne des nombres entiers
  • Exercices

8 sept.

S05

Au menu :

  • Quelle police choisir pour le code et pour le pseudocode?
  • Que faire quand les lignes sont trop longues?
  • Une manière plus simple d'écrire quelque chose comme "------------------------------"
  • Débordements et leur effet (en utilisant un bloc checked... ne faites pas ça à la maison!)

Brève introduction aux fonctions, en pseudocode et en C#...

Pour la partie pseudocode, nous avions :

Lire fahr
cels ← ConvertirFahrÀCels(fahr)
Écrire cels

... pour le programme principal (le code appelant), et :

ConvertirFahrÀCels(degFahr)
   SEUIL_GEL_EAU ← 32
   degCels ← (degFahr - SEUIL_GEL_EAU) * 5 / 9
   Retourner degCels

... pour la fonction appelée.

Pour la partie C# :

  • Nous avons ajouté un fichier (clic droit sur le projet → Ajouter → Classe ou encore menu Projet → Ajouter une classe) au projet
  • Nous avons nommé ce fichier Sf1 (Sf1.cs)
  • Initialement, ce fichier contenait :
// quelques using (omis par souci d'économie)
namespace VOTRE_NAMESPACE
{
   internal class Sf1
   {
   }
}
  • Nous avons remplacé le mot internal par le mot static :
// quelques using (omis par souci d'économie)
namespace VOTRE_NAMESPACE
{
   static class Sf1
   {
   }
}
  • Nous y avons ajouté deux fonctions, soit une qui permettait de convertir une valeur exprimée en degrés Fahrenheit en son équivalent exprimé en degrés Celsius et une autre qui permettait de calculer la somme de deux entiers (notez les mots public et static pour chaque fonction) :
// quelques using (omis par souci d'économie)
namespace VOTRE_NAMESPACE
{
   static class Sf1
   {
      public static float ConvertirFahrÀCels(float degFahr)
      {
         const int SEUIL_GEL_EAU = 32;
         float degCels;
         degCels = (degFahr - SEUIL_GEL_EAU) * 5 / 9;
         return degCels;
      }

      public static int CalculerSomme(int nb0, int nb1)
      {
         int somme;
         somme = nb0 + nb1;
         return somme;
      }
   }
}
  • Enfin, nous avons écrit un programme principal utilisant ces fonctions. Notez la ligne using static VOTRE_NAMESPACE.Sf1; au tout début, qui rend implicitement accessibles les fonctions que nous venons d'écrire :
using static VOTRE_NAMESPACE.Sf1;

Console.WriteLine($"La somme de 2 et 3 est... {CalculerSomme(2,3)}");

float fahr,
      cels;
Console.Write("Température en degrés Fahrenheit? ");
fahr = float.Parse(Console.ReadLine());
cels = ConvertirFahrÀCels(fahr);
Console.WriteLine($"Équivalent en degrés Celsius : {cels}");
Console.WriteLine("En passant, 32 fahr vaut... ");
cels = ConvertirFahrÀCels(32);
Console.WriteLine($"{cels} cels");

Ce n'était qu'une petite introduction; nous y reviendrons plus en détail sous peu.

  • Présentation du laboratoire 03 : APOO volet plongeon (analyse, pseudocode, code C#, jeux d'essai)

À remettre :

  • Laboratoire 02 : pizza! (analyse, pseudocode, code C#, jeux d'essai)

À faire :

  • Travail sur le laboratoire 03 : APOO volet plongeon (analyse, pseudocode, code C#, jeux d'essai)

12 sept.

S06

Au menu :

  • Retour sur le laboratoire 02
    • positionnement des déclarations de variables en C# et prudence en pseudocode
    • afficher une ligne vide?
    • rappel sur la lisibilité
  • Introduction à l'approche que l'on nomme le développement graduel (approche Top-Down), module 04 des notes de cours
  • Fonctions en pseudocode
    • paramètres passés par valeur
    • variables locales
    • retour
  • Fonctions en C#
    • paramètres passés par valeur
    • variables locales
    • retour
  • Diagramme hiérarchique

À faire :

  • Travail sur le laboratoire 03 : APOO volet plongeon (analyse, pseudocode, code C#, jeux d'essai)

15 sept.

S07

Au menu :

  • Premier contact sommaire avec les alternatives, chapitre 05 des notes de cours
  • Structures alternatives (bases)
  • Présentation du laboratoire 04 : introduction aux fonctions
  • Nous allons piger un peu dans la matière de la prochaine séance pour prendre un peu d'avance, mais cette matière ne sera pas applicable au laboratoire 04

À remettre :

  • Laboratoire 03 : APOO volet plongeon (analyse, pseudocode, code C#, jeux d'essai)

À faire :

  • Laboratoire 04 : introduction aux fonctions

19 sept.

S08

Au menu :

  • Premier contact avec les alternatives complexes, chapitre 06 des notes de cours
  • Structures alternatives plus complexes :

À faire :

  • Laboratoire 04 : introduction aux fonctions

22 sept.

S09

Au menu :

  • Fonctions prédicats
  • Exercices
  • Présentation du laboratoire 05 : APOO volet cartésien

À remettre :

  • Remettre la partie imprimée du laboratoire 04 : fonctions assorties (analyse, pseudocode, code C#)

À faire :

  • Travail sur le laboratoire 05 : APOO volet cartésien (code C#)

26 sept.

S10

Au menu :

  • Quelques messages d'erreurs typiques de programmes qui se compliquent, et comment les déchiffrer
    • « Tous les chemins ne retournent pas une valeur »
    • « Utilisation d'une variable non-assignée »
  • Introduction à la logique et aux répétitives, modules 06 et 07 des notes de cours
  • Petits bonbons syntaxiques :
    • autoincrémentation (++cpt et cpt++) et autodécrémentation (--cpt et cpt--)
    • variantes modifiantes de certains opérateurs (p. ex. : x += y; au lieu de x = x + y;)

À faire :

  • Travail sur le laboratoire 05 : APOO volet cartésien (code C#)

29 sept.

S11

Grève étudiante (levée des cours)

3 oct.

S12

Je serai absent cette semaine car je donne des conférences à CppCon. Vous pourrez suivre mes aventures sur : ../../../Sujets/Orthogonal/cppcon2023.html

6 oct.

S13

Je serai absent cette semaine car je donne des conférences à CppCon. Vous pourrez suivre mes aventures sur : ../../../Sujets/Orthogonal/cppcon2023.html

Cependant, aujourd'hui, il y aura cours selon l'horaire normal avec mon collègue et ami Pierre Prud'homme.

10 oct.

s/o

Pas de cours avec moi aujourd'hui (horaire du lundi)

13 oct.

S14

Au menu :

  • Chic examen intra plein d'amour!

17 oct.

S15

Au menu :

  • Retour sur l'intra
  • Fonctions void
  • Variantes de la répétitive classique
    • Boucle for
    • Boucle do ... while
  • Petits bonbons syntaxiques :
    • autoincrémentation (++cpt et cpt++) et autodécrémentation (--cpt et cpt--)
    • variantes modifiantes de certains opérateurs (p. ex. : x += y; au lieu de x = x + y;)
  • Présentation du laboratoire 06 : introduction aux répétitives

À faire :

  • Travail sur le laboratoire 06 : introduction aux répétitives (pseudocode, code C#)

20 oct.

S16

Au menu :

  • Qu'advient-il avec les variables déclarées dans une boucle for?
  • Introduction à la modularisation, chapitre 08 des notes de cours :
    • des rectangles?
    • un sapin!
  • Attention : le cours se corsera à la prochaine séance...

À faire :

  • Travail sur le laboratoire 06 : introduction aux répétitives (pseudocode, code C#)

24 oct.

S17

Au menu :

  • Présentation du laboratoire 07 : roche, papier, ciseaux (code C#)
    • Exceptionnellement, le laboratoire 07 ne sera remis qu'en version électronique et se limitera au code C# puisque la remise tombe pendant une journée pédagogique. Pas de remise imprimée,
  • Travail sur le laboratoire 07 : roche, papier, ciseaux (code C#)

Notez que cette séance sera essentiellement pratique, avec intention de faire du renforcement quant aux fonctions et aux répétitives. Utilisez la séance pour faire le plus possible du laboratoire 07, car il y aura de la nouvelle matière et un nouveau laboratoire dès S18. Si vous ne faites pas l'essentiel du laboratoire 07 aujourd'hui, vous aurez deux laboratoires à faire pendant la semaine de récupération!

27 oct.

S18

Au menu :

  • Introduction aux tableaux unidimensionnels :
    • création
    • distinguer position d'un élément et valeur d'un élément
    • taille
    • parcours
    • tri
    • « ajouter un élément à un tableau »
    • exercices formatifs
  • Travail sur le laboratoire 07 : roche, papier, ciseaux (code C#)
  • Présentation du laboratoire 08 : répétitives et tableaux (code C#, pseudocode de LireValeur)

Pour vous éviter d'avoir à le recopier manuellement, le code de démarrage du programme principal imposé pour le laboratoire 08 est :

#nullable disable
int valeurA = LireValeur("Donnez la première valeur : ");
int valeurB = LireValeur("Donnez la deuxième valeur : ");
AfficherLigneTirets();

int[] diviseursA = TrouverDiviseurs(valeurA);
int[] diviseursB = TrouverDiviseurs(valeurB);
int[] communs = TrouverDiviseursCommuns(diviseursA, diviseursB);

Afficher($"Diviseurs de {valeurA}", diviseursA);
AfficherLigneTirets();

Afficher($"Diviseurs de {valeurB}", diviseursB);
AfficherLigneTirets();

Afficher($"Diviseurs communs de {valeurA} et {valeurB}", communs);
AfficherLigneTirets();

31 oct.

s/o

Journée pédagogique (cours suspendus)

À remettre :

  • Laboratoire 07 (version électronique seulement, code C#)

3 nov.

s/o

Journée de mise à niveau (cours suspendus)

7 nov.

S19

Au menu :

  • Retour sur le laboratoire 06
  • Introduction aux tableaux unidimensionnels (suite)
    • comparer deux tableaux
  • Fonctions, intrants et extrants ()
    • paramètres ref
    • paramètres out
  • Représentation des objets en mémoire (aperçu)
  • Bonbon : quelle est la différence entre ++i et i++?

Cours bouleversé (surtout pour le groupe 02) par une panne de courant importante qui a mené à une levée de cours au Collège. On ajustera à S20.

À remettre :

  • Laboratoire 08 : répétitives et tableaux (code C#, pseudocode de LireValeur)

10 nov.

S20

Au menu :

  • On récupère du bouleversement de S19
  • Présentation du laboratoire 09 

À faire :

  • Travail sur le laboratoire 09

Pendant que vous travaillerez sur le laboratoire 09, je ferai la correction « live » avec chacune et chacun d'entre vous de votre laboratoire 07.

14 nov.

S21

Au menu :

  • Introduction à Console.ReadKey
  • Introduction aux sélectives (switch)
  • Introduction aux tableaux 2D :
    • Équivalent 1D
    • Déclaration
    • Dimensions
    • Affichage à la console
    • Accès à une case par ses indices
  • Où en sommes-nous? On s'amuse...!

À faire :

  • Travail sur le laboratoire 09

J'ai fait avec vous un petit exemple amusant avec un héros et un monstre sur une surface rectangulaire. Le code de 2022 allait comme suit (note : c'est la version d'un des deux groupes, mais les deux sont semblables) :

using System;

const char HÉROS = 'H';
const char GAZON = 'g';
const char MONSTRE = 'M';
const int HAUTEUR = 20,
          LARGEUR = 60;

// créer une carte de HAUTEUR x LARGEUR
// la remplir de GAZON
char [,] carte = CréerCarte(HAUTEUR, LARGEUR, GAZON);
// placer le HÉROS quelque part (mettons, coin haut + gauche)
int hérosX = 0,
    hérosY = 0;
carte[hérosY, hérosX] = HÉROS;
// placer le MONSTRE quelque part (mettons, 10,15)
carte[10, 15] = MONSTRE;
Afficher(carte);

bool poursuivre = true;
while(poursuivre)
{
   ConsoleKeyInfo clé = Console.ReadKey(true);
   int nouvX,
       nouvY;
   switch(clé.Key)
   {
      case ConsoleKey.RightArrow:
      case ConsoleKey.UpArrow:
      case ConsoleKey.LeftArrow:
      case ConsoleKey.DownArrow:
         CalculerDéplacement(hérosX, hérosY, out nouvX, out nouvY, clé.Key);
         if(EstPositionValide(nouvX, nouvY, carte))
         {
            Permuter(ref carte[hérosY, hérosX],
                     ref carte[nouvY, nouvX]);
            hérosX = nouvX;
            hérosY = nouvY;
         }
         break;
      case ConsoleKey.Escape:
         poursuivre = false;
         break;
      default:
         Console.Beep();
         break;
   }
   Afficher(carte);
}

static void Afficher(char [,] carte)
{
   Console.Clear();
   for(int ligne = 0; ligne !=carte.GetLength(0); ++ligne)
   {
      for(int colonne = 0; colonne != carte.GetLength(1); ++colonne)
      {
         AfficherSymbole(carte[ligne, colonne]);
      }
      Console.WriteLine();
   }
}

static void AfficherSymbole(char c)
{
   const ConsoleColor SYMBOLE_GAZON = ConsoleColor.Green;
   const ConsoleColor SYMBOLE_HÉROS = ConsoleColor.Blue;
   const ConsoleColor SYMBOLE_MONSTRE = ConsoleColor.Red;
   ConsoleColor avant = Console.ForegroundColor;
   switch(c)
   {
      case GAZON:
         Console.ForegroundColor = SYMBOLE_GAZON;
         break;
      case HÉROS:
         Console.ForegroundColor = SYMBOLE_HÉROS;
         break;
      case MONSTRE:
         Console.ForegroundColor = SYMBOLE_MONSTRE;
         break;
      default:
         Console.ForegroundColor = ConsoleColor.White;
         break;
   }
   Console.Write(c);
   Console.ForegroundColor = avant;
}

static char[,] CréerCarte(int hauteur, int largeur,
                          char symboleRempl)
{
   char[,] carte = new char[hauteur, largeur];
   for(int ligne = 0; ligne != carte.GetLength(0); ++ligne)
   {
      for(int colonne = 0; colonne != carte.GetLength(1); ++colonne)
      {
         carte[ligne, colonne] = symboleRempl;
      }
   }
   return carte;
}

static void Permuter(ref char a, ref char b)
{
   char temp = a;
   a = b;
   b = temp;
}

static void CalculerDéplacement(int x, int y, out int nouvX, out int nouvY, ConsoleKey touche)
{
   nouvX = x;
   nouvY = y;
   switch(touche)
   {
      case ConsoleKey.RightArrow:
         ++nouvX;
         break;
      case ConsoleKey.UpArrow:
         --nouvY;
         break;
      case ConsoleKey.LeftArrow:
         --nouvX;
         break;
      case ConsoleKey.DownArrow:
         ++nouvY;
         break;
   }
}

static bool EstPositionValide(int x, int y, char [,] carte)
{
   return 0 <= x && 0 <= y &&
          x < carte.GetLength(1) && y < carte.GetLength(0);
}

Le code de 2023, quant à lui, était, pour le groupe:

const int HAUTEUR = 20,
          LARGEUR = 75;
const char HÉROS = 'H',
           MONSTRE = 'X',
           GAZON = ',';

const int CHOIX_DROITE = 0,
          CHOIX_HAUT = 1,
          CHOIX_GAUCHE = 2,
          CHOIX_BAS = 3,
          CHOIX_QUITTER = 4;

char[,] grille = CréerGrille(HAUTEUR, LARGEUR, GAZON);
Afficher(grille);
Console.ReadLine();
// positionner les protagonistes
Random dé = new();
int ligneHéros,
    colHéros;
PositionnerÉlément(grille, HÉROS, dé, out ligneHéros, out colHéros);
Afficher(grille);
Console.ReadLine();
int ligneMonstre,
    colMonstre;
PositionnerÉlément(grille, MONSTRE, dé, out ligneMonstre, out colMonstre);
Afficher(grille);

bool fini = Déplacer(grille, ref ligneHéros, ref colHéros);
Afficher(grille);
while (!fini)
{
   fini = Déplacer(grille, ref ligneHéros, ref colHéros);
   Afficher(grille);
}

//////////////////////

static char[,] CréerGrille(int hauteur, int largeur, char valInit)
{
   char[,] tab = new char[hauteur, largeur];
   for (int ligne = 0; ligne != tab.GetLength(0); ++ligne)
   {
      for(int col = 0; col != tab.GetLength(1); ++col)
      {
         tab[ligne, col] = valInit;
      }
   }
   return tab;
}

static ConsoleColor ChoisirCouleur(char symbole)
{
   ConsoleColor c;
   switch(symbole)
   {
      case HÉROS:
         c = ConsoleColor.Red;
         break;
      case MONSTRE:
         c = ConsoleColor.Magenta;
         break;
      case GAZON:
         c = ConsoleColor.Green;
         break;
      default:
         c = ConsoleColor.White;
         break;
   }
   return c;
}
static void AfficherSymbole(char symbole)
{
   ConsoleColor avant = Console.ForegroundColor;
   ConsoleColor après = ChoisirCouleur(symbole);
   Console.ForegroundColor = après;
   Console.Write(symbole);
   Console.ForegroundColor = avant;
}

static void Afficher(char[,] grille)
{
   Console.Clear();
   for (int ligne = 0; ligne != grille.GetLength(0); ++ligne)
   {
      for (int col = 0; col != grille.GetLength(1); ++col)
      {
         AfficherSymbole(grille[ligne, col]);
      }
      Console.WriteLine();
   }
}

static void PositionnerÉlément(
   char[,] grille, char symbole, Random gen,
   out int ligne, out int col
)
{
   ligne = gen.Next(0, grille.GetLength(0));
   col = gen.Next(0, grille.GetLength(1));
   grille[ligne, col] = symbole;
}

static bool EstToucheValide(char c)
{
   return c == 'W' || c == 'A' || c == 'S' || c == 'D' || c == 'Q';
}

// c est présumé valide à ce point
static int DéterminerChoix(char c)
{
   int choix = CHOIX_QUITTER; // par défaut
   switch (c)
   {
      case 'W':
         choix = CHOIX_HAUT;
         break;
      case 'A':
         choix = CHOIX_GAUCHE;
         break;
      case 'S':
         choix = CHOIX_BAS;
         break;
      case 'D':
         choix = CHOIX_DROITE;
         break;
   }
   return choix;
}

static char LireTouche()
{
   char c = char.ToUpper(Console.ReadKey(true).KeyChar);
   while(!EstToucheValide(c))
   {
      c = char.ToUpper(Console.ReadKey(true).KeyChar);
   }
   return c;
}

static bool EstDansGrille(char[,] grille, int ligne, int col)
{
   return 0 <= ligne && ligne < grille.GetLength(0) &&
          0 <= col && col < grille.GetLength(1);
}

static void Permuter(ref char a, ref char b)
{
   char temp = a;
   a = b;
   b = temp;
}

static bool Déplacer(char[,] grille, ref int ligne, ref int col)
{
   bool fini = false;
   char touche = LireTouche();
   int choix = DéterminerChoix(touche);
   int ligneAprès = ligne;
   int colAprès = col;
   switch(choix)
   {
      case CHOIX_DROITE:
         ++colAprès; // valider...
         break;
      case CHOIX_HAUT:
         --ligneAprès;
         break;
      case CHOIX_GAUCHE:
         --colAprès;
         break;
      case CHOIX_BAS:
         ++ligneAprès;
         break;
      case CHOIX_QUITTER:
         fini = true;
         break;
   }
   if (EstDansGrille(grille, ligneAprès, colAprès))
   {
      Permuter(ref grille[ligne, col], ref grille[ligneAprès, colAprès]);
      ligne = ligneAprès;
      col = colAprès;
   }
   else
   {
      Console.Beep();
   }
   return fini;
}

... et toujours en 2023, le code était, pour le groupe:

const int HAUTEUR = 20,
          LARGEUR = 70;

const char HÉROS = 'H',
           MONSTRE = 'M',
           GAZON = ',';

const int CHOIX_DROITE = 0,
          CHOIX_HAUT = 1,
          CHOIX_GAUCHE = 2,
          CHOIX_BAS = 3,
          CHOIX_QUITTER = 4;


char[,] grille = CréerGrille(HAUTEUR, LARGEUR, GAZON);
Afficher(grille);
Console.ReadLine();
Random dé = new();
int ligneHéros,
    colHéros;
Positionner(grille, HÉROS, dé, out ligneHéros, out colHéros);
Afficher(grille);
Console.ReadLine();
int ligneMonstre,
    colMonstre;
Positionner(grille, MONSTRE, dé, out ligneMonstre, out colMonstre);
Afficher(grille);

bool fini = Déplacer(grille, ref ligneHéros, ref colHéros);
Afficher(grille);
while (!fini)
{
   fini = Déplacer(grille, ref ligneHéros, ref colHéros);
   Afficher(grille);
}


/////////////////////////////

static bool EstToucheValide(ConsoleKey c)
{
   return c == ConsoleKey.W ||
          c == ConsoleKey.A ||
          c == ConsoleKey.S ||
          c == ConsoleKey.D ||
          c == ConsoleKey.Escape;
}
static ConsoleKey LireTouche()
{
   ConsoleKey c = Console.ReadKey(true).Key;
   while(!EstToucheValide(c))
   {
      c = Console.ReadKey(true).Key;
   }
   return c;
}

static int DéterminerChoix(ConsoleKey c)
{
   int choix = CHOIX_QUITTER;
   switch(c)
   {
      case ConsoleKey.W:
         choix = CHOIX_HAUT;
         break;
      case ConsoleKey.A:
         choix = CHOIX_GAUCHE;
         break;
      case ConsoleKey.S:
         choix = CHOIX_BAS;
         break;
      case ConsoleKey.D:
         choix = CHOIX_DROITE;
         break;
   }
   return choix;
}

static void Permuter(ref char a, ref char b)
{
   char temp = a;
   a = b;
   b = temp;
}

static bool EstPositionValide(char[,] tab, int ligne, int col)
{
   return 0 <= ligne && ligne < tab.GetLength(0) &&
          0 <= col && col < tab.GetLength(1);
}
static bool Déplacer(char [,] grille, ref int ligne, ref int col)
{
   bool fini = false;
   ConsoleKey touche = LireTouche(); // subtilité ici...
   int choix = DéterminerChoix(touche);
   int ligneAprès = ligne;
   int colAprès = col;
   switch(choix)
   {
      case CHOIX_DROITE:
         ++colAprès;
         break;
      case CHOIX_HAUT:
         --ligneAprès;
         break;
      case CHOIX_GAUCHE:
         --colAprès;
         break;
      case CHOIX_BAS:
         ++ligneAprès;
         break;
      case CHOIX_QUITTER:
         fini = true;
         break;
   }
   if(EstPositionValide(grille, ligneAprès, colAprès))
   {
      Permuter(ref grille[ligne, col], ref grille[ligneAprès, colAprès]);
      ligne = ligneAprès;
      col = colAprès;
   }
   else
   {
      Console.Beep();
   }
   return fini;
}

static void Positionner(
   char[,] tab, char symbole, Random r,
   out int ligne, out int col
   )
{
   ligne = r.Next(0, tab.GetLength(0));
   col = r.Next(0, tab.GetLength(1));
   tab[ligne, col] = symbole;
}

static char[,] CréerGrille(int hauteur, int largeur, char valInit)
{
   char[,] tab = new char[hauteur, largeur];
   for(int ligne = 0; ligne != hauteur; ++ligne)
   {
      for(int col = 0; col != largeur; ++col)
      {
         tab[ligne, col] = valInit;
      }
   }
   return tab;
}

static ConsoleColor DéterminerCouleur(char symbole)
{
   ConsoleColor c;
   switch(symbole)
   {
      case HÉROS:
         c = ConsoleColor.Red;
         break;
      case MONSTRE:
         c = ConsoleColor.Magenta;
         break;
      case GAZON:
         c = ConsoleColor.Green;
         break;
      default:
         c = ConsoleColor.White;
         break;
   }
   return c;
}

static void AfficherSymbole(char symbole)
{
   ConsoleColor avant = Console.ForegroundColor;
   ConsoleColor après = DéterminerCouleur(symbole);
   Console.ForegroundColor = après;
   Console.Write(symbole);
   Console.ForegroundColor = avant;
}

static void Afficher(char[,] tab)
{
   Console.Clear();
   for (int ligne = 0; ligne != tab.GetLength(0); ++ligne)
   {
      for (int col = 0; col != tab.GetLength(1); ++col)
      {
         AfficherSymbole(tab[ligne, col]);
      }
      Console.WriteLine();
   }
}

17 nov.

S22

Au menu :

  • Présentation du labo 10
  • Travail sur le labo 10

21 nov.

S23

Au menu : grève du front commun. Votre chic prof est devant le Collège et chante des chansons, pancartes à la main.

On m'a demandé ceci, la veille du démarrage de la grève (je me suis permis de corriger les fautes) :

« Salut monsieur [...] face a la grève cest possible que nous ne nous voyons pas pendant plusieurs jours. Alors [...] je ne veux pas passer trop de dans sans programmer. Si possible, pourriez-vous m'envoyer les consignes de l'ancienne PFI? Le projet avait l'air très intéressant.

Merci et bonne soirée »

Rassurez-vous : la grève du Front commun cette semaine ne dure que trois jours (21, 22 et 23  novembre) alors nous nous reverrons à la séance S24. Cela dit, si vous cherchez du divertissement, les consignes de la PFI de A2022 (qui n'est pas du tout la même que celle de A2023) sont disponibles sur PFI-420201(A2022).pdf alors que le projet de démarrage (qui ne compile pas) est Paysagiste.zip

Pour un exécutable de démonstration de la PFI, allez chercher Paysagiste-Solution.zip puis dézippez le tout dans un dossier avant d'exécuter le .exe qui s'y trouve. C'est ce à quoi on souhaite que vous arriviez à la fin.

24 nov.

S24

Au menu :

  • Présentation succincte des énumérations
  • Présentation des bases (très naïves) de la POO
  • Exercices formatifs sur les bases (très naïves) de la POO
  • Remise du laboratoire 10 : les pyramides (code C#)

28 nov.

S25

Au menu :

  • Présentation de la PFI
  • Travail sur la PFI

1 déc.

S26

Au menu :

  • Travail sur la PFI

5 déc.

S27

Au menu :

  • Travail sur la PFI

8 déc.

S28

Au menu :

  • Travail sur la PFI

12 déc.

S29

Au menu :

  • Chic examen final

À remettre :

  • La PFI de la session A2023

Petits coups de pouces

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

Comment accéder à du code .NET à partir d'un client C++ natif.

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

Quelques solutionnaires suivent. Référez-vous aux règles programmatiques pour plus de détails sur les normes de programmation appliquées dans ce cours.

Travail

À venir

À venir

À venir

Conversion °F à °C

Énoncé : écrivez le pseudocode de l'algorithme qui lit une valeur en degrés Fahrenheit, calcule la valeur équivalente exprimée en degrés Celsius, puis affiche cette dernière.

Intrant(s) :

Extrant(s) :

tempCelsius (température exprimée en °C)

Autres informations pertinentes :

Pseudocode :

SEUIL_GEL_EAU ← 32
Lire tempFahrenheit
tempCelsius ← (tempFahrenheit - SEUIL_GEL_EAU) * 5 / 9
Écrire tempCelsius

Code C# :

using System;

const int SEUIL_GEL_EAU = 32;
float tempFahrenheit,
      tempCelsius;
tempFahrenheit = float.Parse(Console.ReadLine());
tempCelsius = (tempFahrenheit - SEUIL_GEL_EAU) * 5 / 9;
Console.WriteLine(tempCelsius);

Jeu d'essai :

tempFahrenheit

tempCelsius

32

0

41

5

23

-5

-40

-40

Permutation de deux valeurs

Énoncé : écrivez le pseudocode de l'algorithme qui lit deux entiers nb0 et nb1, permute leurs valeurs, puis affiche les valeurs permutées

Pseudocode (une variable temporaire) :

Lire nb0
Lire nb1
temp ← nb0
nb0 ← nb1
nb1 ← temp
Écrire nb0
Écrire nb1

Pseudocode (sans variable temporaire; attention, solution limitée aux variables numériques) :

Lire nb0
Lire nb1
nb0 ← nb0 + nb1
nb1 ← nb0 - nb1
nb0 ← nb0 - nb1
Écrire nb0
Écrire nb1

Calculer la distance entre deux points

Énoncé : écrire une fonction prenant en paramètre les coordonnées de deux points et sur le plan cartésien, et retournant la distance entre ces deux points, de même qu'un petit programme testant cette fonction .

Code C# :

using System;

Console.WriteLine("distance entre (0,0) et (0,1) : {0}",
                  CalculerDistance(0, 0, 0, 1)); // 1
Console.WriteLine("distance entre (1,0) et (3,0) : {0}",
                  CalculerDistance(1, 0, 3, 0)); // 2
Console.WriteLine("distance entre (0,0) et (1,1) : {0}",
                  CalculerDistance(0,0,1,1)); // 1,41...

static double CalculerDistance(float x0, float y0, float x1, float y1)
{
   double distance;
   distance = Math.Sqrt(Math.Pow(x0 - x1, 2) +
                        Math.Pow(y0 - y1, 2));
   return distance;
}

Calculer la pente d'une courbe non-verticale

Énoncé : écrire une fonction calculant la pente d'une droite non-verticale étant donné l'ordonnée à l'origine et un point par lequel passe cette droite, de même qu'un petit programme testant cette fonction.

Code C# :

using System;

Console.WriteLine(CalculerPente(2, 2, 0)); // -1

static double CalculerPente(float b, float x, float y)
{
   double pente;
   pente = (y - b) / x;
   return pente;
}

Convertir un poids de Kg en Lbs

Énoncé : écrire une fonction prenant en paramètre un poids exprimé en kilogrammes et retournant la valeur équivalente, mais exprimée en livres, de même qu'un petit programme testant cette fonction.

Code C# :

using System;

float poidsKg;
Console.Write("Votre poids en Kg? ");
poidsKg = float.Parse(Console.ReadLine());
Console.WriteLine($"Cela équivaut à {ConvertirKgLbs(poidsKg)} lbs");

static float ConvertirKgLbs(float poidsKg)
{
   const float FACTEUR_CONVERSION = 2.2f;
   float poidsLbs;
   poidsLbs = poidsKg * FACTEUR_CONVERSION;
   return poidsLbs;
}

Valid XHTML 1.0 Transitional

CSS Valide !