== Première partie
=================================================================

1.
Jouez avec les expressions Python en ipython3.

2.
Définissez une variable n, en lui donnant une valeur entière.
En utilisant n (mais sans faire des hypothèses sur sa valeur),
assignez à la variable p:
  - la valeur vraie si n est paire ;
  - la valeur fausse si n est impaire.
Enfin (pour tester), affichez la valeur de la variable p.
« p » signifie « parité ».

3.
Définissez une variable n, en lui donnant une valeur entière.
En utilisant n (mais sans faire des hypothèses sur sa valeur),
assignez à la variable a la valeur absolue de n.
Enfin (pour tester), affichez la valeur de la variable a.
« a » signifie « absolue ».

4.
Définissez deux variables a et b, en leur donnant des valeurs
entières.
En utilisant a et b (mais sans faire des hypothèses sur leur
valeurs), assignez à la variable m la moyenne arithmétique
entre a et b.
Enfin (pour tester), affichez la valeur de la variable m.
« m » signifie « moyenne ».
Testez en utilisant ces valeurs, respectivement, pour a et
b : 10, 20 ;
    10, 11.

5.
Définissez deux variables a et b, en leur donnant des valeurs
flottantes.
Calculer le minimum entre a et b, et stockez-le dans une
variable m.  Affichez la valeur de m.  «m» signifie
«minimum».

6.
Écrivez un programme qui demande le prénom de l'utilisateur,
et puis le salue en répétant le prénom.

7.
Écrivez un programme qui demande le prénom de l'utilisateur,
et puis le salue en répétant le prénom juste si le prénom est
exactement « Alice » ou « Bob ».

8.
Modifiez la version jolie de la solution de l'exercice 7
pour écrire correctement « amie » à la place de « ami »
quand le prénom est « Alice ».
Suggestion : utilisez une variable « suffixe » contenant
soit la chaîne vide "", soit la chaîne "e".

9. Tortue : généralisez mon code dessinant un hexagone
   pour dessiner un polygone de n côtés.  n est une
   variable entière.

10. Tortue : dessinnez une spirale carrée.
    La taille peut être infinie, ou limitée par un
    nombre fixe de côtés.


== Partie B
===========================================================

[rappels : boucle while
           boucle for, juste dans le cas déjà montré dans les slides.
           Développement interactif.  Passer d'un programme correct à l'autre.
]

B.-2. Étant donné un prix sans rabais est un rabais en percentage (une réduction entre 0%
      et 100%), calculez et affichez le prix final à payer.
      le prix initial, le rabais et le prix final sont à stocker en trois variables.  Les
      deux premières sont constantes, ou obtenues par input ().

B.-1. Calculez la factorielle d'un nombre entier stocké
      dans une variable n.  Le résultat est à stocker
      dans une variable f.  Affichez la valeur de f.
      Exemples (en notation mathématique) :
        0!                  = 1   (par définition)
        1!                  = 1
        2!  = 2 * 1         = 2
        3!  = 3 * 2 * 1     = 6
        4!  = 4 * 3 * 2 * 1 = 24
        10! = ...           = 3628800

B.0. Affichier tout nombre naturel, en ordre, un par ligne.  Le programme ne termine jamais.
     Les nombres naturels sont 0, 1, 2, 3, ...

B.1. Affichier 3 astérisques dans des lignes séparées, comme ça, en utilisant une boucle for :
*
*
*

B.2. Affichier 3 astérisques dans des lignes séparées, comme ça, en utilisant une boucle while :
*
*
*

B.3. Affichier ces lignes d'astérisques en utilisant une boucle for et la multiplication
     entre une chaîne de caractères et un nombre :
*
**
***

B.4. Affichier ces lignes d'astérisques en utilisant une boucle for, la
     multiplication entre une chaîne de caractères et un nombre, et la somme
     entre chaînes de caractères.
     Suggestion : on a combien d'espaces et combien d'astérisques dans chaque
     ligne ?  Dans la ligne i-ème en général ?
  *
 **
