Defensive programming, unit tests and documentation

Programming – Session 3

  • Exceptions and assertions
  • Defensive programming
  • Writing tests
  • Documenting and commenting the code

Exceptions and assertions

Exceptions

Runtime errors

  • Les erreurs de syntaxe sont détectées par l’interpréteur Python avant l’exécution du code

  • Un code, bien que syntaxiquement correct, peut générer des erreurs à l’exécution :

    • Ces erreurs sont appelées exceptions
TAXES_RATE = 1.2
init_price = input("Price without taxes:")
price = init_price * TAXES_RATE
TypeError: can't multiply sequence by non-int of type 'float'

Exceptions and assertions

Exceptions

Recovering from an exception

  • Les exceptions sont des erreurs survenant à l’exécution
  • Les exceptions peuvent être capturées à l’aide de l’instruction try ... except ...
# Statements that may raise an exception
try:
    TAXES_RATE = 1.2
    #convert input to int if possible
    init_price = int(input("Price without taxes:"))
    price = init_price * TAXES_RATE

# Capture an exception of type TypeError to handle it
except TypeError as e:
    print(e)

# Continue the execution of the program here

Exceptions and assertions

Exceptions

Raising an exception

  • Vous pouvez aussi générer des exceptions depuis votre code
  • Cela peut être utile pour indiquer une erreur particulière
raise NameError('Unexpected behavior')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: Unexpected behavior

Exceptions and assertions

Assertions

Qu’est-ce qu’une assertion

  • Un cas particulier d’exception
  • Les assertions documentent et assurent l’exécution du code

En quoi diffèrent-elles des exceptions ?

  • Utilisées uniquement en phase de développement
  • Aident au débogage de votre code
  • Lève une AssertionError si le test retourne False
def euclidean_division (a: int, b: int) -> int:

    # This assertion will fail when a division by 0 is attempted
    assert b != 0, "Division by zero"

    # If we pass all assertions, we are fine
    return a // b

Defensive programming

A programming philosophy

Anticiper les erreurs possibles qui peuvent survenir à l’exécution et empêcher le programme de planter


Pourquoi ?

  • Rendre votre code plus résistant aux entrées et conditions inattendues

  • Assurer qu’un logiciel continuera à fonctionner dans des circonstances imprévues

Comment ?

  • Identifier les situations problématiques puis les actions correctives

  • Valider les entrées, éviter les hypothèses, utiliser des valeurs par défaut sûres, et gérer les erreurs avec élégance

Writing tests

Different types of tests

Les tests et la documentation ensemble assurent la robustesse et la pérennité du logiciel :

  • Unit Tests — Se concentrent sur une unité particulière (composant)

  • Integration Tests — Vérifient la compatibilité globale des différents composants d’une application

  • Regression Tests — Vérifient la stabilité du code précédemment intégré

  • Security Tests – Évitent les vulnérabilités du code

Writing tests

Unit tests

def inverse_capitalization (word: str) -> str:
    result = []
    for char in word:
        result.append(char.lower() if char.isupper() else char.upper())
    return ''.join(result)
# Import the function to test
from my_functions import inverse_capitalization
import unittest

# Define a Unittest class
class TestMyFunctions (unittest.TestCase):

    # Good practice is to define one method per function to test
    def test_inverse_capitalization (self):
        self.assertEqual("hello!", inverse_capitalization("HELLO!"))
    
    # ...

# Start the tests
if __name__ == "__main__":
    unittest.main()

Documenting and commenting the code

To share and reuse code

Documentation

Un code sans commentaires ni documentation est inutile :

  • Documentation du code – Dans le code (commentaires, annotations, et docstrings)
  • Documentation technique – Complète le code avec des détails techniques (souvent des diagrammes) sur l’architecture logicielle
  • Documentation utilisateur – Se concentre sur les fonctionnalités du code du point de vue de l’utilisateur

Commentaires

  • Annotations textuelles ajoutées directement au code source
  • Expliquent les choix d’implémentation ou les étapes de l’algorithme

Docstrings

  • Une docstring est une chaîne de caractères littérale pour décrire un module, une fonction, une classe ou une définition de méthode
  • De nombreuses extensions VSCode existent pour générer automatiquement la docstring à partir de la signature de la fonction

Documenting and commenting the code

Altogether in an example

def inverse_capitalization (word: str) -> str:

    """
        Inverse the capitalization of a word.
        It consists in iterating over the characters of the word and for each character, inverting its capitalization.
        That is, if a letter is uppercase, it will be transformed to lowercase and vice-versa.
        In:
            * word: A word to inverse the capitalization.
        Out:
            * The word with the capitalization inversed 
    """

    # Temporary list to store the result
    result = []

    # Process character by character to reverse lowercase and uppercase
    for char in word:
        result.append(char.lower() if char.isupper() else char.upper())
    
    # Make a string out of the result list
    return "".join(result)

Recap of the session

Main elements to remember

  • Exceptions are raised when there is a runtime error

  • Assertions are particular types of exceptions for debugging and documenting

  • Defensive programming aims at anticipating possible errors to inform the user

  • Unit tests allow to (semi-automatically) ensure that functions behave as expected

  • Documentation consists in many aspects beyond commenting a code

  • All these elements together allow to write maintainable codes

Recap of the session

What’s next?

Practical activity (~2h30)

  • Defensive programming
  • Tests
  • Documenting your code

After the session

  • Review the articles of the session
  • Check your understanding with the quiz
  • Complete the practical activity
  • Check next session’s “Before the class” section