diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..8696372
Binary files /dev/null and b/.DS_Store differ
diff --git a/0 - Installation Python.pptx b/0 - Installation Python.pptx
new file mode 100644
index 0000000..4ca68b7
Binary files /dev/null and b/0 - Installation Python.pptx differ
diff --git a/1-introduction.ipynb b/1-introduction.ipynb
new file mode 100644
index 0000000..4c7381d
--- /dev/null
+++ b/1-introduction.ipynb
@@ -0,0 +1,357 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Introduction à Python"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Créer et lancer des programmes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il existe de deux types de fichier pour créer des programmes en python:\n",
+ "- **Les fichiers scripts .py** : Ils sont légers et on peut facilement importer le contenu d'un script dans un autre script, on s'en servirra quand on développera des programes complexes qu'on voudra diviser en plusieurs fichiers comme par exemple des applications web\n",
+ "- **Les notebooks .ipynb** (comme ce fichier): ils permettent d'afficher directement le code utilisé, d'ajouter des commentaires complexes (titres, images, liens...). Ils sont très utilisés quand on veut explorer une base de données ou quand on veut expliquer quelque chose en intégrant du code. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Les fichiers scripts"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il suffit de créer un nouveau fichier, de lui donner un nom et d'ajouter .py à la fin (appelons le hello.py)\n",
+ "\n",
+ "On va pouvoir écrire notre premier programme à l'intérieur. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Hello World\n",
+ "This is my first python program\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"Hello World\")\n",
+ "\n",
+ "print(\"This is my first python program\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On décomposera plus tard ce code, on va se contenter de le lancer en appuyant sur la flèche.\n",
+ "Cela lance un terminal (ou une console) où on voit apparaitre ce qu'on voulait voir apparaitre.\n",
+ "\n",
+ "On a également souvent l'habitude de lancer le code directement depuis le terminal à l'aide de la commande suivante:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\"python3 hello.py\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Les notebooks"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Lancer un programme"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Faisons la même chose avec un notebook.\n",
+ "\n",
+ "Créons un fichier appelé hello.ipynb\n",
+ "\n",
+ "Un notebook est divisé en cellules. Les cellules peuvent être lancées individuellement mais partagent le même environnement (on verra plus tard quand on parlera des variables par exemple que si on déclare une variable dans une cellule, on peut y accéder dans les autres cellules)\n",
+ "\n",
+ "Dans la première cellule on peut écrire print(\"Hello World\")\n",
+ "\n",
+ "On va écrire le même programme et le lancer à l'aide de la flèche qui se trouve en haut à gauche de la cellule (print(Hello Word))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Hello World\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"Hello World\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Ceci est une cellule **markdown** :\n",
+ "- ceci est un puce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On peut également la lancer avec le raccourci CTRL + Entrer ou Shift + Enter. Les raccourcis sont très utilisés dans les notebooks ( [voir liste des raccourcis](https://towardsdatascience.com/jypyter-notebook-shortcuts-bf0101a98330))\n",
+ "\n",
+ "Pour bien les maitriser il faut comprendre la différence entre:\n",
+ "- **Le mode \"edit\"** : où on va écrire du code et le lancer (Quand on est sur une cellule, il faut appuyer sur entrer pour passer en mode \"edit\", c'est la même chose que de cliquer dans une cellule)\n",
+ "- **Le mode \"action\"** (ou commande): permet de gérer les cellules (Quand on est dans une cellule, appuyer sur echap pour passer en mode action)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Les raccourcis"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les raccourcis les plus utiles à mon gout:\n",
+ "- Les deux modes confondus:\n",
+ " - Ctrl + Enter: lance la ou les cellules selectionnées\n",
+ " - Ctrl + S: enregistre \n",
+ " - Ctrl + F: permet de faire une recherche\n",
+ "- En mode \"Edit\":\n",
+ " - Esc: passe en mode action\n",
+ " - Ctrl + A: sélectionne toute la cellule\n",
+ " - Ctrl + Z: supprime ce qu'on vient de faire\n",
+ " - Ctrl + shift + Z: remet ce qu'on vient de supprimer \n",
+ "- En mode \"Action\":\n",
+ " - Enter: passe en mode Edit\n",
+ " - A: insert une cellule au dessus\n",
+ " - B: insert une cellule en dessous\n",
+ " - X: coupe une cellule (qu'on peut utiliser aussi pour la supprimer sinon deux fois D)\n",
+ " - C: copie une cellule \n",
+ " - V: colle une cellule\n",
+ " - Y: transforme une cellule Markdown en cellule Code \n",
+ " - M: transforme une cellule Code en cellule Markdown\n",
+ "\n",
+ "Il existe en effet deux types de cellule:\n",
+ "- Les cellules Code: pour écrire et lancer du code\n",
+ "- Les cellules Markdown: pour écrire des commentaires, des titres, ajouter des liens ou des images\n",
+ "\n",
+ "`Exercice (Utiliser les raccourcis)`: \n",
+ "- Créer une cellule en dessous\n",
+ "- Ecrivez print(\"This is my first python program\")\n",
+ "- Transformer cette cellule en Markdown puis de nouveau en code puis exécutez la (lancez la)\n",
+ "- Créer une cellule Markdown puis ajouter le commentaire \"Dans un notebook, les cellules se lancent indépendamment\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Les markdowns en détails"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On peut créer différentes choses:\n",
+ "- des puces\n",
+ "- par exemple\n",
+ " - et des sous-puces naturellement\n",
+ "\n",
+ "Mettre des choses en `évidence` ou en **gras**, voire *en italique* \n",
+ "\n",
+ "Créer des liens: [le lien](https://en.wikipedia.org/wiki/Python_(programming_language))\n",
+ "\n",
+ " Changer de couleur en s'inspirant de HTML \n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Et insérer des images\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Découvrir les commentaires"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Nous avons vu que les markdowns permettaient de créer des commentaires, cependant ils ne sont pas accessibles dans les fichiers scripts et parfois on veut commenter différemment."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Nous sommes bien ici dans une cellule de code\n",
+ "Les commentaires ne s'affichent pas quand on lance le code\n"
+ ]
+ }
+ ],
+ "source": [
+ "# commentaire\n",
+ "# ligne\n",
+ "# à ligne\n",
+ "\n",
+ "print(\"Nous sommes bien ici dans une cellule de code\") # un commentaire ligne à ligne peut se mettre ici\n",
+ "\n",
+ "\"\"\" Commentaire \n",
+ "\n",
+ "\n",
+ "\n",
+ "multi ligne\"\"\"\n",
+ "\n",
+ "print(\"Les commentaires ne s'affichent pas quand on lance le code\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Autre différence entre ces deux types de commentaires\n",
+ "- Les commentaires ligne à ligne ne sont pas lus par python, il faut donc les utiliser en général.\n",
+ "- Les commentaires multi ligne sont lus par python mais pas affichés sauf dans certaines foncitons. On s'en sert généralement pour décrire une fonction, une classe ou un package"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on function f in module __main__:\n",
+ "\n",
+ "f(x)\n",
+ " cette fonction ajoute 1 à x\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "def f(x):\n",
+ " \"\"\" cette fonction ajoute 1 à x\"\"\"\n",
+ " # tu le savais ?\n",
+ " if True:\n",
+ " print(True)\n",
+ " return x +1\n",
+ "\n",
+ "help(f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Enfin, on utilise souvent un raccourci qui permet de commenter ligne à ligne plusieurs lignes en même temps: \n",
+ "Ctrl + SHIFT + / ou Ctrl + shift (sur les lignes selectionnées)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**: \n",
+ "- copier coller les règles de la pep 8 dans votre fichier script en tant que commentaire multiligne et ligne à ligne (essayez les raccourcis et relancer le script)\n",
+ "- copier coller les règles de la pep 8 dans une cellule code, faite le même exercice que précédemment puis copier coller dans un cellule markdown et faire une mise en page correcte"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Règles Pep8:\n",
+ "\n",
+ "Pep 8 sur les commentaires.\n",
+ "Ecrivez des phrases complètes, ponctuées et compréhensibles.\n",
+ "Le commentaire doit être cohérent avec le code.\n",
+ "Il doit suivre la même indentation que le code qu'il commente.\n",
+ "Evitez d'enfoncer des portes ouvertes : ne décrivez pas le code, expliquez plutôt à quoi il sert.\n",
+ "Il doit être en anglais."
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "4822798685b95d90cac6b9eac85a216cd3011e561666c6311e8088bbadca8e0f"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.8.6 64-bit ('3.8.6': pyenv)",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.12"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2-les-variables.ipynb b/2-les-variables.ipynb
new file mode 100644
index 0000000..cab7bd2
--- /dev/null
+++ b/2-les-variables.ipynb
@@ -0,0 +1,1151 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Les variables et les types de variables"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les variables"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Déclarer une variable"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Jérémy\n"
+ ]
+ }
+ ],
+ "source": [
+ "formateur = \"Jérémy\"\n",
+ "\n",
+ "nombre_apprenants = 12\n",
+ "\n",
+ "print(formateur)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Antoine\n",
+ "Antoine\n",
+ "Antoine\n",
+ "Patrick\n"
+ ]
+ }
+ ],
+ "source": [
+ "# double déclaration\n",
+ "apprenant = eleve = \"Antoine\"\n",
+ "print(eleve)\n",
+ "print(apprenant)\n",
+ "apprenant = \"Patrick\"\n",
+ "print(eleve)\n",
+ "print(apprenant)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les valeurs sont stockées en mémoire à des adresses précises par exemple :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4298080848\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(id(12))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "valeur_12 = 12"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4298080848\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(id(valeur_12))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4298080848\n",
+ "4298080848\n",
+ "4298080880\n",
+ "4298080880\n"
+ ]
+ }
+ ],
+ "source": [
+ "nombre_apprenants = 12\n",
+ "print(id(12))\n",
+ "print(id(nombre_apprenants))\n",
+ "\n",
+ "nombre_apprenants = 13\n",
+ "\n",
+ "print(id(13))\n",
+ "print(id(nombre_apprenants))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Hello World\n",
+ "Hello World 2\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"Hello World\")\n",
+ "print(\"Hello World 2\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "La variable est donc un pointeur vers l'objet en mémoire."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Afficher une variable"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Jérémy\n",
+ "nombre_apprenants: 13\n",
+ "Jérémy a 13 apprenants dans ma formation, dont: Patrick\n",
+ "Jérémy a 13 apprenants dans ma formation, dont: Patrick\n",
+ "formateur='Jérémy'\n"
+ ]
+ }
+ ],
+ "source": [
+ "# affichage d'une variable\n",
+ "print(formateur)\n",
+ "\n",
+ "# affichage de plusieurs éléments \n",
+ "print(\"nombre_apprenants:\", nombre_apprenants)\n",
+ "\n",
+ "# commentaire avec l'attribut format\n",
+ "print( \"{} a {} apprenants dans ma formation, dont: {}\".format(formateur,nombre_apprenants,apprenant))\n",
+ "\n",
+ "# commentaires avec les f-strings\n",
+ "print( f\"{formateur} a {nombre_apprenants} apprenants dans ma formation, dont: {apprenant}\")\n",
+ "\n",
+ "print (f\"{formateur=}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Quand on ajoute des variables dans une chaîne de caractères à l'aide de méthode, on parle de \"string formatting\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Modifier une variable"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "nombre_apprenants: 17\n",
+ "apprenant: Antoine\n",
+ "eleve: Denis\n",
+ "7\n"
+ ]
+ }
+ ],
+ "source": [
+ "apprenant = eleve = \"Antoine\"\n",
+ "eleve = \"Denis\"\n",
+ "\n",
+ "# incrémentation\n",
+ "nombre_apprenants = nombre_apprenants + 2\n",
+ "nombre_apprenants += 2 # on peut également utiliser -= /= *=\n",
+ "\n",
+ "print(\"nombre_apprenants: \", nombre_apprenants)\n",
+ "print(\"apprenant: \", apprenant)\n",
+ "print(\"eleve: \", eleve)\n",
+ "\n",
+ "eleve = 7\n",
+ "print(eleve)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Supprimer une variable"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4298081808\n"
+ ]
+ }
+ ],
+ "source": [
+ "var_to_delete = 42\n",
+ "\n",
+ "print(id(var_to_delete))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "NameError",
+ "evalue": "name 'var_to_delete' is not defined",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32m/Users/jeremyvangansbeg/Documents/project/intro_python/python-course/2-les-variables.ipynb Cell 20\u001b[0m line \u001b[0;36m3\n\u001b[1;32m 1\u001b[0m \u001b[39mdel\u001b[39;00m var_to_delete\n\u001b[0;32m----> 3\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mid\u001b[39m(var_to_delete))\n",
+ "\u001b[0;31mNameError\u001b[0m: name 'var_to_delete' is not defined"
+ ]
+ }
+ ],
+ "source": [
+ "del var_to_delete\n",
+ "\n",
+ "print(id(var_to_delete))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Nommer une variable avec la Pep-8"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "La pep 8 est une convention qui définit les bonnes pratiques pour code en python."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "- Mettez un espace avant et après le signe égal\n",
+ " - apprenant = \"Charles\" et non apprenant=\"Charles\"\n",
+ "- Utilisez des noms descriptifs dans votre code.\n",
+ " - exemple: Au lieu de quantite (ou pire,qte), ajoutez des détails : quantite_en_stock, solde_actuel, etc.\n",
+ "- Utilisez des mots complets.\n",
+ " - exemple,revenu_annuelest plus clair querev_annuel.\n",
+ "- Suivez une convention d’appellation commune.\n",
+ " - le snake case : des noms composés de plusieurs mots séparés par des tirets bas(_)\n",
+ " - exemple nombre_de_chats, reponse_finale , le_meilleur_developpeur_python_du_monde, etc.\n",
+ " - commencez avec une lettre minuscule (surtout pas par un nombre)\n",
+ " - Utilisez uniquement des caractères alphanumériques et des tirets bas... et donc pas d'accents !\n",
+ "- N’oubliez pas que les noms de variables sont sensibles à la casse.\n",
+ " - age, Age et AGE sont trois variables différentes. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il existe d'autres conventions de nommage comme le CamelCase ou le camelCase. La seconde version est utilisée en python qu'on définit des classes."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### S'exercer à manipuler les variables"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**: créez l'état civil de votre voisin \n",
+ "- déclarer les variables nom, prénom et deuxième prénom puis une variable nom complet à l'aide des trois précédentes en les concaténant à l'aide de l'opérateur + \n",
+ "- déclarer les variables année actuelle et année de naissance puis créer la variable âge à l'aide des deux pécédentes en les soustrayant\n",
+ "- remplacer la valeur de la variable nom par celle de nom complet puis supprimer la variable nom complet"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les types primitifs de variable"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "En Python, les variables ne stockent pas directement les valeurs; elles référencent des objets. Tout en Python est un objet, y compris les nombres, les chaînes, les listes, etc. Cependant, la manière dont les variables référencent ces objets diffère en fonction de la mutabilité de l'objet et de la manière dont il est assigné.\n",
+ "\n",
+ "Pour simplifier, on parle parfois de types \"primitifs\" en Python pour désigner les types de données de base comme les entiers, les flottants, les booléens et les chaînes. Bien que le terme \"primitif\" ne soit pas strictement correct en Python (car, comme mentionné, tout est objet), il est parfois utilisé pour faire référence à ces types de base."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " 7\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Les \"integers\", ou nombres entiers en français\n",
+ "nombre_apprentants = 7\n",
+ "print(type(nombre_apprentants),nombre_apprentants)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "En réalité, même ces types \"primitifs\" sont des instances de classes en Python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "25.0\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Les \"floats\", ou nombres à virgule en français\n",
+ "age_moyen_promo = 25.0\n",
+ "print(type(age_moyen_promo), age_moyen_promo)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Jérémy\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Les \"strings\" (str), ou chaines de caractères en français\n",
+ "apprenant = \"Jérémy\"\n",
+ "print(type(apprenant), apprenant)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Les \"Booléens\" (bool), ou booléen en français, c'est à dire vrai ou faux\n",
+ "\n",
+ "est_ce_que_1_plus_1_egale_2 = 1 + 1 == 2\n",
+ "\n",
+ "print(type(est_ce_que_1_plus_1_egale_2),est_ce_que_1_plus_1_egale_2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Attention à ne pas confondre \"=\" qui permet d'assigner une variable et \"==\" qui est un opérateur de comparaison"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les integers et les floats en détail "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Opérations sur les integers et les floats"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "somme=15.5\n",
+ "difference=9.5\n",
+ "produit=37.5\n",
+ "quotient=4.166666666666667\n",
+ "quotient_sans_reste=4.0\n",
+ "reste=0.5\n",
+ "puissance=1953.125\n"
+ ]
+ }
+ ],
+ "source": [
+ "x = 12.5\n",
+ "y = 3\n",
+ "\n",
+ "#la somme de x et y (x plus y).\n",
+ "somme = x + y \n",
+ "print (f\"{somme=}\")\n",
+ "\n",
+ "#la différence entre x et y \n",
+ "difference = x - y \n",
+ "print (f\"{difference=}\")\n",
+ "\n",
+ "#le produit de x et y\n",
+ "produit = x * y \n",
+ "print (f\"{produit=}\")\n",
+ "\n",
+ "# le quotient de x et y (x divisé par y).\n",
+ "quotient = x / y \n",
+ "print (f\"{quotient=}\")\n",
+ "\n",
+ "# le quotient de x et y sans reste.\n",
+ "quotient_sans_reste = x // y \n",
+ "print (f\"{quotient_sans_reste=}\")\n",
+ "\n",
+ "# le reste de x divisé par y.\n",
+ "reste = x % y \n",
+ "print (f\"{reste=}\")\n",
+ "\n",
+ "# x à la puissance y\n",
+ "puissance = x**y\n",
+ "print (f\"{puissance=}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "D'une mannière générale, quand on effectue une opération entre un **float** et un **integer**, le résultat est un float"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "5.0"
+ ]
+ },
+ "execution_count": 36,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "5 / 1.0"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 1`**: Quelle est la valeur prise par z? (de tête)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 13\n",
+ "y = 4"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "z = x == (( x // y ) * y) + (x % y) "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 2`**: Ajoutez des parenthèses à l'expression suivante afin que l'output soit 1."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(5 - 3 // 2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 3`**: Ajoutez des parenthèses à l'expression suivante afin que l'output soit 0."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(8 - 3 * 2 - 1 + 1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 4`**: \n",
+ "Alice, Bob et Carol ont décidé de mettre en commun leurs bonbons d'Halloween et de les partager équitablement entre eux. Pour le bien de leur amitié, les bonbons restants seront écrasés. Par exemple, s'ils ramènent collectivement 91 bonbons à la maison, ils en prendront 30 chacun et en écraseront 1.\n",
+ "\n",
+ "Écrivez une expression arithmétique ci-dessous pour calculer le nombre de bonbons qu'ils doivent écraser pour une quantité donnée."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Variables representing the number of candies collected by alice, bob, and carol\n",
+ "alice_candies = 121\n",
+ "bob_candies = 77\n",
+ "carol_candies = 109\n",
+ "\n",
+ "# Your code goes here! Replace the right-hand side of this assignment with an expression\n",
+ "# involving alice_candies, bob_candies, and carol_candies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### fonctions utiles liées aux integers ou aux float "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10.542321\n",
+ "-10.54\n"
+ ]
+ }
+ ],
+ "source": [
+ "x = -10.542321\n",
+ "\n",
+ "# Valeur absolue de x\n",
+ "print(abs(x))\n",
+ "\n",
+ "# obtenir l'arrondi d'un float\n",
+ "print(round(x,2))\n",
+ "\n",
+ "# Convert an object to integer\n",
+ "s = \"8\"\n",
+ "s_as_an_integer = int(s)\n",
+ "\n",
+ "# Convert an object to float\n",
+ "\n",
+ "s_as_a_float = float(s)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "9"
+ ]
+ },
+ "execution_count": 53,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "int(9.6)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "PLus de méthodes dans la documentation: https://docs.python.org/3/library/stdtypes.html"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les strings en détail"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Les astuces concernant les strings"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il existe une liste de caractères spéciaux dans les chaînes de caractères qu'on peut appeler à l'aide du \\ (backslash). En anglais on parle de \"escape characters\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "J'aime \"le\" Python!\n",
+ "J'aime \"le\" Python! comme dit le poète \"slkdfnsklfdn\" a line \n",
+ " to an another\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Pour utiliser le symbole ` dans une string il faut écrire \\``\t\n",
+ "a_string = \"J'aime \\\"le\\\" Python!\"\n",
+ "print(a_string)\n",
+ "the_same_string = \"comme dit le poète \\\"slkdfnsklfdn\\\"\"\n",
+ "\n",
+ "# Pour sauter une ligne \\n\n",
+ "a_string_with_a_space =\t\"a line \\n to an another\"\n",
+ "\n",
+ "print(a_string, the_same_string, a_string_with_a_space)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Vous trouverez plus d'informations ici sur les escapes characters : \n",
+ "https://www.w3schools.com/python/gloss_python_escape_characters.asp"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Le parcours des chaines de caractères"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 67,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "n\n"
+ ]
+ }
+ ],
+ "source": [
+ "n = -2\n",
+ "the_string = \"string\"\n",
+ "\n",
+ "# Renvoie le n ème élément d'une liste \n",
+ "print(the_string[n]) "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### fonctions utiles"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 68,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "6"
+ ]
+ },
+ "execution_count": 68,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Renvoie le nombre de caractère dans la string\n",
+ "len(the_string)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Les méthodes de la classe str"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 73,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_string = \"Quelle belle journée belle journée\"\n",
+ "\n",
+ "# Mettre tout en minuscule\n",
+ "lower_string = my_string.lower()\n",
+ "\n",
+ "# Mettre tout en majuscule\n",
+ "upper_string = my_string.upper()\n",
+ "\n",
+ "# Mettre une majuscule au début\n",
+ "capitalized_string = my_string.capitalize()\n",
+ "\n",
+ "# Remplacez une expression\n",
+ "replaced_string = my_string.replace(\"journée\", \"soirée\")\n",
+ "\n",
+ "# Cherchez un bout de la chaine\n",
+ "emplacement_de_belle = my_string.find(\"belle\")\n",
+ "\n",
+ "# Compte le nombre de fois ou apparait un caractère\n",
+ "count_string = my_string.count(\"l\")\n",
+ "\n",
+ "# Diviser une chaine de caractères pour créer une liste\n",
+ "splited_string = my_string.split(\" \")\n",
+ "\n",
+ "# Remplace les {} par la valeur définie dans format\n",
+ "my_string = \"Quelle {} et {} journée\".format(\"belle\", \"bonne\")\n",
+ "my_string = \"Quelle {adjectif_1} et {adjectif_2} journée\".format(adjectif_2=\"belle\", adjectif_1=\"bonne\")\n",
+ "belle_var = \"belle\"\n",
+ "bonne_var = \"bonne\"\n",
+ "my_string = \"Quelle {} et {} journée\".format(belle_var, bonne_var)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 71,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "my_string : Quelle bonne et belle journée\n",
+ "Quelle bonne et belle journée\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"my_string :\", my_string)\n",
+ "print(f\"{my_string=}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**: travaillez sur la définition de python \n",
+ "- remplacez python par lovely python partout dans la chaine de caractère suivante en utilisant une variable et le string formatting\n",
+ "- Affichez la chaine suivante en une seule chaine de caractères en sautant une ligne entre chaque phrase\n",
+ "- bonus : améliorer la lisibilité en faisant un retour à la ligne dans le code. Attention à ne pas confondre retour à la ligne dans l'input et dans l'output."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 93,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "python_definition = \"python is an interpreted high-level general-purpose programming language. its design philosophy emphasizes code readability with its use of significant indentation. its language constructs as well as its object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 103,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "new_python_definition = python_definition.replace\\\n",
+ "(\"python\", \"lovely python\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 104,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "lovely python is an interpreted high-level general-purpose programming language.\n",
+ "its design philosophy emphasizes code readability with its use of significant indentation.\n",
+ "its language constructs as well as its object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(new_python_definition.replace(\". \", \".\\n\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 110,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "a\\b\n"
+ ]
+ }
+ ],
+ "source": [
+ "test = \"a\\\\b\"\n",
+ "\n",
+ "print(test)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 94,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "new_python_definition = python_definition.replace(\"python\", \"lovely python\").replace(\".\", \". \\n\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les booléens en détail"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n",
+ "True\n",
+ "True\n",
+ "False\n",
+ "False\n",
+ "True\n",
+ "True\n",
+ "False\n",
+ "True\n",
+ "True\n",
+ "False\n",
+ "True\n",
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "x = 8\n",
+ "y = 9\n",
+ "z = [7 ,8]\n",
+ "\n",
+ "\"\"\"Les booléens sont souvent le résultat d'une comparaison \"\"\"\n",
+ "\n",
+ "print( x == y ) #equal\n",
+ "\n",
+ "print( x != y ) # not equal\n",
+ "\n",
+ "print( x < y ) #strictly less than\n",
+ "\n",
+ "print( x <= y ) #less than or equal\n",
+ "\n",
+ "print( x > y ) #strictly greater than\n",
+ "\n",
+ "print( x >= y ) #greater than or equal\n",
+ "\n",
+ "\"\"\" ou le résultat d'affirmation \"\"\"\n",
+ "\n",
+ "print( type(x) is int ) # être\n",
+ "\n",
+ "print( type(x) is not str ) # ou ne pas être\n",
+ "\n",
+ "print( x in z) # appartenir\n",
+ "\n",
+ "print( y not in z ) # ou ne pas appartenir\n",
+ "\n",
+ "\"\"\" enfin ils peuvent être combiné grâve à des opérateurs logique \"\"\"\n",
+ "t = True\n",
+ "f = False\n",
+ "\n",
+ "print( t and f) # s'écrit aussi &\n",
+ "print( t or f) # s'écrit aussi | \n",
+ "print( not t)\n",
+ "print( not f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 112,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 112,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "0 == False"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 119,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 119,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "True or True"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 121,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "exercice : 1,2,3,4"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3.9.12 ('env': venv)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.12"
+ },
+ "orig_nbformat": 2,
+ "vscode": {
+ "interpreter": {
+ "hash": "f9351f71b73ea8a230435cc436bb534a46778c892f07a974c8047a435918be1c"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/3-data-structures.ipynb b/3-data-structures.ipynb
new file mode 100644
index 0000000..5fd4c9a
--- /dev/null
+++ b/3-data-structures.ipynb
@@ -0,0 +1,2125 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Data structures"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "En python, il existe 4 grands types de data structures qui permettent de stocker une collection de données :\n",
+ "- Les listes\n",
+ "- les dictionnaires\n",
+ "- les sets\n",
+ "- les tuples"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les listes "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### définition et déclaration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Une liste est une collection d'objets:\n",
+ "- dont l'ordre compte, elle est ordonnée (contrairement aux dictionnaires et aux sets) \n",
+ "- dont les éléments peuvent être modifiés (contrairement aux tuples et aux sets)\n",
+ "- dont un élément peut être répétés plusieurs fois (contrairement aux sets)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Créer des listes contenants des éléments:\n",
+ "liste_de_nombres = [1, 2, 3, 5, 7, 11, 13, 17, 17]\n",
+ "liste_de_strings = [\"a\", \"b\", \"abc\"]\n",
+ "liste_foutoire = [7, 4.2, \"un truc\", True, [\"une\",\"autre\",\"liste\"]]\n",
+ "\n",
+ "# Créer des listes vides: \n",
+ "liste_vide = []\n",
+ "liste_vide = list()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On accède aux éléments d'une liste par leur indice :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# On accède aux éléments d'une liste ainsi:\n",
+ "# soit en partant du début\n",
+ "# le premier élément se trouve à l'indice 0\n",
+ "print(liste_de_nombres[0], \" est le 1er élément\")\n",
+ "print(liste_de_nombres[4], \" est le 5ème élément\") \n",
+ "\n",
+ "# soit par la fin\n",
+ "print(liste_de_nombres[-1], \" est le dernier élément\")\n",
+ "\n",
+ "# On peut également selectionner une partie de la liste\n",
+ "print(liste_de_nombres[1:3]) # L'indice final est exclusif tandis que le premier indice est inclusif\n",
+ "\n",
+ "# On peut également selectionner tous les premiers ou tous les derniers éléments\n",
+ "print(liste_de_nombres[:3])\n",
+ "print(liste_de_nombres[3:-1])\n",
+ "liste_de_nombres[::-1]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Exercice : Que sélectionne cette expression ? (décommenter à l'aide d'un raccourci pour afficher la réponse)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_foutoire = [7, 4.2, \"un truc\", True, [\"une\",\"autre\",\"liste\"]]\n",
+ "\n",
+ "# liste_foutoire[3]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "first_selection = liste_foutoire[4]\n",
+ "print(first_selection)\n",
+ "second_selection = first_selection[1]\n",
+ "print(second_selection)\n",
+ "third_selection = second_selection[1]\n",
+ "print(third_selection)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_foutoire[4][1][1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_foutoire[3]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# On peut supprimer un élément en se servant de son indice\n",
+ "del liste_foutoire[3]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_foutoire"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_de_nombres = [1, 2, 3, 8, 7, 11, 13, 17, 17]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# On peut ainsi modifier les valeurs d'une liste à un certain indice\n",
+ "liste_de_nombres[3] = \"Un changement\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "L'**indexation** en Python permet d'accéder à des éléments spécifiques dans des structures de données comme les listes, tuples ou chaînes de caractères. Les éléments sont référencés en utilisant des indices, qui commencent à **0** pour le premier élément. Par exemple, dans une liste `L = [10, 20, 30, 40]`, l'élément à l'indice 1 est `L[1]`, soit **20**. Python permet aussi une **indexation négative**, où `-1` désigne le dernier élément, `-2` l'avant-dernier, etc.\n",
+ "\n",
+ "En plus de l'indexation simple, il est possible de faire du **slicing** (découpage) avec la syntaxe `liste[start:end:step]`. Par exemple, pour récupérer tous les éléments d'une liste entre l’indice 1 et 3 (exclus) : `L[1:3]` renvoie `[20, 30]`. Le paramètre `step` permet de définir l'intervalle entre les indices. Ainsi, `L[::2]` renverra `[10, 30]`, prenant un élément sur deux.\n",
+ "\n",
+ "Les **`:`** peuvent donc être utilisés pour omettre les valeurs par défaut : si `start` est omis, l'indexation commencera au début de la liste, et si `end` est omis, elle ira jusqu'à la fin.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 3, 'Un changement', 7, 11, 13, 17, 17]"
+ ]
+ },
+ "execution_count": 30,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['Un changement', 3, 2, 1]"
+ ]
+ },
+ "execution_count": 33,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres[3::-1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[17, 17, 13, 11, 7, 'Un changement', 3, 2, 1]"
+ ]
+ },
+ "execution_count": 34,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "#Obtenir une liste en sens inverse\n",
+ "liste_de_nombres[::-1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['Un changement', 7, 11, 13, 17]"
+ ]
+ },
+ "execution_count": 35,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres[3:-1]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Explications ChatGPT :"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "liste_de_nombres[:3:-1]\n",
+ "\n",
+ "Le début du découpage n'est pas spécifié (il est vide avant le premier :), donc cela commence à partir de la fin de la liste (car le pas est -1, ce qui signifie que le découpage est en mode inversé).\n",
+ "3 est la fin du découpage. Cela signifie que le découpage s'arrêtera avant l'index 3 (sans inclure l'élément à l'index 3).\n",
+ "Le pas est -1, donc la liste sera retournée à l'envers.\n",
+ "En résumé, cette expression prend tous les éléments de la fin de la liste jusqu'à, mais sans inclure, l'élément à l'index 3, et les renvoie dans l'ordre inverse.\n",
+ "\n",
+ "liste_de_nombres[3:-1]\n",
+ "\n",
+ "3 est le début du découpage. Cela signifie que le découpage commencera à partir de l'élément à l'index 3.\n",
+ "-1 est la fin du découpage. En Python, un index négatif compte à partir de la fin. Ainsi, -1 représente le dernier élément. Donc, le découpage s'arrêtera avant le dernier élément (sans inclure le dernier élément).\n",
+ "Le pas n'est pas spécifié, donc il est par défaut de 1, ce qui signifie que la liste sera retournée dans l'ordre normal.\n",
+ "En résumé, cette expression prend tous les éléments à partir de l'index 3 jusqu'à, mais sans inclure, le dernier élément."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "L'expression liste_de_nombres[3::-1] est une autre variante de la fonctionnalité de découpage des listes en Python. Voici comment elle fonctionne :\n",
+ "\n",
+ "3 est le début du découpage. Cela signifie que le découpage commencera à partir de l'élément à l'index 3.\n",
+ "La fin du découpage n'est pas spécifiée (elle est vide après le premier :), ce qui, en combinaison avec un pas négatif, signifie que le découpage continuera jusqu'au début de la liste.\n",
+ "Le pas est -1, donc la liste sera retournée à l'envers.\n",
+ "En d'autres termes, cette expression prend tous les éléments depuis l'index 3 jusqu'au début de la liste, et les renvoie dans l'ordre inverse.\n",
+ "\n",
+ "Si nous prenons l'exemple précédent où liste_de_nombres = [0, 1, 2, 3, 4, 5] :\n",
+ "\n",
+ "liste_de_nombres[3::-1] renverra [3, 2, 1, 0]."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### fonctions utiles"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 47,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 3, 100, 7, 11, 13, 17, 17]"
+ ]
+ },
+ "execution_count": 47,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres[3] = 100\n",
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "9"
+ ]
+ },
+ "execution_count": 48,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# connaitre le nombre d'éléments dans une liste\n",
+ "len(liste_de_nombres)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 50,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "100"
+ ]
+ },
+ "execution_count": 50,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# connaitre la somme d'une liste numérique\n",
+ "sum(liste_de_nombres)\n",
+ "\n",
+ "# connaitre le maximum ou le minimum d'une liste numérique\n",
+ "max(liste_de_nombres)\n",
+ "\n",
+ "# min(liste_de_nombres)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "'>' not supported between instances of 'str' and 'int'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[61], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m liste_de_strings \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m2\u001b[39m,\u001b[38;5;241m3\u001b[39m,\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m1\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;43mmax\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mliste_de_strings\u001b[49m\u001b[43m)\u001b[49m\n",
+ "\u001b[0;31mTypeError\u001b[0m: '>' not supported between instances of 'str' and 'int'"
+ ]
+ }
+ ],
+ "source": [
+ "liste_de_strings = [1,2,3,'1']\n",
+ "max(liste_de_strings)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Méthodes associées à la classe liste"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_de_nombres = [3,8,7]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 88,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_de_nombres_2 = [1,3,5,6,7]\n",
+ "liste_de_nombres.extend(liste_de_nombres_2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 89,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[3, 8, 7, 1, 3, 5, 6, 7, 'test']"
+ ]
+ },
+ "execution_count": 89,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres += ['test']\n",
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 90,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[3, 8, 7, 1, 3, 5, 6, 7, 'test']"
+ ]
+ },
+ "execution_count": 90,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 91,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_de_nombres.insert(2,'insert_test')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 92,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[3, 8, 'insert_test', 7, 1, 3, 5, 6, 7, 'test']"
+ ]
+ },
+ "execution_count": 92,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 82,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['abc', 'abc', 3, 8, 7, 1, 1, 3, 5, 6, 7, [1, 3, 5, 6, 7], 'test', 'test']"
+ ]
+ },
+ "execution_count": 82,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_de_nombres"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 92,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_de_strings[3] = \"antoine\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "liste_de_strings"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 79,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# ajouter un élément à la fin une liste\n",
+ "liste_de_nombres.append(89)\n",
+ "\n",
+ "# Ajoute un élément à une liste à une certaine position (ici au début: 0)\n",
+ "liste_de_nombres.insert(0, -1) # d'abord l'indice puis ce qu'on ajoute\n",
+ "\n",
+ "# # concatène deux listes (ajoute une liste à une autre)\n",
+ "liste_de_nombres.extend(liste_de_nombres_2)\n",
+ "\n",
+ "# # supprimer un élément d'une liste en utilisant sa valeur\n",
+ "liste_de_strings.remove(\"abc\")\n",
+ "\n",
+ "# # supprime un élément d'une liste en utilisant son indice\n",
+ "# # si aucun argument est founi, supprime le dernier élément de la liste\n",
+ "liste_de_strings.pop()\n",
+ "\n",
+ "# # ordonner les éléments d'une liste\n",
+ "liste_de_nombres.sort()\n",
+ "\n",
+ "# # retrouve l’indice de la première occurrence d’un élément à chercher dans notre liste ;\n",
+ "liste_de_strings.index('antoine')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour les autres méthodes voir la : https://docs.python.org/fr/3/tutorial/datastructures.html"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 104,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "6"
+ ]
+ },
+ "execution_count": 104,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "liste_nombres = [1, 6, 98, 52, 1045, 3]\n",
+ "\n",
+ "# 1) classez la liste en ordre croissant\n",
+ "liste_nombres.sort()\n",
+ "\n",
+ "# 2) supprimez le premier élément de la liste\n",
+ "liste_nombres.pop(0)\n",
+ "# 3) ajoutez le nombre \"1097\" à la fin de la liste\n",
+ "liste_nombres.append(1097)\n",
+ "# 4) récupérez le deuxième élément dans une variable \"deuxieme_element\"\n",
+ "deuxieme_element = liste_nombres[1]\n",
+ "print(deuxieme_element) # la console devrait afficher \"6\" !\n",
+ "\n",
+ "# 5) affichez la longueur de la liste\n",
+ "len(liste_nombres)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les dictionnaires"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Définition et création"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Un dictionnaire est un objet permettant de stocker des informations à l'aide d'un système clé/valeur.\n",
+ "A chaque clé correspond une valeur, les clés n'ont pas d'ordre entre elles."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Créer un dictionnaire vide"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "new_dict = {}\n",
+ "new_dict = dict()\n",
+ "print(new_dict)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Créer un dictionnaire contenant des données"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 153,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'lesstrings': 'exemple', 'lesintegers': 9, 'leslistes': [7, 8, 9], 'les booleen': True}\n"
+ ]
+ }
+ ],
+ "source": [
+ "trucs_appris_en_python = { \n",
+ " \"lesstrings\": \"exemple\", \n",
+ " \"lesintegers\": 9, \n",
+ " \"leslistes\": [7,8,9], \n",
+ " \"les booleen\": True \n",
+ "}\n",
+ "\n",
+ "print(trucs_appris_en_python)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 108,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'4.3': 3}"
+ ]
+ },
+ "execution_count": 108,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "{\"4.3\":3}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Restriction:\n",
+ "- Les clés peuvent être des int, des float, des str (tout object immutable (voir plus loin)) mais une clé ne peut être utilisée qu'une seule fois \n",
+ "- les valeurs peuvent être ne n'importe quel type"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Accéder aux valeurs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 109,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'lesstrings': 'exemple',\n",
+ " 'lesintegers': 9,\n",
+ " 'leslistes': [7, 8, 9],\n",
+ " 'les booleen': True}"
+ ]
+ },
+ "execution_count": 109,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 110,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'exemple'"
+ ]
+ },
+ "execution_count": 110,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Accéder à une valeur à partir de sa clé\n",
+ "trucs_appris_en_python[\"lesstrings\"]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 111,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'lesstrings': 'exemple',\n",
+ " 'lesintegers': 9,\n",
+ " 'leslistes': [7, 8, 9],\n",
+ " 'les booleen': True,\n",
+ " 'lesfloats': 3.8}"
+ ]
+ },
+ "execution_count": 111,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# On peut à tout moment ajouter une nouvelle clé à un dictionnaire en lui attribuant une valeur\n",
+ "trucs_appris_en_python['lesfloats'] = 3.8\n",
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 124,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# On modifie la valeur comme on modifierait une variable\n",
+ "trucs_appris_en_python['leslistes'].append(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 154,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_new_list = [86,87]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 155,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'lesstrings': 'exemple',\n",
+ " 'lesintegers': 9,\n",
+ " 'leslistes': [7, 8, 9],\n",
+ " 'les booleen': True}"
+ ]
+ },
+ "execution_count": 155,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 156,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trucs_appris_en_python[\"leslistes2\"] = my_new_list"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 160,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'lesstrings': 'exemple',\n",
+ " 'lesintegers': 9,\n",
+ " 'leslistes': [7, 8, 9],\n",
+ " 'les booleen': True,\n",
+ " 'leslistes2': [86, 87, 88]}"
+ ]
+ },
+ "execution_count": 160,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 158,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_new_list.append(88)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 159,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[86, 87, 88]"
+ ]
+ },
+ "execution_count": 159,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "my_new_list"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 134,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# On modifie la valeur comme on modifierait une variable\n",
+ "trucs_appris_en_python['lesintegers'] = test_value"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 135,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'lesintegers': 86, 'leslistes': [7, 8, 9, 3], 'les booleen': True}"
+ ]
+ },
+ "execution_count": 135,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 114,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'lesstrings': 'exemple', 'lesintegers': 9, 'leslistes': [7, 8, 9], 'les booleen': True}\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "{'lesintegers': 9, 'leslistes': [7, 8, 9], 'les booleen': True}"
+ ]
+ },
+ "execution_count": 114,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# supprimer un couple clef/valeur\n",
+ "del trucs_appris_en_python['lesfloats']\n",
+ "print(trucs_appris_en_python)\n",
+ "\n",
+ "# une autre manière de supprimer un couple cle/valeur:\n",
+ "trucs_appris_en_python.pop('lesstrings') \n",
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Parcourir un dictionnaire"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 115,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'lesintegers': 9, 'leslistes': [7, 8, 9], 'les booleen': True}"
+ ]
+ },
+ "execution_count": 115,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trucs_appris_en_python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 116,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# vérifier l'existence d'une clef:\n",
+ "print(\"leslistes\" in trucs_appris_en_python)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 118,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "dict_keys(['lesintegers', 'leslistes', 'les booleen'])\n",
+ "dict_values([9, [7, 8, 9], True])\n",
+ "dict_items([('lesintegers', 9), ('leslistes', [7, 8, 9]), ('les booleen', True)])\n"
+ ]
+ }
+ ],
+ "source": [
+ "# trois méthodes importantes liées aux dictionnaires:\n",
+ "print(trucs_appris_en_python.keys())\n",
+ "print(trucs_appris_en_python.values())\n",
+ "print(trucs_appris_en_python.items())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 119,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Utilisation de values()\n",
+ "print( 9 in trucs_appris_en_python.values() )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 121,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Utilisation de items()\n",
+ "print( (\"lesintegers\",9) in trucs_appris_en_python.items() )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 120,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"leslistes\" in trucs_appris_en_python.keys())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## La Mutabilité"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Définition"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Observons quelque chose:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 136,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "jeremy\n",
+ "JEREMY\n"
+ ]
+ }
+ ],
+ "source": [
+ "a = \"JEREMY\"\n",
+ "\n",
+ "print(a.lower())\n",
+ "\n",
+ "print(a)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 137,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1, 2, 3]\n"
+ ]
+ }
+ ],
+ "source": [
+ "b = [1,2]\n",
+ "\n",
+ "b.append(3)\n",
+ "\n",
+ "print(b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Quand on définit une variable en python on définit toujours un nom qui pointe vers une valeur enregistrée en mémoire. En fonction du type d'objet la valeur inscrite en mémoire peut être modifiée ou non. On appelle cela la mutabilité\n",
+ "- Les Objets immutables sont ceux dont la valeur en mémoire ne peut changer: Entiers, flottants, complexes, tuples, chaînes de caractères, …\n",
+ "- LEs Objets mutables sont ceux dont la valeur en mémoire change: Listes, dictionnaires, …"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Récupérer le résultat des opérations "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Quand on modifie un object immutable, ce que l'on fait en réalité c'est de déclarer une nouvelle valeur en mémoire. Cette nouvelle valeur si on veut s'en servir il faut lui donner un nouveau nom et donc l'assigner à une variable\n",
+ "\n",
+ "Pour les object mutable, quand on les modifie, c'est directement l'objet en mémoire qui est modifié, pas besoin donc d'assigner un nouveau nom de variable pour ce résultat. Si on le fait, python n'enregistrera pas la nouvelle valeur prise mais un objet nul ou parfois le résultat de l'opération. C'est donc le meilleur moyen de perdre ses données:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 162,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "JEREMY\n",
+ "Jeremy\n"
+ ]
+ }
+ ],
+ "source": [
+ "a = \"Jeremy\"\n",
+ "\n",
+ "a_bis = a.upper()\n",
+ "\n",
+ "print(a_bis)\n",
+ "\n",
+ "# a = a.upper()\n",
+ "\n",
+ "print(a)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 166,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 3]"
+ ]
+ },
+ "execution_count": 166,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "b"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 164,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "b = [1,2]\n",
+ "b.append(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 163,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "None\n",
+ "None\n"
+ ]
+ }
+ ],
+ "source": [
+ "b = [1,2]\n",
+ "\n",
+ "b_bis = b.append(3)\n",
+ "\n",
+ "print(b_bis)\n",
+ "\n",
+ "b = b.append(3)\n",
+ "\n",
+ "print(b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Créer des alias et des copies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On peut faire en sorte qu'une variable soit égale à la valeur d'une autre variable"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 167,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2"
+ ]
+ },
+ "execution_count": 167,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "b = [1,2]\n",
+ "value_deleted = b.pop(1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 168,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "a = \"Jeremy\"\n",
+ "b = [1,2]\n",
+ "\n",
+ "a_alias = a\n",
+ "b_alias = b"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 169,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2]"
+ ]
+ },
+ "execution_count": 169,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "b_alias"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Dans ce cas là, on crée en réalité un alias, on crée un nouveau nom qui point vers la même valeur en mémoire."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On a vue que pour les immutables, la valeur en mémoire ne changeait pas, si on fait donc pointer l'un des deux alias vers une nouvelle valeur, l'autre pointera toujours vers l'ancienne valeur inchangée"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 170,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'JEREMY'"
+ ]
+ },
+ "execution_count": 170,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a.upper()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 171,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "JEREMY\n",
+ "Jeremy\n"
+ ]
+ }
+ ],
+ "source": [
+ "a = a.upper()\n",
+ "print(a)\n",
+ "print(a_alias)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour les objets mutables, c'est la valeur en mémoire qui change. Si donc on la modifie en utilisant un des deux alias, l'autre alias pointera égaement vers la valeur modifiée"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 172,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2]"
+ ]
+ },
+ "execution_count": 172,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "b"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 174,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1, 2, 3, 3]\n",
+ "[1, 2, 3, 3]\n"
+ ]
+ }
+ ],
+ "source": [
+ "b.append(3)\n",
+ "print(b)\n",
+ "print(b_alias)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Si on veut conserver l'état initial d'un objet mutable, il ne faut pas créer un alias mais une copie"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 175,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 3, 3]"
+ ]
+ },
+ "execution_count": 175,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "b"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 176,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1, 2, 3, 3, 4]\n",
+ "[1, 2, 3, 3]\n"
+ ]
+ }
+ ],
+ "source": [
+ "b_copie = b.copy()\n",
+ "\n",
+ "b.append(4)\n",
+ "\n",
+ "print(b)\n",
+ "print(b_copie)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**: \n",
+ "\n",
+ "- Déclarer une variable de type float égale à -3.9874. \n",
+ " - Conserver une copie de cette état initial\n",
+ " - Calculer la valeur absolue de cette variable. \n",
+ " - Puis ajouter cette valeur absolue à la valeur initiale de la variable \n",
+ " - (Toutes ces étapes sont à faire séparement et pas sur une seule ligne)\n",
+ "- Créer un dictionnaire avec une cle \"nombre\" et comme valeur l'int 90\n",
+ " - Conserver une copie de cette état initial\n",
+ " - Modifier la cle pour lui donner comme valeur 150\n",
+ " - additionner les valeurs de cette clé pour l'état initial et l'état modifié\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 183,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-3.9874\n",
+ "0.0\n",
+ "-3.9874\n"
+ ]
+ }
+ ],
+ "source": [
+ "var_immuable = -3.9874\n",
+ "var_immuable_copy = var_immuable\n",
+ "abs(var_immuable_copy)\n",
+ "# print(var_immuable_copy_abs)\n",
+ "print(var_immuable)\n",
+ "var_immuable_copy = var_immuable_copy + abs(var_immuable_copy)\n",
+ "print(var_immuable_copy)\n",
+ "print(var_immuable)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 189,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'nombre': 90}\n",
+ "{'nombre': 240}\n",
+ "{'nombre': 240}\n"
+ ]
+ }
+ ],
+ "source": [
+ "\n",
+ "my_dict = {'nombre' : 90}\n",
+ "my_dict_copy = my_dict.copy()\n",
+ "my_dict_fake_copy = my_dict\n",
+ "\n",
+ "my_dict['nombre'] += 150\n",
+ "print(my_dict_copy)\n",
+ "print(my_dict)\n",
+ "print(my_dict_fake_copy)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les sets"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Un set est une collection non ordonnée et non indexée d'éléments uniques. En d'autres termes, les éléments d'un ensemble ne peuvent pas être dupliqués. Les ensembles sont très utiles pour effectuer des opérations d'ensemble, comme l'union, l'intersection, la différence, etc.\n",
+ "\n",
+ "Valeurs acceptées : \n",
+ "- int\n",
+ "- float\n",
+ "- str"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 196,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{1, 2, 3, 4, 5}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Création d'un set\n",
+ "mon_set = {1, 2, 3, 4, 5}\n",
+ "print(mon_set)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 207,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{}"
+ ]
+ },
+ "execution_count": 207,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "{}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 197,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_list_with_duplicates = [1,1,1,2,2,3]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 199,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 3]"
+ ]
+ },
+ "execution_count": 199,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(set(my_list_with_duplicates))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 201,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "dict_values(['exemple', 9, [7, 8, 9], True, [86, 87, 88]])"
+ ]
+ },
+ "execution_count": 201,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trucs_appris_en_python.values()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 200,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "unhashable type: 'list'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[200], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# connaitre tous les élements uniques\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;43mset\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtrucs_appris_en_python\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalues\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n",
+ "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'"
+ ]
+ }
+ ],
+ "source": [
+ "# connaitre tous les élements uniques\n",
+ "set()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 208,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{1, 2, 3, 4, 5, 6}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Ajouter un élément à un set\n",
+ "mon_set.add(6)\n",
+ "print(mon_set) # {1, 2, 3, 4, 5, 6}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 211,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "'set' object is not subscriptable",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[211], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmon_set\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\n",
+ "\u001b[0;31mTypeError\u001b[0m: 'set' object is not subscriptable"
+ ]
+ }
+ ],
+ "source": [
+ "mon_set[1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 210,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "KeyError",
+ "evalue": "2",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[210], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# Supprimer un élément d'un set\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[43mmon_set\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mremove\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(mon_set) \u001b[38;5;66;03m# {1, 3, 4, 5, 6}\u001b[39;00m\n\u001b[1;32m 5\u001b[0m mon_set[\u001b[38;5;241m1\u001b[39m]\n",
+ "\u001b[0;31mKeyError\u001b[0m: 2"
+ ]
+ }
+ ],
+ "source": [
+ "# Supprimer un élément d'un set\n",
+ "\n",
+ "mon_set.remove(2)\n",
+ "print(mon_set) # {1, 3, 4, 5, 6}\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Opérations avec les sets"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 212,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{1, 2, 3, 4, 5, 6, 7, 8}\n",
+ "{4, 5}\n",
+ "{1, 2, 3}\n"
+ ]
+ }
+ ],
+ "source": [
+ "set1 = {1, 2, 3, 4, 5}\n",
+ "set2 = {4, 5, 6, 7, 8}\n",
+ "\n",
+ "# Union\n",
+ "print(set1 | set2)\n",
+ "\n",
+ "# Intersection\n",
+ "print(set1 & set2)\n",
+ "\n",
+ "# Différence\n",
+ "print(set1 - set2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Exercices sur les sets :\n",
+ "\n",
+ "1. Créez un set contenant les lettres de votre prénom.\n",
+ "2. Ajoutez une lettre à votre set.\n",
+ "3. Supprimez une lettre de votre set.\n",
+ "4. Créez un second set avec un autre prénom, et trouvez les lettres communes aux deux prénoms."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 225,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'a', 'b', 'e', 'i', 'j', 'm', 'n'}"
+ ]
+ },
+ "execution_count": 225,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "set(\"benjamin\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 226,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'e', 'm'}"
+ ]
+ },
+ "execution_count": 226,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "name_set = {\"j\", \"e\", \"r\", \"e\", \"m\", \"y\"}\n",
+ "name_set.add('z')\n",
+ "name_set.remove(\"j\")\n",
+ "name_set & set(list(\"benjamin\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Tuples en Python\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Un tuple est une collection ordonnée et immuable d'éléments. Contrairement aux listes, une fois qu'un tuple est créé, vous ne pouvez pas modifier, ajouter ou supprimer d'éléments."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 227,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(1, 2, 3, 4, 5)\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Création d'un tuple\n",
+ "\n",
+ "mon_tuple = (1, 2, 3, 4, 5)\n",
+ "print(mon_tuple)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 228,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Accéder à un élément d'un tuple\n",
+ "\n",
+ "print(mon_tuple[1]) # 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 229,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "'tuple' object does not support item assignment",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[229], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# Tenter de modifier un tuple générera une erreur\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[43mmon_tuple\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m6\u001b[39m \u001b[38;5;66;03m# TypeError\u001b[39;00m\n",
+ "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
+ ]
+ }
+ ],
+ "source": [
+ "# Tenter de modifier un tuple générera une erreur\n",
+ "\n",
+ "mon_tuple[1] = 6 # TypeError"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 231,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mon_tuple2 = (\"a\", 8.5, [1,2], {1,2}, {\"key\":\"value\"}, 1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Exercices sur les tuples :\n",
+ "\n",
+ "1. Créez un tuple avec vos 5 films préférés.\n",
+ "2. Affichez le premier et le dernier film de votre tuple.\n",
+ "3. Essayez de remplacer un film par un autre pour vérifier l'immutabilité du tuple."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 237,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "'tuple' object does not support item assignment",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[237], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m my_tuple \u001b[38;5;241m=\u001b[39m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLa Haine\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m Intouchables\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIndependance Day\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mJurrasic Park\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mDikkenek\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m----> 3\u001b[0m \u001b[43mmy_tuple\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUn film\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 4\u001b[0m my_tuple[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]\n",
+ "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
+ ]
+ }
+ ],
+ "source": [
+ "my_tuple = (\"La Haine\", \" Intouchables\", \"Independance Day\", \"Jurrasic Park\", \"Dikkenek\")\n",
+ "\n",
+ "my_tuple[0] = \"Un film\"\n",
+ "my_tuple[-1]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Exercice combinant les listes, tuples, dictionnaires et sets :\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 240,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mylist = [\"La Haine\",\n",
+ "\"Amélie\",\n",
+ "\"La La Land\",\n",
+ "\"La Haine\",\n",
+ "\"Intouchables\",\n",
+ "\"Le Fabuleux Destin d'Amélie Poulain\",\n",
+ "\"Intouchables\",\n",
+ "\"La Cité des enfants perdus\",\n",
+ "\"Les Misérables\"\n",
+ "\"La Cité des enfants perdus\"]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "- Créez un set pour obtenir la liste unique des films.\n",
+ "- Créez un dictionnaire où la clé est le film et la valeur est sa position initiale dans la liste (utilisez un tuple pour stocker les positions si un film apparaît plusieurs fois).\n",
+ "- Ajoutez à votre dictionnaire un autre film de votre choix avec sa position fictive.\n",
+ "- Affichez le nom du film et ses positions à partir du dictionnaire."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 282,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "set_list = set(mylist)\n",
+ "\n",
+ "my_dict = {}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 283,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0 La Haine\n",
+ "1 Amélie\n",
+ "2 La La Land\n",
+ "3 La Haine\n",
+ "4 Intouchables\n",
+ "5 Le Fabuleux Destin d'Amélie Poulain\n",
+ "6 Intouchables\n",
+ "7 La Cité des enfants perdus\n"
+ ]
+ }
+ ],
+ "source": [
+ "for i in range(len(mylist)-1):\n",
+ " # print(i)\n",
+ " # print(mylist[i])\n",
+ " print(i, mylist[i])\n",
+ " if mylist[i] in my_dict:\n",
+ " my_dict[mylist[i]]= (my_dict[mylist[i]], i)\n",
+ " else :\n",
+ " my_dict[mylist[i]] = i"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 284,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'La Haine': (0, 3),\n",
+ " 'Amélie': 1,\n",
+ " 'La La Land': 2,\n",
+ " 'Intouchables': (4, 6),\n",
+ " \"Le Fabuleux Destin d'Amélie Poulain\": 5,\n",
+ " 'La Cité des enfants perdus': 7}"
+ ]
+ },
+ "execution_count": 284,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "my_dict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/3b-data-structures.ipynb b/3b-data-structures.ipynb
new file mode 100644
index 0000000..eb64dc1
--- /dev/null
+++ b/3b-data-structures.ipynb
@@ -0,0 +1,342 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Compréhension de listes, dictionnaires et opérateurs ternaires en Python\n",
+ "\n",
+ "Dans ce cours, nous allons explorer trois concepts très pratiques et concis en Python :\n",
+ "1. La **compréhension de listes** pour générer des listes de manière élégante.\n",
+ "2. La **compréhension de dictionnaires** pour créer des dictionnaires en une seule ligne.\n",
+ "3. Les **opérateurs ternaires**, qui permettent de simplifier des expressions conditionnelles.\n",
+ "\n",
+ "Commençons par la compréhension de listes !\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1. Compréhension de listes\n",
+ "\n",
+ "La **compréhension de listes** est une manière compacte et lisible de générer des listes à partir d'itérables, souvent en appliquant une condition ou une transformation sur chaque élément.\n",
+ "\n",
+ "### Structure de base :\n",
+ "```python\n",
+ "[expression for element in iterable if condition]\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Carrés : [1, 4, 9, 16, 25]\n"
+ ]
+ }
+ ],
+ "source": [
+ "nombres = [1, 2, 3, 4, 5]\n",
+ "carres = [x**2 for x in nombres]\n",
+ "print(\"Carrés :\", carres)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exemple 2 : Appliquer une condition dans la compréhension de liste\n",
+ "\n",
+ "On peut aussi ajouter une **condition** pour filtrer les éléments. Ici, on va seulement garder les nombres pairs et calculer leur carré.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Carrés des nombres pairs : [4, 9, 16, 36, 64]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exemple avec condition\n",
+ "nombres = [1, 2, 3, 4, 5, 6, 7, 8]\n",
+ "carres_pairs = [x**2 for x in nombres if x % 2 == 0 or x % 3 == 0]\n",
+ "print(\"Carrés des nombres pairs :\", carres_pairs)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exemple 3 : Compréhension avec une double boucle\n",
+ "\n",
+ "Il est possible d'utiliser plusieurs boucles imbriquées dans une compréhension de liste. Par exemple, si on veut créer toutes les paires possibles à partir de deux listes :\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Paires possibles : [(2, 'a'), (2, 'b'), (2, 'c')]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Double boucle dans une compréhension de liste\n",
+ "liste1 = [1, 2, 3]\n",
+ "liste2 = ['a', 'b', 'c']\n",
+ "paires = [(x, y) for x in liste1 for y in liste2 if x % 2 == 0]\n",
+ "print(\"Paires possibles :\", paires)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2. Compréhension de dictionnaires\n",
+ "\n",
+ "La compréhension de dictionnaires fonctionne de la même manière que celle des listes, mais elle permet de créer un dictionnaire en une seule ligne.\n",
+ "\n",
+ "### Structure de base :\n",
+ "```python\n",
+ "{key_expression: value_expression for element in iterable if condition}\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Dictionnaire de carrés : {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exemple 1 : Créer un dictionnaire avec des carrés\n",
+ "nombres = [1, 2, 3, 4, 5]\n",
+ "carres_dict = {x: x**2 for x in nombres}\n",
+ "print(\"Dictionnaire de carrés :\", carres_dict)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exemple 2 : Ajouter une condition dans la compréhension d'un dictionnaire\n",
+ "\n",
+ "On peut aussi filtrer les éléments avec une condition, par exemple, créer un dictionnaire uniquement pour les nombres pairs.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Dictionnaire des carrés des nombres pairs : {2: 4, 4: 16}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exemple avec condition\n",
+ "carres_pairs_dict = {x: x**2 for x in nombres if x % 2 == 0}\n",
+ "print(\"Dictionnaire des carrés des nombres pairs :\", carres_pairs_dict)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3. Opérateurs ternaires\n",
+ "\n",
+ "L'opérateur ternaire en Python est une manière concise d'écrire des instructions conditionnelles sur une seule ligne.\n",
+ "\n",
+ "### Structure de base :\n",
+ "```python\n",
+ "valeur_si_vrai if condition else valeur_si_faux\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "majeur\n"
+ ]
+ }
+ ],
+ "source": [
+ "age = 15\n",
+ "\n",
+ "if age >= 18 : \n",
+ " status = \"majeur\"\n",
+ "else :\n",
+ " status = \"majeur\"\n",
+ "\n",
+ "print(status)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Statut : majeur\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exemple 1 : Simple utilisation de l'opérateur ternaire\n",
+ "age = 18\n",
+ "status = \"majeur\" if age >= 18 else \"mineur\"\n",
+ "print(\"Statut :\", status)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exemple 2 : Utiliser un opérateur ternaire dans une boucle\n",
+ "\n",
+ "On peut aussi utiliser l'opérateur ternaire dans une compréhension de liste. Par exemple, transformer les éléments selon une condition.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Parité des nombres : ['rien', 'pair', 'rien', 'multiple de 4', 'rien']\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exemple avec opérateur ternaire dans une compréhension de liste\n",
+ "nombres = [1, 2, 3, 4, 5]\n",
+ "parite = [ \"multiple de 4\" if x%4 == 0 else \"pair\" if x % 2 == 0 else \"rien\" for x in nombres ]\n",
+ "print(\"Parité des nombres :\", parite)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exemple 3 : Opérateurs ternaires dans une fonction\n",
+ "\n",
+ "Tu peux également utiliser les opérateurs ternaires pour retourner une valeur basée sur une condition dans une fonction.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "majeur\n",
+ "mineur\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Fonction avec opérateur ternaire\n",
+ "def check_age(age):\n",
+ " return \"majeur\" if age >= 18 else \"mineur\"\n",
+ "\n",
+ "print(check_age(20)) # Devrait afficher \"majeur\"\n",
+ "print(check_age(15)) # Devrait afficher \"mineur\"\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Conclusion\n",
+ "\n",
+ "Les compréhensions de listes et de dictionnaires, ainsi que les opérateurs ternaires, sont des outils puissants en Python pour écrire du code concis, lisible et efficace. Ils sont particulièrement utiles dans les situations où l'on doit transformer, filtrer ou manipuler des collections d'éléments.\n",
+ "\n",
+ "**Résumé :**\n",
+ "- La **compréhension de listes** permet de générer des listes en une ligne, avec éventuellement des conditions.\n",
+ "- La **compréhension de dictionnaires** permet de créer des dictionnaires de manière tout aussi concise.\n",
+ "- Les **opérateurs ternaires** permettent d'écrire des expressions conditionnelles sur une seule ligne.\n",
+ "\n",
+ "N'hésite pas à expérimenter ces concepts dans ton propre code pour en tirer le meilleur parti !\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exercices\n",
+ "\n",
+ "1. Crée une liste des cubes des nombres de 1 à 10.\n",
+ "2. Crée un dictionnaire où les clés sont des nombres de 1 à 5 et les valeurs sont \"pair\" ou \"impair\" selon la parité du nombre.\n",
+ "3. Utilise un opérateur ternaire pour écrire une fonction qui renvoie \"positif\", \"négatif\" ou \"zéro\" en fonction de l'input.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "api",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.8"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/4-les_conditions_et_les_boucles.ipynb b/4-les_conditions_et_les_boucles.ipynb
new file mode 100644
index 0000000..24fcc05
--- /dev/null
+++ b/4-les_conditions_et_les_boucles.ipynb
@@ -0,0 +1,447 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Les conditions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if True:\n",
+ " print('The condition passed')\n",
+ "\n",
+ "if False:\n",
+ " print('The condition not passed')\n",
+ "\n",
+ "if 0 :\n",
+ " print('The condition not passed')\n",
+ "\n",
+ "if 1:\n",
+ " print('The condition passed')\n",
+ "\n",
+ "if 1 == True:\n",
+ " print('The condition passed')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\"\"\" Structure générale d'une condition if \"\"\"\n",
+ "if mon_booleen:\n",
+ " # exécuter le code quand mon_booleen est vrai\n",
+ "else:\n",
+ " # exécuter le code quand mon_booleen est faux"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\"\"\" Exemple \"\"\"\n",
+ "\n",
+ "ensoleille = False\n",
+ "\n",
+ "if ensoleille:\n",
+ " print(\"on va à la plage !\")\n",
+ "else:\n",
+ " print(\"on reste à la maison !\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "0 == 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\"\"\" Il est également possible d'ajouter d'autres conditions\"\"\"\n",
+ "\n",
+ "ensoleille = False\n",
+ "neige = True\n",
+ "\n",
+ "if ensoleille:\n",
+ " print(\"on va à la plage !\")\n",
+ "elif neige:\n",
+ " print(\"on fait un bonhomme de neige\")\n",
+ "else:\n",
+ " print(\"on reste à la maison !\")\n",
+ "\n",
+ "a = 8\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "a = 1\n",
+ "\n",
+ "if a > 2:\n",
+ " print(a, \" est plus grand 2\")\n",
+ "\n",
+ "print(\"fin du programme\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Rappel: Les booléens peuvent être combinés avec des opérateurs logiques (and, or ..) ou issus de comparaisons (<, >, == ...)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Exemple\n",
+ "x = 7\n",
+ "\n",
+ "if x < 10 and x > 3 :\n",
+ " print(f\"{x} est compris entre 3 et 10, non-inclus\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 1`**: quelle est la valeur de x?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "a = True\n",
+ "b = False\n",
+ "c = True\n",
+ "\n",
+ "if a and b:\n",
+ " x = 5\n",
+ "elif not c:\n",
+ " x = 4\n",
+ "elif a:\n",
+ " x = 8\n",
+ "else:\n",
+ " x = 7\n",
+ "\n",
+ "print(x)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 2`**: devinez ce qui va être affiché"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "a = 3\n",
+ "b = 7\n",
+ "c = 5\n",
+ "\n",
+ "if a < b or b != c and c >= b: #True, True, False\n",
+ " print(\"c'est vrai\")\n",
+ "else:\n",
+ " print(\"c'est faux\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Les boucles"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## La boucle for"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Le principal interet de la boucle for est de parcourir des listes\n",
+ "liste_apprenants = [\"Pascal\", \"Azel\", \"Tony\", \"Vladimir\", \"Sabrina\"]\n",
+ "\n",
+ "for i in liste_apprenants:\n",
+ " print(i, \" présent\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On peut également s'en servir avec la fonction range, cela permet de parcourir une liste d'entiers"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(type(range(5)))\n",
+ "print(range(5))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for i in range(10):\n",
+ " print(i)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# la fonction range peut prendre plusieurs arguments:\n",
+ "premier_element = 2\n",
+ "dernier_element_plus_1 = 11\n",
+ "pas = 2 # on compte tous les combien\n",
+ "\n",
+ "for j in range(premier_element,dernier_element_plus_1,pas):\n",
+ " print(f\"j = {j}\")\n",
+ "\n",
+ "premier_element = 11\n",
+ "dernier_element_plus_1 = 6\n",
+ "pas = -3 # on compte tous les combien\n",
+ "\n",
+ "print('--------')\n",
+ "\n",
+ "for k in range(premier_element,dernier_element_plus_1,pas):\n",
+ " print(f\"k = {k}\") "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 2`**: écrivez un code qui utilise range et la liste \"ma liste\" et qui à la sortie suivante: \n",
+ "canari 1 \n",
+ "avion 2 \n",
+ "papier 3 \n",
+ "ciseaux 4 \n",
+ "toiture 5 "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ma_liste = [\"canari\", \"avion\", \"papier\", \"ciseaux\", \"toiture\"]\n",
+ "\n",
+ "range(len(ma_liste))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Boucle While"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# La structure générale de la boucle while est la suivante:\n",
+ "\n",
+ "i = 0\n",
+ "\n",
+ "while (10 > i) :\n",
+ " print(f\"la condition est encore vraie car i vaut {i}\")\n",
+ " i += 1 # on appelle cela l'incrementation\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# l'incrémentation permet de ne pas créer de boucle infinie\n",
+ "i=11\n",
+ "condition = 12 > i\n",
+ "while condition:\n",
+ " print(\"ceci est une boucle infinie\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 1`**: \n",
+ "- Utilisez une boucle for et la fonction \"range\" pour calculer la somme des 100 premier entier naturel\n",
+ "- Utilisez la boucle while pour calculer le produit des 100 premiers entier naturel"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# vous aurez surement besoin d'un counter\n",
+ "counter = 0\n",
+ "somme = 0\n",
+ "\n",
+ "#...\n",
+ "\n",
+ "print(somme)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "product = 1\n",
+ "i = 1\n",
+ "while \"condition sur i à écrire\":\n",
+ " # ...\n",
+ "\n",
+ "print(product)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 2`**: \n",
+ "- Dans un fichier script, A l'aide de la fonction while et la fonction input (help(input)) écrivez cette blague\n",
+ "- \"Si repete et pepete sont dans un bateau, pepete tombe à l'eau, qu'est ce qui reste?\"\n",
+ "- si la personne répond \"repète\", le programme pose la meme question : \"Si repete et pepete sont dans un bateau, pepete tombe à l'eau, qu'est ce qui reste?\"\n",
+ "- si la personne répond autre chose le programme pose comme question: \"Mais non tu comprends pas, si repete et pepete sont dans un bateau, pepete tombe à l'eau, qu'est ce qui reste \"\n",
+ "- si la personne répond \"tu es lourd\" enfin le programme s'arrete"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 3`**: \n",
+ "- Reprenez votre programme en utilisant l'instruction `break`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 4`**: Plus classique et beaucoup moins drole \n",
+ "- écrivez un programme script qui demande deux nombres puis renvoie leur somme si les nombres sont valides sinon il renvoie une erreur et demande à nouveaux deux nombres valides."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "exercice 5,6,7,8,9,10,11(faire une recherche), 12, 13,14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "4822798685b95d90cac6b9eac85a216cd3011e561666c6311e8088bbadca8e0f"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.8.6 64-bit ('3.8.6': pyenv)",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/5-Les_fonctions.ipynb b/5-Les_fonctions.ipynb
new file mode 100644
index 0000000..f8ffea3
--- /dev/null
+++ b/5-Les_fonctions.ipynb
@@ -0,0 +1,449 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Les fonctions"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Une fonction est un bloc de code avec un but spécifique auquel vous pouvez donner un nom. \n",
+ "- Elles sont dans un premier temps définies \n",
+ "- Puis exécuter. \n",
+ "Quand vous appelez une fonction, vous exécutez le code qu’elle contient. Les fonctions vous laissent saisir des paramètres pour exécuter le même code sur différentes valeurs."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les fonctions de base"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Certaines fonctions sont déja définies dans python, on en a déja rencontré quelques unes:\n",
+ "- len(x)\n",
+ "- type(x)\n",
+ "- max(x)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour savoir à quoi sert une fonction (ou une classe) il existe une autre fonction:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on built-in function max in module builtins:\n",
+ "\n",
+ "max(...)\n",
+ " max(iterable, *[, default=obj, key=func]) -> value\n",
+ " max(arg1, arg2, *args, *[, key=func]) -> value\n",
+ " \n",
+ " With a single iterable argument, return its biggest item. The\n",
+ " default keyword-only argument specifies an object to return if\n",
+ " the provided iterable is empty.\n",
+ " With two or more arguments, return the largest argument.\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "help(max)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour les autres fonctions built-in : https://docs.python.org/3/library/functions.html#help"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Définir une fonction"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il est également possible de créer ses propres fonctions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "NameError",
+ "evalue": "name 'result' is not defined",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32m/Users/jeremyvangansbeg/Documents/project/intro_python/python-course/5-Les_fonctions.ipynb Cell 10\u001b[0m line \u001b[0;36m9\n\u001b[1;32m 6\u001b[0m \u001b[39mreturn\u001b[39;00m result\n\u001b[1;32m 8\u001b[0m \u001b[39m# étape de l'appel\u001b[39;00m\n\u001b[0;32m----> 9\u001b[0m resultat \u001b[39m=\u001b[39m fonction_name(\u001b[39m\"\u001b[39;49m\u001b[39mquelque_chose\u001b[39;49m\u001b[39m\"\u001b[39;49m,\u001b[39m\"\u001b[39;49m\u001b[39mautre_chose\u001b[39;49m\u001b[39m\"\u001b[39;49m)\n",
+ "\u001b[1;32m/Users/jeremyvangansbeg/Documents/project/intro_python/python-course/5-Les_fonctions.ipynb Cell 10\u001b[0m line \u001b[0;36m6\n\u001b[1;32m 4\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mfonction_name\u001b[39m(parametre_1,parametre_2):\n\u001b[1;32m 5\u001b[0m \u001b[39m#instructions\u001b[39;00m\n\u001b[0;32m----> 6\u001b[0m \u001b[39mreturn\u001b[39;00m result\n",
+ "\u001b[0;31mNameError\u001b[0m: name 'result' is not defined"
+ ]
+ }
+ ],
+ "source": [
+ "\"\"\"Structure générale d'une fonction\"\"\"\n",
+ "\n",
+ "# étape de la définition\n",
+ "def fonction_name(parametre_1,parametre_2):\n",
+ " #instructions\n",
+ " return result\n",
+ "\n",
+ "# étape de l'appel\n",
+ "resultat = fonction_name(\"quelque_chose\",\"autre_chose\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "7\n"
+ ]
+ }
+ ],
+ "source": [
+ "\"\"\"Exemple\"\"\"\n",
+ "def add(a,b):\n",
+ " c = a + b\n",
+ " return c\n",
+ "\n",
+ "print(add(3,4))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Ecrivez une fonction qui permet de calculer le produit des éléments d'une liste contenant des integers.\n",
+ "def produit_entiers(liste_entiers):\n",
+ " result = 1\n",
+ " for x in liste_entiers:\n",
+ " result *= x\n",
+ " return result\n",
+ "\n",
+ " # écrivez le code ici"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Ecrivez une fonction qui permet de calculer le produit des éléments d'une liste contenant des integers.\n",
+ "def produit_entiers(liste_entiers):\n",
+ " result = 1\n",
+ " for x in liste_entiers:\n",
+ " if type(x) is int or type(x) is float :\n",
+ " result *= x\n",
+ " else :\n",
+ " return \"Merci de fournir une liste valide\"\n",
+ " return result\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from typing import List, Union\n",
+ "\n",
+ "def produit_entiers(liste_entiers: List[Union[int, float]]) -> float:\n",
+ " result = 1.0\n",
+ " for x in liste_entiers:\n",
+ " try:\n",
+ " result *= x\n",
+ " except TypeError:\n",
+ " raise ValueError(f\"L'élément {x} n'est pas un nombre valide\")\n",
+ " return result"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'Merci de fournir une liste valide'"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "produit_entiers([5,\"ff\", 8.5])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0, 0, 0, 0, 0]"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[0] * 5"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def produit_entiers(liste_entiers: list) -> int:\n",
+ " return \"ok\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ok'"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "produit_entiers(2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Ecrire correctement ses fonctions avec la Pep8"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Une docstring est un ensemble de mots qui documente un bout de code. Elle commence par trois guillemets ouvrants, le commentaire que vous souhaitez apporter puis trois guillemets fermants."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "Exemple :\n",
+ "\n",
+ "\"\"\" This is a docstring. I'm here to explain what the following code will do.\n",
+ "Oh, I'm multiline too!\n",
+ "\"\"\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Selon la PEP 8, chaque partie de votre code devrait contenir une Docstring.\n",
+ "- tous les modules publics\n",
+ "- toutes les fonctions\n",
+ "- toutes les classes\n",
+ "- toutes les méthodes de ces classes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def add(a,b):\n",
+ " \"\"\" \n",
+ " This function returns the sum of the two parameters\n",
+ "\n",
+ " parameters\n",
+ " ----------\n",
+ " a: int\n",
+ " b: int\n",
+ " \"\"\"\n",
+ " aprime = abs(a) # on prend la valeur absolue\n",
+ " bprime = abs(b) \n",
+ " return a + b"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on function add in module __main__:\n",
+ "\n",
+ "add(a, b)\n",
+ " This function returns the sum of the two parameters\n",
+ " \n",
+ " parameters\n",
+ " ----------\n",
+ " a: int\n",
+ " b: int\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "help(add)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Cependant la Pep 8 nous demande également d'être concis dans nos commentaires et de ne pas commenter des évidences. Il faut donc se poser la question de savoir si ce que nous écrivons est évident pour quelqu'un qui n'a pas écrit le code (ici oui), si ce n'est pas évident alors il faut commenter"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`règles d'écriture`**:\n",
+ "- fonctions: minuscules et tiret du bas : my_function()\n",
+ "- arguments des méthodes et fonctions : identique aux fonctions. my_function(param=False) (attention pas d'espace)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Fonctions et Méthodes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les fonctions et les méthodes sont des objets proches mais qui possèdent des différences et donc ne doivent pas être confondus:\n",
+ "- Une fonction est défninie independement de tous objets, les objets auxquels elle s'applique sont tous précisés dans ses paramètres\n",
+ " - **exemple**: round(un_float,2), sum(une_liste), sum(un_int, autre_int)...\n",
+ "- Une méthode est liée à une classe d'objet, elle est définie au moment de la défnition de la classe. On applique toujours une méthode à une instance de classe. Comme on appelle la méthode à partir de cette instance, on ne la rappelle pas dans les paramètres:\n",
+ " - **exemple**: une_instance_str.upper(), une_instance_liste.append(3)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "De même que pour les fonctions, on peut obtenir de l'aide sur les méthodes:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on method_descriptor:\n",
+ "\n",
+ "upper(self, /)\n",
+ " Return a copy of the string converted to uppercase.\n",
+ "\n",
+ "Help on method_descriptor:\n",
+ "\n",
+ "append(self, object, /)\n",
+ " Append object to the end of the list.\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "help(str.upper)\n",
+ "help(list.append)"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "4822798685b95d90cac6b9eac85a216cd3011e561666c6311e8088bbadca8e0f"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.8.6 64-bit ('3.8.6': pyenv)",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.12"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/5b-lambda.ipynb b/5b-lambda.ipynb
new file mode 100644
index 0000000..50577b6
--- /dev/null
+++ b/5b-lambda.ipynb
@@ -0,0 +1,493 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Fonctions Lambda en Python"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Introduction"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "En Python, une fonction lambda est une petite fonction anonyme. Elle peut prendre un nombre quelconque d'arguments, mais ne peut avoir qu'une seule expression. L'expression est évaluée et renvoyée lors de l'appel de la fonction lambda.\n",
+ "\n",
+ "Syntaxe\n",
+ "La syntaxe pour définir une fonction lambda est :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(arguments)>"
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "lambda arguments: expression"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "La fonction peut avoir n'importe quel nombre d'arguments, mais seulement une expression. L'expression est évaluée et renvoyée lors de l'appel."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Différences avec les fonctions régulières"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "1. Les fonctions lambda n'ont pas de nom lorsqu'elles sont définies. C'est pourquoi on les appelle aussi fonctions anonymes.\n",
+ "2. Vous ne pouvez écrire qu'une expression dans une fonction lambda, et non des blocs de code.\n",
+ "3. Les fonctions lambda renvoient automatiquement la valeur de leur expression unique, sans avoir besoin d'utiliser le mot-clé return."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exemples"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Fonction lambda sans argument"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Hello, World!\n"
+ ]
+ }
+ ],
+ "source": [
+ "f = lambda : \"Hello, World!\"\n",
+ "print(f())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "()\n",
+ "Hello, World!\n"
+ ]
+ }
+ ],
+ "source": [
+ "def f():\n",
+ " return \"Hello, World!\"\n",
+ "\n",
+ "print(f())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Fonction lambda avec un argument"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "15\n"
+ ]
+ }
+ ],
+ "source": [
+ "g = lambda x: x + 10\n",
+ "print(g(5)) # Affiche 15"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Foncton lambda avec plusieurs arguments"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "12\n"
+ ]
+ }
+ ],
+ "source": [
+ "h = lambda x, y: x * y\n",
+ "print(h(3, 4)) # Affiche 12"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Utilisation courante des fonctions lambda"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "L'une des utilisations les plus courantes des fonctions lambda est de les utiliser comme arguments pour des fonctions de niveau supérieur comme map(), filter(), et sorted().\n",
+ "\n",
+ "Exemple avec map()\n",
+ "Supposons que nous ayons une liste de nombres et que nous voulions augmenter chaque élément de cette liste de 10. Nous pouvons utiliser map() avec une fonction lambda pour cela."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[11, 12, 13, 14, 15]\n"
+ ]
+ }
+ ],
+ "source": [
+ "numbers = [1, 2, 3, 4, 5]\n",
+ "result = map(lambda x: x + 10, numbers)\n",
+ "print(list(result)) # Affiche [11, 12, 13, 14, 15]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[11, 12, 13, 14, 15]"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[x +10 for x in numbers]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[11, 12, 13, 14, 15]\n"
+ ]
+ }
+ ],
+ "source": [
+ "numbers = [1, 2, 3, 4, 5]\n",
+ "\n",
+ "def add10(x):\n",
+ " return x + 10\n",
+ "\n",
+ "result = map(add10, numbers)\n",
+ "\n",
+ "print(list(result))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Exemple avec filter()\n",
+ "Supposons que nous voulions filtrer une liste pour ne garder que les nombres pairs. Encore une fois, filter() et lambda sont utiles."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2, 4, 6]\n"
+ ]
+ }
+ ],
+ "source": [
+ "numbers = [1, 2, 3, 4, 5, 6]\n",
+ "even_numbers = filter(lambda x: x % 2 == 0, numbers)\n",
+ "print(list(even_numbers)) # Affiche [2, 4, 6]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Conclusion"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "Les fonctions lambda sont un outil puissant en Python, offrant une manière concise d'écrire des fonctions simples. Bien qu'elles ne soient pas appropriées pour toutes les situations, elles peuvent rendre le code plus lisible et plus propre dans certains scénarios."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "-----"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 75,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[2, 4, 6, 8, 10, 12]"
+ ]
+ },
+ "execution_count": 75,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "L = [1,2,3,4,5,6]\n",
+ "\n",
+ "list(map(lambda toto : toto*2, L))\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**Exercice** : Gestionnaire de notes\n",
+ "Contexte :\n",
+ "Vous êtes enseignant et vous avez plusieurs étudiants avec leurs notes respectives pour différents devoirs. Vous souhaitez analyser ces notes pour obtenir certaines statistiques.\n",
+ "\n",
+ "**Données** :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "students = [\n",
+ " {\"name\": \"Alice\", \"grades\": [85, 90, 88, 70, 92]},\n",
+ " {\"name\": \"Bob\", \"grades\": [80, 78, 85, 85, 88]},\n",
+ " {\"name\": \"Charlie\", \"grades\": [88, 90, 92, 85, 85]},\n",
+ " {\"name\": \"David\", \"grades\": [85, 85, 83, 87, 90]},\n",
+ " {\"name\": \"Eve\", \"grades\": [90, 92, 90, 88, 85]}\n",
+ "]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**Tâches** :\n",
+ "\n",
+ "1. Moyenne de chaque étudiant:\n",
+ "Utilisez une fonction lambda pour calculer la moyenne des notes de chaque étudiant. Affichez le nom de chaque étudiant avec sa moyenne.\n",
+ "\n",
+ "2. Étudiants au-dessus de la moyenne:\n",
+ "Calculez la moyenne générale de tous les étudiants. Ensuite, utilisez une fonction lambda pour filtrer et lister les noms des étudiants dont la moyenne est supérieure à la moyenne générale.\n",
+ "\n",
+ "3. Note la plus élevée et la plus basse:\n",
+ "Pour chaque étudiant, trouvez sa note la plus élevée et sa note la plus basse en utilisant des fonctions lambda. Affichez le nom de l'étudiant avec ses notes les plus élevées et les plus basses."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'Alice': 85.0, 'Bob': 83.2, 'Charlie': 88.0, 'David': 86.0, 'Eve': 89.0}"
+ ]
+ },
+ "execution_count": 29,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dict(map(lambda x: (x['name'],sum(x['grades'])/len(x['grades'])), students))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#1\n",
+ "{'Alice': 85.0, 'Bob': 83.2, 'Charlie': 88.0, 'David': 86.0, 'Eve': 89.0}\n",
+ "#2\n",
+ "{'Charlie': 88.0, 'Eve': 89.0}\n",
+ "#3\n",
+ "{'Alice': {'min': 70, 'max': 92},\n",
+ " 'Bob': {'min': 78, 'max': 88},\n",
+ " 'Charlie': {'min': 85, 'max': 92},\n",
+ " 'David': {'min': 83, 'max': 90},\n",
+ " 'Eve': {'min': 85, 'max': 92}}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[('Alice', 85.0), ('Bob', 83.2), ('Charlie', 88.0), ('David', 86.0), ('Eve', 89.0)]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# 1\n",
+ "moyenne_eleve = list(map(lambda x: (x['name'], sum(x['grades'])/len(x['grades'])), students))\n",
+ "print(moyenne_eleve)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**Conseils** :\n",
+ "\n",
+ "- Pour la tâche 1, vous pourriez utiliser la fonction map() pour appliquer une fonction qui calcule la moyenne à chaque étudiant.\n",
+ "- Pour la tâche 2, après avoir trouvé la moyenne générale, vous pourriez utiliser la fonction filter() pour filtrer les étudiants.\n",
+ "- Pour la tâche 3, vous pourriez utiliser les fonctions max() et min() en combinaison avec des fonctions lambda pour trouver les notes les plus élevées et les plus basses."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/5c-le_typage.ipynb b/5c-le_typage.ipynb
new file mode 100644
index 0000000..950bdba
--- /dev/null
+++ b/5c-le_typage.ipynb
@@ -0,0 +1,155 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Typage dans les fonctions Python"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Introduction"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "À partir de Python 3.5, le langage a introduit un support optionnel pour les annotations de type. Cela vous permet d'indiquer le type attendu des arguments et de la valeur renvoyée d'une fonction. Bien que Python reste un langage à typage dynamique, ces annotations offrent un moyen d'indiquer comment une fonction est censée être utilisée.\n",
+ "\n",
+ "Syntaxe\n",
+ "La syntaxe de base pour annoter une fonction est la suivante:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "SyntaxError",
+ "evalue": "invalid syntax (1725628101.py, line 1)",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;36m Input \u001b[0;32mIn [1]\u001b[0;36m\u001b[0m\n\u001b[0;31m def function_name(arg: arg_type, ...) -> return_type:\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+ ]
+ }
+ ],
+ "source": [
+ "def function_name(arg: arg_type, ...) -> return_type:\n",
+ " pass"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Utilité\n",
+ "1. Lisibilité: Les annotations de type améliorent la lisibilité du code en fournissant des informations supplémentaires sur la façon dont une fonction doit être utilisée.\n",
+ "2. Détection d'erreurs: Avec des outils comme mypy, les annotations de type peuvent être utilisées pour détecter des erreurs potentielles avant l'exécution du code.\n",
+ "3. Documentation: Les annotations agissent comme une forme de documentation pour les autres développeurs (ou pour vous-même à l'avenir)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Exemples\n",
+ "### Fonction simple avec typage"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def greet(name: str) -> str:\n",
+ " return \"Hello, \" + name"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Fonction avec plusieurs arguments"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def add_numbers(a: int, b: int) -> int:\n",
+ " return a + b"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Utilisation de types complexes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Si vous travaillez avec des listes, des dictionnaires ou d'autres structures de données, vous pouvez également spécifier des types pour eux."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from typing import List, Dict\n",
+ "\n",
+ "def average(numbers: List[float]) -> float:\n",
+ " return sum(numbers) / len(numbers)\n",
+ "\n",
+ "def get_name(person: Dict[str, str]) -> str:\n",
+ " return person[\"name\"]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from typing import List, Union\n",
+ "\n",
+ "def average(numbers: List[Union[int, float]]) -> float:\n",
+ " return sum(numbers) / len(numbers)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/6-les-packages.ipynb b/6-les-packages.ipynb
new file mode 100644
index 0000000..cb2f7e2
--- /dev/null
+++ b/6-les-packages.ipynb
@@ -0,0 +1,435 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Importation: packages et fichiers"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Présentation des packages"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Un package est un fichier ou un ensemble de fichiers qui contient des fonctions et des classes qui peuvent être réutilisés dans d'autres programmes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Importer un package dans son environnement de dev depuis votre librairie de package"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour utiliser un package il faut l'importer depuis votre librairie de package. \n",
+ "Celle-ci est constituée par python et par anaconda "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "5\n"
+ ]
+ }
+ ],
+ "source": [
+ "# exemple d'utilisation\n",
+ "import math \n",
+ "\n",
+ "x = 5.8999\n",
+ "print( math.floor(x))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "5"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# en utilisant import math on est obligé de préciser le nom du package:\n",
+ "math.floor(5.8999)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "5\n",
+ "0.9244298774134548\n"
+ ]
+ }
+ ],
+ "source": [
+ "\"\"\" il existe trois manières d'importer un package: deux légales et une illégale\"\"\"\n",
+ "# LEGAL: importer tout un package en s'obligeant en indiquant le nom du package avant:\n",
+ "import math as m\n",
+ "x = m.floor(5.899999)\n",
+ "\n",
+ "\n",
+ "# LEGAL: importer une partie d'un package sans devoir indiquer le nom du package avant de s'en servir:\n",
+ "from random import randint\n",
+ "y = randint(0,10)\n",
+ "print(y)\n",
+ "\n",
+ "# ILLEGAL: importer tout un package sans devoir indiquer le nom du package avant de s'en servir:\n",
+ "from random import *\n",
+ "z = uniform(0,1)\n",
+ "print(z)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Installer un package dans sa librairie de package puis l'importer"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Vous pouvez trouver des packages qui ne sont ni dans python ni anaconda"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ModuleNotFoundError",
+ "evalue": "No module named 'pandas'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32m/Users/jeremyvangansbeg/Documents/project/intro_python/python-course/6-les-packages.ipynb Cell 11\u001b[0m line \u001b[0;36m1\n\u001b[0;32m----> 1\u001b[0m \u001b[39mimport\u001b[39;00m \u001b[39mpandas\u001b[39;00m\n",
+ "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'pandas'"
+ ]
+ }
+ ],
+ "source": [
+ "import pandas"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Vous devez auparavant installer ce package dans votre librairie de package à l'aide de la commande:\n",
+ "- **`pip3 install pandas`**\n",
+ "\n",
+ "Cette commande doit être tapée dans votre terminal"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# vous pouvez ensuite l'importer dans votre environnement de dev\n",
+ "import pipe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Autres commandes utiles:\n",
+ "- pip show \n",
+ "- pip list\n",
+ "- pip freeze"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Se servir d'un package"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour connaitre comment se servir d'un package vous pouvez procéder en deux temps"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "D'abord obtenir la liste des objets et fonctions dans ce package"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(range(10))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ensuite demander l'aide sur une fonction particulière"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on built-in function tan in module math:\n",
+ "\n",
+ "tan(x, /)\n",
+ " Return the tangent of x (measured in radians).\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "help(math.tan)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Les environnements virtuels"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Un environnement virtuel est un dossier qui regroupe une certaine version de python et ainsi que certains packages et leurs versions propres à un projet. Le projet sera exécuté au sein de cet environnement.\n",
+ "Cela permet:\n",
+ "- de garder un environnement léger: savoir quel package il faut installer quand on clone un nouveau projet et non tous les packages de l'ordinateur de la personne qui a créé le projet\n",
+ "- connaître la version des packages et des dépendances où le projet fonctionne (des mises à jour peuvent rendre un projet inutilisable)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il existe de nombreux outils de gestion d'environnement virtuel:\n",
+ "- venv: inclus dans python\n",
+ "- virtualenv: le plus ancien, permet de gérer des version de python 2\n",
+ "- conda: qui vient avec anaconda\n",
+ "- Pipenv: la solution en vue, qui regroupe pip et virtualenv"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Nous allons voir venv, ce n'est pas le plus recommandé pour des usages complexes mais il a l'avantage d'être inclu dans python."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les commandes qu'il faut connaitre (à taper dans le terminal):\n",
+ "- **`python -m venv venv`** : crée un environnement appelé env\n",
+ "- **`venv env/bin/activate`** (Unix) ou **`..\\env\\Scripts\\activate`** (WIndows): active l'environnement virtuel: à partir de maintenant quand on lance un fichier depuis le terminal ou qu'on install un package avec pip, ce sera dans cet environnement\n",
+ "- **`deactivate`** : désactive l'environnement\n",
+ "- **`rm -rf env`** : supprimer l'environnement virtuel\n",
+ "- **`pip freeze > requirements.txt`** : crée un fichier requirements.txt avec tous les packages du projet et leur version\n",
+ "- **`pip install -r requirements.txt`** : install tous les packages fu fichier requirement"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Article médium sur l'équivalent en [Pipenv](https://medium.com/analytics-vidhya/why-pipenv-over-venv-for-python-projects-a51fb6e4f31e) et l'interet d'utiliser ce package"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Importer des fichiers et des packages qu'on a soit même créé."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il existe une bonne pratique chez les développeurs de créer leurs classes et leurs fonctions dans des fichiers séparés (normalement une classe ou une fonction par fichier). Pour pouvoir faire cela il faut pouvoir importer un fichier."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "this is a function from a same level file\n",
+ "this is a function from a same level file\n"
+ ]
+ }
+ ],
+ "source": [
+ "# il est assez facile d'importer une fonction du même niveau\n",
+ "\n",
+ "from Same_level import same_level_function, same_level_function2\n",
+ "same_level_function(\"Same\")\n",
+ "same_level_function2(\"Same\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ModuleNotFoundError",
+ "evalue": "No module named 'child_folder'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[2], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# De même pour un fichier enfant\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mchild_folder\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mchild_file\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m child_file_function\n\u001b[1;32m 4\u001b[0m child_file_function()\n",
+ "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'child_folder'"
+ ]
+ }
+ ],
+ "source": [
+ "# De même pour un fichier enfant\n",
+ "\n",
+ "from child_folder.child_file import child_file_function\n",
+ "child_file_function()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['/Users/jeremyvangansbeg/Documents/project/intro_python/python-course',\n",
+ " '/opt/miniconda3/lib/python39.zip',\n",
+ " '/opt/miniconda3/lib/python3.9',\n",
+ " '/opt/miniconda3/lib/python3.9/lib-dynload',\n",
+ " '',\n",
+ " '/Users/jeremyvangansbeg/Documents/project/intro_python/python-course/venv/lib/python3.9/site-packages']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sys\n",
+ "from pprint import pprint\n",
+ "pprint(sys.path)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Dans l'autre sens ça se complique, voir le fichier child_folder/child_file.py"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**: \n",
+ "- Créer un dossier appelé \"exercice_package\"\n",
+ "- Dans ce dossier créer fichier \"parent_file\" et définir une fonction multiply(a,b) qui permet de multiplier 2 entiers\n",
+ "- Dans le dossier \" exercice_package\", créer un dossier appelé \"principal\" et dedans un fichier \"slevel\" ou vous définissez une fonction add(a,b)\n",
+ "- Dans le dossier \"principal\", créer un dossier appelé \"child_folder\" et dedans un fichier appelé \"child\" ou vous définissez la fonction divide(a,b)\n",
+ "- Enfin dans le dossier \"principal\", créer un fichier \"main\" ou vous calculerez l'arrondi tronqué avec 2 chiffres derrière la virgule de (5 + 2 * 3 ) / 3 en utilisant les trois fonctions définies précédemment. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "exos : 25-74"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "api",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.8"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/7-functions-args.ipynb b/7-functions-args.ipynb
new file mode 100644
index 0000000..83eb035
--- /dev/null
+++ b/7-functions-args.ipynb
@@ -0,0 +1,618 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Arguments de Fonction en Python\n",
+ "\n",
+ "Lorsque nous définissons une fonction en Python, nous spécifions souvent des arguments pour capturer des valeurs que nous souhaitons utiliser dans cette fonction. Ces arguments peuvent être passés de différentes manières, et cette flexibilité est l'une des caractéristiques qui rendent Python si puissant. Dans ce notebook, nous explorerons différentes manières de passer des arguments à une fonction.\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1. Arguments par position\n",
+ "\n",
+ "Les arguments positionnels sont les plus basiques et les plus couramment utilisés. Lorsque nous appelons une fonction avec des arguments positionnels, les valeurs sont assignées aux paramètres de la fonction basées sur leur ordre.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Prénom: John\n",
+ "Nom: Doe\n"
+ ]
+ }
+ ],
+ "source": [
+ "def afficher_nom(prenom, nom):\n",
+ " print(f\"Prénom: {prenom}\")\n",
+ " print(f\"Nom: {nom}\")\n",
+ "\n",
+ "afficher_nom(\"John\", \"Doe\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2. Arguments par nom d'argument (ou mots-clés)\n",
+ "\n",
+ "Plutôt que de dépendre de l'ordre des arguments, nous pouvons également spécifier des arguments en utilisant le nom des paramètres. Cela nous permet de passer des arguments dans un ordre différent de la définition de la fonction, et rend notre code plus lisible."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Nom: Alice\n",
+ "Age: 30\n"
+ ]
+ }
+ ],
+ "source": [
+ "def afficher_details(nom, age):\n",
+ " print(f\"Nom: {nom}\")\n",
+ " print(f\"Age: {age}\")\n",
+ "\n",
+ "afficher_details(age=30, nom=\"Alice\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3. `*args` : Arguments positionnels variables\n",
+ "\n",
+ "Il se peut que nous voulions créer une fonction où le nombre exact d'arguments n'est pas déterminé à l'avance. Dans ces cas, nous pouvons utiliser `*args`, qui permet à une fonction d'accepter un nombre quelconque d'arguments positionnels."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "1\n",
+ "2\n",
+ "3\n",
+ "4\n",
+ "5\n"
+ ]
+ }
+ ],
+ "source": [
+ "def afficher_nombres(*args):\n",
+ " print(type(args))\n",
+ " for num in args:\n",
+ " print(num)\n",
+ "\n",
+ "afficher_nombres(1, 2, 3, 4, 5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 4. `**kwargs` : Arguments par mots-clés variables\n",
+ "\n",
+ "De manière similaire à `*args`, si nous souhaitons permettre un nombre variable d'arguments par mots-clés, nous pouvons utiliser `**kwargs`. Cela traite les arguments comme un dictionnaire où les noms des arguments sont les clés.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "nom: Martin\n",
+ "age: 25\n",
+ "pays: France\n"
+ ]
+ }
+ ],
+ "source": [
+ "def afficher_data(**kwargs):\n",
+ " print(type(kwargs))\n",
+ " for key, value in kwargs.items():\n",
+ " print(f\"{key}: {value}\")\n",
+ "\n",
+ "afficher_data(nom=\"Martin\", age=25, pays=\"France\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Combinaison des différents types d'arguments\n",
+ "\n",
+ "Il est possible de combiner arguments positionnels, arguments par mots-clés, `*args` et `**kwargs` dans une seule fonction. Cependant, leur ordre dans la liste des paramètres de la fonction est crucial :\n",
+ "1. Arguments positionnels\n",
+ "2. Arguments par mots-clés\n",
+ "3. `*args`\n",
+ "4. `**kwargs`\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 2\n",
+ "3\n",
+ "4\n",
+ "5\n",
+ "Majeur : True\n",
+ "nom: Lucas\n",
+ "age: 28\n"
+ ]
+ }
+ ],
+ "source": [
+ "def exemple_combinaison(a, b, *args, majeur=True, **kwargs):\n",
+ " print(a, b)\n",
+ " for arg in args:\n",
+ " print(arg)\n",
+ " print(f\"Majeur : {majeur}\")\n",
+ " for key, value in kwargs.items():\n",
+ " print(f\"{key}: {value}\")\n",
+ "\n",
+ "exemple_combinaison(1, 2, 3, 4, 5, nom=\"Lucas\", age=28)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Conclusion\n",
+ "\n",
+ "Les arguments de fonction en Python offrent une flexibilité remarquable, permettant aux développeurs de créer des fonctions modulaires et réutilisables. Que vous passiez des arguments de manière positionnelle, par mots-clés, ou que vous utilisiez `*args` et `**kwargs` pour accepter un nombre variable d'arguments, la maîtrise de ces concepts est essentielle pour la programmation efficace en Python.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 5. Unpacking de collections\n",
+ "\n",
+ "L'unpacking permet de décomposer les éléments d'une collection directement dans des variables. En Python, nous pouvons \"déballer\" ou \"décomposer\" les éléments des listes, tuples et dictionnaires dans des variables individuelles. Cela est souvent utilisé en combinaison avec les fonctions pour passer des arguments.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 5.1 Unpacking de listes et tuples"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 2 3\n",
+ "4 5\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Unpacking de liste\n",
+ "nombres = [1, 2, 3]\n",
+ "a, b, c = nombres\n",
+ "print(a, b, c)\n",
+ "\n",
+ "# Unpacking de tuple\n",
+ "coords = (4, 5)\n",
+ "x, y = coords\n",
+ "print(x, y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 5.2 Utilisation de l'unpacking avec *args\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(1, 2, 3, 4, 5)\n",
+ "15\n"
+ ]
+ }
+ ],
+ "source": [
+ "def somme(*args):\n",
+ " print(args)\n",
+ " return sum(args)\n",
+ "\n",
+ "# Si nous avons une liste\n",
+ "nombres = [1, 2, 3, 4, 5]\n",
+ "\n",
+ "# Nous pouvons utiliser l'unpacking pour passer les éléments de la liste comme arguments\n",
+ "print(somme(*nombres))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "15\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Bien comprendre la différence avec cette syntaxe\n",
+ "\n",
+ "def somme(args):\n",
+ " return sum(args)\n",
+ "\n",
+ "nombres = [1, 2, 3, 4, 5]\n",
+ "\n",
+ "# Ici args est un argument qui est une liste\n",
+ "print(somme(nombres))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3\n",
+ "10\n"
+ ]
+ }
+ ],
+ "source": [
+ "def somme(a, b, *args):\n",
+ " total = a + b\n",
+ " for num in args:\n",
+ " total += num\n",
+ " return total\n",
+ "\n",
+ "# Utilisation de la fonction\n",
+ "print(somme(1, 2)) # 3, car nous n'avons que deux arguments\n",
+ "print(somme(1, 2, 3, 4)) # 10, car nous avons des arguments supplémentaires\\"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 5.3 Unpacking de dictionnaires\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Nom: Alice, Age: 30\n",
+ "Nom: Alice, Age: 30\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Unpacking de dictionnaire\n",
+ "personne = {\"nom\": \"Alice\", \"age\": 30}\n",
+ "\n",
+ "# ** peut être utilisé pour déballer le contenu d'un dictionnaire en arguments par mots-clés\n",
+ "def afficher_personne(nom, age):\n",
+ " print(f\"Nom: {nom}, Age: {age}\")\n",
+ "\n",
+ "afficher_personne(**personne)\n",
+ "\n",
+ "afficher_personne(nom=\"Alice\", age=30)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 5.4 Utilisation de l'unpacking avec **kwargs\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "nom: Lucas\n",
+ "age: 28\n",
+ "pays: France\n"
+ ]
+ }
+ ],
+ "source": [
+ "def afficher_data(**kwargs):\n",
+ " for key, value in kwargs.items():\n",
+ " print(f\"{key}: {value}\")\n",
+ "\n",
+ "# Si nous avons un dictionnaire\n",
+ "data = {\"nom\": \"Lucas\", \"age\": 28, \"pays\": \"France\"}\n",
+ "\n",
+ "# Nous pouvons utiliser l'unpacking pour passer les éléments du dictionnaire comme arguments\n",
+ "afficher_data(**data)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "nom: Lucas\n",
+ "age: 28\n",
+ "pays: France\n",
+ "nom: Lucas\n",
+ "age: 28\n",
+ "pays: France\n",
+ "profession: Développeur\n",
+ "nom: Lucas\n",
+ "age: 28\n",
+ "pays: France\n",
+ "profession: Développeur\n",
+ "hobby: Lecture\n"
+ ]
+ }
+ ],
+ "source": [
+ "def afficher_profil(**kwargs):\n",
+ " for key, value in kwargs.items():\n",
+ " print(f\"{key}: {value}\")\n",
+ "\n",
+ "# Utilisation normale\n",
+ "afficher_profil(nom=\"Lucas\", age=28, pays=\"France\")\n",
+ "\n",
+ "# Plus tard, vous réalisez que vous voulez ajouter une profession sans changer la signature de la fonction\n",
+ "afficher_profil(nom=\"Lucas\", age=28, pays=\"France\", profession=\"Développeur\")\n",
+ "\n",
+ "# Encore plus tard, vous voulez ajouter une autre information\n",
+ "afficher_profil(nom=\"Lucas\", age=28, pays=\"France\", profession=\"Développeur\", hobby=\"Lecture\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Unpacking de *args vs **kwargs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Bonjour Camille, vous avez 32 ans\n",
+ "Bonjour Camille, vous avez 32 ans\n"
+ ]
+ }
+ ],
+ "source": [
+ "def greetings(name,age):\n",
+ " return f\"Bonjour {name}, vous avez {age} ans\"\n",
+ "\n",
+ "my_args = [\"Camille\", 32]\n",
+ "\n",
+ "print(greetings(*my_args))\n",
+ "\n",
+ "my_kwargs = {\"name\":\"Camille\", \"age\": 32}\n",
+ "\n",
+ "print(greetings(**my_kwargs))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Conclusion sur l'Unpacking\n",
+ "\n",
+ "L'unpacking est une fonctionnalité puissante en Python qui permet une affectation multiple et une manière concise de passer des arguments à des fonctions. Que ce soit pour les listes, les tuples ou les dictionnaires, l'unpacking facilite la manipulation et le passage de collections.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 6. Arguments par défaut (valeurs par défaut)\n",
+ "\n",
+ "En Python, nous pouvons définir une valeur par défaut pour un ou plusieurs arguments dans la signature de la fonction. Cela signifie que si l'argument n'est pas fourni lors de l'appel de la fonction, la valeur par défaut sera utilisée à la place.\n",
+ "\n",
+ "### 6.1 Exemple basique\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Bonjour, Alice!\n",
+ "Bonjour, Utilisateur!\n"
+ ]
+ }
+ ],
+ "source": [
+ "def saluer(nom=\"Utilisateur\"):\n",
+ " return f\"Bonjour, {nom}!\"\n",
+ "\n",
+ "# Appel avec un argument\n",
+ "print(saluer(\"Alice\"))\n",
+ "\n",
+ "# Appel sans argument, utilisant la valeur par défaut\n",
+ "print(saluer())\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 6.2 Précautions avec les arguments par défaut\n",
+ "\n",
+ "Il est important de faire preuve de prudence lorsque vous utilisez des objets mutables, comme des listes ou des dictionnaires, comme valeurs par défaut. Ces objets sont créés une seule fois lors de la définition de la fonction, ce qui peut entraîner un comportement inattendu.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1]\n",
+ "[1, 2]\n"
+ ]
+ }
+ ],
+ "source": [
+ "def ajouter_a_liste(valeur, liste_defaut=[]):\n",
+ " liste_defaut.append(valeur)\n",
+ " return liste_defaut\n",
+ "\n",
+ "print(ajouter_a_liste(1))\n",
+ "print(ajouter_a_liste(2))\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Notez comment la même liste est utilisée à chaque appel de fonction. Pour éviter ce comportement, nous utilisons généralement une valeur par défaut de `None` et initialisons l'objet mutable à l'intérieur de la fonction."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1]\n",
+ "[2]\n"
+ ]
+ }
+ ],
+ "source": [
+ "def ajouter_a_liste_corrige(valeur, liste_defaut=None):\n",
+ " if liste_defaut is None:\n",
+ " liste_defaut = []\n",
+ " liste_defaut.append(valeur)\n",
+ " return liste_defaut\n",
+ "\n",
+ "print(ajouter_a_liste_corrige(1))\n",
+ "print(ajouter_a_liste_corrige(2))\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Conclusion sur les arguments par défaut\n",
+ "\n",
+ "Les arguments par défaut permettent d'écrire des fonctions flexibles qui peuvent être appelées avec un nombre variable d'arguments. Ils sont particulièrement utiles pour définir des comportements par défaut pour une fonction. Cependant, il est essentiel de faire preuve de prudence lors de l'utilisation d'objets mutables comme valeurs par défaut pour éviter des comportements inattendus.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "venv",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "-1.-1.-1"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/8-fonction-recursive.ipynb b/8-fonction-recursive.ipynb
new file mode 100644
index 0000000..fc37b32
--- /dev/null
+++ b/8-fonction-recursive.ipynb
@@ -0,0 +1,192 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Fonctions récursives en Python\n",
+ "\n",
+ "Une fonction récursive est une fonction qui s'appelle elle-même. La récursivité est une technique puissante de programmation, mais elle nécessite une compréhension approfondie et une attention particulière pour éviter des appels infinis. Dans ce notebook, nous explorerons les bases de la récursivité et quelques exemples classiques.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Principe de base de la récursivité\n",
+ "\n",
+ "Pour qu'une fonction récursive fonctionne correctement, elle doit avoir :\n",
+ "\n",
+ "1. **Un cas de base** : une condition qui arrête la récursivité.\n",
+ "2. **Un pas récursif** : une partie où la fonction s'appelle elle-même, généralement avec des arguments modifiés.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exemple : Factorielle\n",
+ "\n",
+ "La factorielle d'un nombre non négatif \\( n \\) est le produit de tous les entiers positifs inférieurs ou égaux à \\( n \\). Elle est généralement notée par \\( n! \\).\n",
+ "\n",
+ "La factorielle peut être définie récursivement comme suit :\n",
+ "1. \\( 0! = 1 \\) (cas de base)\n",
+ "2. \\( n! = n \\times (n-1)! \\) (pour \\( n > 0 \\))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "120\n"
+ ]
+ }
+ ],
+ "source": [
+ "def factorielle(n):\n",
+ " # Cas de base\n",
+ " if n == 0:\n",
+ " return 1\n",
+ " # Pas récursif\n",
+ " else:\n",
+ " return n * factorielle(n-1)\n",
+ "\n",
+ "print(factorielle(5)) # Devrait afficher 120 (car 5! = 5x4x3x2x1 = 120)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Étape par étape pour `factorielle(5)` :\n",
+ "\n",
+ "1. **Appel initial** : `factorielle(5)`\n",
+ " - Le programme teste `if n == 0` (5 n'est pas égal à 0), donc on passe au `else`.\n",
+ " - On entre dans le cas récursif : `n * factorielle(n - 1)`, ce qui devient `5 * factorielle(4)`.\n",
+ "\n",
+ "2. **Deuxième appel** : `factorielle(4)`\n",
+ " - Encore une fois, `n == 0` est faux (car 4 n'est pas égal à 0).\n",
+ " - On calcule `4 * factorielle(3)`.\n",
+ "\n",
+ "3. **Troisième appel** : `factorielle(3)`\n",
+ " - On teste encore `if n == 0`, ce qui est faux (car 3 n'est pas égal à 0).\n",
+ " - On calcule `3 * factorielle(2)`.\n",
+ "\n",
+ "4. **Quatrième appel** : `factorielle(2)`\n",
+ " - Le test `if n == 0` échoue encore (2 n'est pas égal à 0).\n",
+ " - On calcule `2 * factorielle(1)`.\n",
+ "\n",
+ "5. **Cinquième appel** : `factorielle(1)`\n",
+ " - Le test `if n == 0` échoue encore (1 n'est pas égal à 0).\n",
+ " - On calcule `1 * factorielle(0)`.\n",
+ "\n",
+ "6. **Sixième appel** : `factorielle(0)`\n",
+ " - Cette fois, `if n == 0` est **vrai** !\n",
+ " - On atteint le **cas de base**, donc la fonction retourne 1.\n",
+ "\n",
+ "#### Maintenant, revenons en arrière (remontée de la récursion) :\n",
+ "Après avoir atteint le cas de base, on revient à chaque étape précédente et on effectue les multiplications :\n",
+ "\n",
+ "7. **Retour à `factorielle(1)`** :\n",
+ " - On remplace `factorielle(0)` par 1 (valeur obtenue du cas de base).\n",
+ " - On calcule : `1 * 1 = 1`. La fonction retourne 1.\n",
+ "\n",
+ "8. **Retour à `factorielle(2)`** :\n",
+ " - On remplace `factorielle(1)` par 1.\n",
+ " - On calcule : `2 * 1 = 2`. La fonction retourne 2.\n",
+ "\n",
+ "9. **Retour à `factorielle(3)`** :\n",
+ " - On remplace `factorielle(2)` par 2.\n",
+ " - On calcule : `3 * 2 = 6`. La fonction retourne 6.\n",
+ "\n",
+ "10. **Retour à `factorielle(4)`** :\n",
+ " - On remplace `factorielle(3)` par 6.\n",
+ " - On calcule : `4 * 6 = 24`. La fonction retourne 24.\n",
+ "\n",
+ "11. **Retour à `factorielle(5)`** :\n",
+ " - On remplace `factorielle(4)` par 24.\n",
+ " - On calcule : `5 * 24 = 120`. La fonction retourne 120.\n",
+ "\n",
+ "### Résultat final :\n",
+ "La fonction retourne finalement 120 pour `factorielle(5)`.\n",
+ "\n",
+ "### Résumé du processus récursif :\n",
+ "- Chaque appel récursif divise le problème en un sous-problème plus petit, en soustrayant 1 à \\( n \\).\n",
+ "- La récursion s'arrête lorsqu'on atteint le **cas de base** (quand \\( n == 0 \\)).\n",
+ "- Ensuite, chaque étape effectue les multiplications lors du retour des appels récursifs, ce qui permet de remonter jusqu'à la solution finale.\n",
+ "\n",
+ "### Visualisation :\n",
+ "\n",
+ "```\n",
+ "factorielle(5) => 5 * factorielle(4)\n",
+ "factorielle(4) => 4 * factorielle(3)\n",
+ "factorielle(3) => 3 * factorielle(2)\n",
+ "factorielle(2) => 2 * factorielle(1)\n",
+ "factorielle(1) => 1 * factorielle(0)\n",
+ "factorielle(0) => 1 # Cas de base\n",
+ "```\n",
+ "\n",
+ "En remontant :\n",
+ "```\n",
+ "factorielle(1) => 1 * 1 = 1\n",
+ "factorielle(2) => 2 * 1 = 2\n",
+ "factorielle(3) => 3 * 2 = 6\n",
+ "factorielle(4) => 4 * 6 = 24\n",
+ "factorielle(5) => 5 * 24 = 120\n",
+ "```\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Exercice : Suite de Fibonacci\n",
+ "\n",
+ "La suite de Fibonacci est une série de nombres où chaque nombre est la somme des deux précédents. Les deux premiers nombres de la suite de Fibonacci sont généralement 0 et 1.\n",
+ "\n",
+ "La suite commence comme suit : 0,1,1,2,3,5,8,13,21,34,…\n",
+ "\n",
+ "La suite de Fibonacci peut être définie récursivement comme suit :\n",
+ "1. \\( F(0) = 0 \\)\n",
+ "2. \\( F(1) = 1 \\)\n",
+ "3. \\( F(n) = F(n-1) + F(n-2) \\) (pour \\( n > 1 \\))\n",
+ "\n",
+ "Écrire une fonction récursive qui renvoie la valeur du n-ème nombre de la suite de Finocci.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "venv",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.12"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/9-falsy-values.ipynb b/9-falsy-values.ipynb
new file mode 100644
index 0000000..e25879a
--- /dev/null
+++ b/9-falsy-values.ipynb
@@ -0,0 +1,131 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Falsy Values en Python\n",
+ "\n",
+ "En Python, certaines valeurs sont considérées comme \"falsy\" lorsqu'elles sont évaluées dans un contexte booléen, tel qu'une condition `if`. Si une valeur est \"falsy\", cela signifie qu'elle sera considérée comme `False` dans un contexte booléen, sinon elle est considérée comme \"truthy\" et sera évaluée comme **`True`**.\n",
+ "\n",
+ "\n",
+ "Exemples de valeurs Falsy:\n",
+ "- **`None`**\n",
+ "- **`False`**\n",
+ "- **`0`** (zéro - pour tous les types numériques: int, float, complex)\n",
+ "- **`\"\"`** (chaîne vide)\n",
+ "- **`[]`** (liste vide)\n",
+ "- **`{}`** (dictionnaire vide)\n",
+ "- **`set()`** (ensemble vide)\n",
+ "- **`()`** (tuple vide)\n",
+ "- Et d'autres objets qui définissent leur méthode **`__bool__()`** ou **`__len__()`** pour renvoyer False ou 0 respectivement."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Démonstration:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'None' est falsy\n",
+ "'False' est falsy\n",
+ "'0' est falsy\n",
+ "'' est falsy\n",
+ "'[]' est falsy\n",
+ "'{}' est falsy\n",
+ "'set()' est falsy\n",
+ "'()' est falsy\n"
+ ]
+ }
+ ],
+ "source": [
+ "falsy_values = [None, False, 0, \"\", [], {}, set(), ()]\n",
+ "\n",
+ "for value in falsy_values:\n",
+ " if value:\n",
+ " print(f\"'{value}' est truthy\")\n",
+ " else:\n",
+ " print(f\"'{value}' est falsy\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Attention, il y a des valeurs qu'on pourrait penser falsy mais qui ne le sont pas :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'None' est falsy\n",
+ "'False' est falsy\n",
+ "'0' est falsy\n",
+ "'' est falsy\n",
+ "'[]' est falsy\n",
+ "'{}' est falsy\n",
+ "'set()' est falsy\n",
+ "'()' est falsy\n",
+ "' ' est truthy\n",
+ "'False' est truthy\n",
+ "'10' est truthy\n",
+ "'[False]' est truthy\n",
+ "'{'': None}' est truthy\n",
+ "'{None}' est truthy\n",
+ "'(False,)' est truthy\n"
+ ]
+ }
+ ],
+ "source": [
+ "falsy_values = [None, False, 0, \"\", [], {}, set(), ()]\n",
+ "truthy_values = [\" \", \"False\", 10, [False], {\"\": None}, set([None]), (False,)]\n",
+ "\n",
+ "all_values = falsy_values + truthy_values\n",
+ "\n",
+ "for value in all_values:\n",
+ " if value:\n",
+ " print(f\"'{value}' est truthy\")\n",
+ " else:\n",
+ " print(f\"'{value}' est falsy\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "venv",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.12"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/README.md b/README.md
index cbb918a..e403b0d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,62 @@
-# cours-python
-Cours python pour simplon
+# Projet d'Introduction à Python
+
+Ce projet contient une série de notebooks Jupyter pour apprendre les bases de Python, y compris les variables, les structures de données, les conditions, les boucles, les fonctions, la programmation orientée objet, et plus encore.
+
+## Contenu des Notebooks
+
+- **0 - Installation Python.pptx** : Présentation sur l'installation de Python.
+- **1-introduction.ipynb** : Introduction à Python.
+- **2-les-variables.ipynb** : Les variables en Python.
+- **3-data-structures.ipynb** : Les structures de données en Python.
+- **3b-data-structures.ipynb** : Suite des structures de données.
+- **4-les_conditions_et_les_boucles.ipynb** : Les conditions et les boucles.
+- **5-Les_fonctions.ipynb** : Les fonctions en Python.
+- **5b-lambda.ipynb** : Les fonctions lambda.
+- **5c-le_typage.ipynb** : Le typage en Python.
+- **6-les-packages.ipynb** : Gestion des packages et environnements virtuels.
+- **7-functions-args.ipynb** : Les arguments de fonctions.
+- **8-fonction-recursive.ipynb** : Les fonctions récursives.
+- **9-falsy-values.ipynb** : Les valeurs falsy en Python.
+- **exos.ipynb** : Exercices pratiques.
+
+## Programmation Orientée Objet (POO)
+
+Le dossier `oop` contient des notebooks et des scripts pour apprendre la programmation orientée objet en Python :
+
+- **1-Introduction_POO.ipynb** : Introduction à la POO.
+- **class_to_test.py** : Script de classe à tester.
+- **correction_conce_bis.py** : Correction des exercices de conception.
+
+## Utilisation des Environnements Virtuels
+
+Dans le notebook **6-les-packages.ipynb**, vous apprendrez à utiliser les environnements virtuels avec `venv`, `virtualenv`, et `conda`.
+
+### Commandes Principales
+
+- **Créer un environnement virtuel** :
+ ```bash
+ python -m venv venv
+ ```
+- **Activer l'environnement virtuel** :
+ - Unix : `source venv/bin/activate`
+ - Windows : `venv\Scripts\activate`
+- **Désactiver l'environnement virtuel** :
+ ```bash
+ deactivate
+ ```
+
+## Installation des Dépendances
+
+Pour installer les dépendances nécessaires, utilisez la commande suivante après avoir activé votre environnement virtuel :
+
+```bash
+pip install -r requirements.txt
+```
+
+## Contribuer
+
+Les contributions sont les bienvenues ! Veuillez soumettre une pull request ou ouvrir une issue pour discuter des changements que vous souhaitez apporter.
+
+## Licence
+
+Ce projet est sous licence MIT. Voir le fichier `LICENSE` pour plus de détails.
diff --git a/Same_level.py b/Same_level.py
new file mode 100644
index 0000000..30aec66
--- /dev/null
+++ b/Same_level.py
@@ -0,0 +1,12 @@
+def same_level_function(source):
+ if source == "Same":
+ print("this is a function from a same level file")
+ elif source == "Child":
+ print("this is a function from a parent level file")
+
+
+def same_level_function2(source):
+ if source == "Same":
+ print("this is a function from a same level file")
+ elif source == "Child":
+ print("this is a function from a parent level file")
\ No newline at end of file
diff --git a/exos.ipynb b/exos.ipynb
new file mode 100644
index 0000000..cd9a9ac
--- /dev/null
+++ b/exos.ipynb
@@ -0,0 +1,2153 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 France 36.2\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 1\n",
+ "a = 1\n",
+ "b = 'France'\n",
+ "c = 36.2\n",
+ "\n",
+ "a, b, c = 1, \"France\", 36.2\n",
+ "\n",
+ "print(a,b,c)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "ça va\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 2\n",
+ "ch = \"Salut\"\n",
+ "ch = \"ça va\"\n",
+ "print(ch)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 3\n",
+ "x = 3\n",
+ "y = 8.5\n",
+ "\n",
+ "x = str(x)\n",
+ "y = str(y)\n",
+ "\n",
+ "print(type(x))\n",
+ "print(type(y))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Le poids de l'utilisateur est de : 90kg\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 4\n",
+ "poids = input(\"Quel est votre poids ?\")\n",
+ "\n",
+ "print(\"Le poids de l'utilisateur est de : \" + poids + \"kg\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Chaîne de caractères\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 5\n",
+ "var = \"Bonjour\"\n",
+ "\n",
+ "if type(var) is int:\n",
+ " print(\"Entier\")\n",
+ "elif type(var) is str:\n",
+ " print(\"Chaîne de caractères\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Positive\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 6\n",
+ "d = 5\n",
+ "\n",
+ "if d > 0: \n",
+ " print(\"Positive\")\n",
+ "\n",
+ "else :\n",
+ " print(\"Négative\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "L'utilisateur est mineur\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 7\n",
+ "age = int(input(\"Quel âge avez-vous ?\"))\n",
+ "\n",
+ "if age >= 18 :\n",
+ " print(\"L'utilisateur est majeur\")\n",
+ "else :\n",
+ " print(\"L'utilisateur est mineur\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1\n",
+ "2\n",
+ "3\n",
+ "4\n",
+ "5\n",
+ "6\n",
+ "7\n",
+ "8\n",
+ "9\n",
+ "10\n",
+ "11\n",
+ "12\n",
+ "13\n",
+ "14\n",
+ "15\n",
+ "16\n",
+ "17\n",
+ "18\n",
+ "19\n",
+ "20\n",
+ "1\n",
+ "2\n",
+ "3\n",
+ "4\n",
+ "5\n",
+ "6\n",
+ "7\n",
+ "8\n",
+ "9\n",
+ "10\n",
+ "11\n",
+ "12\n",
+ "13\n",
+ "14\n",
+ "15\n",
+ "16\n",
+ "17\n",
+ "18\n",
+ "19\n",
+ "20\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 8\n",
+ "for i in range(1,21):\n",
+ " print(i)\n",
+ "\n",
+ "i=1\n",
+ "while i < 21 :\n",
+ " print(i)\n",
+ " i+=1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 112,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "11\n",
+ "13\n",
+ "15\n",
+ "17\n",
+ "19\n"
+ ]
+ }
+ ],
+ "source": [
+ "# # Exo 9\n",
+ "# for i in range(11, 20, 2):\n",
+ "# print(i)\n",
+ "\n",
+ "i=11\n",
+ "while i < 21 :\n",
+ " print(i)\n",
+ " i+=2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 10\n",
+ "\n",
+ "[x for x in range(1,11)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0, 2, 4, 6, 8, 10]"
+ ]
+ },
+ "execution_count": 27,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 11\n",
+ "[x for x in range(0,11,2)]\n",
+ "\n",
+ "# -- \n",
+ "list(range(0,11,2))\n",
+ "\n",
+ "# --\n",
+ "[x for x in range(0,11) if x % 2 == 0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 2, 2, 3, 4, 6, 8, 9, 12]"
+ ]
+ },
+ "execution_count": 30,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 12\n",
+ "L = [6,8,3,4,1,12,2,9,2]\n",
+ "L.sort()\n",
+ "L"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 13\n",
+ "L = [6,8,3,4,1,12,2,9,2]\n",
+ "L.count(1)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[10, 25, 30, 45, 90, 'ab', 'cd', 'ef']\n",
+ "[10, 25, 30, 45, 90, 'ab', 'cd', 'ef']\n",
+ "[10, 25, 30, 45, 90, 'ab', 'cd', 'ef']\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 14\n",
+ "L = []\n",
+ "L.extend([10,25,30,45,90, \"ab\", \"cd\", \"ef\"])\n",
+ "print(L)\n",
+ "\n",
+ "# ou\n",
+ "L = []\n",
+ "L += [10,25,30,45,90, \"ab\", \"cd\", \"ef\"]\n",
+ "print(L)\n",
+ "\n",
+ "# ou\n",
+ "L = []\n",
+ "L_extend = [10,25,30,45,90, \"ab\", \"cd\", \"ef\"]\n",
+ "for elem in L_extend:\n",
+ " L.append(elem)\n",
+ "print(L)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 324,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 4, 7, 10]"
+ ]
+ },
+ "execution_count": 324,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "#Exo 15\n",
+ "L = [x for x in range(1,11)]\n",
+ "L1 = L[::3]\n",
+ "L1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 65,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'acefnr'"
+ ]
+ },
+ "execution_count": 65,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 16\n",
+ "c = 'france'\n",
+ "c = list(c)\n",
+ "c.sort()\n",
+ "c = \"\".join(c)\n",
+ "c\n",
+ "\n",
+ "# ----- #\n",
+ "\n",
+ "c = 'france'\n",
+ "c = sorted(c)\n",
+ "c = \"\".join(c)\n",
+ "c"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 67,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[9, 3, 'p', 'b']\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 17\n",
+ "L1 = [9, 8, 7, 14, 3, 2, \"a\", \"p\", \"bonjour\", \"b\"]\n",
+ "L2 = [\"b\", 1, 9.2, 6, 3, 9, \"p\"]\n",
+ "\n",
+ "L3_set = set(L1) & set(L2)\n",
+ "L3 = list(L3_set) \n",
+ "print(L3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 83,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[2, 8, 9, 12, 15]"
+ ]
+ },
+ "execution_count": 83,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(map(lambda x : x[1], L))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# 18\n",
+ "\n",
+ "L = [(\"Pomme\", 15), (\"Banane\", 8), (\"Fraise\", 12), (\"Kiwi\", 9), (\"Peche\", 2)]\n",
+ "\n",
+ "L.sort(key=lambda x : x[1])\n",
+ "\n",
+ "# ou\n",
+ "\n",
+ "L = [(\"Pomme\", 15), (\"Banane\", 8), (\"Fraise\", 12), (\"Kiwi\", 9), (\"Peche\", 2)]\n",
+ "\n",
+ "def sort_second_elem(elem):\n",
+ " return elem[1]\n",
+ "\n",
+ "L.sort(key=sort_second_elem)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 89,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ednom el tuot ruojnoB'"
+ ]
+ },
+ "execution_count": 89,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# 19\n",
+ "ch = \"Bonjour tout le monde\"\n",
+ "\n",
+ "ch[::-1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 90,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3 7\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 20 \n",
+ "mydict = {\"Pomme\": 3,\n",
+ " \"Banane\": 7,\n",
+ " \"Kiwi\": 1}\n",
+ "\n",
+ "print(mydict[\"Pomme\"], mydict['Banane'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 91,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "34"
+ ]
+ },
+ "execution_count": 91,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 21\n",
+ "mydict = {\"Pomme\": 15,\n",
+ " \"Banane\": 8,\n",
+ " \"Kiwi\": 9,\n",
+ " \"Peche\":2 }\n",
+ "\n",
+ "sum([x for x in mydict.values()])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 102,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "187.63\n",
+ "187.63\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 22\n",
+ "\n",
+ "c = 187.632587\n",
+ "\n",
+ "\"{:.2f}\".format(c)\n",
+ "\n",
+ "# ---\n",
+ "\n",
+ "print(f\"{c:.2f}\")\n",
+ "\n",
+ "# ---\n",
+ "\n",
+ "print(f\"{187.632587:.2f}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 105,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Je m'appelle Julien et j'ai 32 ans, J'apprends le langage Python\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 23\n",
+ "monNom = \"Julien\"\n",
+ "age = 32\n",
+ "nomLangage = \"Python\"\n",
+ "\n",
+ "print(f\"Je m'appelle {monNom} et j'ai {age} ans, J'apprends le langage {nomLangage}\".format())\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 109,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "8 x 0 = 0\n",
+ "8 x 1 = 8\n",
+ "8 x 2 = 16\n",
+ "8 x 3 = 24\n",
+ "8 x 4 = 32\n",
+ "8 x 5 = 40\n",
+ "8 x 6 = 48\n",
+ "8 x 7 = 56\n",
+ "8 x 8 = 64\n",
+ "8 x 9 = 72\n",
+ "8 x 10 = 80\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 24\n",
+ "for i in range(11):\n",
+ " print(\"{} x {} = {}\".format(8, i, 8*i))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "/Users/jeremyvangansbeg/Documents/project/intro_python/python-course\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 25\n",
+ "import os\n",
+ "\n",
+ "print(os.getcwd())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2, 3, 4, 5]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 26\n",
+ "L = [1,2,3,4,5]\n",
+ "\n",
+ "L.remove(1)\n",
+ "\n",
+ "print(L)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "('my_file', '.txt')\n",
+ "File Name: my_file\n",
+ "File Extension: .txt\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 27\n",
+ "import os\n",
+ " \n",
+ "# this will return a tuple of root and extension\n",
+ "split_tup = os.path.splitext('my_file.txt')\n",
+ "print(split_tup)\n",
+ " \n",
+ "# extract the file name and extension\n",
+ "file_name = split_tup[0]\n",
+ "file_extension = split_tup[1]\n",
+ " \n",
+ "print(\"File Name: \", file_name)\n",
+ "print(\"File Extension: \", file_extension)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "8 x 0 = 0\n",
+ "8 x 1 = 8\n",
+ "8 x 2 = 16\n",
+ "8 x 3 = 24\n",
+ "8 x 4 = 32\n",
+ "8 x 5 = 40\n",
+ "8 x 6 = 48\n",
+ "8 x 7 = 56\n",
+ "8 x 8 = 64\n",
+ "8 x 9 = 72\n",
+ "8 x 10 = 80\n",
+ "Temps d'execution du programme (secondes) : 6.198883056640625e-05\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 28\n",
+ "import time\n",
+ "\n",
+ "start_time = time.time()\n",
+ "\n",
+ "for i in range(11):\n",
+ " print(\"{} x {} = {}\".format(8, i, 8*i))\n",
+ "\n",
+ "execution_time = time.time() - start_time\n",
+ "\n",
+ "print(\"Temps d'execution du programme (secondes) :\", execution_time)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['d', 8, 3, 'ch', 6, 2, 's', 7]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 29\n",
+ "import random\n",
+ "\n",
+ "L = [3,6,8,7,2, \"s\", \"ch\", \"d\"]\n",
+ "\n",
+ "random.shuffle(L)\n",
+ "\n",
+ "print(L)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "30\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 30\n",
+ "import random\n",
+ "\n",
+ "print(random.randint(20,30))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n",
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n",
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n",
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n",
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n",
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n",
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n",
+ "5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 31\n",
+ "for j in range(8) :\n",
+ " print(*[i for i in range(5,21)]) "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[3, 6, 9, 12, 15, 18, 21, 24]\n",
+ "[1, 2, 3, 4, 5, 6, 7, 8]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 32\n",
+ "L = [i for i in range(3,25,3)]\n",
+ "print(L)\n",
+ "L1 = [int(i/3) for i in range(3,25,3)]\n",
+ "print(L1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[5, 2, 8]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 33\n",
+ "L= [-6, 5, -3, -1, 2, 8, -3.6]\n",
+ "\n",
+ "L1 = [i for i in L if i > 0 ]\n",
+ "print(L1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "9\n",
+ "2\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 34\n",
+ "def f(a,b,x):\n",
+ " return a*(x**3) + 2*a*(x**2) +b\n",
+ "\n",
+ "print(f(3,0,1))\n",
+ "print(f(0,2,2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n",
+ "False\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 35\n",
+ "def verif_presence(a,L):\n",
+ " if a in L :\n",
+ " return True\n",
+ " else:\n",
+ " return False\n",
+ " \n",
+ "print(verif_presence(2, list(range(7))))\n",
+ "print(verif_presence(-1, [3,6,9,7,\"abcr\"]))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "[1, 4, 9]\n",
+ "14\n",
+ "\n",
+ "[3, 0, 1, 8]\n",
+ "12\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 36\n",
+ "def somme_des_chiffres(num):\n",
+ " str_num = str(num)\n",
+ " print(type(str_num))\n",
+ " ma_liste_de_chiffres = [int(chiffre) for chiffre in str_num]\n",
+ " print(ma_liste_de_chiffres)\n",
+ " return sum(ma_liste_de_chiffres)\n",
+ " \n",
+ "print(somme_des_chiffres(149))\n",
+ "print(somme_des_chiffres(3018))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "24\n",
+ "1\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 37\n",
+ "def calcul_somme(L):\n",
+ " \n",
+ " return sum(L)\n",
+ " \n",
+ "print(calcul_somme([3,2,6,9,-1,5]))\n",
+ "print(calcul_somme([-3, -6,0,1,2,7]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[-1, 0, 1, 3, 5, 7]\n",
+ "[-3, 0, 1, 3.2, 5, 9, 10]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 38\n",
+ "def supprimer_doublons(L):\n",
+ " L_cleaned = list(set(L))\n",
+ " L_cleaned.sort()\n",
+ " return L_cleaned\n",
+ " \n",
+ "print(supprimer_doublons([0,3,5,7,3,5,1,-1]))\n",
+ "print(supprimer_doublons([0,5,9,10,3.2,1,-3]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'julien': 14, 'laurent': 31, 'baptiste': 29}\n",
+ "{'poids': 65.3}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 39\n",
+ "def ajout_element_dict(cle, valeur,d):\n",
+ " d[cle] = valeur\n",
+ " return d\n",
+ "print(ajout_element_dict(\"baptiste\", 29, {\"julien\" :14, \"laurent\"\n",
+ " :31}))\n",
+ "print(ajout_element_dict(\"poids\", 65.3, {}))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 57,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "8\n",
+ "7\n",
+ "8\n",
+ "7\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 40\n",
+ "def maximum(L):\n",
+ " L.sort()\n",
+ " return L[-1]\n",
+ "print(maximum([-9,2,4,1,8]))\n",
+ "print(maximum([-3,1,7,6,2,3]))\n",
+ "\n",
+ "# ---\n",
+ "def maximum(L):\n",
+ " maximum = L[0]\n",
+ " for value in L :\n",
+ " if value > maximum :\n",
+ " maximum = value\n",
+ " return maximum\n",
+ "print(maximum([-9,2,4,1,8]))\n",
+ "print(maximum([-3,1,7,6,2,3]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "46\n",
+ "12\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 41\n",
+ "def somme_sous_liste(L,i,j):\n",
+ " L = L[i:j+1]\n",
+ " return sum(L)\n",
+ "print(somme_sous_liste([4,10,12,16,18], 2, 4))\n",
+ "print(somme_sous_liste(list((range(2,13,2))), 0, 2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "*\n",
+ "**\n",
+ "****\n",
+ "******\n",
+ "********\n",
+ "**********\n",
+ "\n",
+ "*\n",
+ "**\n",
+ "****\n",
+ "******\n",
+ "********\n",
+ "**********\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 42\n",
+ "print(\"*\") \n",
+ "for i in range(2,11,2):\n",
+ " print(\"*\" * i) \n",
+ "\n",
+ "\n",
+ "for i in range(0,11):\n",
+ " if i % 2 == 0 or i == 1:\n",
+ " print(\"*\" * i) "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 73,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-9\n",
+ "-3\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 43\n",
+ "def minimum(L):\n",
+ " minimum = L[0]\n",
+ " for value in L:\n",
+ " if value < minimum :\n",
+ " minimum = value\n",
+ " return minimum\n",
+ "\n",
+ "print(minimum([-9,2,4,1,8]))\n",
+ "print(minimum([-3,1,7,6,2,3]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 76,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "0\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 44\n",
+ "def longueur(L):\n",
+ " i = 0\n",
+ " for v in L:\n",
+ " i+=1\n",
+ " return i\n",
+ "\n",
+ "print(longueur([3,6,7,\"abde\", [1,3,57], True]))\n",
+ "print(longueur([]))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 81,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4.0\n",
+ "5.571428571428571\n",
+ "4.0\n",
+ "5.571428571428571\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 45\n",
+ "def moyenne_liste(L):\n",
+ " return sum(L) / len(L)\n",
+ "\n",
+ "print(moyenne_liste(list(range(1,8))))\n",
+ "print(moyenne_liste([3,0,-1,5,6,9,17]))\n",
+ "\n",
+ "#---\n",
+ "def moyenne_liste(L):\n",
+ " total = 0\n",
+ " i = 0\n",
+ " for value in L :\n",
+ " total += value\n",
+ " i+=1\n",
+ " if i ==0:\n",
+ " return 0\n",
+ " return total / i\n",
+ "\n",
+ "print(moyenne_liste(list(range(1,8))))\n",
+ "print(moyenne_liste([3,0,-1,5,6,9,17]))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 101,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1, 3]\n",
+ "[1, 3, 9]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 46\n",
+ "def diviseur(n):\n",
+ " return [x for x in range(1, n+1) if n%x == 0]\n",
+ "\n",
+ "print(diviseur(3))\n",
+ "print(diviseur(9))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 105,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n",
+ "False\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 47\n",
+ "def verif_maj(phrase):\n",
+ " for letter in phrase :\n",
+ " if letter.isupper():\n",
+ " return True\n",
+ " else:\n",
+ " return False\n",
+ "\n",
+ "print(verif_maj(\"Les légumes sont bons pour la santé\"))\n",
+ "print(verif_maj(\"j'apprends le langage python\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 109,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[0, 9, 8, 2, 6, 9, True, False, 'abc']\n",
+ "[[39, -1], 3, -9, 'xz', 'France']\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 48\n",
+ "def concat_liste(L1,L2,L3):\n",
+ " L1 += L2\n",
+ " L1 += L3\n",
+ " return L1\n",
+ "\n",
+ "print(concat_liste([0,9,8],[2,6,9],[True,False,\"abc\"]))\n",
+ "print(concat_liste([[38,-1], 3, -9],[\"xz\",\"France\"],[]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 111,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "4\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 49\n",
+ "def nbr_valeur_dict(d):\n",
+ " compteur = 0\n",
+ " for values in d.values():\n",
+ " compteur += len(values)\n",
+ "\n",
+ " return compteur\n",
+ "\n",
+ "\n",
+ "print(nbr_valeur_dict({'a':[1,2,3], 'b' :[3,'p'], \"c\":[8]}))\n",
+ "print(nbr_valeur_dict({'Julie':[12, 60.1], 'Fred' :[26, 75.6], \"David\":[]}))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 113,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "d1 = {\"test1\":\"value1\"}\n",
+ "d2 = {\"test2\":\"value2\"}\n",
+ "\n",
+ "for k,v in d2.items():\n",
+ " d1[k] =v"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "c 2\n",
+ "d -1\n",
+ "{'a': 3, 'b': 6, 'c': 2, 'd': -1}\n",
+ "p []\n",
+ "{'d': [2.9, 4.1], 'p': []}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 50\n",
+ "def concat_dict(d1,d2):\n",
+ " for key, value in d2.items():\n",
+ " d1[key] = value\n",
+ " return d1\n",
+ "\n",
+ "print(concat_dict({\"a\":3, \"b\":6},{\"c\":2, \"d\":-1}))\n",
+ "print(concat_dict({\"d\":[2.9,4.1]}, {'p':[]}))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "362880\n",
+ "1\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 51\n",
+ "def calcul_factoriel(n):\n",
+ " total = 1\n",
+ " for i in range(1, n+1) :\n",
+ " total *= i\n",
+ " return total\n",
+ "\n",
+ "\n",
+ "print(calcul_factoriel(3))\n",
+ "print(calcul_factoriel(9))\n",
+ "print(calcul_factoriel(0))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 126,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[5, 15, 25, 35, 45, 55, 65, 75, 85, 95]\n",
+ "[11, 22, 44, 55, 77]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 52\n",
+ "def diviseur_mult(n,a,nbr_seuil):\n",
+ " result_list = []\n",
+ " for i in range(1,nbr_seuil) :\n",
+ " if i%n ==0 and i%a !=0:\n",
+ " result_list.append(i)\n",
+ "\n",
+ " return result_list\n",
+ "\n",
+ "\n",
+ "print(diviseur_mult(5,2,100))\n",
+ "print(diviseur_mult(11,3,85))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[True, True, True, True, True, True, True, True, True]\n",
+ "True\n",
+ "[]\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 53\n",
+ "def presence_voyelle(phrase):\n",
+ " voyelles = [\"a\", \"e\", \"i\", \"o\", \"u\", \"y\"]\n",
+ "\n",
+ " test = [True for x in phrase if x in voyelles]\n",
+ "\n",
+ " return any(test)\n",
+ "\n",
+ "print(presence_voyelle(\"Je vais prendre ma douche\"))\n",
+ "print(presence_voyelle(\"rbhpm\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 141,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "LaFranceestbelle!\n",
+ "Jevaisprendremonvélo\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 54\n",
+ "def suppr_espace(phrase):\n",
+ " phrase = phrase.replace(\" \", \"\")\n",
+ " return phrase\n",
+ "\n",
+ "print(suppr_espace(\"La France est belle !\"))\n",
+ "print(suppr_espace(\"Je vais prendre mon vélo\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2, 6]\n",
+ "L'élément -1 ne se trouve pas dans la liste [6, 8, 9, 1, 3, 7]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 55\n",
+ "def position_elt_liste(L,x) :\n",
+ " indices = []\n",
+ " for i in range(len(L)):\n",
+ " if L[i] == x :\n",
+ " indices.append(i)\n",
+ " if len(indices) :\n",
+ " return indices\n",
+ " else :\n",
+ " return print(f\"L'élément {x} ne se trouve pas dans la liste {L}\")\n",
+ " \n",
+ "\n",
+ "# Exo 55\n",
+ "def position_elt_liste(L,x) :\n",
+ " indices = []\n",
+ " for i in range(len(L)):\n",
+ " if L[i] == x :\n",
+ " indices.append(i)\n",
+ " return indices or f\"L'élément {x} ne se trouve pas dans la liste {L}\"\n",
+ "\n",
+ " \n",
+ "print(position_elt_liste([1,2,3,6,8,7,3],3))\n",
+ "print(position_elt_liste([6,8,9,1,3,7],-1))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 159,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Salut\n",
+ "origine\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 56\n",
+ "def filtrer_mots(phrase, longueur_mini) :\n",
+ " liste_de_mots = phrase.split(\" \")\n",
+ " liste_de_mots_sup_longueur_mini = [word for word in liste_de_mots if len(word) > longueur_mini ]\n",
+ " return \" \".join(liste_de_mots_sup_longueur_mini)\n",
+ "\n",
+ "\n",
+ " \n",
+ "print(filtrer_mots(\"Salut toi\",4))\n",
+ "print(filtrer_mots(\"Quel est ton origine ?\",5))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 161,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "monde le tout bonjour\n",
+ "Pomme\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 57\n",
+ "def inverser_phrase(phrase) :\n",
+ " liste_de_mots = phrase.split(\" \")\n",
+ " liste_de_mots_inversee = liste_de_mots[::-1]\n",
+ " return \" \".join(liste_de_mots_inversee)\n",
+ "\n",
+ "\n",
+ " \n",
+ "print(inverser_phrase(\"bonjour tout le monde\"))\n",
+ "print(inverser_phrase(\"Pomme\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 167,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[(1, 2), (-4, 1), (2, 2), (-3, 2), (8, 2), (9, 1)]\n",
+ "[(3, 2), (4, 1), ('b', 1), ('a', 2)]\n",
+ "[(-4, 1), (8, 2), (-3, 2), (2, 2), (1, 2), (9, 1)]\n",
+ "[('a', 2), (3, 2), (4, 1), ('b', 1)]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 58\n",
+ "def nombre_occurence(L):\n",
+ " return list(set([(x,L.count(x)) for x in L]))\n",
+ "\n",
+ "print(nombre_occurence([-4,8,-3,2,1,2,9,-3,8,1]))\n",
+ "print(nombre_occurence([\"a\",3,4,\"b\",\"a\",3]))\n",
+ "\n",
+ "\n",
+ "# Exo 58\n",
+ "def nombre_occurence(L):\n",
+ " occurences = []\n",
+ " for value in L:\n",
+ " if (value,L.count(value)) not in occurences :\n",
+ " occurences.append((value,L.count(value)))\n",
+ " return occurences\n",
+ "\n",
+ "print(nombre_occurence([-4,8,-3,2,1,2,9,-3,8,1]))\n",
+ "print(nombre_occurence([\"a\",3,4,\"b\",\"a\",3]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 169,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[0, 1, 3, 6, 9, 12]\n",
+ "[-3, 2, 7, 44]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 59\n",
+ "def union_list(L1,L2,L3):\n",
+ " new_list = list(set(L1) | set(L2) | set(L3))\n",
+ " new_list.sort()\n",
+ " return new_list\n",
+ "\n",
+ "print(union_list([3,6,9,3], [1,0,3], [12,6,0]))\n",
+ "print(union_list([7,44,-3], [], [7,2,7]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "5 % 15"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 185,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3\n",
+ "5\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 60\n",
+ "def calcul_PGCD(a,b):\n",
+ " min_number = min([a,b])\n",
+ " max_number = max([a,b])\n",
+ " r = max_number % min_number\n",
+ " b = max_number // min_number\n",
+ " q = (max_number - r) / b\n",
+ " return int(q)\n",
+ "\n",
+ "print(calcul_PGCD(3,5))\n",
+ "print(calcul_PGCD(5,15))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 188,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Ceci est\n",
+ "un \n",
+ "text\n",
+ "None\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 61\n",
+ "def lire_fichier(chemin_fichier):\n",
+ " with open(chemin_fichier) as my_file:\n",
+ " print(my_file.read())\n",
+ "\n",
+ "\n",
+ "print(lire_fichier('test.txt'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 197,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['Je', 'suis', 'jeremy.\\nJe', 'suis', 'un', 'formateur']\n",
+ "0\n",
+ "['Je', 'suis', 'jeremy.', 'Je', 'suis', 'un', 'formateur']\n",
+ "0\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 62\n",
+ "def nbr_occ_fichier(chemin_fichier, mot):\n",
+ " with open(chemin_fichier) as my_file:\n",
+ " my_list_of_words = my_file.read().split(\" \")\n",
+ " print(my_list_of_words)\n",
+ " \n",
+ " return my_list_of_words.count(mot)\n",
+ "\n",
+ "\n",
+ "print(nbr_occ_fichier('test.txt', \"je\"))\n",
+ "\n",
+ "import re\n",
+ "\n",
+ "def nbr_occ_fichier(chemin_fichier, mot):\n",
+ " with open(chemin_fichier) as my_file:\n",
+ " # Dans cette version on sépare quand il y a un espace\n",
+ " # ou un retour à la ligne.\n",
+ " my_list_of_words = re.split(r' |\\n', my_file.read())\n",
+ " print(my_list_of_words)\n",
+ " \n",
+ " return my_list_of_words.count(mot)\n",
+ "\n",
+ "\n",
+ "print(nbr_occ_fichier('test.txt', \"je\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 202,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'Je suis jeremy.\\nJe suis un ormateur'"
+ ]
+ },
+ "execution_count": 202,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 63\n",
+ " \n",
+ "def suppr_carac(chemin_fichier, caractere):\n",
+ " \n",
+ " with open(chemin_fichier, 'r') as my_file:\n",
+ " to_return = my_file.read().replace(caractere,\"\")\n",
+ "\n",
+ " with open(chemin_fichier, 'w') as my_file:\n",
+ " my_file.write(to_return)\n",
+ "\n",
+ " return to_return\n",
+ " \n",
+ "suppr_carac(\"test.txt\", \"f\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 204,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 204,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 64\n",
+ " \n",
+ "def presence_nombre(chemin_fichier):\n",
+ " \n",
+ " with open(chemin_fichier, 'r') as my_file:\n",
+ " text = my_file.read()\n",
+ " for letter in text:\n",
+ " if letter.isdigit():\n",
+ " return True\n",
+ " return False\n",
+ " \n",
+ "presence_nombre(\"test.txt\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 210,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "26"
+ ]
+ },
+ "execution_count": 210,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 65\n",
+ "def nombre_fichier(chemin_dossier=\".\"):\n",
+ " return len(os.listdir(path=chemin_dossier))\n",
+ " \n",
+ "nombre_fichier()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 212,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'Bonjour, ...'"
+ ]
+ },
+ "execution_count": 212,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 66\n",
+ "\n",
+ "def ecrire_fichier(nom_fichier, text):\n",
+ " with open(nom_fichier, 'w') as my_file:\n",
+ " my_file.write(text)\n",
+ " return text\n",
+ " \n",
+ "ecrire_fichier(\"test.txt\", \"Bonjour, ...\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 216,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "a\n",
+ "dtg\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 67\n",
+ "\n",
+ "def cle_max_valeur_dict(d):\n",
+ " max_len = 0\n",
+ " key = \"\"\n",
+ " for k, v in d.items():\n",
+ " curr_len = len(set(v))\n",
+ " if curr_len > max_len :\n",
+ " max_len = curr_len\n",
+ " key = k\n",
+ " return key\n",
+ "\n",
+ "\n",
+ " \n",
+ "print(cle_max_valeur_dict({'a' : [9,10,9,7,3,1],\n",
+ " 'b':[5,3,2,2,2],\n",
+ " 'c': [1,1,1,1,1,1,8,2]}))\n",
+ "\n",
+ "print(cle_max_valeur_dict({'dtg' : [6,8,1],\n",
+ " 'fgb':[2.5,\"a\"],\n",
+ " 'klm': [\"p\", 3.3]}))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 220,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "['3', '2']\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 68\n",
+ "\n",
+ "list_user = input(\"Entrer une liste d'utilisateur\")\n",
+ "list_user = list_user.replace('[','').replace(']','').split(',')\n",
+ "\n",
+ "print(type(list_user))\n",
+ "print(list_user)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 257,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Exo 69\n",
+ "\n",
+ "def nbr_jour_heure(date_debut, date_fin):\n",
+ " import datetime\n",
+ " date_debut = date_debut.split(\"/\")\n",
+ " date_fin = date_fin.split(\"/\")\n",
+ " date_debut = datetime.datetime(year=int(date_debut[0]), month=int(date_debut[1]), day=int(date_debut[2]))\n",
+ " date_fin = datetime.datetime(year=int(date_fin[0]), month=int(date_fin[1]), day=int(date_fin[2]))\n",
+ "\n",
+ " nb_jours = abs((date_fin - date_debut).days)\n",
+ "\n",
+ " return (nb_jours, nb_jours*24)\n",
+ "\n",
+ "\n",
+ "print(nbr_jour_heure('2022/05/15', \"2022/06/20\"))\n",
+ "print(nbr_jour_heure('2022/04/1', \"2022/04/27\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 285,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "a2e12b\n",
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n",
+ "nghd7^\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 70\n",
+ "\n",
+ "def generer_mdp(caracteres, taille_mdp):\n",
+ " import random\n",
+ " return \"\".join(random.choices(caracteres, k=taille_mdp))\n",
+ "\n",
+ "print(generer_mdp(\"abcdefg1234\", 6))\n",
+ "\n",
+ "import string\n",
+ "liste_caracteres = string.ascii_letters + string.digits + \"!@#$%^&*()\"\n",
+ "print(liste_caracteres)\n",
+ "print(generer_mdp(liste_caracteres, 6))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 288,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "9.207106781186548\n",
+ "8.0\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 71\n",
+ "def fonct_trigo(x):\n",
+ " import math\n",
+ " return math.cos(x)*math.sin(x)+math.sin(x)+8\n",
+ "\n",
+ "import math\n",
+ "print(fonct_trigo(math.pi/4))\n",
+ "print(fonct_trigo(math.pi))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 296,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 120, 123, 130, 132, 138, 140, 145, 150, 154, 159, 160, 167, 170, 176, 180, 183, 189, 190, 195, 198, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 213, 220, 224, 230, 231, 235, 240, 242, 246, 250, 253, 257, 260, 264, 268, 270, 275, 279, 280, 286, 290, 297, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 312, 318, 320, 321, 325, 330, 333, 340, 345, 347, 350, 352, 354, 357, 360, 369, 370, 374, 375, 380, 381, 390, 396, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 415, 420, 422, 426, 430, 435, 437, 440, 448, 450, 451, 453, 456, 459, 460, 462, 465, 466, 470, 473, 480, 484, 490, 495, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 514, 519, 520, 523, 527, 530, 532, 534, 537, 540, 541, 543, 546, 549, 550, 560, 564, 570, 572, 573, 578, 579, 580, 587, 590, 591, 594, 597, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 617, 620, 624, 628, 630, 639, 640, 642, 645, 646, 650, 654, 660, 664, 666, 670, 671, 678, 680, 682, 687, 690, 693, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 716, 720, 725, 729, 730, 734, 735, 740, 743, 750, 752, 753, 758, 759, 760, 761, 768, 770, 780, 785, 786, 789, 790, 792, 795, 798, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 813, 819, 820, 826, 830, 831, 840, 844, 850, 857, 860, 862, 867, 870, 875, 876, 879, 880, 890, 891, 897, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 915, 918, 920, 927, 930, 936, 940, 945, 950, 951, 954, 957, 960, 963, 970, 972, 975, 978, 980, 981, 987, 990, 999]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Exo 72\n",
+ "L = []\n",
+ "\n",
+ "for i in range(100,1000):\n",
+ " istr = str(i)\n",
+ " a,b,c = istr\n",
+ " a = int(a)\n",
+ " b = int(b)\n",
+ " c = int(c)\n",
+ " somme = a+b+c\n",
+ " produit = a*b*c\n",
+ " if produit%somme == 0:\n",
+ " L.append(int(str(a)+str(b)+str(c)))\n",
+ "\n",
+ "L.sort()\n",
+ "print(list(set(L)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 312,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "10"
+ ]
+ },
+ "execution_count": 312,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Exo 73\n",
+ "def calcul_somme(L):\n",
+ " if not L:\n",
+ " return 0\n",
+ " else:\n",
+ " return L[0] + calcul_somme(L[1:])\n",
+ "\n",
+ "calcul_somme([2,3,5])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "La notation lst[1:] crée en fait une nouvelle sous-liste qui commence à partir du deuxième élément de la liste lst jusqu'à la fin de la liste. Donc, à chaque appel récursif, nous passons une liste qui est plus courte d'un élément.\n",
+ "\n",
+ "Prenons l'exemple de la liste ma_liste = [1, 2, 3, 4, 5] pour mieux comprendre :\n",
+ "\n",
+ "Lors du premier appel à somme_recursive(ma_liste), la liste est [1, 2, 3, 4, 5]. Nous prenons 1 (le premier élément) et ajoutons le résultat de somme_recursive([2, 3, 4, 5]) (la liste sans le premier élément).\n",
+ "Dans le deuxième appel, la liste est [2, 3, 4, 5]. Nous prenons 2 et ajoutons le résultat de somme_recursive([3, 4, 5]).\n",
+ "Dans le troisième appel, la liste est [3, 4, 5]. Nous prenons 3 et ajoutons le résultat de somme_recursive([4, 5]).\n",
+ "Dans le quatrième appel, la liste est [4, 5]. Nous prenons 4 et ajoutons le résultat de somme_recursive([5]).\n",
+ "Dans le cinquième appel, la liste est [5]. Nous prenons 5 et ajoutons le résultat de somme_recursive([]).\n",
+ "Finalement, lors du sixième appel, la liste est vide [], et nous retournons simplement 0 car c'est notre cas de base.\n",
+ "Si vous additionnez tous ces appels :\n",
+ "1\n",
+ "+\n",
+ "(\n",
+ "2\n",
+ "+\n",
+ "(\n",
+ "3\n",
+ "+\n",
+ "(\n",
+ "4\n",
+ "+\n",
+ "(\n",
+ "5\n",
+ "+\n",
+ "0\n",
+ ")\n",
+ ")\n",
+ ")\n",
+ ")\n",
+ "1+(2+(3+(4+(5+0)))) = 15"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 323,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2"
+ ]
+ },
+ "execution_count": 323,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def suite_fibonacci(n):\n",
+ " if n<=1:\n",
+ " return n\n",
+ " else :\n",
+ " return suite_fibonacci(n-1) + suite_fibonacci(n-2)\n",
+ " \n",
+ "suite_fibonacci(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/oop/1-Introduction_POO.ipynb b/oop/1-Introduction_POO.ipynb
new file mode 100644
index 0000000..7628a33
--- /dev/null
+++ b/oop/1-Introduction_POO.ipynb
@@ -0,0 +1,2593 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Programmation orienté objet"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Les objets en python"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Quels sont les objets dans le code suivant ?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "14"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Les éléments en python\n",
+ "a = 3\n",
+ "b = 9\n",
+ "c = [4,5]\n",
+ "\n",
+ "d = 'Hi'\n",
+ "\"Hello\"\n",
+ "\n",
+ "def mutipliby_by_2(x):\n",
+ " return x * 2\n",
+ "\n",
+ "mutipliby_by_2(7)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**Répondre ici**\n",
+ "\n",
+ "Les objets sont : "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "En python, il existe 8 elements fondamentaux :\n",
+ "- objects (objets)\n",
+ "- identifiers (identifiants)\n",
+ "- operators (opérateurs)\n",
+ "- delimiters (délimiteurs)\n",
+ "- keywords (mots-clés)\n",
+ "- comments (commentaires)\n",
+ "- blank lines (ligne blanche)\n",
+ "- white space (espace)\n",
+ "- indentation "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "---\n",
+ "Solution\n",
+ "\n",
+ "Les objets sont : 2, 9, 4, 5, 'Hi', 'Hello', function definition, 2, 7, 14\n",
+ "\n",
+ "Les identifiants sont : a, b, c, d, mutipliby_by_2, x\n",
+ "\n",
+ "Les opérateurs sont : *\n",
+ "\n",
+ "Les délimiteurs sont : , [] () '' \"\" =\n",
+ "\n",
+ "Keywords : def, return\n",
+ "\n",
+ "Commentaires : # Les éléments en python\n",
+ "\n",
+ "Voir dans le code pour les espaces, les blanks lines et l'indentation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Plus d'opérateurs : https://www.w3schools.com/python/python_operators.asp"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## I.1 Vocabulaire"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Métaphore cullinère:\n",
+ "- une classe : la recette du \"gateau\"\n",
+ "- une instanciation de classe : la préparation d'un gateau à partir de la recette.\n",
+ "- un objet ou une instance de classe : un gateau avec un cetain gout et un certain nombre de parts.\n",
+ "\n",
+ "On comprend qu'avec une recette on peut créer une infinité de gateaux.\n",
+ "\n",
+ "Une classe peut contenir:\n",
+ "- des attributs\n",
+ "- des méthodes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1.2 Point Pep 8"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Comment nommer ce dont on se sert:\n",
+ "- **`Class names`**: should normally use the CapWords convention.\n",
+ "- **`Method names and attribute names`** : Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# II Coder ses premières classes et instances de classe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## II.1 Coder les classes et les méthodes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Cake :\n",
+ " # on définit ensuite, le constructeur: l'ensemble des attributs d'instance\n",
+ " # le constructeur est lui même une méthode mais une méthode très particulière\n",
+ " def __init__(self, flavor, number_share):\n",
+ " \"\"\" Initialise les attributs\n",
+ "\n",
+ " Args:\n",
+ " flavor ([type]): [description]\n",
+ " number_share ([type]): [description]\n",
+ " \"\"\"\n",
+ " self.flavor = flavor\n",
+ " self.number_share = number_share\n",
+ "\n",
+ " # on définit ensuite les méthodes qui peuvent utiliser les attributs de classe et d'instance\n",
+ " def be_cut(self):\n",
+ " \"\"\" couper le gateau\"\"\"\n",
+ " return print(\"the {} cake is now cut in {} shares\".format(self.flavor, self.number_share)) \n",
+ "\n",
+ " def add_candles(self,candle):\n",
+ " \"\"\" ajoute des bougies au gateau\"\"\"\n",
+ " return print(\"{} candles have been added on the {} cake\".format(candle, self.flavor))\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "the banana cake is now cut in 10 shares\n",
+ "the carrot cake is now cut in 12 shares\n",
+ "18 candles have been added on the banana cake\n"
+ ]
+ }
+ ],
+ "source": [
+ "banana_cake = Cake(\"banana\",10)\n",
+ "banana_cake.number_share\n",
+ "\n",
+ "\n",
+ "carrot_cake = Cake(\"carrot\",12)\n",
+ "carrot_cake.flavor\n",
+ "\n",
+ "banana_cake.be_cut()\n",
+ "carrot_cake.be_cut()\n",
+ "\n",
+ "banana_cake.add_candles(18)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "type(banana_cake)=\n",
+ "banana_cake.flavor='banana'\n",
+ "banana_number_share: 8\n",
+ "the banana cake is now cut in 8 shares\n",
+ "8 candles have been added on the banana cake\n"
+ ]
+ }
+ ],
+ "source": [
+ "# On crée maintenant nos objets à partir de la classe définie plus haut\n",
+ "\n",
+ "# L'instanciation nécessite de définir les attributs d'instance (mais pas de classe)\n",
+ "banana_cake = Cake(\"banana\",8)\n",
+ "carrot_cake = Cake(\"carrot\",10)\n",
+ "\n",
+ "print(f\"{type(banana_cake)=}\" )\n",
+ "print(f\"{banana_cake.flavor=}\")\n",
+ "print(\"banana_number_share:\",banana_cake.number_share)\n",
+ "\n",
+ "# On peut appeler les méthodes, comme on l'a toujours fait\n",
+ "banana_cake.be_cut()\n",
+ "banana_cake.add_candles(8)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 1`**: \n",
+ "Reprennez votre diagramme de class et coder les classes et les objets qui s'y trouvent"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## II.2 Les différents types d'attribut et de méthode"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "En programmation orientée objet, il existe trois types d’attributs :\n",
+ "- les attributs d’instance et les méthodes d'instance sont propres aux instances créées\n",
+ " - les méthodes d'instances sont les méthodes normales, on donne implicitement à celles-ci l'instance comme premier paramètre (self)\n",
+ "- les attributs de classe (propres à la classe, et partagés entre les instances): Les attributs de classe sont souvent utilisés pour créer des données ou des actions globales à la classe, qui ne dépendent pas d’une instance. \n",
+ " - Elles peuvent être accédées par la classe, sans passer par l’instanciation. \n",
+ " - Les attributs de classe peuvent se référencer entre eux, mais ne peuvent pas accéder aux attributs d’instance.\n",
+ " - On donne implicitement aux méthodes de classe comme premier argument la classe elle-même (cls)\n",
+ "- et les attributs statiques et les méthodes statiques sont presque indépendants de la classe, on ne les verra pas car il n'est pas conseillé de les utiliser, ils ont précédés de @staticmethod).\n",
+ " - On ne leur donne pas implicitement de premier paramètre\n",
+ "\n",
+ "Si chaque type d’attribut possède une utilité propre, essayez autant que possible de privilégier les attributs d’instance, qui permettent d’utiliser la programmation orientée objet à son plein potentiel.\n",
+ "\n",
+ "good to know:\n",
+ "When you try to access an attribute from an instance of a class, it first looks at its instance namespace. If it finds the attribute, it returns the associated value. If not, it then looks in the class namespace and returns the attribute (if it’s present, throwing an error otherwise)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Pie:\n",
+ " \"\"\"Objet Cake qui permettra d'alimenter ma boulangerie\n",
+ " \"\"\"\n",
+ " # on crée les attributs de classe en dehors du constructeur\n",
+ " taste = \"good\"\n",
+ "\n",
+ " def __init__(self, flavor,number_share):\n",
+ " \"\"\" Initialise les attributs\n",
+ "\n",
+ " Args:\n",
+ " flavor ([type]): [description]\n",
+ " number_share ([type]): [description]\n",
+ " \"\"\"\n",
+ " self.flavor = flavor\n",
+ " self.number_share = number_share\n",
+ "\n",
+ " def be_cut(self):\n",
+ " \"\"\" couper le gateau\"\"\"\n",
+ " print(\"the {} cake is now cut in {} share\".format(self.flavor, self.number_share)) \n",
+ "\n",
+ " def add_candles(self,candle):\n",
+ " \"\"\" ajoute des bougies au gateau\"\"\"\n",
+ " print(\"{} candles have been added on the {} {} cake\".format(candle, self.__class__.taste,self.flavor))\n",
+ " print(\"each share has\") \n",
+ " \n",
+ "\n",
+ " #on les utilise dans des méthodes de classe\n",
+ " @classmethod\n",
+ " def is_it_good(cls):\n",
+ " return cls.taste == \"good\"\n",
+ " \n",
+ " @staticmethod\n",
+ " def my_addition(a,b):\n",
+ " return a + b\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "apple\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "15"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "apple_pie = Pie(\"apple\",10)\n",
+ "print(apple_pie.flavor)\n",
+ "apple_pie.my_addition(7,8)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'good'"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "Pie.taste\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'good'"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "apple_pie = Pie(\"apple\",10)\n",
+ "apple_pie.taste"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "Pie.taste\n",
+ "print(Pie.is_it_good())\n",
+ "apple_pie = Pie(\"apple\",10)\n",
+ "apple_pie.is_it_good()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Pie.taste='good'\n",
+ "Pie.is_it_good()=True\n",
+ "apple_pie.taste='good'\n",
+ "apple_pie.taste='bad'\n",
+ "raspberry_pie.taste='good'\n",
+ "raspberry_pie.taste='just okay'\n",
+ "stawberry_pie.taste='just okay'\n",
+ "apple_pie.taste='bad'\n"
+ ]
+ }
+ ],
+ "source": [
+ "# On peut accéder aux variables de classe sans instanciation.\n",
+ "print(f\"{Pie.taste=}\")\n",
+ "print(f\"{Pie.is_it_good()=}\")\n",
+ "\n",
+ "# Les instances peuvent accéder à ces attributs:\n",
+ "apple_pie = Pie(\"apple\",8)\n",
+ "raspberry_pie = Pie(\"raspberry\",9)\n",
+ "\n",
+ "# modifier cette attribut ne fonctionnera que pour l'instance en question\n",
+ "print(f\"{apple_pie.taste=}\")\n",
+ "apple_pie.taste = \"bad\"\n",
+ "print(f\"{apple_pie.taste=}\")\n",
+ "print(f\"{raspberry_pie.taste=}\")\n",
+ "\n",
+ "# On peut changer cette valeur pour toutes les instances\n",
+ "Pie.taste = \"just okay\"\n",
+ "\n",
+ "# Cela modifie automatiquement toutes les instances\n",
+ "print(f\"{raspberry_pie.taste=}\")\n",
+ "\n",
+ "# Y compris les nouvelles crées\n",
+ "stawberry_pie = Pie(\"stawberry\",8)\n",
+ "print(f\"{stawberry_pie.taste=}\")\n",
+ "\n",
+ "# Par contre quand on a modifié la valeur de taste pour apple, on l'a part la meme occasion transformé\n",
+ "# en attribut d'instance d'apple. Il ne peut donc plus être modifié.\n",
+ "print(f\"{apple_pie.taste=}\")\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 50,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'flavor': 'apple', 'number_share': 8, 'taste': 'bad'}\n",
+ "{'__module__': '__main__', '__doc__': \"Objet Cake qui permettra d'alimenter ma boulangerie\\n \", 'taste': 'good', '__init__': , 'be_cut': , 'add_candles': , 'is_it_good': , 'my_addition': , '__dict__': , '__weakref__': }\n",
+ "{'__module__': '__main__', '__doc__': \"Objet Cake qui permettra d'alimenter ma boulangerie\\n \", 'taste': 'good', '__init__': , 'be_cut': , 'add_candles': , 'is_it_good': , 'my_addition': , '__dict__': , '__weakref__': }\n"
+ ]
+ }
+ ],
+ "source": [
+ "apple_pie = Pie(\"apple\",8)\n",
+ "\n",
+ "apple_pie.taste = \"bad\"\n",
+ "\n",
+ "print(apple_pie.__dict__)\n",
+ "print(apple_pie.__class__.__dict__)\n",
+ "print(Pie.__dict__)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice`**\n",
+ "- Créer des classes: boite à outils, marteau, tournevis, clou, visse \n",
+ "- Instanciez une boîte à outils, un tournevis, et un marteau.\n",
+ "- Placez le marteau et le tournevis dans la boîte à outils.\n",
+ "- Instanciez une visse, et serrez-la avec le tournevis. Affichez la vis avant et après avoir été serrée.\n",
+ "- Instanciez un clou, puis enfoncez-le avec le marteau. Affichez le clou avant et après avoir été enfoncé.\n",
+ "- Une boite à outil possède 5 emplacements. (classe attributs)\n",
+ "- Régulièrement le constructeur des boites à outils sort un nouveau modèle qui permet d'etendre la capacité des boites à outils de 1 emplacement.\n",
+ "\n",
+ "Pour chaque classe vous devez définir les attributs et les méthodes qui permettront d'éxecuter et de rapporter dans le terminal ces actions et ces états."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# III L'héritage"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## III.1 La notion d'héritage"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Le grand avantage des classes c'est l'héritage.\n",
+ "\n",
+ "L'héritage consiste à créer une classe enfant à partir d'une classe parent.\n",
+ "La classe enfant récupère toutes les méthodes de la classe parent et tous les attributs de classe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pourquoi l’héritage ?\n",
+ "- **`La réutilisabilité`**: quand on veut écrire plusieurs classes proches, il faut créer une classe parente et ensuite facilement créer les classes enfants. Pour modifier une méthode existante dans toutes les classes, il ne faudra plus que la changer à un endroit."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**'Exercice'** Ecrire le diagramme de classe correspondant au cas suivant:\n",
+ "Fort de votre expérience en pâtisserie, vous décidez de créer un forum en ligne pour parler de gâteaux ! \n",
+ "- Vous devez définir et instancier trois classes: Utilisateurs (et ses héritiers), fil de discussion et post (et ses héritiers)\n",
+ "\n",
+ "\n",
+ "Sur ce forum\n",
+ "- les utilisateurs fans de pâtisserie pourront : s’inscrire et se connecter ;\n",
+ "- parler de leurs gâteaux préférés, en créant de nouveaux fils de discussion ;\n",
+ "- répondre à des messages, dans les fils existants.\n",
+ "- Un fil de discussion sur ce forum a un titre, une date de création et une collection de posts lui correspondant.\n",
+ "- Chaque post contient du texte, l’utilisateur qui l’a publié et la date de publication.\n",
+ "- Les utilisateurs ont la possibilité d’attacher des fichiers à leurs posts :\n",
+ "- Partez du principe qu’il peut y avoir de nombreux types de fichiers, mais nous sommes surtout intéressés par les fichiers images (GIF ou JPEP).\n",
+ "- Un post peut avoir un fichier attaché, ce qui changera la façon dont le post est affiché. Ce serait donc un nouveau type de post.\n",
+ "- Enfin, il y a des utilisateurs spéciaux nommés modérateurs, qui ont la capacité de modifier un post pour qu’il contienne du contenu nouveau, et de supprimer ceux qui ne parlent pas de gâteaux. ;)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Comment représenter les différentes [associations](https://creately.com/blog/diagrams/class-diagram-relationships/) en UML?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## III.2 Coder ses classes héritées"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 73,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Exemple\n",
+ "\n",
+ "class Stylo:\n",
+ " \"\"\" Classe stylo\"\"\"\n",
+ " tient_dans_une_trousse = True\n",
+ " \n",
+ " def __init__(self,couleur,taille):\n",
+ " self.couleur = couleur\n",
+ " self.taille = taille\n",
+ " \n",
+ " def ecrire(self,content):\n",
+ " print(f'J\\'écris {content} avec mon stylo {self.couleur}')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dir(object)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "J'écris un truc avec mon stylo noir\n"
+ ]
+ }
+ ],
+ "source": [
+ "bic = Stylo(\"noir\",10)\n",
+ "bic.ecrire(\"un truc\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 71,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class StyloPlume(Stylo):\n",
+ " fais_des_tache = True\n",
+ " \n",
+ " def __init__(self, couleur, taille, type_cartouche):\n",
+ " self.couleur = couleur\n",
+ " self.taille = taille\n",
+ " self.type_cartouche = type_cartouche"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 72,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "J'écris un contenu avec mon stylo rouge\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 72,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ma_plume = StyloPlume(\"rouge\",10,\"parker\")\n",
+ "ma_plume.ecrire(\"un contenu\")\n",
+ "ma_plume.fais_des_tache"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'rouge'"
+ ]
+ },
+ "execution_count": 61,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ma_plume = StyloPlume(\"rouge\",10,\"parker\")\n",
+ "ma_plume.couleur"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 62,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "voici ce que j'écris : un contenu\n"
+ ]
+ }
+ ],
+ "source": [
+ "ma_plume.ecrire(\"un contenu\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ma_plume.tient_dans_une_trousse"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## III.3 Surcharger une méthode et utilisation de super()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Surcharger une méthode consiste à définir à nouveau une méthode existant dans la classe parent dans la classe enfant.\n",
+ "\n",
+ "C'est la définition dans la classe enfant qui l'emportera"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 76,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class StyloPlume(Stylo):\n",
+ " \"\"\" Classe stylo\"\"\"\n",
+ " def __init__(self, couleur, type_cartouche):\n",
+ " self.couleur = couleur\n",
+ " self.type_cartouche = type_cartouche\n",
+ "\n",
+ " def ecrire(self,content):\n",
+ " print(f'J\\'écris {content} avec mon stylo PLUME {self.couleur}')\n",
+ "\n",
+ " def ecrire_old(self,content):\n",
+ " super().ecrire(content)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "J'écris autre chose avec mon stylo PLUME bleu\n"
+ ]
+ }
+ ],
+ "source": [
+ "StyloPlume(\"bleu\",\"parker\").ecrire(\"autre chose\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "J'écris autre chose avec mon stylo bleu\n"
+ ]
+ }
+ ],
+ "source": [
+ "StyloPlume(\"bleu\",\"parker\").ecrire_old(\"autre chose\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On peut également si on le souhaite réutiliser une classe parente surcharger à l'aide de super()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 112,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class StyloBic(Stylo):\n",
+ " \"\"\" Classe stylo\"\"\"\n",
+ " def __init__(self, couleur,marque):\n",
+ " super().__init__(couleur) #Quand il y a beaucoup d'argument ça devient utile\n",
+ " self.marque = marque\n",
+ "\n",
+ " def ecrire(self,content):\n",
+ " print(f'J\\'écris {content} avec mon stylo BIC {self.couleur}')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 113,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mon_stylo_bic = StyloBic(\"rouge\",\"bic\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 114,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'rouge'"
+ ]
+ },
+ "execution_count": 114,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mon_stylo_bic.couleur"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 1`**\n",
+ "\n",
+ "Coder le diagramme de classe que vous vennez d'écrire "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 2`**:\n",
+ "\n",
+ "Réaliser la série d'exercices [suivante](https://holypython.com/advanced-python-exercises/exercise-5-inheritence/)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice 3`**:\n",
+ "\n",
+ "Réaliser la série d'exercices suivants sur [codewars](https://www.codewars.com/collections/python-classes-5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# IV Encapsulation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## IV.1 Les attibuts protégés"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les attributs protégés sont des attributs qu'on ne peut pas appeler en dehors de la classe. Ils ne sont accessible qu'au sein de la classe et dans les sous classes.\n",
+ "\n",
+ "Les attributs protégés existent dans différents langages (jave, C++) mais sont un peu particuliers en python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Profil:\n",
+ " def __init__(self,name):\n",
+ " self.name = name\n",
+ " # les attributs protégés sont caractérisés par un \"_\" avant leurs noms\n",
+ " self.password = \"pass\"\n",
+ "\n",
+ " # généralement on y accède au moyen de méthodes spécifique:\n",
+ " def setPassword(self,password):\n",
+ " if len(password)>=8:\n",
+ " self.password = password\n",
+ " else:\n",
+ " print(\"mot de passe pas assez secure: len> 8 exigée\")\n",
+ "\n",
+ " def getPassword(self):\n",
+ " return self.password"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 93,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'1234'"
+ ]
+ },
+ "execution_count": 93,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "charles = Profil(\"charles\")\n",
+ "charles.password\n",
+ "charles.setPassword(\"12345678\")\n",
+ "\n",
+ "charles.password = \"1234\"\n",
+ "charles.password"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 99,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Profil:\n",
+ " def __init__(self,name):\n",
+ " self.name = name\n",
+ " # les attributs protégés sont caractérisés par un \"_\" avant leurs noms\n",
+ " self._password = \"pass\"\n",
+ "\n",
+ " # généralement on y accède au moyen de méthodes spécifique:\n",
+ " def setPassword(self,password):\n",
+ " if len(password)>=8:\n",
+ " self._password = password\n",
+ "\n",
+ " def getPassword(self):\n",
+ " return self._password[0:3] + \"*****\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 111,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'123*****'"
+ ]
+ },
+ "execution_count": 111,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mon_profil = Profil(\"charles\")\n",
+ "\n",
+ "mon_profil.setPassword(\"12345678\")\n",
+ "\n",
+ "\n",
+ "mon_profil._password\n",
+ "mon_profil.getPassword()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 109,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'name': 'charles', '_password': '12345678', 'password': '888'}"
+ ]
+ },
+ "execution_count": 109,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mon_profil.__dict__"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 118,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'1234567809'"
+ ]
+ },
+ "execution_count": 118,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "my_profil=Profil(\"Charles\")\n",
+ "my_profil.setPassword(\"1234567809\")\n",
+ "my_profil.getPassword()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 96,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "trynew\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Théoriquement, le code suivant ne devrait pas marcher:\n",
+ "my_profil._password = \"trynew\"\n",
+ "print(my_profil._password)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'name': 'charles', '_password': 8}"
+ ]
+ },
+ "execution_count": 46,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# remarque\n",
+ "# On retrouve dans le dictionnaire d'attribut _password, c'est pour cela qu'on peut y accéder de l'extérieur\n",
+ "mon_profil.__dict__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Cependant ça marche, le \"_\" est juste une convention qui dit qu'on déconseille d'accéder à cet élément en dehors de ma classe mais on peut néanmoins le faire sans obtenir d'erreur.\n",
+ "\n",
+ "Par contre, comme dit précédement, on peut accéder aux attributs protégé depuis une classe fille."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 114,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Compte(Profil):\n",
+ " def __init__(self, name):\n",
+ " super().__init__(name)\n",
+ "\n",
+ " def getPassword(self):\n",
+ " return self._password"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 115,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'pass'"
+ ]
+ },
+ "execution_count": 115,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mon_compte = Compte(\"C.Ben\")\n",
+ "mon_compte.getPassword()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 123,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'name': 'C.Ben', '_password': 'pass'}"
+ ]
+ },
+ "execution_count": 123,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# remarque\n",
+ "# On retrouve dans le dictionnaire d'attribut _password, c'est pour cela qu'on peut y accéder de l'extérieur\n",
+ "mon_compte.__dict__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "L'idée des attributs protégés c'est qu'on veut forcer l'utilisateur à y accéder via les methodes set, del et get définies dans la classe et qui vont poser des restrictions."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## IV.2 Les attributs privés"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les attributs privés ne peuvent être appelés qu'au sein de la classe. Ils sont caractérisés par des doubles underscore (dunders) \"__\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 132,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Profil2:\n",
+ " \n",
+ " __private_classe_attribut = 8\n",
+ " \n",
+ " def __init__(self,name):\n",
+ " self.name = name\n",
+ " # les attributs protégés sont caractérisés par un \"_\" avant leurs noms\n",
+ " self.__password = \"pass\"\n",
+ "\n",
+ " # généralement on y accède au moyen de méthodes spécifique:\n",
+ " def setPassword(self,password):\n",
+ " self.__password = password\n",
+ "\n",
+ " def getPassword(self):\n",
+ " return self.__password"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 119,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "pass\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "'1234'"
+ ]
+ },
+ "execution_count": 119,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Pas de soucis, on peut toujours y accéder au sein de la classe\n",
+ "my_profil2=Profil2(\"Charles\")\n",
+ "print(my_profil2.getPassword())\n",
+ "my_profil2.setPassword(\"1234\")\n",
+ "my_profil2.getPassword()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 127,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "'Profil2' object has no attribute '__password'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_1880/3176204372.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Mais ça ne marche plus\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmy_profil2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__password\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m#my_profil2.__private_classe_attribut\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mAttributeError\u001b[0m: 'Profil2' object has no attribute '__password'"
+ ]
+ }
+ ],
+ "source": [
+ "# Mais ça ne marche plus\n",
+ "my_profil2.__password\n",
+ "#my_profil2.__private_classe_attribut"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 131,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'name': 'Charles', '_Profil2__password': 2}"
+ ]
+ },
+ "execution_count": 131,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# remarque\n",
+ "# On ne trouve pas dans le dictionnaire d'attribut __password, alors meme qu'on le manipule dans la fonction getPassword\n",
+ "my_profil2.__dict__\n",
+ "\n",
+ "# On trouve _Profil2__password mais les gens respectables ne manipulent pas ce genre de chose.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 133,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "mappingproxy({'__module__': '__main__',\n",
+ " '_Profil2__private_classe_attribut': 8,\n",
+ " '__init__': ,\n",
+ " 'setPassword': ,\n",
+ " 'getPassword': ,\n",
+ " '__dict__': ,\n",
+ " '__weakref__': ,\n",
+ " '__doc__': None})"
+ ]
+ },
+ "execution_count": 133,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# remarque\n",
+ "# Il en est de même pour l'attribut de classe __private_classe_attribut\n",
+ "my_profil2.__class__.__dict__"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 134,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Compte2(Profil2):\n",
+ " def __init__(self, name):\n",
+ " super().__init__(name)\n",
+ "\n",
+ " def getPassword(self):\n",
+ " return self.__password\n",
+ " \n",
+ " def getPrivate_herited(self):\n",
+ " return self.__private_classe_attribut"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 135,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mon_compte2 = Compte2(\"C.Ben\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 136,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "'Compte2' object has no attribute '_Compte2__password'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_1880/4036005713.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# mais ceci n'est plus possible\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmon_compte2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetPassword\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m#mon_compte2.getPrivate_herited()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_1880/3881013715.py\u001b[0m in \u001b[0;36mgetPassword\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgetPassword\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__password\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgetPrivate_herited\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mAttributeError\u001b[0m: 'Compte2' object has no attribute '_Compte2__password'"
+ ]
+ }
+ ],
+ "source": [
+ "# mais ceci n'est plus possible\n",
+ "mon_compte2.getPassword()\n",
+ "#mon_compte2.getPrivate_herited()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 116,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'name': 'C.Ben', '_Profil2__password': 'pass'}"
+ ]
+ },
+ "execution_count": 116,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# On remarque que dans le dict, l'attribut s'appelle _Profil2__password et non pas Compte2__password\n",
+ "mon_compte2.__dict__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## IV.3 Les méthodes privées"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice user_creation`**\n",
+ "\n",
+ "- créer une classe user avec un attribut publique \"profil\", des attribut protégés \"password\" et \"user_name\" et un attribut privée \"validation_code\"\n",
+ "- créer des méthodes publiques \"set_password\", \"get_password\" et \"get_user_name\"\n",
+ "- créer une méthode publique \"set_username\" qui prend comme argument un code et un nouveau user name. Cette méthode fait appelle à une autre méthode, privée cette fois qui compare le code avec le code de validation. Si le code correspond au validation_code alors le changement est réalisé.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# V Usages avancés"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## V.1 Le décorateur: @Property"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les attributs protégés c'est bien mais c'est peu maintenable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 122,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Supposons le code suivant:\n",
+ "class Celsius:\n",
+ " def __init__(self, temperature:int = 0):\n",
+ " self.temperature = temperature\n",
+ "\n",
+ " def to_fahrenheit(self):\n",
+ " return (self.temperature * 1.8) + 32"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Dans une mise à jour de notre code, on veut empecher la création de températures inférieures à -273.15 degré. Ces restrictions il va falloir les inscrires dans une méthode setter et faire en sorte que la seule manière de définir la température, ce soit par ce moyen setter. On transforme donc temperature en attribut protégé"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Making Getters and Setter methods\n",
+ "class Celsius:\n",
+ " def __init__(self, temperature=0):\n",
+ " self.set_temperature(temperature)\n",
+ "\n",
+ " def to_fahrenheit(self):\n",
+ " return (self.get_temperature() * 1.8) + 32\n",
+ "\n",
+ " # getter method\n",
+ " def get_temperature(self):\n",
+ " return self._temperature\n",
+ "\n",
+ " # setter method\n",
+ " def set_temperature(self, value):\n",
+ " if value < -273.15:\n",
+ " raise ValueError(\"Temperature below -273.15 is not possible.\")\n",
+ " self._temperature = value"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "temperature = Celsius(7.2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on method set_temperature in module __main__:\n",
+ "\n",
+ "set_temperature(value) method of __main__.Celsius instance\n",
+ " # setter method\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "help(temperature.set_temperature)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 143,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['__class__',\n",
+ " '__delattr__',\n",
+ " '__dict__',\n",
+ " '__dir__',\n",
+ " '__doc__',\n",
+ " '__eq__',\n",
+ " '__format__',\n",
+ " '__ge__',\n",
+ " '__getattribute__',\n",
+ " '__gt__',\n",
+ " '__hash__',\n",
+ " '__init__',\n",
+ " '__init_subclass__',\n",
+ " '__le__',\n",
+ " '__lt__',\n",
+ " '__module__',\n",
+ " '__ne__',\n",
+ " '__new__',\n",
+ " '__reduce__',\n",
+ " '__reduce_ex__',\n",
+ " '__repr__',\n",
+ " '__setattr__',\n",
+ " '__sizeof__',\n",
+ " '__str__',\n",
+ " '__subclasshook__',\n",
+ " '__weakref__',\n",
+ " '_temperature',\n",
+ " 'get_temperature',\n",
+ " 'set_temperature',\n",
+ " 'to_fahrenheit']"
+ ]
+ },
+ "execution_count": 143,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dir(temperature)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Le problème c'est qu'il va falloir modifier l'ensemble de notre programme.\n",
+ "\n",
+ "A chaque fois qu'on avait **`obj.temperature`** il faut mettre **`obj.get_temperature()`** et à chaque fois qu'on a **`obj.temperature = val`** il faut mettre **`set_temperature(val)`**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour ne pas rencontrer ce problème, on peut utiliser les décorateurs @property, @setter.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 71,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Using @property decorator\n",
+ "class Celsius:\n",
+ " def __init__(self, temperature=0):\n",
+ " self.temperature = temperature\n",
+ "\n",
+ " def to_fahrenheit(self):\n",
+ " return (self.temperature * 1.8) + 32\n",
+ "\n",
+ " @property\n",
+ " def temperature(self):\n",
+ " print(\"Getting value...\") # a ne pas écrire dans un vrai code\n",
+ " return self._temperature\n",
+ "\n",
+ " @temperature.setter\n",
+ " def temperature(self, value):\n",
+ " print(\"Setting value...\") # a ne pas écrire dans un vrai code\n",
+ " if value < -273.15:\n",
+ " raise ValueError(\"Temperature below -273 is not possible\")\n",
+ " self._temperature = value\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 72,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "can't set attribute",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_2921/2193769133.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mhuman\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mCelsius\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m37\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_2921/1803078970.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, temperature)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mclass\u001b[0m \u001b[0mCelsius\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtemperature\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtemperature\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtemperature\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mto_fahrenheit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mAttributeError\u001b[0m: can't set attribute"
+ ]
+ }
+ ],
+ "source": [
+ "human = Celsius(37)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'_temperature': 47}"
+ ]
+ },
+ "execution_count": 69,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "human.__dict__"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dir(human)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 164,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Getting value...\n",
+ "37\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(human.temperature)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 157,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Setting value...\n"
+ ]
+ },
+ {
+ "ename": "ValueError",
+ "evalue": "Temperature below -273 is not possible",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_11213/1994104652.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mhuman\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtemperature\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m280\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_11213/3974558698.py\u001b[0m in \u001b[0;36mtemperature\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Setting value...\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# a ne pas écrire dans un vrai code\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m273.15\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Temperature below -273 is not possible\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 19\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_temperature\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Temperature below -273 is not possible"
+ ]
+ }
+ ],
+ "source": [
+ "human.temperature = -280"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 125,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Setting value...\n",
+ "Getting value...\n",
+ "37\n",
+ "Getting value...\n",
+ "98.60000000000001\n",
+ "Setting value...\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Quand on instancie un objet, le paramètre se définit directement via le setter.\n",
+ "human = Celsius(37)\n",
+ "\n",
+ "# Quand on le print, c'est via le geet\n",
+ "print(human.temperature)\n",
+ "\n",
+ "\n",
+ "# les autre méthodes y accèdent également via le getter\n",
+ "print(human.to_fahrenheit())\n",
+ "\n",
+ "# on le modifie églament via le setter\n",
+ "human.temperature = 39"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il est possible également de défnir des attributs privés"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Using @property decorator\n",
+ "class Password:\n",
+ " def __init__(self, password=0):\n",
+ " self.__password = password\n",
+ "\n",
+ " @property\n",
+ " def password(self):\n",
+ " return self.__password # dunders!\n",
+ "\n",
+ " # @password.setter\n",
+ " # def password(self, value):\n",
+ " # self.__password = value ## dunders too"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_password = Password(\"secret\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 80,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "can't set attribute",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/var/folders/py/4rt338cj1ks4z3332m7l3f880000gp/T/ipykernel_2921/3247830432.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_password\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpassword\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m9\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m: can't set attribute"
+ ]
+ }
+ ],
+ "source": [
+ "my_password.password = 9"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice user_creation_bis`**\n",
+ "\n",
+ "Refaite l'exercice user_creation à l'aide cette fois du décorateur @property"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## V.2 Les classes abstraites"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Il peut être utile de créer une classe parente dont on veut faire hériter les méthodes mais qui ne peut pas être instanciée\n",
+ "\n",
+ "Dans ce cas on utilisera une [classe abstaite](https://towardsdatascience.com/abstract-base-classes-in-python-fundamentals-for-data-scientists-3c164803224b). C'est une classe qui est définie, dont on peut hériter mais qu'on ne peut pas instancier."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# On crée ici un classe MaterielScolaire qui ne correspond à rien de précis mais dont on peut hériter:\n",
+ "\n",
+ "from abc import ABCMeta, abstractmethod # permet de définir des classes de base\n",
+ "\n",
+ "class MaterielScolaire(metaclass = ABCMeta):\n",
+ " \n",
+ " user = \"student\"\n",
+ "\n",
+ " def get_date_achat(self):\n",
+ " print(\"a la rentrée\")\n",
+ "\n",
+ " # abstactmethod permet de définir des méthodes que les classes filles seront obligées de posseder. \n",
+ " @abstractmethod\n",
+ " def tient_dans_une_trousse(self,untruc):\n",
+ " return \"nimporte quoi\"\n",
+ "\n",
+ " @abstractmethod\n",
+ " def nom_methode(self):\n",
+ " pass\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "ma_regle.tient_dans_une_trousse()='nimporte quoi'\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Je ne peux définir une classe enfant qui ne contient pas de définition des méthodes suivants abstactmethod\n",
+ "class Regle(MaterielScolaire):\n",
+ " \n",
+ " def __init__(self, longueur):\n",
+ " self.longueur = longueur\n",
+ " #self.marque = marque\n",
+ " def tient_dans_une_trousse(self):\n",
+ " return super().tient_dans_une_trousse(\"mon argument\")\n",
+ " \n",
+ "\n",
+ "# Pour le reste, le principe d'héritage fonctionne\n",
+ "ma_regle = Regle(20)\n",
+ "print(f\"{ma_regle.tient_dans_une_trousse()=}\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**`Exercice le zoo`**\n",
+ "\n",
+ "Vous gérez un zoo qui abrite des poissons, des oiseaux et des félins.\n",
+ "- Tous les animaux possèdent un nom\n",
+ "- tous les animaux doivent pouvoir manger selon leur régime alimentaire\n",
+ "\n",
+ "- Pour que les félins mangent il faut vérifier que ce qu'on leur donne soit bien de la viande\n",
+ "- Pour que les poissons mangent il faut vérifier que ce qu'on leur donne soit bien de la nourriture pour poisson\n",
+ "- Pour que les oiseaux mangent il faut vérifier que ce qu'on leur donne soit bien des graines\n",
+ "\n",
+ "- Tous les poissons doivent pouvoir nager\n",
+ "- Tous les oiseaux doivent piailler\n",
+ "\n",
+ "- Les lions doivent rugir et les chats miauler, les panthères ne font rien\n",
+ "- les canaris piaillent en disant \"cuicui\" les autruches piaillent en disant \"CUICUI\"\n",
+ "\n",
+ "Créer votre zoo avec 2 lion , 3 chat, 1 canari, 2 autruches, 3 raies et 1 dauphin."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## V.3 Typing classes in python."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### V.4.1 Typing in python: typing hint"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Depuis python 3.5 il est possible d'inclure des annotations de type comme celle-ci:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "7\n"
+ ]
+ }
+ ],
+ "source": [
+ "\n",
+ "# On précise ici que les deux arguments attendus sont de types int \n",
+ "# et que la fonction est sensé renvoyer quelque chose de type int\n",
+ "# la valeur par défaut se met après\n",
+ "def f(x: int , y: int = 0) -> int :\n",
+ " return x + y\n",
+ "\n",
+ "print(f(3, 4))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "8.0\n",
+ "ab\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(f(3.2, 4.8))\n",
+ "print(f(\"a\", \"b\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Cependant, Python est un langage dynamique, c'est à dire qu'on peut changer le type assigné à une variable. Ce typage n'est donc qu'indicatif et n'est pas contraignant.\n",
+ "\n",
+ "On considère que le typage n'est pas une compétence de python mais un compétence du développeur ou de l'IDE. On peut donc modifier l'ide pour qu'il mette en évidence nos erreurs de type:\n",
+ "Dans VS Code: setting -> pylance -> python analysis Type Checking mode (activer)\n",
+ "\n",
+ "On peut également utiliser le package mypy qui permet de lancer le code entre utilisant ce typage comme stricte."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on function f in module __main__:\n",
+ "\n",
+ "f(x: int, y: int = 0) -> int\n",
+ " # On précise ici que les deux arguments attendus sont de types int \n",
+ " # et que la fonction est censé renvoyer quelque chose de type int\n",
+ " # la valeur par défaut se met après\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "#Le typage s'affiche quand j'utilise help\n",
+ "help(f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### V.4.2 Typing classes in python."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 142,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " un cake à ['chocolat', 'banace'] de 10.8 part\n",
+ "[<__main__.TypeCake object at 0x10d847730>]\n"
+ ]
+ }
+ ],
+ "source": [
+ "from typing import List, Optional\n",
+ "\n",
+ "class TypeCake:\n",
+ " def __init__(self, flavor: List[str], number_share: int):\n",
+ " self.flavor: List[str] = flavor\n",
+ " self.number_share: int = number_share\n",
+ " self.new_number_share : float = self.number_of_shareplusdeuxpointcinq()\n",
+ " \n",
+ " def __str__(self):\n",
+ " return f\" un cake à {self.flavor} de {self.number_share} part\"\n",
+ " \n",
+ " def number_of_shareplusdeuxpointcinq (self):\n",
+ " \n",
+ " return self.number_share + 2.5\n",
+ "\n",
+ "\n",
+ "my_weird_cake = TypeCake(flavor=[\"chocolat\",\"banace\"], number_share=10.8)\n",
+ "my_weird_cake.number_share\n",
+ "\n",
+ "\n",
+ "print(my_weird_cake)\n",
+ "my_list= [my_weird_cake]\n",
+ "print(my_list)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'flavor': 5, 'number_share': '10'}"
+ ]
+ },
+ "execution_count": 45,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "my_weird_cake.__dict__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## V.4 Les méthodes \\_\\_str\\_\\_ et \\_\\_repr\\_\\_"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 159,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Stylo (object):\n",
+ " def __init__(self, couleur, taille):\n",
+ " self.couleur = couleur\n",
+ " self.taille = taille\n",
+ "\n",
+ " def __repr__(self):\n",
+ " return f\"Stylo : {self.__dict__}\" \n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 93,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[{ couleur :rouge , taille: 10 }]\n"
+ ]
+ }
+ ],
+ "source": [
+ "ma_liste = []\n",
+ "ma_liste.append(mon_stylo)\n",
+ "print(ma_liste)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Python \\_\\_str\\_\\_()\n",
+ "\n",
+ "Cette méthode retourne la chaine de charactère qui représente l'objet. Cette méthode est appelée quand on fait print() ou str().\n",
+ "\n",
+ "Si on n'implémente pas \\_\\_str\\_\\_() pour une classe, alors la représentation c'est \\_\\_repr\\_\\_() qui est appelée."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Python \\_\\_repr\\_\\_()\n",
+ "Cette fonction est appelée quand on fait repr(). L'idée est de transformer n'importe quel objet python en une chaine de charactère qui permettrait de reconstruire cet objet. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2021-11-29 11:31:12.443989\n",
+ "datetime.datetime(2021, 11, 29, 11, 31, 12, 443989)\n"
+ ]
+ }
+ ],
+ "source": [
+ "#Python __str__ and __repr__ examples\n",
+ "#Let’s look at a built-in class where both __str__ and __repr__ functions are defined.\n",
+ "\n",
+ "import datetime\n",
+ "now = datetime.datetime.now()\n",
+ "print(str(now))\n",
+ "#'2020-12-27 22:28:00.324317'\n",
+ "print(repr(now))\n",
+ "#'datetime.datetime(2020, 12, 27, 22, 28, 0, 324317)'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "On voit que le résultat de \\_\\_str\\_\\_() est plus facilement lisible que celui de \\_\\_repr\\_\\_() qui possède plus d'information et est donc plus utile pour une machine."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Cake:\n",
+ " def __init__(self, flavor:str, number_share: int):\n",
+ " self.flavor: str = flavor\n",
+ " self.number_share: int = number_share\n",
+ " \n",
+ " def __str__(self):\n",
+ " return f\" un cake à {self.flavor} de {self.number_share} part\"\n",
+ "\n",
+ "\n",
+ "my_weird_cake = Cake(flavor=\"banana\", number_share=10)\n",
+ "my_weird_cake.number_share\n",
+ "\n",
+ "\n",
+ "print(my_weird_cake)\n",
+ "my_list= [my_weird_cake]\n",
+ "print(my_list)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "En conclusion si la méthode str n'est pas défnie, c'est la méthode repr qui est appelée. Donc si on ne veut pas distinguer l'affichage pour l'homme et l'affichage pour la machine, il suffit de définir seulement la méthode repr."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## V.5 \\_\\_eq\\_\\_ method"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\\_\\_eq\\_\\_ permet de définir sous quels critère un objet de votre class est équivalent à un autre."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 168,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<__main__.card object at 0x10c421550>\n",
+ "<__main__.card object at 0x10d8526d0>\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# De base, deux objets instanciés de la même manière ne sont pas équivalent\n",
+ "class card:\n",
+ " def __init__ (self,rank, suit):\n",
+ " self.rank = rank\n",
+ " self.suit = suit\n",
+ " \n",
+ "\n",
+ "\n",
+ "queenofheart_a = card(\"Q\",\"heart\")\n",
+ "queenofheart_b = card(\"Q\",\"heart\")\n",
+ "\n",
+ "print(queenofheart_a)\n",
+ "print(queenofheart_b)\n",
+ "print(queenofheart_a != queenofheart_b )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 171,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n",
+ "False\n"
+ ]
+ }
+ ],
+ "source": [
+ "class cardeq:\n",
+ " def __init__ (self,rank, suit):\n",
+ " self.rank = rank\n",
+ " self.suit = suit\n",
+ " self.card_value = self.__card_value()\n",
+ " \n",
+ " def __eq__(self, other):\n",
+ " if type(other) is type(self):\n",
+ " return (self.rank == other.rank) and (self.suit == other.suit)\n",
+ " else:\n",
+ " return False \n",
+ "\n",
+ " def __card_value(self):\n",
+ " order = {\"J\":11, \"Q\" : 12 , \"K\" : 13, \"A\": 14}\n",
+ " if isinstance(self.rank, str):\n",
+ " return order[self.rank]\n",
+ " else:\n",
+ " return self.rank\n",
+ "\n",
+ " def __lt__(self,other): \n",
+ " if type(other) is type(self):\n",
+ " return self.card_value < other.card_value\n",
+ " raise TypeError(\"les deux objets ne sont pas du même type\")\n",
+ "\n",
+ "\n",
+ "queenofheart_a = cardeq(\"Q\",\"heart\")\n",
+ "queenofheart_b = cardeq(\"Q\",\"heart\")\n",
+ "dix_de_coeur = cardeq(10,\"heart\")\n",
+ "kingofgeart = cardeq(\"K\",\"heart\")\n",
+ "\n",
+ "print(queenofheart_a == queenofheart_b )\n",
+ "print(dix_de_coeur > kingofgeart )\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 286,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# écriture alternative\n",
+ "class cardeq:\n",
+ " def __init__ (self,rank, suit):\n",
+ " self.rank = rank\n",
+ " self.suit = suit\n",
+ " \n",
+ " def __members(self):\n",
+ " return (self.rank, self.suit)\n",
+ "\n",
+ " def __eq__(self, other):\n",
+ " if type(other) is type(self):\n",
+ " return self.__members() == other.members()\n",
+ " else:\n",
+ " return False \n",
+ "\n",
+ "\n",
+ "queenofheart_a = cardeq(\"Q\",\"heart\")\n",
+ "queenofheart_b = cardeq(\"Q\",\"heart\")\n",
+ "\n",
+ "print(queenofheart_a == queenofheart_b )"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## V.6 Python datamodel"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dir(object)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Plus sur les méthodes spéciales: [documentation](https://docs.python.org/3/reference/datamodel.html#special-method-names)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# VI Les dataclasses "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Reprennons notre exemple de gateau, l'initialisation est longue et ne permet même pas de typer.\n",
+ "Est ce qu'il n'y aurait pas moyen de faire plus simple?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 64,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class card:\n",
+ " def __init__ (self,rank, suit):\n",
+ " self.rank = rank\n",
+ " self.suit = suit\n",
+ "\n",
+ " \n",
+ " def __eq__(self, other):\n",
+ " if type(other) is type(self):\n",
+ " return (self.rank == other.rank) and (self.suit == other.suit)\n",
+ " else:\n",
+ " return False \n",
+ " \n",
+ " def __repr__(self):\n",
+ " return f\"un truc beau\"\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 65,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "un truc beau\n"
+ ]
+ }
+ ],
+ "source": [
+ "queenofheart_b = card(\"Q\",\"heart\")\n",
+ "print(queenofheart_b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "C'est possible avec le module dataclasses"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 89,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "11"
+ ]
+ },
+ "execution_count": 89,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from dataclasses import dataclass, field\n",
+ "from typing import ClassVar\n",
+ "\n",
+ "@dataclass\n",
+ "class Cake:\n",
+ " \n",
+ " # on initialise les attributs d'instance\n",
+ " flavor: str #equivalent à dans init self.flavor: str = flavor\n",
+ " number_share: int \n",
+ " init_value: int = field(default=0)\n",
+ " ma_liste = field(default_factory=[])\n",
+ " cream: bool = False # on peut préciser une valeur par défaut\n",
+ " version_recette: ClassVar[float] = 3.2 # on peut aussi créer des attributs de classe\n",
+ "\n",
+ " \n",
+ " def __post_init__(self):\n",
+ " self.number_share_plus_one = self.__number_share_plus_one()\n",
+ "\n",
+ " def __number_share_plus_one(self):\n",
+ " return self.number_share + 1\n",
+ " \n",
+ "# mieux encore, une repr est automatiquement généré:\n",
+ "\n",
+ "banana_cake = Cake(flavor=\"banana\",number_share=10)\n",
+ "banana_cake.flavor\n",
+ "banana_cake.number_share_plus_one"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 90,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'flavor': 'banana',\n",
+ " 'number_share': 10,\n",
+ " 'init_value': 0,\n",
+ " 'cream': False,\n",
+ " 'number_share_plus_one': 11}"
+ ]
+ },
+ "execution_count": 90,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "banana_cake.__dict__"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 72,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Cake(flavor='banana', number_share=10, cream=False)\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(banana_cake)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Les dataclasses implémentent également une méthode \\_\\_eq\\_\\_"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 71,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 71,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "banana_cake_bis = Cake(\"banana\",10)\n",
+ "banana_cake == banana_cake_bis"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pour aller plus loin vous pouvez découvrir le package [pydantic](https://www.youtube.com/watch?v=Vj-iU-8_xLs) qui a des fonctionnalités supplémentaires par rapport aux dataclasses comme la présence de validator."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "More about [dataclasses](https://www.youtube.com/watch?v=vBH6GRJ1REM&t=455s)\n",
+ "\n",
+ "[documentation](https://docs.python.org/3/library/dataclasses.html#module-dataclasses)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# VII Tester ses classes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "voir les fichiers:\n",
+ "- class_to_test.py\n",
+ "- test_class_to_test.py"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Ressources"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Le cours s'inspire des cours suivant:\n",
+ "- [openclassroom](https://openclassrooms.com/fr/courses/7150616-apprenez-la-programmation-orientee-objet-avec-python/7197146-comprenez-la-programmation-orientee-objet)\n",
+ "- [programiz (property)](https://www.programiz.com/python-programming/property)\n",
+ "- [journal dev (str, repr)](https://www.journaldev.com/22460/python-str-repr-functions)\n",
+ "- [Docstring (youtube)](https://www.youtube.com/watch?v=6Ltk49YhrWY)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3.9.12 ('env': venv)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.12"
+ },
+ "orig_nbformat": 4,
+ "vscode": {
+ "interpreter": {
+ "hash": "0607a848ffd73ecc9cc21824b435c3b7f19a6ddc6b88730c443268397d59d817"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/oop/Correction_exercice_concessionnaire.ipynb b/oop/Correction_exercice_concessionnaire.ipynb
new file mode 100644
index 0000000..916e1ea
--- /dev/null
+++ b/oop/Correction_exercice_concessionnaire.ipynb
@@ -0,0 +1,207 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Voiture:\n",
+ " def __init__(self, marque, couleur, prix):\n",
+ " self.marque = marque\n",
+ " self.couleur = couleur\n",
+ " self.prix = prix\n",
+ "\n",
+ " def __str__(self):\n",
+ " return f'{self.marque} {self.couleur} à {self.prix}'\n",
+ "\n",
+ " def __repr__(self):\n",
+ " return f'{self.marque} {self.couleur} à {self.prix}'\n",
+ "\n",
+ " def drive(self):\n",
+ " print(f\"je conduis ma super {self.marque}€\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Magasin:\n",
+ " def __init__(self, nom):\n",
+ " self.nom = nom\n",
+ " self.inventaire = {}\n",
+ " self.stock = []\n",
+ "\n",
+ " def ajout_voiture(self,voiture):\n",
+ " self.stock.append(str(voiture))\n",
+ " if voiture.marque not in self.inventaire:\n",
+ " self.inventaire[voiture.marque] = 0\n",
+ " self.inventaire[voiture.marque] += 1\n",
+ " print(f\"la {voiture.marque} a été ajoutée à l'inventaire\")\n",
+ "\n",
+ " def delete_voiture(self,voiture):\n",
+ " self.stock.remove(str(voiture))\n",
+ " self.inventaire[voiture.marque] -= 1\n",
+ " print(f\"la {voiture.marque} a été retirée de l'inventaire\")\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "la Toyota a été ajoutée à l'inventaire\n",
+ "la Toyota a été ajoutée à l'inventaire\n",
+ "la Toyota a été ajoutée à l'inventaire\n",
+ "la Toyota a été ajoutée à l'inventaire\n",
+ "la BMW a été ajoutée à l'inventaire\n",
+ "la BMW a été ajoutée à l'inventaire\n",
+ "la Honda a été ajoutée à l'inventaire\n",
+ "la Honda a été ajoutée à l'inventaire\n",
+ "{'Toyota': 4, 'BMW': 2, 'Honda': 2}\n",
+ "['Toyota rouge à 20000', 'Toyota bleue à 20000', 'Toyota noire à 20000', 'Toyota grise à 20000', 'BMW rouge à 20000', 'BMW kaki à 20000', 'Honda verte à 20000', 'Honda noire à 20000']\n"
+ ]
+ }
+ ],
+ "source": [
+ "mon_magasin = Magasin(\"Simplon shop\")\n",
+ "\n",
+ "mon_magasin.ajout_voiture(Voiture(\"Toyota\",\"rouge\", 20000))\n",
+ "mon_magasin.ajout_voiture(Voiture(\"Toyota\",\"bleue\", 20000))\n",
+ "mon_magasin.ajout_voiture(Voiture(\"Toyota\",\"noire\", 20000))\n",
+ "mon_magasin.ajout_voiture(Voiture(\"Toyota\",\"grise\", 20000))\n",
+ "mon_magasin.ajout_voiture(Voiture(\"BMW\",\"rouge\", 20000))\n",
+ "mon_magasin.ajout_voiture(Voiture(\"BMW\",\"kaki\", 20000))\n",
+ "mon_magasin.ajout_voiture(Voiture(\"Honda\",\"verte\", 20000))\n",
+ "mon_magasin.ajout_voiture(Voiture(\"Honda\",\"noire\", 20000))\n",
+ "\n",
+ "print(mon_magasin.inventaire)\n",
+ "print(mon_magasin.stock)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Client:\n",
+ " def __init__(self, name, id, email):\n",
+ " self.name = name\n",
+ " self.id = id\n",
+ " self.email = email\n",
+ " \n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Vente:\n",
+ " def __init__(self,magasin,voiture,client,vendeur):\n",
+ " self.magasin = magasin\n",
+ " self.voiture =voiture\n",
+ " self.client = client\n",
+ " self.vendeur = vendeur\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Vendeur:\n",
+ " def __init__(self,name):\n",
+ " self.name = name\n",
+ " self.nb_vente = 0\n",
+ "\n",
+ " @staticmethod\n",
+ " def checkstock(magasin,voiture):\n",
+ " return str(voiture) in magasin.stock\n",
+ "\n",
+ " def creer_vente(self,magasin,voiture,client):\n",
+ " if self.checkstock(magasin,voiture):\n",
+ " self.nb_vente +=1\n",
+ " magasin.delete_voiture(voiture)\n",
+ " return Vente(magasin,voiture,client,self)\n",
+ " else:\n",
+ " print(\"la voiture n'est pas dans le stock, la vente ne peut être effectuée\")\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 57,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "la Honda a été retirée de l'inventaire\n"
+ ]
+ }
+ ],
+ "source": [
+ "denis = Vendeur(\"Denis\")\n",
+ "\n",
+ "ma_vente = denis.creer_vente(mon_magasin,Voiture(\"Honda\",\"noire\",20000),Client(\"robert\",324342,\"rb@gmail.com\"))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 60,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'Toyota': 4, 'BMW': 2, 'Honda': 1}"
+ ]
+ },
+ "execution_count": 60,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mon_magasin.inventaire"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "949777d72b0d2535278d3dc13498b2535136f6dfe0678499012e853ee9abcab1"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.8.6 64-bit",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.6"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/oop/Correction_forum.ipynb b/oop/Correction_forum.ipynb
new file mode 100644
index 0000000..af0cc40
--- /dev/null
+++ b/oop/Correction_forum.ipynb
@@ -0,0 +1,222 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Post:\n",
+ " def __init__(self,texte,user, date,fil):\n",
+ " self.texte = texte\n",
+ " self.user = user\n",
+ " self.date = date\n",
+ " self.fil = fil\n",
+ " \n",
+ " def __repr__(self):\n",
+ " return f\"user:{self.user} date:{self.date} \\n fil de discussion: {self.fil} content : \\n {self.texte}\"\n",
+ "\n",
+ "class GifPost(Post):\n",
+ " def __init__(self,texte,user,date,fil,file_type,file_path):\n",
+ " super().__init__(texte,user, date,fil,file_type)\n",
+ " self.gif_path=file_path\n",
+ "\n",
+ "class JpegPost(Post):\n",
+ " def __init__(self,texte,user,date,fil,file_type,file_path):\n",
+ " super().__init__(texte,user, date,fil,file_type)\n",
+ " self.jpeg_path=file_path\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Fil():\n",
+ " def __init__(self, titre, date, texte_first_content,user,file_type=None,file_path=None):\n",
+ " self.titre = titre\n",
+ " self.date = date\n",
+ " self.collection_post =[]\n",
+ " self.add_post(texte_first_content,user,date,file_type,file_path)\n",
+ "\n",
+ " def add_post(self,texte,user,date,file_type=None,file_path=None):\n",
+ " if file_type == \"Gif\":\n",
+ " self.collection_post.append(GifPost(texte,user,date,self,file_type,file_path))\n",
+ " elif file_type == \"Jpeg\":\n",
+ " self.collection_post.append(JpegPost(texte,user,date,self,file_type,file_path))\n",
+ " else:\n",
+ " self.collection_post.append(Post(texte,user,date,self))\n",
+ " \n",
+ " def del_post(self,index_post):\n",
+ " del self.collection_post[index_post]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class User:\n",
+ " def __init__(self,identifiant, password, email):\n",
+ " self.identifiant = identifiant\n",
+ " self.password = password\n",
+ " self.email = email\n",
+ " \n",
+ " def new_fil(self,titre, date, texte_first_content,file_type=None,file_path=None):\n",
+ " return Fil(titre, date, texte_first_content,self,file_type=None,file_path=None)\n",
+ "\n",
+ " def new_post(self,texte, date, fil, file_type=None,file_path=None):\n",
+ " fil.add_post(texte,date,self,file_type=None,file_path=None)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Moderateur(User):\n",
+ " def modify_post(self,fil,index_post,new_content):\n",
+ " fil.collection_post[index_post].texte = new_content\n",
+ " \n",
+ " def delete_post(self,fil,index_post):\n",
+ " fil.del_post(index_post)\n",
+ "\n",
+ " def delete_fil(self,fil):\n",
+ " del fil"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 50,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "denis = User(\"denis\",\"1234\",\"dd@gmail.com\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 51,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "first_fil = denis.new_fil(\"mes passions\",\"01012020\",\"J'aimerais mieux connaitre mes passions, avez vous des idées?\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[user:<__main__.User object at 0x113af2a30> date:01012020 \n",
+ " fil de discussion: <__main__.Fil object at 0x112786eb0> content : \n",
+ " J'aimerais mieux connaitre mes passions, avez vous des idées?]"
+ ]
+ },
+ "execution_count": 52,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "first_fil.collection_post"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "jeanne = User(\"Jeanne\",\"1234\",\"jeanne@gmail.com\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 54,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "jeanne.new_post(\"cherche au plus profond de toi\",\"lendemain\",first_fil,\"Gif\",\"the path\") "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 58,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[user:<__main__.User object at 0x113af2a30> date:01012020 \n",
+ " fil de discussion: <__main__.Fil object at 0x112786eb0> content : \n",
+ " J'aimerais mieux connaitre mes passions, avez vous des idées?]"
+ ]
+ },
+ "execution_count": 58,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "first_fil.collection_post"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "anais = Moderateur(\"Anais\",\"12345\",\"ana@gmail.com\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 57,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "anais.delete_post(first_fil,1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "949777d72b0d2535278d3dc13498b2535136f6dfe0678499012e853ee9abcab1"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.8.6 64-bit",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.6"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/oop/class_to_test.py b/oop/class_to_test.py
new file mode 100644
index 0000000..bfbdd3e
--- /dev/null
+++ b/oop/class_to_test.py
@@ -0,0 +1,51 @@
+from abc import ABC, abstractmethod
+
+class Vehicule(ABC):
+ def drive(self) -> str:
+ return "the vehicule is on its wheels!"
+
+ @property
+ @abstractmethod
+ def prix(self):
+ pass
+
+class Voiture(Vehicule):
+ def __init__(self, marque, couleur, prix, reduction_applicable):
+ self.marque = marque
+ self.couleur = couleur
+ self.prix = prix
+ self.reduction_applicable = reduction_applicable
+
+ def __str__(self):
+ return f'{self.marque} {self.couleur} à {self.prix}'
+
+ def __repr__(self):
+ return f'{self.marque} {self.couleur} à {self.prix}'
+
+ @property
+ def prix(self):
+ return self._prix
+
+ @prix.setter
+ def prix(self, value):
+ if not isinstance(value,int):
+ raise ValueError("prix should be int")
+ self._prix = value
+
+ def prix_apres_reduction(self):
+ return self.prix * (1-self.reduction_applicable)
+
+ def prix_apres_double_reduction(self):
+ return self.prix * (1 - 2*self.reduction_applicable)
+
+ def prix_apres_triple_reduction(self):
+ return self.prix * (1 - 3*self.reduction_applicable)
+
+ def fonction_sans_fin(self):
+ while True:
+ print("sans fin!")
+
+ def I_want_to_quit(self):
+ self.fonction_sans_fin()
+ return "I quit"
+
diff --git a/oop/correction.txt b/oop/correction.txt
new file mode 100644
index 0000000..70498bc
--- /dev/null
+++ b/oop/correction.txt
@@ -0,0 +1,136 @@
+classe héritage: https://github.com/OpenClassrooms-Student-Center/7150626-Apprenez-la-programmation-orientee-objet-avec-Python/blob/main/exercices/p2c2_forum.py
+
+
+
+user_creation (encapsulation)
+
+class User:
+ def __init__(self,profil):
+ self.profil = profil
+ self._password = ""
+ self._user_name = ""
+ self.__validation_code = "AB2X"
+
+ def set_password(self,new_password):
+ self._password = new_password
+
+ def get_password(self):
+ return self._password
+
+ def get_user_name(self):
+ return self._user_name
+
+ def __check_validation_code(self,code):
+ return code == self.__validation_code
+
+ def set_user_name(self,code,user_name):
+ if self.__check_validation_code(code):
+ self._user_name = user_name
+ else:
+ print("error code")
+
+user_creation_bis
+
+class User:
+ def __init__(self,profil, password="", code_value = ("AB2X","")):
+ self.profil = profil
+ self.password = password
+ self.__validation_code = "AB2X"
+ self.user_name = code_value
+
+ @property
+ def password(self):
+ return self._password
+
+ @password.setter
+ def password(self,new_password):
+ self._password = new_password
+
+
+ @property
+ def user_name(self):
+ return self._user_name
+
+ @user_name.setter
+ def user_name(self,code_value):
+ code,value = code_value
+ print(code)
+ print(self.__validation_code)
+ if self.__check_validation_code(code):
+ self._user_name = value
+ else:
+ print("error code")
+
+ def __check_validation_code(self,code):
+ return code == self.__validation_code
+
+
+
+Zoo
+
+from abc import ABCMeta, abstractmethod
+
+class Animal (metaclass = ABCMeta ):
+ def __init__(self, name):
+ self.name = name
+
+ @abstractmethod
+ def manger(self):
+ pass
+
+class Felin(Animal, metaclass = ABCMeta):
+ def manger (self,value):
+ if value == "viande":
+ print("le félin est nourri")
+ else:
+ print("cela ne correspond pas à un félin")
+
+class Poisson(Animal, metaclass = ABCMeta):
+ def manger (self,value):
+ if value == "nourriture pour poisson":
+ print("le poisson est nourri")
+ else:
+ print("cela ne correspond pas à un poisson")
+
+ @abstractmethod
+ def nager():
+ pass
+
+class Oiseau(Animal, metaclass = ABCMeta):
+ def manger (self,value):
+ if value == "graine":
+ print("l'oiseau est nourri")
+ else:
+ print("cela ne correspond pas à un oiseau")
+
+ @abstractmethod
+ def piailler():
+ pass
+
+
+class Lion(Felin):
+ def rugier(self):
+ print("RRRRRrrrr")
+
+class Chat(Felin):
+ def miauler(self):
+ print("Miaou")
+
+class Panthère(Felin):
+ pass
+
+class Canari(Oiseau):
+ def piaillier(self):
+ print("cuicui")
+
+class Autruche(Oiseau):
+ def piaillier(self):
+ print("CUICUI")
+
+class Raie(Poisson):
+ def nager(self):
+ pass
+
+class Dauphin(Poisson):
+ def nager(self):
+ pass
diff --git a/oop/correction_conce_bis.py b/oop/correction_conce_bis.py
new file mode 100644
index 0000000..851ad2a
--- /dev/null
+++ b/oop/correction_conce_bis.py
@@ -0,0 +1,108 @@
+
+from dataclasses import dataclass, field
+from abc import ABC, abstractmethod
+
+@dataclass
+class Vehicule(ABC):
+
+ couleur: str
+ _marque: str
+ modele: str
+ prix_ht: float
+ reduction_applicable: float
+
+ @property
+ @abstractmethod
+ def marque(self):
+ return self._marque
+
+ def __post_init__(self):
+ self.prix_ttc: float = self.prix_ht * 1.20
+
+
+@dataclass
+class Voiture(Vehicule):
+
+ boitier: str
+
+ @property
+ def marque(self):
+ return self._marque
+
+@dataclass
+class Moto(Vehicule):
+
+ visiere: str
+
+ @property
+ def marque(self):
+ return self._marque
+
+@dataclass
+class Camion(Vehicule):
+
+ remorque: str
+
+ @property
+ def marque(self):
+ return self._marque
+
+@dataclass
+class Vente:
+
+ vendeurs: list["Vendeur"]
+ vehicule: Vehicule
+ reduction: bool = False
+
+ def __post_init__(self):
+ self.prix_de_vente: float = self.vehicule.prix_ttc
+
+ def imprimer_en_pdf(self):
+ print(f"Impression en PDF terminée: {self}")
+
+ def appliquer_reduction(self, Vendeur):
+ if not Vendeur.senior:
+ raise ValueError("Ce vendeur n'est pas habilité à appliquer une réduction")
+ self.reduction = True
+ self.prix_de_vente = self.prix_de_vente*(1-self.vehicule.reduction_applicable)
+ if not Vendeur in self.vendeurs:
+ self.vendeurs.append(Vendeur)
+
+@dataclass
+class Vendeur:
+
+ nom: str
+ senior: bool
+ nombre_ventes: int = 0
+
+ def creer_vente(self, voiture):
+ self.nombre_ventes += 1
+ return Vente([self], voiture)
+
+@dataclass
+class Concessionnaire:
+
+ adresse: str
+ siret: int
+ vendeurs: list[Vendeur]
+ inventaire: list[Vehicule] = field(default_factory=list)
+
+ def afficher_voiture_par_marque(self, marque):
+ return len([vehicule for vehicule in self.inventaire if vehicule.marque == marque])
+
+ def add_inventaire(self, vehicule: Vehicule):
+ self.inventaire.append(vehicule)
+
+ def remove_inventaire(self, vehicule: Vehicule):
+ self.inventaire.remove(vehicule)
+
+
+ma_voiture = Voiture("rouge","Toyota","Iaris",20000,0.1,"automatique")
+mon_vendeur = Vendeur("denis",True)
+ma_vente = Vente([mon_vendeur],ma_voiture)
+print(ma_vente.prix_de_vente)
+ma_vente.appliquer_reduction(mon_vendeur)
+print(ma_vente.prix_de_vente)
+#print(ma_vente)
+print(ma_vente.imprimer_en_pdf())
+
diff --git a/oop/correction_concessionnaire.py b/oop/correction_concessionnaire.py
new file mode 100644
index 0000000..8d8dea7
--- /dev/null
+++ b/oop/correction_concessionnaire.py
@@ -0,0 +1,186 @@
+
+from abc import ABC, abstractmethod
+
+
+
+class Vehicule(ABC):
+
+ def __init__(self, couleur, marque, modele, prix_HT, reduction_applicable, TVA = 0.2):
+ self.couleur = couleur
+ self.marque = marque
+ self.modele = modele
+ self.prix_HT = prix_HT
+ self.prix_TTC = prix_HT * (1 + TVA )
+ self.reduction_applicable = reduction_applicable
+
+
+
+ def __repr__(self):
+ return str({"marque":self.marque, "modele":self.modele})
+
+
+class Voiture(Vehicule):
+ def __init__(self, couleur: str, marque :str, modele, prix_HT, reduction_applicable, nbr_portes: int, TVA = 0.2):
+ self.nbr_portes = nbr_portes
+ super().__init__(couleur, marque, modele, prix_HT, reduction_applicable)
+
+ def __repr__(self):
+ return str({"type": "Voiture", "marque":self.marque, "modele":self.modele})
+
+class Moto(Vehicule):
+ def __init__(self, couleur, marque, modele, prix_HT, reduction_applicable, topcase: bool, TVA = 0.2):
+ self.topcase = topcase
+ super().__init__(couleur, marque, modele, prix_HT, reduction_applicable)
+
+ def __repr__(self):
+ return str({"type": "Moto", "marque":self.marque, "modele":self.modele})
+
+class Camion(Vehicule):
+ def __init__(self, couleur, marque, modele, prix_HT, reduction_applicable, tonnage: float, TVA = 0.2):
+ self.tonnage = tonnage
+ super().__init__(couleur, marque, modele, prix_HT, reduction_applicable)
+
+ def __repr__(self):
+ return str({"type": "Camion", "marque":self.marque, "modele":self.modele})
+
+
+class Contrat:
+ pass
+
+
+class Vendeur:
+ def __init__(self, nom, statut, contrat:Contrat):
+ self.nom = nom
+ self.statut = statut
+ self.contrat = contrat
+ self.paie = contrat.calcul_paie(8)
+
+
+from abc import ABC, abstractmethod
+
+class Contrat(ABC):
+
+ @abstractmethod
+ def calcul_paie(self):
+ pass
+
+
+class Contrat_journalier(Contrat):
+ def __init__(self, taux_horraire):
+ self.taux_horraire = taux_horraire
+
+ def calcul_paie (self, nbr_heure_travaillée):
+ return self.taux_horraire * nbr_heure_travaillée
+
+class Contrat_mensuel(Contrat):
+ def __init__(self, salaire_mensuel):
+ self.salaire_mensuel = salaire_mensuel
+
+ def calcul_paie (self):
+ return self.salaire_mensuel
+
+class Contrat_freelance(Contrat):
+ def __init__(self, TJM):
+ self.TJM = TJM
+
+ def calcul_paie (self, nbr_jour_travaillé):
+ return self.TJM * nbr_jour_travaillé
+
+
+
+
+
+
+
+class Vente:
+ def __init__(self, vehicule:Vehicule, vendeur:Vendeur, reduction_demande: bool, vendeur_senior_associe=None):
+ self.vehicule = vehicule
+ self.vendeur = vendeur
+ self.reduction_demande = reduction_demande
+ self.prix_final = self.__calcul_prix_final()
+ self.vendeur_senior_associe = vendeur_senior_associe
+
+ def __calcul_prix_final(self):
+ if self.reduction_demande == True:
+ return self.vehicule.prix_TTC * (1 - self.vehicule.reduction_applicable)
+ else:
+ return self.vehicule.prix_TTC
+
+
+
+def creer_vente(vehicule, vendeur, reduction_demandee, vendeur_senior_associe: Vendeur = None):
+ if vendeur.statut == "senior" or reduction_demandee == False:
+ return Vente(vehicule, vendeur, reduction_demandee)
+ elif vendeur.statut == "junior" and reduction_demandee == True and vendeur_senior_associe == None:
+ print("Pour pouvoir accorder une reduction, il faut un vendeur senior associé")
+ else:
+ if vendeur_senior_associe.statut == "senior":
+ return Vente(vehicule, vendeur, reduction_demandee, vendeur_senior_associe)
+ else:
+ print("le vendeur associé n'est pas non plus senior")
+
+
+"""
+
+il existe trois types de vendeur, les vendeurs payés à l’heure, ceux freelance à la mission et ceux payés au mois. Une méthode permettra de calculer leur paie chaque mois.
+
+
+"""
+
+class Concessionnaire:
+
+ def __init__(self, adresse, siret):
+ self.inventaire = []
+ self.liste_vendeur = []
+ self.adresse = adresse
+ self.siret = siret
+
+ def inventaire_par_marque(self):
+ dictionnaire_par_marque = {}
+ for vehicule in self.inventaire:
+ if vehicule.marque not in dictionnaire_par_marque:
+ dictionnaire_par_marque[vehicule.marque] = 1
+ else:
+ dictionnaire_par_marque[vehicule.marque] += 1
+ return dictionnaire_par_marque
+
+ def ajouter_inventaire(self,vehicule: Vehicule):
+ self.inventaire.append(vehicule)
+
+ def retirer_inventaire(self,vehicule: Vehicule):
+ self.inventaire.remove(vehicule)
+
+ def ajouter_liste_vendeur(self,vendeur: Vendeur):
+ self.inventaire.append(vendeur)
+
+ def retirer_liste_vendeur(self,vendeur: Vendeur):
+ self.inventaire.remove(vendeur)
+
+
+
+mon_vendeur = Vendeur ("Denis", "junior", Contrat_freelance(300))
+mon_vendeur_senior = Vendeur ("Fred", "senior", Contrat_journalier(10))
+
+
+print(mon_vendeur.contrat.calcul_paie(10))
+print(mon_vendeur_senior.contrat.calcul_paie(7))
+
+
+# ma_voiture = Voiture("rouge", "Toyota", 'Hiaris', 25000, 0.1, 4)
+# ma_moto = Moto("rouge", "Toyota", 'ROméo', 15000, 0.1, True)
+
+# ma_vente = creer_vente(ma_voiture,mon_vendeur, True,mon_vendeur_senior)
+
+# mon_concessionnaire = Concessionnaire("5 rue De la République", 38499495)
+
+# mon_concessionnaire.ajouter_inventaire(ma_voiture)
+# mon_concessionnaire.ajouter_inventaire(ma_moto)
+# mon_concessionnaire.retirer_inventaire(ma_moto)
+# print(mon_concessionnaire.inventaire)
+
+# mon_concessionnaire.ajouter_inventaire(Camion("rouge", "Toyota", 'ROméo', 15000, 0.1, 18.5))
+# #mon_concessionnaire.retirer_inventaire(Camion("rouge", "Toyota", 'ROméo', 15000, 0.1, 18.5))
+
+
+# print(mon_concessionnaire.inventaire)
+
diff --git a/oop/correction_exercice_blog.py b/oop/correction_exercice_blog.py
new file mode 100644
index 0000000..2cfb3cb
--- /dev/null
+++ b/oop/correction_exercice_blog.py
@@ -0,0 +1,153 @@
+"""
+**'Exercice'** Ecrire le diagramme de classe correspondant au cas suivant:
+Fort de votre expérience en pâtisserie, vous décidez de créer un forum en ligne pour parler de gâteaux !
+- Vous devez définir et instancier trois classes: Utilisateurs (et ses héritiers), fil de discussion et post (et ses héritiers)
+
+
+Sur ce forum
+- les utilisateurs fans de pâtisserie pourront : s’inscrire et se connecter ;
+- parler de leurs gâteaux préférés, en créant de nouveaux fils de discussion ;
+- répondre à des messages, dans les fils existants.
+- Un fil de discussion sur ce forum a un titre, une date de création et une collection de posts lui correspondant.
+- Chaque post contient du texte, l’utilisateur qui l’a publié et la date de publication.
+- Les utilisateurs ont la possibilité d’attacher des fichiers à leurs posts :
+- Partez du principe qu’il peut y avoir de nombreux types de fichiers, mais nous sommes surtout intéressés par les fichiers images (GIF ou JPEP).
+- Un post peut avoir un fichier attaché, ce qui changera la façon dont le post est affiché. Ce serait donc un nouveau type de post.
+- Enfin, il y a des utilisateurs spéciaux nommés modérateurs, qui ont la capacité de modifier un post pour qu’il contienne du contenu nouveau, et de supprimer ceux qui ne parlent pas de gâteaux. ;)
+
+
+**`Exercice user_creation`**
+
+- créer une classe user avec un attribut publique "profil", des attribut protégés "password" et "user_name" et un attribut privée "validation_code"
+- créer des méthodes publiques "set_password", "get_password" et "get_user_name"
+- créer une méthode publique "set_username" qui prend comme argument un code et un nouveau user name. Cette méthode fait appelle à une autre méthode, privée cette fois qui compare le code avec le code de validation. Si le code correspond au validation_code alors le changement est réalisé.
+
+
+ """
+
+from datetime import datetime
+
+
+
+class User:
+
+ def __init__(self,profil,user_name,password):
+ self.profil = profil
+ self._password = self.set_password(password)
+ self._user_name = user_name
+ self.__validation_code = "XHDJFOD"
+
+
+ def set_password(self, password):
+ if isinstance(password,str) and len(password)>=8:
+ return password
+ else:
+ print("le password de correspond pas")
+
+ def get_password(self):
+ return self._password
+
+ def __validation(self,validation_code):
+ return self.__validation_code == validation_code
+
+ def set_username(self,new_user_name,validation_code):
+ if self.__validation(validation_code):
+ self._user_name = new_user_name
+ else:
+ print("erreur dans le code de validation")
+
+ def get_user_name(self):
+ return self._user_name
+
+
+ def login(self, password):
+ if self._password == password:
+ self.statut = "connecté"
+ print("vous etes bien connecté")
+ else:
+ print("vous n'avez pas de compte ou mot de passe incorrect")
+
+ def new_fil(self,fil:"Fil"):
+ return fil
+
+ def new_post(self,fil,post):
+ fil.add_post(post)
+ print(f"un nouveau post a été ajouté à {fil}")
+ return post
+
+
+class Moderateur(User):
+ def modify_post(self,fil,post,new_text):
+ if post in fil.contenu:
+ post.texte = new_text
+
+
+class Post:
+ def __init__(self,utilisateur,texte):
+ self.utilisateur = utilisateur
+ self.texte = texte
+ self.date_creation = datetime.now()
+
+class Post_fichier(Post):
+ def __init__(self,utilisateur,texte,type_fichier):
+ super().__init__(utilisateur,texte)
+ self.type_fichier = type_fichier
+
+class Fil:
+
+ def __init__(self,titre):
+ self.contenu = []
+ self.date_creation = datetime.now()
+ self.titre = titre
+
+ def add_post(self,post:Post):
+ self.contenu.append(post)
+
+
+
+
+
+
+charles = User("Actif","Charles","SecretKeys")
+
+print(charles.get_password())
+
+charles.set_username("charles B", "XHDJFOD")
+
+
+print(charles.get_user_name())
+
+charles.set_username("charles Be", "XHDJFO")
+
+charles.__validation("XHDJFO")
+
+# charles.sign_in(1234)
+# charles.login(1234)
+
+# mon_fil = Fil("carrotcake")
+
+
+# print(f"{mon_fil.__dict__=}")
+
+# mon_post=Post(charles,"le contenu de mon 1er poste")
+
+# charles.new_post(mon_fil,mon_post)
+
+
+# print(f"{mon_fil.contenu=}")
+
+# denis = Moderateur("denis")
+
+# denis.sign_in(9987)
+# denis.login(9987)
+
+
+# print(f"{mon_post.texte=}")
+
+# denis.modify_post(mon_fil,mon_post, "un nouveau texte" )
+
+# print(f"{mon_post.texte=}")
+
+# mon_post_avec_fichier = Post_fichier(charles,"le contenu de mon 1er poste",type_fichier="GIF")
+
+# print(f"{mon_post.__dict__=}")
diff --git a/oop/correction_toolbox.py b/oop/correction_toolbox.py
new file mode 100644
index 0000000..15b498e
--- /dev/null
+++ b/oop/correction_toolbox.py
@@ -0,0 +1,82 @@
+class Vis:
+ def __init__(self, taille, status="non vissée"):
+ self.taille = taille
+ self.status = status
+
+ def visser(self):
+ self.status = "non vissée" if self.status == "vissée" else "vissée"
+
+class Tournevis:
+ def __init__(self,marque):
+ self.marque = marque
+
+ def vissage(self,vis:Vis):
+ vis.visser()
+
+class Clou:
+ def __init__(self, taille, status="non cloué"):
+ self.taille = taille
+ self.status = status
+
+ def clouer(self):
+ if self.status == "non cloué":
+ self.status = "cloué"
+ elif self.status == "cloué":
+ print("le clou est déja cloué")
+
+
+class Marteau:
+ def __init__(self,marque):
+ self.marque = marque
+
+ def clouage(self,clou:Clou):
+ clou.clouer()
+
+
+class Toolbox:
+ nb_emplacement = 5
+
+ @classmethod
+ def update(cls):
+ cls.nb_emplacement +=1
+
+ def __init__(self):
+ self.contenu = []
+
+ def add_to_toolbox(self,Tool):
+ if len(self.contenu) < self.__class__.nb_emplacement:
+ self.contenu.append(Tool)
+ else:
+ print("ma boite à outil est pleine")
+
+ def remove_from_toolbox(self,Tool):
+ if Tool in self.contenu:
+ self.contenu.remove(Tool)
+
+ma_vis = Vis(10)
+mon_tournevis = Tournevis("facom")
+
+mon_tournevis.vissage(ma_vis)
+print(ma_vis.status)
+mon_tournevis.vissage(ma_vis)
+print(ma_vis.status)
+
+mon_clou = Clou(13)
+mon_marteau = Marteau("facom")
+
+print(mon_clou.status)
+mon_marteau.clouage(mon_clou)
+
+mon_marteau.clouage(mon_clou)
+print(mon_clou.status)
+
+boite_outil = Toolbox()
+
+boite_outil.add_to_toolbox(mon_marteau)
+boite_outil.add_to_toolbox(mon_tournevis)
+print(boite_outil.contenu)
+
+boite_outil.remove_from_toolbox(mon_marteau)
+print(boite_outil.contenu)
+
+boite_outil.remove_from_toolbox(Tournevis("facom"))
\ No newline at end of file
diff --git a/oop/correction_toolbox_bis.py b/oop/correction_toolbox_bis.py
new file mode 100644
index 0000000..f1ea8d3
--- /dev/null
+++ b/oop/correction_toolbox_bis.py
@@ -0,0 +1,128 @@
+"""**`Exercice`**
+- Créer des classes: boite à outils, marteau, tournevis, clou, vis
+- Instanciez une boîte à outils, un tournevis, et un marteau.
+- Placez le marteau et le tournevis dans la boîte à outils.
+- Instanciez une visse, et serrez-la avec le tournevis. Affichez la vis avant et après avoir été serrée.
+- Instanciez un clou, puis enfoncez-le avec le marteau. Affichez le clou avant et après avoir été enfoncé.
+- Une boite à outil possède 5 emplacements. (classe attributs)
+- Régulièrement le constructeur des boites à outils sort un nouveau modèle qui permet d'etendre la capacité des boites à outils de 1 emplacement.
+
+Pour chaque classe vous devez définir les attributs et les méthodes qui permettront d'éxecuter et de rapporter dans le terminal ces actions et ces états.
+"""
+
+
+
+
+
+class Vis:
+ def __init__(self,type,statut = "non vissée"):
+ self.type = type
+ self.statut = statut
+
+ def visser(self):
+ self.statut = "non vissée" if self.statut =="vissée" else "vissée"
+
+
+
+class Clou:
+ def __init__(self,longueur, statut = "non cloué"):
+ self.longueur = longueur
+ self.statut = statut
+
+ def clouer(self):
+ self.statut = "cloué"
+
+ pass
+
+
+class Tournevis:
+ def __init__(self,type):
+ self.type = type
+
+ def vissage(self,vis):
+ if self.type == vis.type:
+ vis.visser()
+ print(f"la vis est maintenant {vis.statut}")
+ else:
+ print("le tournevis ne convient pas à la vis")
+
+class Marteau:
+
+ def clouage(self, clou):
+ clou.clouer()
+ print(f"le clou est maintenant {clou.statut}")
+
+
+class Toolbox:
+ nb_emplacement = 5
+
+ def __init__(self):
+ self.contenu = []
+
+ def add_tool(self,outil):
+ if len(self.contenu) < self.nb_emplacement:
+ self.contenu.append(outil)
+ else:
+ print("la boite à outil est déja pleine")
+
+ @classmethod
+ def update_toolbox(cls,nb_emplacement_supp =1 ):
+ cls.nb_emplacement += nb_emplacement_supp
+
+
+
+
+mon_clou = Clou(4)
+
+
+
+mon_clou.clouer()
+
+
+
+
+ma_vis = Vis("plate")
+
+print(f"{ma_vis.statut=}")
+
+
+
+mon_tournevis = Tournevis("plate")
+
+mon_tournevis.vissage(ma_vis)
+
+
+# print(f"{ma_vis.statut=}")
+
+# mon_marteau = Marteau()
+
+# # print(type(mon_marteau))
+# # print(mon_marteau.__dict__)
+
+# # mon_marteau.clouage(mon_clou)
+
+# ma_toolbox = Toolbox()
+# print(f"{ma_toolbox.contenu=}")
+
+# ma_toolbox.add_tool(mon_marteau)
+# ma_toolbox.add_tool(mon_tournevis)
+
+# marteau_2 = Marteau()
+# marteau_3 = Marteau()
+# marteau_4 = Marteau()
+# marteau_5 = Marteau()
+
+# ma_toolbox.add_tool(marteau_2)
+# ma_toolbox.add_tool(marteau_3)
+# ma_toolbox.add_tool(marteau_4)
+# ma_toolbox.add_tool(marteau_5)
+
+
+# print(f"{ma_toolbox.contenu=}")
+
+# ma_toolbox.update_toolbox(1)
+
+# ma_toolbox.add_tool(marteau_5)
+
+# print(f"{ma_toolbox.contenu=}")
+
diff --git a/oop/correction_zoo.py b/oop/correction_zoo.py
new file mode 100644
index 0000000..e9148ab
--- /dev/null
+++ b/oop/correction_zoo.py
@@ -0,0 +1,53 @@
+"""
+Vous gérez un zoo qui abrite des poissons, des oiseaux et des félins.
+- Tous les animaux possèdent un régime alimentaire de la forme {aliment: bool, aliment: bool}
+- tous les animaux doivent pouvoir manger selon leur régime alimentaire
+
+- Pour que les félins mangent il faut vérifier que ce qu'on leur donne soit bien de la viande
+- Pour que les poissons mangent il faut vérifier que ce qu'on leur donne soit bien de la nourriture pour poisson
+- Pour que les oiseaux mangent il faut vérifier que ce qu'on leur donne soit bien des graines
+
+- Tous les poissons doivent pouvoir nager
+- Tous les oiseaux doivent piailler
+
+- Les lions doivent rugir et les chats miauler, les panthères ne font rien
+- les canaris piaillent en disant "cuicui" les autruches piaillent en disant "CUICUI"
+
+Créer votre zoo avec 2 lion , 3 chat, 1 canari, 2 autruches, 3 raies et 1 dauphin.
+"""
+
+from abc import ABCMeta, abstractmethod # permet de définir des classes de base
+
+
+class Animal (metaclass = ABCMeta):
+ @abstractmethod
+ def manger(self):
+ pass
+
+ @property
+ @abstractmethod
+ def regime_alimentaire(self):
+ pass
+
+class Poisson (Animal):
+ regime_alimentaire = {"nourriture_pour_poisson": True, "Viande":False, "Graine": False}
+
+ def manger(self, aliment):
+ if self.regime_alimentaire[aliment] == True:
+ print ("le poisson a bien mangé")
+ else:
+ print("cet aliment ne convient pas aux poissons")
+
+ @abstractmethod
+ def nager(self):
+ pass
+
+class Raie(Poisson):
+ def nager(self):
+ print("la raie nage")
+
+
+une_raie = Raie()
+une_raie.manger("nourriture_pour_poisson")
+une_raie.manger("Viande")
+une_raie.nager()
diff --git a/oop/img/Class_heritage.drawio.png b/oop/img/Class_heritage.drawio.png
new file mode 100644
index 0000000..6b48b54
Binary files /dev/null and b/oop/img/Class_heritage.drawio.png differ
diff --git a/oop/img/First_class_diagram.drawio.png b/oop/img/First_class_diagram.drawio.png
new file mode 100644
index 0000000..2421b21
Binary files /dev/null and b/oop/img/First_class_diagram.drawio.png differ
diff --git a/oop/test_class_to_test.py b/oop/test_class_to_test.py
new file mode 100644
index 0000000..1f23d68
--- /dev/null
+++ b/oop/test_class_to_test.py
@@ -0,0 +1,69 @@
+from class_to_test import Voiture, Vehicule
+# Tester une classe correspond à tester chacune de ses méthodes.
+# Pour cela on crée une classe de test dont le nom commence par Test
+# Chacunes de ses méthodes permettra de tester les méthodes de la classe à tester
+import pytest
+
+class TestVoiture:
+
+ def test_prix_apres_reduction(self):
+ assert Voiture("toyota", "rouge",20000,0.1).prix_apres_reduction() == 18000
+
+ def test_prix_apres_double_reduction(self):
+ assert Voiture("toyota","rouge",20000,0.1).prix_apres_double_reduction() == 16000
+
+ def test_prix_apres_triple_reduction(self):
+ assert Voiture("toyota","rouge",20000,0.1).prix_apres_triple_reduction() == 14000
+
+ def test_initialisation(self):
+ assert Voiture("toyota","rouge",20000,0.1).prix == 20000
+ with pytest.raises(ValueError) :
+ Voiture("toyota","rouge","20000",0.1)
+
+ def test_I_want_to_quit(self, monkeypatch):
+ def no_func(x):
+ pass
+ #monkeypatch.setattr("class_to_test.Voiture.fonction_sans_fin",no_func)
+ monkeypatch.setattr(Voiture, "fonction_sans_fin",no_func)
+ #monkeypatch.delattr(Voiture, "fonction_sans_fin") (ne marche pas)
+
+ assert Voiture("toyota","rouge",20000,0.1).I_want_to_quit() == "I quit"
+
+# Je dois créer trois fois ma voiture. C'est plutot embettant.
+
+# Je peux préférer utiliser des fixtures
+
+@pytest.fixture
+def voiture_test():
+ return Voiture("toyota","rouge",20000,0.1)
+
+
+class TestVoiture2():
+ def test_prix_apres_reduction(self,voiture_test):
+ assert voiture_test.prix_apres_reduction() == 18000
+
+ def test_prix_apres_double_reduction(self,voiture_test):
+ assert voiture_test.prix_apres_double_reduction() == 16000
+
+ def test_prix_apres_triple_reduction(self,voiture_test):
+ assert voiture_test.prix_apres_triple_reduction() == 14000
+
+ def test_initialisation(self, voiture_test):
+ assert voiture_test.prix == 20000
+ with pytest.raises(ValueError) :
+ Voiture("toyota","rouge","20000",0.1)
+
+
+
+# Test an abstract class:
+# Certaines abstract class possèdent des méthodes qui ne sont pas des abstact méthode
+# On aimerait pouvoir les tester au niveau de la classe parent et pas plusieurs fois
+# Dans les classes enfant
+class TestVehicule():
+ def test_drive(self):
+ #Cette ligne permet de supprimer toutes les abstactmethod
+ Vehicule.__abstractmethods__ = set()
+ # On peut donc instatancier un vehicule
+ my_vehicule = Vehicule()
+ # Et tester ses méthodes qui ne sont pas des abstractmethod
+ assert my_vehicule.drive() == "the vehicule is on its wheels!"
diff --git a/other_folder/other_folder_file.py b/other_folder/other_folder_file.py
new file mode 100644
index 0000000..578cc70
--- /dev/null
+++ b/other_folder/other_folder_file.py
@@ -0,0 +1,4 @@
+def other_folder_function():
+ print("I'm an other folder function")
+
+
\ No newline at end of file
diff --git a/recursif.py b/recursif.py
new file mode 100644
index 0000000..974e7db
--- /dev/null
+++ b/recursif.py
@@ -0,0 +1,8 @@
+def factorielle(n):
+ if n == 0:
+ return 1
+ else:
+ return n * factorielle(n-1)
+
+
+factorielle(4)