Python: Les booléens

Pour une lecture plus agréable (page plus large), je vous invite à cliquer sur ce lien et à lire ce chapitre dans la rubrique consacrée au langage Python.

Aujourd’hui, je vais vous parler des booléens. Les booléens sont des êtres farouches qui vivent au fin fond des forêts binaires recouvrant la terre sacrée du Grand Python Digital. Très difficiles à observer dans leur milieu naturel, bla, bla, bla…

Bon en fait, il s’agit d’une notion de programmation un peu déroutante que j’avais du mal à conceptualiser au début de mon apprentissage du Python.

boole
Très rare cliché d’un booléen pris dans son environnement naturel

Un peu d’histoire avec George Boole

Figurez-vous que celui qui a inventé l’algèbre booléenne s’appelle George Boole. Ce sujet anglais est né en 1815 et vous ne serez pas étonné d’apprendre qu’il est mort. C’est une pneumonie qui l’a emporté à l’âge de 49 ans, après que son épouse l’eût aspergé d’eau pour le soigner! (source: Wikipédia). C’est beau l’Amour!

Il est donc le père de l’algèbre de Boole que je suis bien incapable de vous expliquer. Durant ma scolarité,  je n’ai pas eu l’heur de me plonger plus avant dans cette mathématique mystérieuse (J’ai fait un bac A2). C’est la raison pour laquelle je vous renvoie à la page Wikipédia. Débrouillez-vous!

Cela dit, je peux quand-même vous parler des booléens dans mon langage de programmation préféré.

Définition

En Python, un booléen est un type de variables qui possède deux états :

  • L’état « vrai » : True en anglais
  • Ou bien l’état « faux » : False en anglais

False == 0 et True == 1. Comment le prouver? C’est très simple. Nous allons créer deux variables (faux et vrai) et leur affecter respectivement les valeurs False et True. Ensuite, nous allons créer une liste de deux éléments indicés 0 et 1. Nous allons nous servir des deux variables comme indice pour retourner chacune des deux valeurs dans un print(). C’est parti:

faux = False
vrai = True
liste = ["Corée du Nord", "États-Unis"]
print ("1er pays:", liste[faux])
print("2ème pays:", liste[vrai])

1er pays: Corée du Nord
2ème pays: États-Unis

Je rappelle que l’indice d’une liste ne peut être qu’un nombre entier. Le fait que j’aie réussi à retourner les deux éléments de la liste en utilisant comme indice les variables faux et vrai prouvent que ces dernières stockent des valeurs qui sont respectivement égales aux nombres entiers 0 et 1.

Amusons-nous avec un exemple un peu tordu

J’ai dit que faux était égal à 0, c’est-à dire faux == 0. Attention! J’ai bien écrit faux == 0 et non pas faux = 0. En effet, La variable faux ne stocke pas le nombre entier 0 mais bien le booléen False qui est égal à la valeur 0. En Python, je rappelle que le signe = est un signe d’affectation tandis que le signe == est le signe d’égalité.

Je vais donc évaluer l’expression (faux == 0)  pour savoir si elle est vraie ou fausse et  je vais stocker la valeur retournée dans cette même variable faux.

faux = False
faux = (faux == 0) # Évaluation d'une expression (vraie ou fausse?)
print(faux)

True

L’expression faux == 0 est bien vraie (True). J’ai stocké le résultat dans la variable faux et maintenant faux = True!

Évaluation d’une expression

Bon, il s’agissait d’un exemple qui n’était pas du tout pédagogique. Je voulais simplement vous expliquer de manière ludique que Python évalue des expressions pour savoir si elles sont fausses ou vraies. Prenons un autre exemple plus parlant:

nombre_1 = 5
nombre_2 = 8
result = (nombre_1 < nombre_2)
print(result)

True

La variable result évalue si l’expression (nombre_1 < nombre_2) est vraie ou fausse. Il se trouve qu’elle est vraie puisque 5 est inférieur à 8. Donc le résultat est True.

Le type bool()

Les variables faux et vrai sont de types bool() car elles stockent les valeurs False et True.

faux = False
vrai = True
print (type(faux))
print(type(vrai))
<class 'bool'>


<class 'bool'>

 Si on déclare une variable de cette manière : var = bool(), alors var stockera la valeur False.

var = bool()
print(var)

False

Les conditions sont sous l’emprise des booléens

Lorsque Python évalue une condition, soit le résultat est False (== 0), soit il est True (== 1). C’est comme cela qu’un ordinateur pense… uniquement avec des zéros et des uns!

a = 5
if a < 9:
    print(a, "est inférieur à 9")
else:
    print(a, "est supérieur à 9")

Résultat: 5 est inférieur à 9

Qu’est ce qui s’est passé dans la tête de l’ordinateur? Il a évalué la condition. Est-ce que la variable a est inférieure à 9? Oui, c’est vrai. Donc la condition vaut 1 car elle est True). Remplacez 5 par 12 par exemple et vous verrez que la condition vaudra 0. Elle sera False. Par conséquent, c’est le deuxième message qui s’affichera :