***

B.5. Généralisez B.3 : soit n une variable contenant un entier naturel.
     Affichiez un triangle avec hauteur n.


B.6. Soit n une variable contenant un nombre entier.
     Calculez un booléen et stockez-le dans une variable p : p sera
     vraie si et seulement si la valeur de n est un nombre premier.
     Affichiez la valeur de p.


== Partie C [autres exercices élémentaires]
===========================================================

C.-2. Étant donné la durée d'un film en heures, minutes et
      secondes, affichiez la même durée en secondes.

C.-1. Quand le mathématicien Carl F. Gauss était à l'école
      son enseignant, pour faire travailler les enfants sans
      être dérangé, leur demanda de sommer tout nombre naturel
      entre 1 et 100, compris.
      Gauss trouva la réponse correcte immédiatement, sans
      calculer la somme, en généralisant le problème.
      Calculez la somme comme les petits copains de Gauss.
      [Si vous connaissez la solution intelligente aussi
       calculez la même somme de la façon intelligente, et
       vérifiez que les deux solutions soient identiques]

C.0.  Écrivez un programme demandant à l'utilisateur d'écrire
      « bonjour ».  Le programme continue à demander jusqu'à
      quand l'utilisateur n'écrit exactement « bonjour ».

C.1.  Votre programme stockera dans une variable un nombre
      secret.  Il peut être en réalité une constante choisie
      par vous, ou un nombre aléatoire si vous savez le faire.
      Le programme demande à l'utilisateur de deviner le nombre
      secret, et termine juste quand l'utilisateur a deviné
      correctement.  Le programme demandera encore de deviner
      jusqu'à la réception de la réponse correcte.

C.2.  Une variante de C.1, où après chaque tentative incorrecte
      le programme dit à l'utilisateur si sa dernière entrée
      est majeure ou mineur par rapport à la solution.


== Partie E (à faire avant la partie D)
===========================================================

****************************************************************
Note importante :
  Dorénavant toute fonctionnalité doit être implémentée dans une
  fonction, renvoyant un résultat si l'énoncé ne demande pas
  explicitement d'afficher quelque chose sans calculer rien d'autre.
  « Étant donné » est à interpréter comme la description d'un
  *paramètre* de la fonction.  Bien sûr vous devrez appeler votre
  fonction pour la tester.
  « Calculer », « construire » ou « déterminer », avec une fonction,
  signifie normalement renvoyer un résultat (sinon, ce signifie
  calculer des données auxiliaires utiles à calculer un résultat à
  renvoyer).
  « Déterminer si », avec une fonction, signifie renvoyer un résultat
  booléen.

  Une fonction debuggée ne doit *rien* afficher, si non demandé
  explicitement : on utilise return pour communiquer un résultat
  à l'appeleur qui l'utilisera.  On ne peut certainement pas utiliser
  print à sa place.  Violer cette règle dans un contrôle ou projet
  est une bonne façon de *perdre de points*.
****************************************************************

E.1.  Étant donnée une liste, renvoyez la somme de ses éléments.
      Votre fonction doit marcher (sur un argument de type liste)
      comme la fonction prédéfinie « sum », bien sûr sans utiliser
      sum à l'intérieur.
      Suggestion : la solution la plus simple a un corps de exactement
                   quatre lignes.


Dorénavant vous pouvez définir toute fonction de cette partie dans le même
fichier.  Certaines fonctions peuvent être utiles comme fonctions auxiliaires
pour les fonctions décrites plus en bas.


E.2.  Étant donnée une liste et un objet arbitraire, renvoyez une copie
      da la liste sans la première occurrence de l'objet arbitraire dans
      la liste avec tout autre élément dans l'ordre original, ou juste
      une copie de la liste si l'objet donné n'est pas dans la liste
      donnée.  La liste donnée ne doit pas être modifiée.
      Votre fonction s'appellera « sans ».
      Exemples :
        sans ([10, 20, 30], 20)
          ==>
          [10, 30]
        sans ([10, 20, 30, 20], 20)
          ==>
          [10, 30, 20]
        sans ([10, 20, 30, 20], 50)
          ==>
          [10, 20, 30, 20]
        sans ([10, 20, 30, 20], 50)
          ==>
          [10, 20, 30, 20]

