\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{Modifier 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}