Résultat: 12 est inférieur à 9

Pour vous en convaincre, je vais de nouveau utiliser une expression conditionnelle avec la même variable:

a = 5
result = (a < 9)
print(result)

True

L’expression conditionnelle est vraie.

À l’instar d’autres langages de programmation tels que le « C » par exemple, Python considère que toute valeur autre que 0 est vraie (True). Seule la valeur 0 est fausse (False).

  • Le nombre entier 0 est False tandis que les nombres entiers 6 et -6 sont True.
  • Une chaîne de caractères vide est False, une liste vide aussi.
  • Une chaîne de caractères avec au moins un élément est True, une liste avec au moins un élément est True aussi.
chain_car = ""
if chain_car:
    print("vrai")
else:
    print("faux")

chain_car2 = "Boole"
if chain_car2:
    print("vrai")
else:
    print("faux")

faux

vrai

liste = []
if liste:
    print("vrai")
else:
    print("faux")

liste2 = ["Boole", "George"]
if liste2:
    print("vrai")
else:
    print("faux")

faux

vrai

Comme Python considère que toute valeur autre que 0 est True, je n’ai même pas besoin d’écrire par exemple « if a == 5: »

a = 5
if a == 5:
    print("C'est vrai")
else:
    print("C'est faux")

Je peux me contenter d’écrire « if a: »

a = 5
if a:
    print("C'est vrai")
else:
    print("C'est faux")

La fonction print() affichera « C’est vrai » car elle a évalué que la condition était True.

L’instruction else

Dans une condition, le code indenté qui suit l’instruction else s’exécute lorsque l’évaluation est False (ou les évaluations précédentes sont toutes False). L’instruction else exécute un code qui est False.

L’instruction elif 

Le code indenté qui suit l’instruction elif s’exécute lorsque les tests précédents if et elif sont déclarés False. Mais contrairement à else, l’instruction elif exécute un code qui est True.

a = 5
if a == 6: # False
    print("C'est vrai")
elif a == 7: # False
    print("C'est vrai")
elif a == 5: # True
    print("C'est vrai")
else: # False
    print("C'est faux") 

L’instruction not

En Python, l’instruction not transforme False(0) en True(1) et True(1) en False(0).

not

a = 5
a = not a
print(a)

False

L’instruction and

L’expression a and b est vraie si a et b sont vrais tous les deux. Elle est fausse si a ou b est faux ou si a et b sont faux tous les deux. Voici un tableau qui résume ce que je viens d’écrire:

and

a, b = 5, 13
if a == 5 and b == 13:
    print("C'est vrai.")
else:
    print("C'est faux.")

C’est vrai.

L’instruction or

L’expression a or b est vraie si au moins l’une des deux variables est vraie. Elle est fausse si les deux variables sont fausses. Voici un tableau qui résume ce que je viens d’écrire:

or

a, b = 5, 13
if a == 5 or b == 18:
    print("C'est vrai.")
else:
    print("C'est faux.")

C’est vrai.

Les boucles while et for

On retrouve les booléens dans les boucles while et for qui exécutent un programme tant que la condition est vraie (True). À partir du moment où elle devient fausse (False), la boucle s’interrompt. Il est donc aisé (mais pas très malin!) de créer une boucle infinie si on fait en sorte que la condition soit vraie pour l’éternité (ou au moins pour les capacités de la mémoire RAM!).

a = 5
while a:
    print("Au secours! Je viens de créer une boucle infinie.")

À partir de là, seul un Ctrl + C est à même d’interrompre l’irrémédiable processus.

Au secours! Je viens de créer une boucle infinie.
Au secours! Je viens de créer une boucle infinie.
Au secours! Je viens de créer une boucle infinie.

line 1344, in write
return self.shell.write(s, self.tags)
KeyboardInterrupt

Conclusion

Les booléens sont au coeur de la conscience-machine. Un ordinateur ne comprend que le langage binaire. C’est la raison pour laquelle il évalue la fausseté ou la véracité d’une expression uniquement en utilisant le 0 et le 1.

Half life 2 – Violation Dubstep Remix

Bonjour,

Aujourd’hui, scoop! Dans le Nord de l’Allemagne, il pleut! Alors du coup, j’en profite pour ranger l’indescriptible foutoir qui me sert de bureau et pour me donner du coeur à l’ouvrage, j’écoute ce morceau en boucle:

Tiens, d’ailleurs, c’est l’occasion de vous expliquer comment intégrer une vidéo Youtube en la démarrant ET en l’interrompant à un moment précis. En effet, cette vidéo dure plus d’une heure et je souhaitais seulement vous faire découvrir ce morceau: Half life 2 – Violation Dubstep Remix.

Eh bien figurez-vous que c’est d’une simplissime facilitude. Lors de l’intégration, il suffit de rajouter ce petit bout de code en jaune:

integ

La vidéo démarre donc à la 90ème seconde  (1’30) et s’interrompt à la 265ème seconde (4′ 25).