E.3.  Étant donnée une liste non vide de nombres, renvoyez son plus petit
      élément.  Votre fonction s'appellera « le_plus_petit_de ».
      Exemple :
        le_plus_petit_de ([20, 10, -1, 7])
          ==>
          -1

E.4.  Étant donnée une liste de nombres, qui peut aussi être vide, renvoyez
      une copie de la liste triée.  Votre fonction s'appelera « triee ».
      Exemples :
        triee ([20, 10, -1, 14, 10]
          ==>
          [-1, 10, 10, 14, 20]
     Suggestion : la fonction « triee » peut utiliser les fonctions définies
                  plus en haut dans cette partie.


== Partie D (à faire après la partie E)
===========================================================

D.-1. Affichiez une table de multiplication similaire à la suivante (sans « ... »),
      jusqu'à une limite donnée comme paramètre.
      1 * 0 = 0
      1 * 1 = 1
      1 * 2 = 2
      1 * 3 = 3
      ...
      1 * 10 = 10
      2 * 0 = 0
      2 * 1 = 2
      2 * 2 = 4
      2 * 3 = 6
      ...
      2 * 10 = 20
      3 * 0 = 0
      3 * 1 = 3
      3 * 2 = 6
      ...
      9 * 10 = 90

D.0.  Étant donnée un mois de l'année en tant que nombre de 1 à 12, déterminez
      le nombre de jours dans le mois.  Le résultat sera 28, 30 ou 31.
      Ignorez les ans bissextiles.
      Suggestion : utilisez une liste (constante) dans une variable temporaire.

D.1.  Étant donnée une chaîne de caractères, déterminez si la chaîne
      est palindrome.  Le résultat sera un booléen.
      (https://fr.wikipedia.org/wiki/Palindrome )

D.2.  (optionnel, beaucoup plus difficile).
      Une variante de D.1. où vous ignorez les espaces, la différence
      entre minuscules et majuscules, et la ponctuation.  La chaîne
      "A man, a plan, a canal: Panama!" sera reconnue comme palindrome.

D.3.  Étant donnée une liste et un élément, déterminez si la liste contient
      l'élément.

D.4.  Étant donnée une liste, déterminez si la liste contient des éléments
      dupliqués.

D.5.  Étant donnée une liste, construisez une autre liste qui est une copie
      de la liste donnée dans le même ordre, mais sans éléments dupliqués.
      Par exemple, si votre fonction reçoit [1, 2, 1, 3, 2, -1, 4] elle
      doit renvoyer [1, 2, 3, -1, 4].

D.6.  Étant donnée une liste, construisez un dictionnaire associant à chaque
      élément de la liste sa fréquence d'occurrence.  Les fréquences seront
      des nombres flottantes entre 0 et 1.
      Par exemple si votre fonction reçoit ['foo', 'bar', 'foo', 'foo']
      elle donnera {'foo': 0.75, 'bar': 0.25}.


== Partie F
===========================================================

À réaliser dans un seul fichier, le même pour toute question.

[erreur corrigée : les questions de la partie F étaient étiquetées par
 « E.n. » au lieu de « F.n. »]

F.0. Gardez un dictionnaire associant des noms de couleurs en français
     à leur traduction en anglais
       [erreur corrigée : j'avais écrit « français » à la place
        de « anglais » ici]
     , dans une variable globale.
     Écrivez une fonction acceptant un mot en français et renvoyant
     sa traduction en anglais.
     Exemple :
       du_francais_a_langlais ('rouge')
         ==>
         'red'

F.1. Étant donné un dictionnaire, renvoyez une copie du dictionnaire
     inversé : dans le dictionnaire inversé ce qui était une clé dans
     le dictionnaire original devient une valeur associée, et ce qui
     était une valeur associée devient une clé.
     Exemple :
       dictionnaire_inverse ({1: 'un', 3: 'trois', 10: 'dix'})
         ==>
         {'un': 1, 'trois': 3, 'dix': 10}

F.2. Définissez une autre fonction similaire à cela de F.1, mais
     traduisant dans l'autre sens, *sans* ajouter des variable globales.
     Utilisez la fonction de la question F.1. dans votre nouvelle
     fonction.
     Exemple :
       de_langlais_au_francais ('green')
         ==>
         'vert'

F.3. Donnez une nouvelle solution à la question D.0, en utilisant
     un dictionnaire à la place d'une liste.


== Exercices pour ces qui ont déjà programmé
===========================================================

* Écrivez une fonction « trim » qui, étant donné une chaîne de caractères,
  renvoie une copie de la chaîne sans les espaces initiaux et finaux.
  Par exemple trim ('  abc ') donnera 'abc' comme résultat.
  Suggestions : Les chaînes de caractères en Python sont immutables, mais
                vous pouvez construire des nouvelles chaînes en utilisant
                l'opérateur +.
                Commencez en éliminant juste les espaces à gauche, puis
                occupez-vous de la partie à droite aussi.

* Calculez les nombres premiers jusqu'à une limite donnée en utilisant le
  crible d'Ératosthène :
  https://fr.wikipedia.org/wiki/Crible_d%27%C3%89ratosth%C3%A8ne
  Suggéstion : utilisez une liste Python contenant des booléens.  On peut
               l'initialiser en utilisant cette idée :
               le résultat de [False] * 3 est [False, False, False].


== Exercices avancés pour les bons programmeurs
===========================================================

* Étudiez les fonctions anonymes (« lambda ») en Python, individuellement
  (appelez-moi si vous avez des questions).

* Écrivez une fonction, qui, étant donné un nombre a, renvoie une fonction ;
  la fonction renvoyée acceptera un nombre x et donnera comme résultat x + a.

* Écrivez une fonction, qui, étant donné une autre fonction, renvoie sa dérivée
  (elle-même une fonction).  Suggestion : utilisez la définition de dérivée
  comme limite, en utilisant un intervalle de petite taille comme approximation
  de la limite.
  Par exemple :
import math

# ... Définition de derivee, à écrire ...

import math  # Si vous ne comprenez pas encore cette ligne, acceptez-la comme « magique ».
mycos = derivee (math.sin)
mycos (0)  # Résultat : une approximation de math.cos (0), c'est à dire 1.0
  Le corps de derivee peut être écrit en une seule ligne.

* Même chose mais cette fois, au lieu de la dérivée, calculez une approximation
  de l'intégrale définie d'une fonction donnée, dans un intervalle donné.
  Utilisez la méthode des rectangles :
  https://fr.wikipedia.org/wiki/Int%C3%A9gration_(math%C3%A9matiques)#Calcul_num%C3%A9rique_d'une_int%C3%A9grale
  Suggestion : testez en utilisant des fonctions ayant une intégrale
  « facile », ou bien connue dans l'intervalle que vous utilisez.


== Exercices supplémantaires
===========================================================

Débutants :
  http://www.practicepython.org/
  https://snakify.org/en/lessons/print_input_numbers/
  https://codeclubprojects.org/en-GB/python/rock-paper-scissors/
Débutants (style partiel, très (trop) peu de programmation) :
  https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-189-a-gentle-introduction-to-programming-using-python-january-iap-2011/assignments/MIT6_189IAP11_hw1_written.pdf

Plus avancés (je n'ai pas encore présenté tout ce qui est nécessaire ici) :
  http://wasabiapp.org/python_course/exercises_4.pdf

Niveau variable :
  https://www.quora.com/Where-can-I-find-basic-python-practice-problems

Local Variables: eval: (ispell-change-dictionary "francais") eval: (flyspell-mode t) End: