Semaine 1: Introduction + Variables

Introduction

Notion de base

  • Environnement physique (statique ou organique) vs Environnement dynamique (virtuel)
  • Ordinateur: Outil donnant accès à un environnement dynamique
  • Un programme décrit un chemin ou une séquence d'instructions à effectuer (exécuter) visant une tâche spécifique.
  • Un programme est décrit à l'aide d'un langage de programmation. Un langage offre une abstraction facilitant la manipulation de l'ordinateur.
  • Un langage de programmation est défini par sa syntaxe (représentation) et sa sémantique (sens, interprétation)
  • Paradigme de programmation: Approche et style utilisé pour concevoir et formuler un programme (Ex: impératif, procédural, orienté-objet, déclaratif, fonctionnel )
  • Exécution du code: Compilateur (2 phases: Traduction → Exécution) vs Interpréteur (1 phase: Exécution)

Concevoir un programme

Un problème bien posé est à moitié résolu.
Avant de se lancer dans un quelconque chemin de résolution (coder), il faut prendre soin de bien cerner les caractéristiques du problème et établir un plan de résolution clair (indépendant du langage de programmation).
Pour cela nous définissons: l'objectif du programme, les entités à manipuler dans le programme et les prérequis du programme.

  1. Objectif: Définir la tache principale à accomplir, sans s'intéresser au comment
  2. Entités cibles: Identifier avec précision les entités ou structures à manipuler
  3. Prérequis: Déterminer ce qui est minimalement nécessaire pour la manipulation

Variables

  • Variable: Emplacement mémoire où une valeur est stockée
  • Nom de variable: Un bon identificateur clarifie ce à quoi il réfère (évite les ambiguïtés)

Type de données

Décide de l'espace réservé pour préserver la valeur. Definit la quantité de mémoire que prend une variable

Général Python Java Javascript
Nombre int, float, complex byte, short, int, long, float, double number, bigint
Chaine de caractères str char, String (type composé) string
Booléen bool boolean boolean
Ensemble list, tuple, range, dict, set, frozenset
Null NoneType null, undefined

Contenu

  • Ouverture du cours: Présentation, Plan de cours
  • Introduction à la programmation
  • Variables et types de données

Semaine 2: Expressions

Expressions

Une expression est une construction qui décrit comment calculer une valeur particulière. Son évaluation produit toujours une valeur.

  • Une expression est souvent composé d'opérateurs.
  • Type d'opérateur: unaire (une opérande), binaire (deux opérandes), ternaire (trois opérandes)

Opérateur de base en Python

Opérateur Opération Exemple
** Exposant 2 ** 3 = 8
% Modulo 20 % 3 =2
// Division entière (euclidienne) 15 // 2 = 7
/ Division (décimale) 15 / 2 = 7.5
* Multiplication 4 * 5 - 20
- Soustraction 12 - 4 = 8
+ Addition 2 + 2 = 4

Affectation

Une affectation consiste à attribuer une valeur à une variable. De nombreux langages offrent diverses mécanismes d'affectation pour alléger l'écriture.

  • Affection composée: Opérateurs combinant une opération et une affectation
    • +=
    • -=
    • /=
    • //=
    • <<=
    • >>=
    • &=
    • ^=
    • |=
    • %=
  • Affection parallèle: Affecter des valeurs à plusieurs variables en une seule instruction.
    • x, y, z = 10, 3, 5
    • r, g, b = 100, 203, 85
  • Affection multiple: Affecter un même valeur à plusieurs variables en une seule instruction.
    • x = y = z = 1
    • s1, s2, s3 = False

Commentaires

Les commentaires peuvent servir à expliquer une partie compliquée d'un programme ou à mettre des indications dans le code (ex: auteur, date...).

  • N'utilisez de commentaires que lorsque cela s'avère nécessaire
  • S'assurer d'avoir travaillé la clarté du code au maximum
  • Décrire le sens, pas l'instruction
  • Éviter de commenter l'évidence

Contenu

  • Expressions: Opérateurs de base, Type d'opérateurs, Opération arithmétique
  • Affectation: composé, parallèle, multiple
  • Entrée et Sortie

Semaine 3: Flux de controle

Conditions

  • Permettre au programme de choisir entre plusieurs chemins en formulant des propositions logiques (basé sur les opérations booléennes)
  • 2 types d'instruction: if et switch

Boucles

Une boucle offre un moyen d'itérer un nombre de fois sur un bloc d'instruction. La quantité d'itération dépend d'une condition émise sur la boucle.

  • Permettre au programme de choisir entre plusieurs chemins en formulant des propositions logiques (basé sur les opérations booléennes)
  • 3 types d'instruction: while (tant que), do-while (repeter...tant que) et for (pour une séquence ou intervalle)

Contenu

  • Conditions
  • Boucles

Semaine 4: Abstractions procédurales

Fonctions

L'encapsulation d'un comportement dans un programme à l'aide de fonction offre de nombreux avantages

  • Évite la répétition et promeus la réutilisabilité
  • Offre un premier niveau d'abstraction
  • Facilite la détection/correction d'erreur
  • Facilite la collaboration (travail d'équipe)

Modularité

La modularité d'un programme se mesure par deux facteurs: cohésion et couplage

  • Cohésion: Degré d'interaction au sein du module. Chaque méthode accomplie une tache reliée à une seule notion
  • Couplage: Degré d'interaction entre des modules. Chaque méthode effectue sa tache de façon indépendante du reste du programme

Paramètres

Les paramètres présentes les options de configuration d'une fonction. Ils permettent de faire varier le comportement et le résultat d'une fonction. Une fonction peut admettre 0 ou plusieurs paramètres.

  • Paramètres formels: Variables se trouvant dans la déclaration de la fonction. Utilisés pour passé des arguments à la fonction.
  • Paramètre avec valeur par défaut: Une fonction peut avoir un comportement par défaut basé sur une configuration initiale (de ses paramètres). Une fonction peut être composé uniquement de paramètres optionnels.
  • Paramètre à arguments variables: Il arrive parfois qu'on ne sache pas le nombre exact d'arguments que peut recevoir une fonction.
    • Args: Utilisé pour recevoir une liste d'arguments positionnels
    • Kwargs: Utilisé pour recevoir une liste d'arguments par mots-clés

Arguments

Les arguments sont les valeurs passés à ces paramètres lors de l'appel de la fonction. Les arguments peuvent être assignés de deux façons: positionnels ou par mots-clés.

  • Arguments positionnels: Ordre des arguments détermine les valeurs des paramètres
  • Arguments par mots-clés: Nom des paramètres est utilisé dans l'appel pour assigner les valeurs. L'ordre n'a pas d'importance.
  • Les deux types peuvent être utilisés conjointement (dans le même appel).

Contenu

  • Fonctions

Semaine 5: Encodage binaire

Encodage binaire

Opération bit-à-bit

Contenu

  • Encodage binaire
  • Opération bit-à-bit

Semaine 6: Révision

Contenu

  • Révision: Trivia, Questions-réponses

Semaine 7: Tests

Tests

Vérification & Validation

L'activité de Vérification & Validation est essentielle au développement d'applications ou programmes de qualité.
La vérification consiste à comparer la solution produite aux spécifications établies. On se demande ici si le programme a été fait correctement, indépendamment de l'usage réel qui en sera fait.
La validation consiste à évaluer la solution produite en fonction des besoins actuels des clients et utilisateurs. On se demande si le programme fait la bonne chose, pour répondre aux besoins.

Tests unitaires

Tester ne peut que montrer la présence d'erreurs, pas leur absence. Les tests (Ex: test unitaire, test d'intégration, test d'acceptation...) consistent à détecter des fautes dans le programme par assertion (comportement attendu vs comportement observé).

Les tests unitaires visent à démontrer la présence d'erreur, c.-à-d. que l'implémentation d'une unité individuelle donnée (ex: fonction) contredit sa spécification. En principe, chaque fonction définie devrait avoir ses propres tests unitaires.

Pour assurer une bonne couverture des tests, il faut une bonne variabilité dans les valeurs utilisées pour les tests.

  • Valeurs "normales": Valeurs aléatoires raisonnables couvrant l'usage habituel (attendu)
  • valeurs extrêmes: 0, très grande valeur, tableau vide, string vide
  • Valeurs inattendues: null, caractères invalides dans une chaine, index négatif
  • Différentes catégories d'entrées: Entier positif, négatif, zéro
  • Différents comportements possibles: message d’erreur, différentes valeurs de retour

TDD

Le développement dirigié par les tests (TDD) est une méthodologie de développement agile où les tests sont utilisés pour spécifier ce qui doit être programmer.

  • Production de tests automatisés pour diriger la conception et la programmation
  • Test utilisé comme spécification
  • Tests écrits avant de commencer l’implémentation
  • Processus en petites étapes (incrémentales)

Contenu

  • Vérification & Validation
  • Tests unitaires: Énoncé assert, Couverture
  • TDD: Méthodologie, Spécification

Semaine 8: Relache

Contenu

  • Relache: Révision, Travail pratique 1

Semaine 9: Structure et Tableau

Structure

Enregistrement

Un enregistrement est une structure (objet) regroupant des données liées sémantiquement ou structurellement. Au sein de cette structure, chaque donnée est libellée (étiquette identifiant la donnée), formant ainsi un champ.

  • Un champ peut être accédé ou modifié en utilisant le libellé.
  • Les champs peuvent être de types différents (primitives, structures, tableaux...)
Construction avec struct

Simplification d'une classe pour créer des objets en Python avec Codeboot.

joueur = struct(
    nom = "Alex",
    mots = ["reine", "ocean", "meres"]
    score = 6,
    stats = struct(essai= 5, rejets= 2)
)
  • Accès à un champ: joeur.nom ou joeur.stats.essai
  • Modifier un champ: joeur.nom = "Tintin" ou joeur.score = struct(record = 13, val = 7)
  • Un champ ne peut être supprimé de la structure et ne peut être ajouté à une structure existante (après sa déclaration)
Construction avec dict

Python offre le type dict pour stocker des collections sous la forme de paire <clé:valeur>, où chaque clé est unique.

joueur = {
    "nom": "Alex",
    "mots": ["reine", "ocean", "meres"]
    "score": 6,
    "stats": {essai: 5, rejets: 2}
}
  • Accès à un champ: joeur["nom"] ou joeur["stats"]["essai"]
  • Modifier un champ: joeur["nom"] = "Tintin" ou joeur["score"] = { "record": 13, "val": 7 }
  • Ajouter un champ: joeur["inscrit"] = False ou joeur["stats"]["temps"] = 133
  • Supprimer un champ: del joeur["inscrit"] ou joeur.pop("inscrit")

Tableau

Un moyen de stocker une collection d'éléments (même type ou diverses) est avec un tableau.
Un tableau est une structure composée d'une séquence contiguë de données indexées, c-à-d, chaque donnée est assignée un index (position) utilisé pour la récupérer dans le tableau.

  • Un tableau possède une longueur (cardinalité de l'ensemble). En Python, la fonction len() nous permet de récupérer la longueur d’un tableau
  • Dans la plupart des langages, le premier élément est à l'index 0
Construction de tableau

Un tableau peut être construit en énumérant tous ses éléments entre crochets [].

jours = ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"]
Index 0 1 2 3 4 5 6
Valeur dim lun mar mer jeu ven sam
  • Accès à une valeur: jours[2]
  • Modifier une valeur: jours[1] = "Lundi"

Modèle en mémoire

Contenu

  • Structures: Enregistrement
  • Tableaux
  • Vue en mémoire

Semaine 10: Traitement de texte & Tortue

Traitement de texte

Méthodes prédéfinies

Les textes (chaine de caractères) ont des caractéristiques similaires aux tableaux car les deux représentent des séquences.
La plupart des langages tel que Python offrent de nombreuses méthodes prédéfinies pour manipuler du texte:
upper(), lower(), isalpha(), isdecimal()
strip(), split(), replace()
startswith(), endswith(), find()

Expressions régulières

Il arrive que nous devions rechercher non pas une chaîne (texte) spécifique mais plutot un patron (Ex: numéro de téléphone, adresse courriel).
Une expression régulière (Regular expression, Regex) est une formule générale de séquence de caractères permettant de trouver des correspondances dans du texte. Si on considère les exemples de code postal suivants:

  • H4P 2C7
  • N7S 2R9
  • A0R 1K2

De manière générale on dira qu'un code postal est formé de la façon suivante:
{Lettre}{Chiffre}{Lettre} {Chiffre}{Lettre}{Chiffre}
Traduction en regex: [A-Z][0-9][A-Z] [0-9][A-Z][0-9]

  • [A-Z] capture toutes les lettres entre A et Z
  • [0-9] capture tous les chiffres entre 0 et 9.

Tortues

Python offre le module turtle qui permet de dessiner différentes formes et images. À l'aide de procédures prédéfinis (dans le module turtle), le programme peut faire bouger une "tortue" qui laisse un tracé sur son passage. Un dessin complet s'obtient par une séquence de mouvements appropriés de la tortue.
>>> from turtle import *
>>> forward(200)

Contenu

  • Traitement de texte: Indexage, Méthodes prédéfinies, Expressions régulières
  • Dessins tortues

Semaine 11: Fichiers

Système de fichier

Sur les systèmes d'exploitation modernes (ex: Windows, Mac OS, Linux), les fichiers sont organisés hiérarchiquement pour les regrouper logiquement. Chaque fichier est assigné une adresse unique (chemin)

  • Un chemin absolu spécifie l'adresse complète d'un fichier ou répertoire (dossier) dans le système de fichiers
    Exemple: C:\Users\bob\documents\code\hello.py
  • Un chemin relatif spécifie l'adresse d'un fichier ou répertoire au sein d'un répertoire donné (généralement le répertoire courant).
    • hello.py est valide si le répertoire courant contient un fichier hello.py
    • code\hello.py est valide si le répertoire courant contient un dossier code qui contient un fichier hello.py
  • Dans un chemin d’accès, on peut se servir du « .. » (deux points) pour désigner le répertoire parent.

Commandes en console (shell)

Unix Windows Action
pwd cd Afficher le répertoire de travail
cd path cd path Changer le répertoire de travail
ls path dir path Lister le contenu du répertoire de travail
rm path del path Supprimer le fichier à l'adresse path
mkdir path mkdir path Créer le répertoire vide à l'adresse path
rmdir path rmdir path Supprimer le répertoire vide à l'adresse path

Contenu

  • Système de fichier
  • Fichiers: Lecture et Écriture

Semaine 12: Exceptions

Erreur

Méthodes prédéfinies

Nous ne pouvons pas éviter les "vrais" accidents ou les erreurs, mais nous pouvons créer un chemin alternatif permettant de rattraper l'erreur ou gérer les dégats causés par l'accident. Il n'est pas nécessaire de prévoir tous les scénarios possibles, mais il faut être prêt à intercepter tout imprévu.

Faute, Erreur, Défaut

La plupart des gens réfèrent à tout comportement indésirable comme bug. Cependant, ceci ne caractérise pas suffisemment le type de problème. Nous pouvons distinguer une erreur, d'une faute ou défaut, d'une défaillance.

  • Erreur (error): Provient d'une mauvaise implémentation (coté programmeur)
  • Faute ou défaut (fault, defect): État interne invalide d'un programme après avoir rencontré une erreur
  • Défaillance (failure): Manifestation externe d'une faute. Elle est observable par l'utilisateur

Gestion des exceptions

La plupart des langages de programmation de haut niveau offrent un mécanisme facilitant le traitement des exceptions (ex: Division par zéro, Index en dehors des limites d'un tableau, Mauvais type de données, Référence à une variable nulle).

Lors de l'exécution d'une série d'opérations, il n'est pas toujours pratique ou possible de signaler un problème au reste du programme. Afin d'interrompre le flux d'exécution, la plupart des langages permettent de soulever une exception, fournissant des détails facilitant la résolution. En Python, l'énoncé raise est utilisé pour soulever une exception (ex: raise Exception("Erreur de calcul") ).

Si une opération ou un appel de fonction risque de causer une erreur ou soulever une exception, il faut encapsuler l'instruction dans un contexte permettant de traiter l'erreur ou l'exception. En Python, l’instruction try..except définit un contexte permettant de répondre aux exceptions soulevées

Débogueur

Débogage

Le débogage regroupe les activités servant à trouver et réduire les défauts d'un programme.

Méthodes de débogage

  • Assertions: Vérifier une condition lors de l'exécution et mettre fin au programme en cas d'échec
  • Exceptions: Détecter une erreur logique ou un cas extrême; Lancer une exception quand une erreur se produit; Traiter une exception pour corriger l'erreur
  • Logging: Afficher ou enregistrer l'information (dans la console, dans un fichier...) sur l'état du programme durant l'exécution
  • Débogueur: Outil permettant une exécution controlée (pas à pas) du programme via des points d'arrêt (breakpoint) afin d'examiner l'état courant et suivre l'évolution des variables.

Contenu

  • Exceptions: Définition, Try..Except
  • Débogage: Assertions, Exceptions, Logging,

Semaine 13: Récursivité

Fonction récursive

Définition

Une fonction récursive est une fonction qui s'appelle elle-même. Similaire à une boucle – Toute boucle peut être convertie en fonction récursive

  • Il faut une condition ou cas d'arrêt, afin d'éviter un appel récursif infini
  • Chaque itération doit nous rapprocher du cas d'arrêt
  • Le cas d'arrêt doit être atteignable

Structure

Tout fonction récursive peut se décomposer en cas de base et cas récursif.

  • Le cas de base peut se traiter sans appel récursif (c’est normalement le cas le plus simple à traiter). Il met fin à la récursion.
  • Le cas récursif requiert un traitement similaire (au cas précédent) mais sur un ensemble d'arguments plus petit.

Exemples

Factoriel

Version récursive
def factoriel(n): 
    if n == 0:     # Cas de base 
        return 1
    else:          # Cas récursif 
        return n * factoriel(n - 1)
Version itérative (équivalente)
def factoriel(n): 
    result = 1
    for i in range(1, n + 1) 
        result *= i

    return result

Somme d'une liste de nombres

Avec accumulateur

Cette version utilise un accumulateur (result) pour stocker la somme à chaque itération.

def somme(nombres, result = 0): 
    if len(nombres) == 0:     # Cas de base 
        return result
    num = nombres.pop()        # Cas récursif (pop réduit la taille de nombres) 
    return somme(nombres, result + num)
Sans accumulateur

Cette version n'utilise pas d'accumulateur. La somme est accumulé sur l'appel de chaque itération.

def somme(nombres): 
    if len(nombres) == 0:     # Cas de base 
        return 0
    num = nombres.pop()        # Cas récursif (pop réduit la taille de nombres) 
    return num + somme(nombres)
    

Contenu

  • Récursivité

Semaine 14: Conclusion

Contenu

  • Conclusion du cours
  • Révision