Ne me remerciez pas.

Python: Les ensembles (sets et frozensets)

Pour une lecture plus agréable (page plus large), je vous invite à cliquer sur ce lien et à lire ce chapitre dans la rubrique consacrée au langage Python.

Aujourd’hui, nous allons aborder une notion moins connue du langage Python, à savoir les ensembles (sets et frozensets).

Définition

Un ensemble est une collection non ordonnée d’objets uniques et immuables (en profondeur). La tentative d’insertion d’un doublon n’a absolument aucun effet et ne lève même pas d’exception. En revanche, la présence d’un élément modifiable tel qu’une liste par exemple lève l’exception ci-dessous:

TypeError: unhashable type: ‘list’

Puisqu’il s’agit d’un ensemble d’objets non ordonné, un set est idéal pour effectuer un test d’appartenance et je vais vous le prouver.

On trouve deux types d’ensembles:

  • Le set qui est un objet modifiable
  • le frozenset qui est un objet immuable (le mot anglais frozen signifie gelé en français)

Déclarer un set

Il y a deux manières de déclarer un set.

  • En utilisant des accolades.
s = { "Hervé", "Jacky", "Didier", "Toufik"}
print(s)

Résultat: {‘Didier’, ‘Toufik’, ‘Hervé’, ‘Jacky’}.

Notez bien qu’il s’agit d’un ensemble non ordonné ce qui explique que print() retourne les éléments dans un ordre aléatoire.

  • En transformant une liste en set grâce au constructeur set().
s2 = set(["Geneviève", "Geneviève", (1,2,3), 7.56])
print(s2)

Résultat: {7.56, ‘Geneviève’, (1, 2, 3)}

Notez que j’ai déclaré mon set avec un doublon (« Geneviève »). Comme je l’ai déjà précisé dans l’introduction, celui-ci n’est pas pris en compte et ne lève même pas d’exception. Le set est une collection d’objets uniques.

  • Il n’est pas possible de déclarer un ensemble vide avec la première méthode. Cela créé un dictionnaire.
 s = {}
print(type(s))

Résultat : <class ‘dict’>

  • Pour créer un ensemble vide, pas d’autre choix que d’utiliser la deuxième méthode.
 s = set()
print(type(s))

Résultat: <class ‘set’>

Pourquoi le set est préférable à la liste pour effectuer un test d’appartenance?

Une liste est une séquence. Elle contient des objets indicés. Lorsqu’on fait un test d’appartenance sur une liste, cette dernière est parcourue de l’indice 0 jusqu’à l’indice de l’objet recherché. Si la liste ne contient que dix éléments, le test d’appartenance est rapide mais si la liste contient cinquante millions d’éléments, la vitesse d’exécution s’en ressent. J’ai fait une courte vidéo pour vous montrer la différence entre une liste et un set contenant cinquante millions d’éléments.

Le set étant une implémentation de table de hachage, la vitesse d’exécution d’un test d’appartenance est identique quel que soit le nombre d’éléments qu’il contient.

Voici les trois exemples de code que j’ai exécutés dans la vidéo.

  • Test d’appartenance sur les premiers éléments d’une liste
l = [i for i in range(50000000)]
for i in range(2, 8):
    if i in l:
        print(i, "appartient à la liste")
  • Test d’appartenance sur les derniers éléments d’une liste
l = [i for i in range(50000000)]
for i in range(49999990, 49999999):
    if i in l:
        print(i, "appartient à la liste")
  • Test d’appartenance sur des éléments présents dans un set
s = {i for i in range(50000000)}
for i in range(49999990, 49999999):
    if i in s:
        print(i, "appartient au set")

Aperçu de quelques méthodes associées aux sets

  • Ajouter un élément avec set.add()
s = {"Kevin", "Kilian", "Morgane"}
s.add("Gustave")
print(s)

Résultat: {‘Morgane’, ‘Kilian’, ‘Gustave’, ‘Kevin’}

  • Ajouter tous les éléments d’un autre set avec set.update()
s = {"Kevin", "Kilian", "Morgane"}
s2 = {1, 2, 3}
s.update(s2)
print("s =", s)
print("s2 =", s2)

s = {1, 2, 3, ‘Kilian’, ‘Kevin’, ‘Morgane’}
s2 = {1, 2, 3}

Comme vous pouvez le constater, cette méthode rajoute les éléments de l’ensemble s2 dans l’ensemble s sans pour autant vider l’ensemble s2.

  • Supprimer un élément avec set.remove() et set.discard()
s = {"Kevin", "Kilian", "Morgane", "Gustave"}
s.remove("Kevin")
print(s)

Résultat: {‘Kilian’, ‘Morgane’, ‘Gustave’}

Attention! Avec set.remove(), Python lève une exception si vous essayez d’enlever un élément qui n’appartient pas au set.

s = {"Kevin", "Kilian", "Morgane", "Gustave"}
s.remove("Robert")
print(s)

KeyError: ‘Robert’

Pour éviter cela, utiliser la méthode set.discard() qui, elle, ne lèvera pas d’exception.

s = {"Kevin", "Kilian", "Morgane", "Gustave"}
s.discard("Robert")
print(s)

Résultat: {‘Morgane’, ‘Gustave’, ‘Kevin’, ‘Kilian’}

  • Vider un set avec la méthode set.clear()
s = {"Kevin", "Kilian", "Morgane", "Gustave"}
s.clear()
print("s =", s)

Résultat: s = set()

Pour découvrir plus de méthodes associées aux sets, je vous invite à consulter la documentation officielle Python.

Aperçu de quelques opérations mathématiques associées aux sets

  • Différence entre deux sets
s = {"Kevin", "Kilian", "Morgane", "Gustave"}
s2 = {"Kevin", "Gustave"}
s3 = s - s2
print("s3 =", s3)

s3 = {‘Morgane’, ‘Kilian’}

  • Union de deux sets
s = {"Patrick", "Jacky"}
s2 = {"R12 Gordini", "Kronenbourg"}
s3 = s | s2
print("s3 =", s3)

s3 = {‘Kronenbourg’, ‘Jacky’, ‘R12 Gordini’, ‘Patrick’}

  • Intersection de deux sets
s = {"Patrick", "Jacky"}
s2 = {"R12 Gordini", "Jacky"}
s3 = s &amp; s2
print("s3 =", s3)

s3 = {‘Jacky’}

Les frozensets

Les sets sont des objets modifiables donc il n’est pas possible d’utiliser un set comme clé de dictionnaire. En effet, je vous rappelle que les clés de dictionnaire doivent être immuables.

Il n’est pas possible non plus de placer un set dans un autre set car comme je l’ai déjà dit au début de ce chapitre, les éléments d’un set doivent être immuables dans toute leur profondeur. Cela signifie que ce genre de code va lever une exception:

s = { {"Jacky", "Hervé"}, 1, 3} # présence d'un set
print("s =", s)

TypeError: unhashable type: ‘set’

s = { 4, ([1, 2], 3)} # présence d'un tuple contenant une liste
print("s =", s)

TypeError: unhashable type: ‘list’

Pour remédier à cet inconvénient, on a inventé le frozenset que l’on pourrait traduire par ensemble gelé. Les frozensets sont des sets immuables. Par conséquent, certaines méthodes telles que add() ou remove() ne peuvent pas leur être associées. En revanche, ils peuvent appartenir à un set ou bien être utilisés comme clés de dictionnaire.

  • Pour déclarer un frozenset, il n’existe pas trente-six solutions:
s = {1, 2, 3}
fr_s = frozenset(s)
print(type(fr_s))

Résultat: <class ‘frozenset’>

  • Notez bien que le constructeur frozenset() fonctionne également avec un tuple ou une liste:
tup = (1, 2, 3)
fr_s = frozenset(tup)
print(type(fr_s))
liste = [1, 2, 3]
fr_s = frozenset(liste)
print(type(fr_s))

Résultat: <class ‘frozenset’>

Comme je l’ai écrit en début de paragraphe, une fois déclaré, un frozenset peut appartenir à un set car il est devenu immuable:

liste = [1, 2, 3]
fr_s = frozenset(liste)
s = {fr_s, 4, 5}
print("s =", s)

Résultat:  s = {5, frozenset({1, 2, 3}), 4}

Conclusion

Un set est un ensemble d’objets immuables qui est préférable à une liste lorsqu’il s’agit d’effectuer un test d’appartenance. Il existe plusieurs méthodes associées aux sets. Les frozensets sont des ensembles devenus immuables et qui peuvent donc être utilisés comme clés de dictionnaire ou bien appartenir à un set.

Python: Les dictionnaires

Pour une lecture plus agréable (page plus large), je vous invite à cliquer sur ce lien et à lire ce chapitre dans la rubrique consacrée au langage Python.

J’habite en Allemagne et l’idiome guttural de ce pays n’est pas ma langue maternelle. Par conséquent, lorsqu’un mot me manque, je consulte un dictionnaire. Je me rends directement à l’emplacement précis du mot français, par exemple Ambulance, et ce mot français est comme une clé qui me donne accès à la valeur correspondante dans la langue de Rammstein :

Ambulance : Krankenwagen

Figurez-vous qu’il existe exactement le même procédé en Python et c’est bien plus pratique qu’une liste. Les dictionnaires sont la solution idéale pour réaliser un test d’appartenance et en extraire une valeur.

dico
Ne jamais laver un dictionnaire à 60°!

Limitation des listes

Le problème des listes, c’est qu’il s’agit d’une séquence d’objets indicés, c’est-à dire que pour avoir accès à un élément précis, il faut connaitre son indice :

mots_fr = ["Ambulance", "Hôpital","Infirmière"]
mots_allemands = ["Krankenwagen", "Krankenhaus","Krankenschwester"]

