\documentclass{beamer} \usepackage[utf8]{inputenc} \usepackage{hyperref} \usepackage{listings} \lstset{language=Python, showstringspaces=false} \usetheme{Madrid} \hypersetup{colorlinks=true} \title{Introduction à la programmation avec Python \\ (chapitre 2)} \author{Dimitri Merejkowsky} \institute{E2L} \begin{document} \frame{\titlepage} \begin{frame} \frametitle{Plan} \begin{itemize} \item Retours sur le chapitre 1 \item Fonctions \item Structures de données \end{itemize} \end{frame} \begin{frame}[fragile] \centering \begin{beamercolorbox}[sep=8pt,center,shadow=true,rounded=true]{title} Retours sur le chapitre 1 \end{beamercolorbox} \end{frame} \begin{frame}[fragile] \frametitle{Combiner assignation et opérations} \begin{lstlisting} >>> a = 3 >>> a = a + 1 3 \end{lstlisting} Même résultat que: \begin{lstlisting} >>> a = 3 >>> a += 1 \end{lstlisting} \vfill Marche aussi avec \texttt{-=}, \texttt{*=} etc. \end{frame} \begin{frame}[fragile] \frametitle{Retour sur les strings} \texttt{\textbackslash n} sert à échapper les retours à la ligne: \begin{lstlisting} >>> text = "Je suis un message\nSur deux lignes") >>> print(text) Je suis un message Sur deux lignes \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Concaténation implicite} Pas besoin de `+` pour concaténer des "littéraux". \begin{lstlisting} >>> text = "Je suis une " "longue" " string" >>> text 'Je suis une longue string' \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Répéter une string} \begin{lstlisting} >>> "argh " * 3 argh argh argh \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Faire une longue string sur plusieurs lignes} \begin{lstlisting} poeme = """ Ceci est un poeme Qui contient "des quotes" Et parle d'autre choses ... """ \end{lstlisting} \begin{block}{Note} Marche aussi avec des "triples-simple-quotes", mais c'est moins lisible :P \end{block} \end{frame} \begin{frame}[fragile] \frametitle{Opérations sur les strings (1)} \begin{lstlisting} >>> text = " bonjour! \n " >>> text.strip() "bonjour!" \end{lstlisting} Nouvelle syntaxe: notez le '.' entre la variable et la "fonction". \end{frame} \begin{frame}[fragile] \frametitle{Opérations sur les strings (2)} Modification de la casse: \begin{lstlisting} >>> text = "Hello" >>> text.upper() "HELLO" >>> text = "Au Revoir" >>> text.lower() "au revoir" >>> text = "ceci est un titre" >>> text.title() "Ceci est un titre" \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Retour sur input()} On peut afficher un message avant de lire l'entrée utilisateur. \begin{lstlisting} # A adapter import random secret = random.randint() print("Devine le nombre auquel je pense") while True: reponse = input("Ta reponse: ") response = int(response) ... \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Retour sur print()} On peut spécifier le caractère de fin. \textbackslash n par défaut. \begin{lstlisting} # Dans hello.py print("Bonjour", end=" ") print("monde", end="!\n") \end{lstlisting} \begin{lstlisting} $ python hello.py Bonjour monde! \end{lstlisting} \end{frame} \begin{frame}[fragile] \begin{beamercolorbox}[sep=8pt,center,shadow=true,rounded=true]{title} Fonctions \end{beamercolorbox} \end{frame} \begin{frame}[fragile] \frametitle{Sans arguments} \begin{lstlisting} def say_hello(): print("Hello") say_hello() \end{lstlisting} \vfill Notez l'utilisation des parenthèses pour \emph{appeler} la fonction \end{frame} \begin{frame}[fragile] \frametitle{Définition simple} \begin{lstlisting} def add(a, b): return a + b nombre_1 = 1 nombre_2 = 2 total = add(nombre_1, nombre_2) print(total) \end{lstlisting} \vfill Affiche \texttt{3}. \end{frame} \begin{frame}[fragile] \frametitle{Paramètres nommés} \begin{lstlisting} def greet(name, shout=False): result = "Hello, " result += name if shout: result += "!" return result >>> greet("John") 'Hello, John' >>> greet("John", shout=False) # meme resultat 'Hello, John' >>> greet("Jane", shout=True) 'Hello, Jane!' \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Note} \texttt{print()} est une fonction :) \vfill On dit qu'elle est "built-in", ou "native" en Français, parce que vous n'avez pas eu à l'implémenter. \end{frame} \begin{frame}[fragile] \begin{beamercolorbox}[sep=8pt,center,shadow=true,rounded=true]{title} Structures de données \end{beamercolorbox} \end{frame} \begin{frame}[fragile] \frametitle{Créer une liste} \begin{lstlisting} >>> ma_liste = list() # liste vide >>> ma_liste = [] # aussi une liste vide >>> ma_liste = [1, 2, 3] # trois entiers \end{lstlisting} \vfill \begin{alertblock}{Note} \texttt{list()} est \textbf{aussi} une fonction :) \end{alertblock} \end{frame} \begin{frame}[fragile] \frametitle{Listes hétérogènes} On peut mettre des types différents dans une même liste: \begin{lstlisting} >>> pommes_et_carottes = [True, 2, "trois"] \end{lstlisting} \vfill Et même des listes dans des listes: \begin{lstlisting} >>> liste_de_liste = [[1, 2], ["un", "deux"]] \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Connaître la taille d'une liste} Avec la fonction \texttt{len()} (encore un built-in). \vfill \begin{lstlisting} >>> liste_vide = [] >>> len(liste_vide) 0 >>> autre_liste = [1, 2, 3] >>> len(autre_liste) 3 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Indexer une liste} \begin{lstlisting} >>> liste = [1, 2, 3] >>> liste[0] # ca commence a zero 1 >>> liste[4] IndexError \end{lstlisting} \vfill Astuce: l'index maximal est \texttt{len(list) -1} ;) \end{frame} \begin{frame}[fragile] \frametitle{Modifer une liste} \begin{lstlisting} >>> liste = [1, 2, 3] >>> liste[1] = 4 >>> liste [1, 4, 3] \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Itérer sur les éléments d'une liste} \begin{lstlisting} names = ["Alice", "Bob", "Charlie"] for name in names: print("Bonjour", name) Bonjour Alice Bonjour Bob Bonjour Charlie \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Test de présence} Avec le mot-clé \texttt{in}: \vfill \begin{lstlisting} >>> fruits = ["pomme", "banane"] >>> "pomme" in fruits True >>> "orange" in fruits False \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Ça marche aussi avec les strings} Les strings sont \emph{presque} des liste de lettres: \begin{lstlisting} for letter in "vache": print(letter) v a c h e \end{lstlisting} \begin{lstlisting} >>> "v" in "vache" True >>> 'x' in "vache" False \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Ajout d'un élément} Avec \texttt{append()} \begin{lstlisting} >>> fruits.append("poire") >>> fruits ['pomme', 'banane', 'poire'] \end{lstlisting} \vfill Notez le point entre `fruits` et `append` \end{frame} \begin{frame}[fragile] \frametitle{Autres opérations} \begin{lstlisting} >>> fruits = ["pomme", "poire"] >>> fruits.insert(1, "abricot") # ['pomme', 'abricot', 'poire'] >>> fruits.remove("pomme") # ['abricot', 'poire'] >>> fruits.remove("pas un fruit") Erreur! \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Découper une string en liste (1)} \begin{lstlisting} >>> path = "documents/e2l/foo.py" >>> message.split("/") ["documents", "e2l", "foo"] \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Découper une string en liste (2)} \begin{lstlisting} >>> texte = """"\ ligne1 ligne2 ligne3 """ >>>texte.splitlines() ["ligne1", "ligne2", "ligne3"] \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Dictionnaires} Des clés et des valeurs: \begin{lstlisting} >>> mon_dico = dict() # dictionaire vide >>> mon_dico = {} # aussi un dictionnaire vide # deux cles et deux valeurs: >>> scores = {"john": 24, "jane": 23} >>> scores.keys() ["john", "jane" >>> mon_dico.values() [24, 23] \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Accès} \begin{lstlisting} >>> scores = {"john": 10 } >>> scores["john"] 10 >>> scores["personne"] KeyError \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Modification} \begin{lstlisting} >>> scores["john"] = 12 # John marque deux points >>> scores["bob"] = 3 # Bob entre dans la partie >>> scores {"john": 12, "bob": 3} \end{lstlisting} \vfill Même code pour mettre à jour une clé et en créer une! \end{frame} \begin{frame}[fragile] \frametitle{Destruction} \begin{lstlisting} >>> scores = {"john": 12, "bob": 23} >>> scores.pop("john") # {"bob': 23} >>> scores.pop("personne") KeyError \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Ensembles} Des objets sans ordre ni doublons. Création avec la fonction \texttt{set()}: \begin{lstlisting} >>> sac = set() >>> sac = {} # oups, c'est un dictionnaire vide! >>> sac = {"un", "deux"} # un ensemble de deux strings >>> len(sac) # les ensembles ont une taille >>> 2 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Ajout d'un élement dans un ensemble} \begin{lstlisting} >>> sac = {"un", "deux"} >>> sac.add("trois"} # {"un", "deux", "trois"} >>> sac.add("un") # {"un", "deux", "trois"} # pas de changement \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Autres opérations} \begin{lstlisting} >>> s1 = {"un", "deux"} >>> s2 = {"deux", "trois"} >>> s2.intersection(s1) # {"deux"} \end{lstlisting} Aussi: \begin{itemize} \item \texttt{update()} \item \texttt{union()} \item \texttt{difference()} \end{itemize} \end{frame} \begin{frame}[fragile] \begin{beamercolorbox}[sep=8pt,center,shadow=true,rounded=true]{title} Jeu du pendu \end{beamercolorbox} \end{frame} \begin{frame}[fragile] \frametitle{Avant de commencer à coder} Coder sans réfléchir nuit à la qualité du code. \vfill Prenons le temps de la réflexion! \end{frame} \begin{frame}[fragile] \frametitle{Squelette} \begin{itemize} \item Lire les mots possibles depuis un fichier texte \item Choisir un mot au hasard \item Afficher un indice ("hint") \item Démarrer une boucle \begin{itemize} \item Demander une lettre \item Afficher l'indice mis à jour \item Vérfier si le jeu est fini \item Repartir au début de la boucle \end{itemize} \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Une liste de mots Français} À télecharger ici: \url{https://github.com/E2L/cours-python/blob/master/sources/pendu.txt}. \end{frame} \begin{frame}[fragile] \frametitle{Une fonction par tâche} \begin{itemize} \item \texttt{read\_words()} \item \texttt{choose\_word()} \item \texttt{display\_hint()} \item \texttt{has\_won()} \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Structure de données} \begin{itemize} \item Une liste pour les mots dans le fichier \item Un ensemble pour les bonnes lettre devinées \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{C'est parti!} Le moment est venu d'écrire le code. Les sources sont sur GitHub: \url{https://github.com/E2L/cours-python}. \\~\\ Mais il vaut mieux recopier le code vous-mêmes. \end{frame} \begin{frame}[fragile] \frametitle{Implémentation: lire un fichier} \begin{itemize} \item \texttt{open()} renvoie un "objet fichier" \item \texttt{file.read()} lit le fichier \textbf{en entier} et retourne une string \item \texttt{file.close()} ferme le fichier \end{itemize} \begin{alertblock}{Note} N'oubliez pas de fermer tous les fichiers que vous ouvrez! \end{alertblock} \end{frame} \begin{frame}[fragile] \frametitle{Implémentation: lire un fichier} \begin{lstlisting} def read_words(): file = open("pendu.txt") contents = file.read() file.close() words = contents.splitlines() return words \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Choisir un mot au hasard dans la liste} \begin{lstlisting} import random # remember me? def choose_word(words): n = len(words) index = random.randint(0, n-1) return words[index] \end{lstlisting} Rappel: les index commencent à zéro et se terminent à \texttt{len - 1}. \end{frame} \begin{frame}[fragile] \frametitle{Afficher les lettres devinées} \begin{lstlisting} def display_hint(word, letters): for letter in word: if letter in letters: print(letter, end="") else: print("_", end="") print("") \end{lstlisting} \begin{lstlisting} >>> display_hint("vache", {"a"}) _a___ >>> display_hint("vache", {"a", "c"}) _ac__ \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Find de partie} Le joueur a gagné si toutes les lettres ont été devinées: \vfill \begin{lstlisting} def has_won(word, letters): for letter in word: if letter not in letters: return False return True \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Boucle principale} \begin{lstlisting} words = read_words() word = choose_word(words) letters = set() display_hint(word, letters) while True: new_letter = input() letters.add(new_letter) display_hint(word, letters) if has_won(word, letters): print("OK") break # interrompt la boucle parente \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Une tradition} Traditionnellement, on appelle ce genre de fonction \texttt{main()}: \begin{lstlisting} def main(): words = read_words() word = choose_word(words) ... if has_won(words, letters): print("Ok") return # sort de la fonction tout de suite main() # ne pas oublier de l'appeler! \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Pour la prochaine fois} Notez que le joueur \textbf{ne peut pas perdre}. \vfill Si vous le souhaitez, essayer d'adapter le code pour limiter le nombre d'essais: \begin{itemize} \item Afficher le nombre d'essais restant à chaque coup \item Afficher la réponse et un message d'erreur si le jouer a dépassé le nombre maximum d'essais. \end{itemize} Envoyez-moi vos solutions à d.merej@gmail.com! \end{frame} \end{document}