% Programmation avec Python (chapitre 4) % Dimitri Merejkowsky
\center \huge Les tuples
mon_tuple = tuple() # un tuple vide
mon_tuple = () # aussi un tuple vide
mon_tuple = (1, 2) # un tuple à deux éléments
C’est la virgule qui fait le tuple, pas les parenthèses (on n’utilise les parenthèses que pour l’esthétique)
\vfill
(1)
# pas un tuple, juste le nombre 1 (entre parenthèses)
(1,)
# un tuple à un élément
1,
# le *même* tuple
>>> couple = ('Starsky', 'Hutch')
>>> couple[0]
'Starsky'
>>> couple[1]
'Hutch'
>>> couple[3]
IndexError
>>> 'Starsky' in couple
True
>>> 'Batman' in couple
False
Rien de nouveau en principe :p
Créer plusieurs variables en une seule ligne
>>> couple = ("Batman", "Robin")
>>> héro, side_kick = couple
>>> héro
'Batman'
>>> side_kick
'Robin'
On dit aussi: unpacking
>>> héro, side_kick, ennemi = couple
ValueError (3 != 2)
>>> (héro,) = couple
ValueError (1 != 2)
# Gare à la virgule:
>>> héro, = couple
ValueError (1 != 2)
f(a, b, c) # appelle f() avec trois arguments
f((a, b, c)) # appelle f() avec un seul argument
# (qui est lui-même un tuple à 3 valeurs)
>>> fruits = ["pomme", "banane", "orange"]
>>> premier, deuxième, troisième = fruits
Retourner plusieurs valeurs:
def tire_carte():
valeur = "10"
couleur = "trèfle"
return (valeur, couleur)
(v, c) = tire_carte()
print(v, "de", c)
# 10 de trèfle
\vfill
En fait c’est juste une manipulation de tuples :)
>>> couple = ('Starsky', 'Hutch')
>>> couple[0] = 'Batman'
TypeError
Les méthodes count()
et index()
existent
parce qu’elles ne modifient pas le tuple.
Les méthodes qui modifieraient le tuple n’existent pas:
>>> couple = ('Starsky', 'Hutch')
>>> couple.clear()
AttributeError
\center Mutables, immuables, et références
En Python, on ne manipule jamais les objets directement, on ne manipule que des références sur ces objets.
x = 3 # x est une référence vers l'objet 'entier 3'
x = "hello" # x référence une string
def ajoute_trois(x):
x = x + 3 # crée une nouvelle référence
mon_entier = 42
ajoute_trois(mon_entier)
# 'mon_entier' vaut toujours 42
def ajoute_trois(liste):
liste.append(3)
# Ne crée pas de nouvelle référence
# Appelle une méthode qui modifie 'liste' sur place
ma_liste = [1, 2]
ajoute_trois(ma_liste)
# 'ma_liste' vaut maintenant [1, 2, 3]
def get_max(liste):
autre_liste = liste.copy()
autre_liste.sort()
return autre_liste[-1]
ma_liste = [1, 3, 2]
x = get_max(ma_liste)
# x = 3
# `ma_liste` n'a pas changé
autre_liste = liste[:]
def exemple_bizarre(liste=[1, 2, 3]):
liste.append(4)
return liste
>>> exemple_bizarre()
[1, 2, 3, 4]
>>> exemple_bizarre()
[1, 2, 3, 4, 4]
Parfois, ce comportement peut être voulu
\vfill
def grosse_fonction(x, cache=dict()):
if x in cache:
return cache[x]
else:
resultat = ... # plein de calculs
cache[x] = resultat
return resultat
Sinon, remplacez l’argument mutable par un argument immutable
def exemple_bizarre(liste=None):
if not liste:
liste = [1, 2, 3]
liste.append(4)
return l
>>> exemple_bizarre()
[1, 2, 3, 4]
>>> exemple_bizarre()
[1, 2, 3, 4]
Une fonction ne peut modifier la valeur de ses arguments qui s’ils sont mutables.
Toutes les copies doivent être explicites
\center \huge Itérer sur les dictionnaires
scores = { "alice": 3, "bob": 4 }
for prénom in scores:
score = scores[prénom]
print(prénom, score)
\vfill
Même chose avec la méthode .keys()
for prénom in scores.keys():
...
scores = { "alice": 3, "bob": 4 }
for score in scores.values():
print(score)
for (prénom, score) in scores.items()
print(prénom, score)
\vfill
Notes:
items()
renvoie une liste de tuplesLes méthodes .keys()
, .values()
et .items()
ne retournent pas des listes,
mais des “vues”.
>>> prénoms = scores.keys()
>>> prénoms[1]
TypeError: 'dict_keys' object does not support indexing
\vfill
On détaillera cette question plus tard.
En attendant, vous pouvez convertir les vues en listes:
>>> prénoms = scores.keys()
>>> premier_prénom = list(prénoms)[0]
\center \huge La programmation n’est pas un art solitaire
Un développeur dans son garage a une idée géniale, l’implémente tout seul et gagne un tas de pognon.
\vfill
Ça n’existe pas (ou plus)
Ce qu’on a fait avec l’exercice de la dernière fois :)
Bonjour Alice, voici une nouvelle fonction:
def ma_fonction():
ma_liste = ...
if len(ma_liste) == 0:
# la liste est vide
signé: Bob
Bonjour Bob, et merci pour ta contribution!
def ma_fonction():
ma_liste = ...
if len(ma_liste) == 0:
# la liste est vide
>> Ici tu pourrais mettre `if not ma_liste`
signé Alice
Bonjour Alice, voici le code corrigé:
def ma_fonction():
ma_liste = ...
if not ma_liste:
...
Croyez-le ou nom, plein de projets fonctionnent comme ça.
Pas d’outil spécifiques, on peut tout faire avec des e-mail et du texte brut.
Et c’est souvent comme ça qu’on contribue à du code open-source.
Des outils essayent de “simplifier” le processus. En vrac: gerrit
, github
, gitlab
, bitbucket
, phabricator
...
\vfill
Mais dans son essence le concept n’a pas changé
\center \huge Un atelier
Ou programmation en foule
On va prendre deux discours politique et faire de l’analyse automatique de texte dessus.
Notamment, repérer les mots qui reviennent le plus
Un universitaire malheureusement décédé s’en était fait une spécialité.
Vous pouvez lire Les Mots du Président si ça vous dit.
Il utilisait d’autres outils, bien sûr, mais ce qu’on va faire n’est pas si loin
\center \huge Let’s go!
\center \huge Lire et écrire des fichiers
file = open("toto.txt", "r") # 'r' comme 'read'
contenu = file.read()
file.close()
Note: le fichier toto.txt
doit exister!
On peut écrire tout le contenu d’un coup:
contenu = "du texte à sauvegarder"
file = open("article.txt", "w") # 'w' comme 'write'
file.write(contenu)
file.close()
article.txt
sera écrasé s’il existe déjà.close()
file = open("article.txt", "w") # 'w' comme 'write'
# ... beacoup de code ici
# ... < une erreur
file.close()
S’il y a une erreur entre open()
et close()
, le fichier ne sera pas fermé!
with open("toto.txt", "w") as file:
file.write("du texte")
Quand on sort du bloc with
on a la garantie que file.close()
sera appelé,
même si on sort du bloc à cause d’une erreur.
Il n’y a maintenant plus aucune raison d’appeler .close()
“à la main”,
donc ne le faites pas ...
Très courant:
with open("toto.txt", "r") as file:
lignes = file.readlines()
# faire quelque chose avec la liste de lignes
with open("toto.txt", "w") as file:
file.writelines(lignes)
Pensez à fermer le premier fichier avant d’ouvrir le second. (ça marche même s’ils ont le même nom)