Par exemple, je sais que l’indice d’Infirmière est le nombre entier 2. Je consulte la liste allemande. Que trouve-t-on à l’indice 2? Krankenschwester.

Pas très pratique tout ça! En plus, est-ce que je suis sûr que les traductions sont rangées dans le bon ordre. Est-ce que le mot allemand qui est à l’indice 1 (Krankenhaus) correspond bien au mot français au même indice (Hôpital)? Si ça se trouve, c’est tout dans le désordre!

Pour éviter ce genre de désagréments, on pourrait alors imaginer une liste de listes contenant des paires mot_allemand – mot_français:

dictionnaire = [["Ambulance", "Krankenwagen"], ["Hôpital", "Krankenhaus"],["Infirmière", "Krankenschwester"], [(...), (...)]]

Et pour trouver la traduction, on pourrait utiliser ce code:

dictionnaire =[["Ambulance", "Krankenwagen"], ["Hôpital", "Krankenhaus"],["Infirmière", "Krankenschwester"]]
for i, element in enumerate (dictionnaire):
    if "Hôpital" in dictionnaire[i]:
        print(dictionnaire[i][1])

Résultat: « Krankenhaus »

« Ça marche, Ordinosor! On l’a, notre dictionnaire français-allemand ».

Ne t’emballe pas, jeune fou! je te rappelle que les listes sont des séquences. Cela signifie que pour faire un test d’appartenance, elles sont parcourues de l’indice 0 jusqu’à l’indice de l’élément recherché. En clair, si tu cherches la traduction de zygomatique qui se trouve à la fin du dictionnaire, il va falloir que tu tournes toutes les pages une par une et que tu lises tous les mots un par un! Tu n’as pas le choix, ton dictionnaire est une liste.

Tu sais quoi? On va se donner rendez-vous en 2025. Tu m’apporteras ta traduction. Allez vas-y, tourne les pages!

Bon… en attendant, entrons dans le vif du sujet.

Définition et déclaration d’un dictionnaire

Définition

Un dictionnaire est un ensemble dont les éléments sont des paires clé-valeur . Au niveau syntaxique, un dictionnaire est contenu entre deux accolades. Les éléments sont séparés par des virgules tandis que les paires clé-valeur sont séparées par deux points. Voici ce que ça donne:

nom_du_dictionnaire = {clé : valeur, clé : valeur, clé : valeur, (…) : (…)}

Un dictionnaire est modifiable et les valeurs peuvent être n’importe quel objet (immuable ou modifiable, il n’y a aucune restriction) mais les clés doivent absolument être des objets immuables (string, nombre entier, nombre décimal, tuple). Si la clé est un tuple, celui-ci ne doit contenir que des éléments immuables. Par exemple, ce genre de clé ([0, 1], [2, 3]) qui est un tuple contenant des listes modifiables va lever une exception (erreur):

TypeError: unhashable type: ‘list’

Déclarer un dictionnaire

  • Pour déclarer un dictionnaire, on utilise des accolades :
dictionnaire = {} # dictionnaire vide
  • Je viens de créer un dictionnaire vide mais je peux très bien créer un dictionnaire et y placer des éléments dès sa déclaration :
capitales = {"France":"Paris", "Allemagne" : "Berlin"}

Dans cet exemple, « France » est une clé tandis que « Paris » est une valeur.

  • Il existe une autre méthode pour créer un dictionnaire. Elle consiste à créer une liste de tuples que l’on transforme en dictionnaire grâce au constructeur dict().
liste_capitales = [("France","Paris"), ("Allemagne","Berlin")]
capitales = dict(liste_capitales)
print(capitales)

Résultat : {‘Allemagne’: ‘Berlin’, ‘France’: ‘Paris’}

  • Il n’est pas possible de dupliquer une clé. Si on le fait, ce sera la dernière valeur entrée pour cette clé qui sera prise en compte.
capitales = {"France":"Paris", "Allemagne" : "Berlin", "France" : "Marseille"}
print(capitales)

Résultat: {‘Allemagne’: ‘Berlin’, ‘France’: ‘Marseille’}

Ajouter un élément (paire clé-valeur)

Si je veux rajouter un élément, c’est très simple, je créé une nouvelle paire clé-valeur. La clé  est contenue entre des crochets et la valeur se trouve à la droite du signe d’affectation. La syntaxe est donc la suivante :

nom_du_dico[clé] = valeur

capitales['Islande'] = "Reykjavik"
print(capitales)

Résultat : {‘Allemagne’: ‘Berlin’, ‘Islande’: ‘Reykjavik’, ‘France’: ‘Paris’}

Diantre! Les éléments ne sont plus dans le même ordre? Comment se fait-ce?

Ça n’a aucune espèce d’importance. L’ordre est aléatoire car un dictionnaire n’est pas une séquence, c’est une implémentation de tables de hachage. Pour retrouver une valeur, nous avons seulement besoin de connaître sa clé.

Accéder à une valeur

Voici comment on accède à une valeur:

capitales = {'Allemagne': 'Berlin', 'Islande': 'Reykjavik', 'France': 'Paris'}
result = capitales["Allemagne"] #Je stocke le résultat dans une variable.
print(result)

Résultat : « Berlin »

C’est simple et instantané! Le programme n’a pas besoin de parcourir le dictionnaire du début à la fin. Grâce à la clé (« Allemagne »), Python est en mesure de se rendre directement à la « page » souhaitée pour trouver la valeur et renvoyer cette dernière. Que le dictionnaire contienne dix éléments ou cinq cent millions, la vitesse d’exécution sera de toute façon identique!

Et si j’utilise une clé qui n’est pas dans le dictionnaire, Python lève une exception (erreur):

result = capitales["Syldavie"]
print(result)

KeyError: ‘Syldavie’

La méthode get() comme test d’appartenance

Pour contourner cette exception et éviter d’avoir un message d’erreur qui stoppe le programme, il suffit d’utiliser la méthode get() en lui passant deux arguments : la clé et le résultat renvoyé au cas où la clé serait absente du dictionnaire. Reprenons le code précédent :

result = capitales.get("Syldavie", "Non répertorié.")
print(result)

Résultat : Non répertorié.

Tester l’appartenance avec l’instruction in

Il est possible de tester l’appartenance d’une clé à un dictionnaire grâce à la puissante instruction in.

capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
if "Islande" in capitales:
    print(capitales["Islande"])

Résultat : Reykjavik

Je précise que l’instruction in ne teste que l’appartenance des clés et non pas l’appartenance des valeurs.

capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
if "Reykjavik" in capitales:
    print("Test d'appartenance réussi")
else:
    print("Cette clé est absente du dictionnaire")

Résultat: Cette clé est absente du dictionnaire

Mettre à jour une valeur

Si on souhaite mettre à jour une valeur, c’est fort simple. Voici comment on procède:

capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
capitales["France"] = "Marseille"
print(capitales)

Résultat: {‘France’: ‘Marseille’, ‘Allemagne’: ‘Berlin’, ‘Islande’: ‘Reykjavik’}

Utiliser un tuple comme clé

C’est tout à fait possible, à la condition que le tuple ne contienne que des objets immuables. Quant à la valeur, elle peut être constituée par n’importe quel objet donc une liste ne pose aucun problème.

Dès lors, on peut très bien imaginer un dictionnaire avec en guise de clés, des tuples contenant les noms de capitales et les noms de pays et en guise de valeurs, des listes contenant la latitude et la longitude.

coords = {("Paris","France"):["48° 51′ N", "2° 21′ E"], ("Berlin","Allemagne"): ["52° 31′ N", "13° 24′ O"]}
result = coords[("Paris", "France")]
print(result)

Résultat : [’48° 51′ N’, ‘2° 21′ E’]

code_dict
Visualisation du code avec Pythontutor

Supprimer un élément grâce à l’instruction del

Nous avons vu comment rajouter un élément dans un dictionnaire. C’est d’une simplicité enfantine. Pas besoin de faire appel à la méthode append().

Pour supprimer un élément, on utilise l’instruction del. En fait, on supprime la clé et par conséquent, la valeur qui lui est associée.

capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
del capitales["Allemagne"]
print(capitales)

Résultat : {‘France’: ‘Paris’, ‘Islande’: ‘Reykjavik’}

Supprimer tout le dictionnaire grâce à l’instruction del

Notez bien que l’instruction del permet également de supprimer tout le dictionnaire. Il suffit pour cela, de ne pas lui passer de clé entre crochets.

capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
del capitales
print(capitales)

NameError: name ‘capitales’ is not defined

Ce message d’erreur nous confirme que le dictionnaire n’existe plus.

Utiliser la fonction intégrée len()

On peut également utiliser la fonction intégrée len() pour connaître le nombre de paires clé-valeur contenues dans un dictionnaire.

capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
print(len(capitales))

Résultat: 3

Aperçu de quelques méthodes associées aux dictionnaires

  • dict.clear() supprime tous les éléments d’un dictionnaire. En clair, il le vide.
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
capitales.clear() # Vide le dictionnaire
print(capitales)

Résultat: {}

  • dict.items() retourne toutes les paires clé-valeur sous la forme d’une liste de tuples
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
result = capitales.items()
print(result)

Résultat: dict_items([(‘Islande’, ‘Reykjavik’), (‘France’, ‘Paris’), (‘Allemagne’, ‘Berlin’)])

  • dict.keys() retourne toutes les clés du dictionnaire sous la forme d’une liste
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
result = capitales.keys()
print(result)

Résultat: dict_keys([‘Islande’, ‘Allemagne’, ‘France’])

  • dict.values() retourne toutes les valeur du dictionnaire sous la forme d’une liste
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
result = capitales.values()
print(result)

Résultat: dict_values([‘Berlin’, ‘Reykjavik’, ‘Paris’])

Conclusion

