% Programmation avec Python (chapitre 4) % Dimitri Merejkowsky # \center \huge Les tuples # Création de tuples ```python mon_tuple = tuple() # un tuple vide mon_tuple = () # aussi un tuple vide mon_tuple = (1, 2) # un tuple à deux éléments ``` # Note C'est la virgule qui fait le tuple, pas les parenthèses (on n'utilise les parenthèses que pour l'esthétique) \vfill ```python (1) # pas un tuple, juste le nombre 1 (entre parenthèses) (1,) # un tuple à un élément 1, # le *même* tuple ``` # Indexation, test d'appartenance ```python >>> 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 # Déstructuration Créer plusieurs variables en une seule ligne ```python >>> couple = ("Batman", "Robin") >>> héro, side_kick = couple >>> héro 'Batman' >>> side_kick 'Robin' ``` On dit aussi: unpacking # Quelques erreurs ```python >>> héro, side_kick, ennemi = couple ValueError (3 != 2) >>> (héro,) = couple ValueError (1 != 2) # Gare à la virgule: >>> héro, = couple ValueError (1 != 2) ``` # Pièges ```python 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) ``` # On peut aussi déstructurer des listes ```python >>> fruits = ["pomme", "banane", "orange"] >>> premier, deuxième, troisième = fruits ``` # Retour multiple Retourner plusieurs valeurs: ```python 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 :) # Les tuples sont immuables ```python >>> couple = ('Starsky', 'Hutch') >>> couple[0] = 'Batman' TypeError ``` Les méthodes `count()` et `index()` existent parce qu'elles ne modifient pas le tuple. # Les tuples sont immuables (2) Les méthodes qui modifieraient le tuple n'existent pas: ```python >>> couple = ('Starsky', 'Hutch') >>> couple.clear() AttributeError ``` # \center Mutables, immuables, et références # Mutables et immuables * Mutables: listes, ensembles, dictionnaires * Immuables: entiers, flottants, booléens, strings # Passage par référence En Python, on ne manipule jamais les objets directement, on ne manipule que des *références* sur ces objets. ```python x = 3 # x est une référence vers l'objet 'entier 3' x = "hello" # x référence une string ``` # Exemple 1 ```python 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 ``` # Exemple 2 ```python 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] ``` # Exemple 3 ```python 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é ``` # Notes * on peut aussi utiliser la fonction native "max()" * on peut aussi utiliser une slice: `autre_liste = liste[:]` # Valeur par défaut ```python 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] ``` * Les arguments par défaut ne sont évalué qu'une seule fois # Valeur par défaut (2) Parfois, ce comportement *peut* être voulu \vfill ```python def grosse_fonction(x, cache=dict()): if x in cache: return cache[x] else: resultat = ... # plein de calculs cache[x] = resultat return resultat ``` # Valeur par défaut (3) Sinon, remplacez l'argument mutable par un argument immutable ```python 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] ``` # Conclusions * 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 # Itérer sur les clés ```python 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()` ```python for prénom in scores.keys(): ... ``` # Itérer sur les valeurs ```python scores = { "alice": 3, "bob": 4 } for score in scores.values(): print(score) ``` # Itérer sur les clés *et* les valeurs ```python for (prénom, score) in scores.items() print(prénom, score) ``` \vfill Notes: * on a gagné une ligne par rapport au premier exemple. * `items()` renvoie une liste de tuples # Presque des listes Les méthodes `.keys()`, `.values()` et `.items()` ne retournent pas des listes, mais des "vues". ```python >>> prénoms = scores.keys() >>> prénoms[1] TypeError: 'dict_keys' object does not support indexing ``` \vfill On détaillera cette question plus tard. # Forcer des listes En attendant, vous pouvez convertir les vues en listes: ```python >>> prénoms = scores.keys() >>> premier_prénom = list(prénoms)[0] ``` # \center \huge La programmation n'est pas un art solitaire # Le mythe > 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) * Sauf dans les fictions * Quasiment mon seul reproche à propos de la série *Silicon Valley* # La code review Ce qu'on a fait avec l'exercice de la dernière fois :) # Par mail - envoi ```text Bonjour Alice, voici une nouvelle fonction: def ma_fonction(): ma_liste = ... if len(ma_liste) == 0: # la liste est vide signé: Bob ``` # Par mail - réponse ```text 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 ``` # Par mail - envoi 2 ```text Bonjour Alice, voici le code corrigé: def ma_fonction(): ma_liste = ... if not ma_liste: ... ``` # Code review 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. # D'autres outils 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 # Mob programming Ou programmation en foule # Les règles * Un pilote: le seul autorisé à modifier le code * Un copilote: indique au pilote quoi faire * On tourne toutes les 15 minutes # Le challenge On va prendre deux discours politique et faire de l'analyse automatique de texte dessus. Notamment, repérer les mots qui reviennent le plus # Jean Véronis - aparté 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! # # À vous maintenant Résultat de l'atelier: https://github.com/E2L/cours-python/blob/master/sources/06-top-words.py À vous de corriger les bugs et de m'envoyer vos solutions par mail (d.merej@gmail.com)