Un dictionnaire est un ensemble non ordonné de paires clé-valeur. Chaque clé donne accès à la valeur qui lui est associée. Plus puissant qu’une liste, Un dictionnaire est idéal pour réaliser un test d’appartenance. En effet, comme il s’agit d’une implémentation de table de hachage et non pas d’une séquence, la vitesse d’exécution du test d’appartenance n’est pas liée au nombre d’éléments que le dictionnaire contient.

Il existe des compréhensions de dictionnaire qui feront l’objet d’un chapitre ultérieur.

#Primtux, une distribution Linux destinée aux élèves du primaire.

Bonjour

Il y a quelques jours, j’ai découvert Primtux, une distribution Linux « développée (je cite) par une petite équipe de professeurs des écoles et de passionnés de l’informatique dans le milieu éducatif. »

Ce diaporama nécessite JavaScript.

Je trouve que c’est une belle initiative. Ludique et éducative à la fois, elle s’adresse aux élèves scolarisés dans l’enseignement primaire. Je l’ai testée en démo dans une machine virtuelle. Elle contient entre autres, une version LibreOffice avec un design beaucoup plus coloré. Cette version offre par exemple la possibilité de coloriser les syllabes d’un mot ou de les souligner, de mettre en évidence les liaisons obligatoires, les lettres muettes, les phonèmes etc…

Au passage, il y a une magnifique faute d’orthographe avec l’onglet aggrandir l’image (oui vous avez bien lu! Avec deux g). Les professeurs des écoles ne l’ont pas remarquée. Carton rouge! Vous me recopierez  cent fois :

« Oh! la! la! Qu’est-ce qu’il aggrandit? Sa lui fait quel âge maintenant? Céding! On voit pas le tant passé! »

C’est le résultat de la méthode globale ou de la méthode syllabique?

Il y a trois niveaux :

  • Mini (pour les 3 – 5 ans)
  • Super (pour les 6-7 ans)
  • Maxi (pour les 8 – 10 ans)

Les niveaux Super et Maxi bénéficient d’un accès internet restreint c’est-à dire qu’il est inutile de taper ebay.fr dans la barre de recherche. Vous obtiendrez un message vous signifiant que l’accès à ce site est interdit. Le moteur de recherche est Qwant Junior.

On trouve également une multitude de petits jeux éducatifs pour assimiler des notions de français, mathématiques, géométrie etc… Voici un aperçu dans la vidéo mise en ligne sur le site officiel.

Il s’agit en tout cas d’une bien belle initiative qui permet à des élèves du primaire de découvrir l’univers Linux. À adopter!

Python: Les tuples

Pour une lecture plus agréable (page plus large), je vous invite à cliquer sur ce lien et à lire ce chapitre dans la rubrique consacrée au langage Python.

Un tuple est un ensemble d’éléments comparable aux listes mais qui, une fois déclaré, ne peut plus être modifié. Il s’agit donc d’une séquence immuable d’objets indicés qui peuvent être des nombres entiers ou décimaux, des chaînes de caractères, des listes, des tuples etc…

tuple_tulipes
Tuple de tulipes

Syntaxe et déclaration

D’un point de vue syntaxique, un tuple est un ensemble d’éléments séparés par des virgules. Cet ensemble d’éléments est entouré de parenthèses mais ce n’est pas une obligation. Cela permet toutefois d’améliorer la lisibilité du code.

Déclarons un tuple :

tuple_1 = (8, "Solange", 5.3)

J’aurais très bien pu écrire :

tuple_1 = 8, "Solange", 5.3

Cela revient au même sauf que c’est moins lisible.

print(type(tuple_1))

<class ‘tuple’>

Sans le savoir, nous avons déjà rencontré des tuples, notamment lorsque nous avons fait des affectations multiples :

a, b = 5, 6

Cette instruction d’affectation correspond à :

(a, b) = (5, 6)

Si nous souhaitons déclarer un tuple ne contenant qu’une seule valeur, il faut absolument que cette dernière soit suivie d’une virgule. En outre, il est vivement conseillé de l’inclure entre parenthèses.

c = (9,)

print(type(c))

<class ‘tuple’>

Si nous oublions la virgule (et malgré la présence de parenthèses), le type de la variable ne sera pas un tuple :

c = (9)

print(type(c))

<class ‘int’>

Utilité d’un tuple par rapport à une liste

Comme nous l’avons vu plus haut, il permet de faire des affectations multiples.

a, b = 5, 6

Le tuple permet également de renvoyer plusieurs valeurs lors d’un appel de fonction.

def information_personne(prenom, nom, age) :
    "Traitement des informations transmises"
    prenom = prenom.capitalize() # Première lettre en majuscule.
    nom = nom.upper() # remplace toutes les minuscules en majuscules
    age = int(age)
    return prenom, nom, age # Tuple sans parenthèses

p = input("Entrez votre prénom: ")
n = input("Entrez votre nom: ")
a = input("Entrez votre âge: ")

prenom, nom, age = information_personne(p, n, a) # Affectation multiple
print("Prénom:", prenom + '\n' + "Nom:", nom + '\n' + "Âge:", age)

Entrez votre prénom: alphonsine
Entrez votre nom: Chafouin
Entrez votre âge: 92

Résultat:

Prénom: Alphonsine
Nom: CHAFOUIN
Âge: 92

Un tuple est « protégé en écriture ».

Vous allez me dire que dans le code ci-dessus, nous pouvons obtenir le même résultat en renvoyant une liste (return [prenom, nom, age]). Mais l’avantage d’un tuple, c’est qu’il s’agit d’une séquence non modifiable (immuable) donc protégée en écriture. Nous sommes sûrs que les données transmises par la fonction input() ne seront pas modifiées en cours d’exécution par un autre programme. Dans le code ci-dessus, je n’ai aucun moyen de modifier les informations transmises.

Par contre, dans le code ci-dessous où je renvoie une liste, je peux modifier les données transmises et rajeunir Mamie Alphonsine!

def information_personne(prenom, nom, age) :
    "Traitement des informations transmises"
    prenom = prenom.capitalize() # Première lettre en majuscule.
    nom = nom.upper() # remplace toutes les minuscules en majuscules
    age = int(age)
    return [prenom, nom, age] # liste

p = input("Entrez votre prénom: ")
n = input("Entrez votre nom: ")
a = input("Entrez votre âge: ")

identification = information_personne(p, n, a) #Liste
identification[2] = '45' # Je modifie l'âge
print("Prénom:", identification[0] + '\n' + "Nom:", identification[1] + '\n' + "Âge:", identification[2])

Entrez votre prénom: alphonsine
Entrez votre nom: Chafouin
Entrez votre âge: 92

Prénom: Alphonsine
Nom: CHAFOUIN
Âge: 45

Un tuple est moins gourmand en ressources système qu’une liste.

Il a besoin de moins de mémoire et il s’exécute plus rapidement.

Opérations sur les tuples

Il n’existe pas de méthodes associées aux tuples

Les tuples sont des séquences non modifiables donc il n’est pas possible d’utiliser les méthodes remove()  ou append() par exemple.

Il n’est pas possible également d’utiliser l’opérateur [] pour insérer ou remplacer un élément :

tuple_1 = (5, 2, 25, 56)
tuple_1[2] = 23
print(tuple_1)

TypeError: ‘tuple’ object does not support item assignment.

L’instruction in

Mais il est possible d’utiliser l’instruction in pour faire un test d’appartenance

tuple_1 = (5, 2, 25, 56)
print(2 in tuple_1)

Résultat: True

La fonction intégrée len()

Il est également possible d’utiliser la fonction intégrée len() pour déterminer la longueur d’un tuple.

tuple_1 = (5, 2, 25, 56)
print(len(tuple_1))

Résultat : 4

La boucle for et la compréhension de liste

Tout comme les chaînes de caractères ou les listes, les tuples peuvent être parcourus par une boucle for ou une compréhension de liste. Dans ce dernier cas, le résultat obtenu est toujours une liste.

Concaténation et multiplication

Nous pouvons créer un nouveau tuple par concaténation ou par multiplication

tuple_1 = (5, 2, 25, 56)
tuple_2 = ("Jacky", "Hervé")
tuple_3 = tuple_1 + tuple_2
print(tuple_3)

Résultat: (5, 2, 25, 56, « Jacky », « Hervé »)

tuple_prenoms = ("Jacky", "Hervé")
tuple_prenoms = tuple_prenoms * 3
print(tuple_prenoms)

Résultat: (‘Jacky’, ‘Hervé’, ‘Jacky’, ‘Hervé’, ‘Jacky’, ‘Hervé’)

Dans ce dernier exemple, certains vont me dire: « Mais Ordinosor! Tu nous a dit qu’un tuple n’était pas modifiable et tu viens juste de modifier tuple_prenoms! »

Faux! Je n’ai appliqué aucune méthode de modification sur tuple_prenoms. J’ai seulement écrasé la valeur contenue dans la variable qui porte le nom de tuple_prenoms en lui affectant une nouvelle valeur.

Conclusion

Les tuples sont des séquences non modifiables qui s’avèrent bien utiles pour protéger en écriture des données transmises. En outre, ils sont moins gourmands en ressource système et sont traités plus rapidement.

Puisqu’il est immuable, il est possible d’utiliser un tuple comme clé de dictionnaire mais à la seule condition que le tuple ne contienne que des éléments non modifiables! Du reste, ce sera l’objet du prochain chapitre.

antiX, une distribution destinée aux ordinateurs de l’Antiquité

Bonjour,

J’ai fait une courte vidéo pour vous présenter antiX, une distribution qui nous vient de Grèce. Très légère, elle ne nécessite que 256 MB de RAM et 2.7 GB pour le disque dur. Elle est donc idéale pour les ordinateurs de l’Antiquité justement. Continuer à lire … « antiX, une distribution destinée aux ordinateurs de l’Antiquité »