diff --git a/Arbres/ARBRES_BINAIRES.md b/Arbres/ARBRES_BINAIRES.md index fdb203a..983249f 100644 --- a/Arbres/ARBRES_BINAIRES.md +++ b/Arbres/ARBRES_BINAIRES.md @@ -14,10 +14,9 @@ Les enfants d'un noeud sont lus de **gauche à droite** et sont appelés **fils ![fig15.png](assets/fig15.png) -### Exercice 1: +### Exercice 1 : Parmi les arbres du cours précédent, lesquels sont binaires ? -Réponse ### Remarque: Les arbres binaires forment une structure de données qui peut se définir de façon récursive. @@ -61,7 +60,7 @@ Il possède 3 niveaux, sa hauteur ou profondeur est donc de 2. La taille du tabl *Il faut compter le nombre de noeuds, y compris les noeuds "fantômes" des feuilles.* -### Exercice : +### Exercice 2 : 1. Quelle est la taille du tableau qui permet de représenter cet arbre ? ![fig19.png](assets/fig19.png) @@ -83,7 +82,7 @@ Le dessiner. Que peut-il représenter ? -> Voici un code python Python qui crée la liste représentant l'arbre de l'exercice 2 +> Voici un code Python qui crée la liste représentant l'arbre de l'exercice 2 @@ -124,7 +123,7 @@ print(arbre) ['r', 'a', 'b', 'c', 'd', 'e', 'f', None, 'h', 'i', 'j', 'k', None, None, None, None, None, None, None, None, None, 'm', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None] -### Exercice 3: +### Exercice 3 : 1. Ecrire une fonction qui retourne le parent d'un noeud s'il est dans l'arbre et None sinon. 2. Ecrire une fonction qui retourne **True** si l'arbre est vide 3. Ecrire une fonction qui retourne les enfants d'un noeud. @@ -132,11 +131,13 @@ print(arbre) 5. Même question pour le fils droit 6. Ecrire une fonction qui renvoie **True** si le noeud est la racine de l'arbre 7. Ecrire une fonction qui renvoie **True** si le noeud est une feuille -8. Ecrire une fonction qui renvoie **true** si le noeud comporte un frère gauche ou droit. +8. Ecrire une fonction qui renvoie **True** si le noeud comporte un frère gauche ou droit. **Rappel : dans un tableau, si on note i l'indice d'un noeud, alors ses fils auront comme indice 2i +1 et 2i +2.** -**Inversement, pour trouver le parent d'un noeud, il faut vérifier : i - 1 //2** +**Inversement, pour trouver le parent d'un noeud, il faut calculer : (i - 1) // 2** + +*Attention aux parenthèses : en Python, `i - 1 // 2` vaut `i` (la division est prioritaire sur la soustraction) !* --------- @@ -152,7 +153,7 @@ Cet arbre se représente par le tableau: ['r', ['a', [ ], [ ]], ['b', [ ], [ ]]] -### Exercice : +### Exercice 4 : Ecrire le tableau représentant l'arbre ci-dessous et le stocker dans une variable **t** ![fig21.png](assets/fig21.png) @@ -194,7 +195,7 @@ print(arbre1) ['r', ['a', ['c', [], ['h', [], []]], ['d', ['i', [], []], ['j', ['m', [], []], []]]], ['b', ['e', ['k', [], []], []], ['f', [], []]]] -### Exercice : +### Exercice 5 : Ecrire toutes les fonctions de l'exercice 3 dans le cas de cette implémentation de l'arbre. -------- @@ -215,7 +216,7 @@ Voici l'algorithme: ![fig22.png](assets/fig22.png) -### Exercice : +### Exercice 6 : 1. Ecrire cette fonction pour l'arbre précédent et vérifier que sa profondeur est de 4. @@ -246,7 +247,7 @@ Voici l'algorithme: ![fig25.png](assets/fig25.png) -### Exercice 7 +### Exercice 7 : 1. Rappeler les fonction permettant de définir une structure de file en python. 2. Implémenter alors cette fonction et l'essayer sur l'arbre précédent. @@ -261,7 +262,7 @@ On se balade autour de l'arbre en suivant les pointillés Voici un algorithme permettant de réaliser ce parcours: ![fig26.png](assets/fig26.png) -### Exercice +### Exercice 8 : 1. Proposer une fonction permettant de réaliser le parcours en profondeur d'un arbre @@ -278,7 +279,7 @@ Dans le schéma ci-dessus, on a rajouté des "noeuds fantômes" pour montrer que Dans un parcours **préfixe**, on liste le noeud la première fois qu'on le rencontre. -### Exercice +### Exercice 9 : 1. Ecrire les sommets dans l'ordre d'un parcours préfixe @@ -290,7 +291,7 @@ Ce qui correspond à: * On liste chaque noeud ayant un fils gauche la seconde fois qu'on le voit * on liste chaque noeud sans fils gauche la première fois qu'on le voit -### Exercice +### Exercice 10 : 1. Ecrire les sommets dans l'ordre d'un parcours infixe @@ -298,12 +299,12 @@ Ce qui correspond à: ### Definition: Dans un parcours **suffixe**, on note le noeud la dernière fois qu'on le rencontre. -Exercice 11 +### Exercice 11 : 1. Ecrire les sommets dans l'ordre d'un parcours suffixe -### Exercice +### Exercice 12 : 1. Voici trois algorithmes récursifs, dire pour chacun d'entre eux à quel parcours il correspond. ![fig27.png](assets/fig27.png) ![fig28.png](assets/fig28.png) @@ -319,7 +320,7 @@ Nous allons créer une classe **Noeud** dont les attributs d'instances seront: * son fils gauche (None par défaut) ou de type Noeud * son fils droit (None par défaut) ou de type Noeud -### Exercice +### Exercice 13 : 1. Implémentez cette classe Noeud 2. Stocker l'arbre comme étant l'objet de type "Noeud" correspondant à la racine. 3. Ecrire une méthode estFeuille qui renvoie True si le noeud est une feuille et False sinon diff --git a/Arbres/README.md b/Arbres/README.md index 2e59a3c..331fb3d 100644 --- a/Arbres/README.md +++ b/Arbres/README.md @@ -56,8 +56,10 @@ On parle également de **hauteur d'un arbre** : - Elle correspond à la **profondeur maximale** d’un nœud dans l’arbre, c’est-à-dire le **plus grand nombre d’arêtes** depuis la racine jusqu’à une feuille. - La hauteur est le nombre maximum de niveaux dans l’arbre, en partant de la racine jusqu’à la feuille la plus profonde. -- Selon les points de vue, la hauteur est parfois définie différemment : - - On peut considérer la hauteur d'un arbre vide à 0, soit à 1. +- Selon les conventions, la hauteur est parfois définie différemment : + - Si on compte le nombre d'**arêtes** du plus long chemin (convention utilisée dans ce cours), un arbre réduit à sa racine a une hauteur de 0, et l'arbre vide une hauteur de -1. + - Si on compte le nombre de **niveaux**, un arbre réduit à sa racine a une hauteur de 1, et l'arbre vide une hauteur de 0. + - Les sujets de bac précisent toujours la convention choisie : lisez bien l'énoncé ! **Question** : *Quelle est la hauteur de l'arbre du dessus ?* @@ -89,7 +91,7 @@ Comprendre ces caractéristiques nous aidera à explorer comment manipuler effic ---------------- -Auteurs : Florian Mathieu, Timothée Decoster, Enzo Frémaux +Auteurs : Florian Mathieu, Timothée Decoster, Enzo Frémeaux Licence CC BY NC diff --git a/BDD_SGBD/README.md b/BDD_SGBD/README.md index b141012..399b787 100644 --- a/BDD_SGBD/README.md +++ b/BDD_SGBD/README.md @@ -23,7 +23,7 @@ Dans les années 1970, un certain **Edgar F. Codd**, mathématicien chez IBM, in --- -Avec le big data, il a fallu trouver une solution pour permettre aux entreprises de manipuler ces données entrantes. C'est alors que sont nés les premiers **S**ystème de **G**estion de **B**ases de **D**onnées, appelé **SGBD**. +Dès les années 1960-1970, bien avant qu'on parle de « big data », les entreprises et administrations ont eu besoin de manipuler des volumes de données croissants (réservations aériennes, banques, recensements...). C'est alors que sont nés les premiers **S**ystèmes de **G**estion de **B**ases de **D**onnées, appelés **SGBD**. Ces derniers ont plusieurs fonctions dont 4 qui sont primordiales : diff --git a/BDD_SGBD/RELATION.md b/BDD_SGBD/RELATION.md index 4720b39..81d8388 100644 --- a/BDD_SGBD/RELATION.md +++ b/BDD_SGBD/RELATION.md @@ -105,9 +105,9 @@ Si l’attribut `Age` est défini comme un entier positif, une valeur comme `-3` --- -## Anecdote : Le bug de la clé étrangère oubliée +## Expérience de pensée : Le bug de la clé étrangère oubliée -Dans les années 1990, une banque a oublié d’appliquer la contrainte d’intégrité référentielle dans sa base de données. Résultat : des milliers de transactions faisaient référence à des comptes clients inexistants. Moralité : quand on parle d'argent, mieux vaut éviter les erreurs de clé étrangère ! +Imaginez une banque qui oublierait d'appliquer la contrainte d'intégrité référentielle dans sa base de données. Rien n'empêcherait alors d'enregistrer des virements vers des comptes clients... inexistants. Où irait l'argent ? Personne ne le sait. Moralité : quand on parle d'argent, mieux vaut éviter les erreurs de clé étrangère ! --- diff --git a/Calculabilité/README.md b/Calculabilité/README.md index b62e1e2..2b2b2d1 100644 --- a/Calculabilité/README.md +++ b/Calculabilité/README.md @@ -29,7 +29,7 @@ On peut par exemple prendre des problèmes assez élémentaires : - X est il un nombre pair ? - Y est il une puissance de 3 ? - - Dans un graphe, quel est le chemin le plus court passant par tous les sommets ? + - Dans un graphe, existe-t-il un chemin passant par tous les sommets de longueur inférieure à k ? Dans notre premier cas, nous avons en **instance de départ :** un entier naturel, qui, après être traité via le **paramètre** choisi (Si reste = 0 après une division par 2, alors nombre est pair) dans **l'algorithme**, ressortira en une réponse simple : *Oui* ou *Non* selon la **décision** prise. @@ -39,11 +39,9 @@ En informatique ou mathématiques, on peut parler d'une **fonction algorithmique Un ***prédicat*** est une fonction qui ne prendra que des valeurs booléennes. -> La réponse à un problème de décision est donc soit un booléen, soit une valeur qui permet de répondre à un prédicat. +> La réponse à un problème de décision est donc un booléen : oui ou non. > -> **Exemple** : Dans un graphe, connaître le nombre de sommets permet de répondre à la question : « Le chemin que j'ai choisi est-il le plus court passant par tous les sommets de ce graphe ? » -> -> Question dont la réponse est bel et bien un prédicat. +> **Exemple** : « Ce chemin passe-t-il par tous les sommets du graphe ? » est une question dont la réponse est Vrai ou Faux : la fonction qui y répond est bel et bien un prédicat. ### Définition : Décidabilité @@ -68,7 +66,7 @@ Quel rapport avec la calculabilité ? Et bien une fonction mathématique, que l' ### Un peu d'histoire -En 1943, un mathématicien américain, du nom d'Alonzo Church définit une thèse dite "thèse de Church" qui affirme la notion de calculabilité : Tout traitement d'un système réalisable par un processus quel qu'il soit, peut être exprimé par un ensemble de règles de calcul. +En 1936, un mathématicien américain, du nom d'Alonzo Church, formule ce qu'on appellera la "thèse de Church" (la même année, Alan Turing arrive indépendamment à un résultat équivalent avec sa machine). Cette thèse affirme la notion de calculabilité : Tout traitement d'un système réalisable par un processus quel qu'il soit, peut être exprimé par un ensemble de règles de calcul. Cet ensemble est défini lui même par les règles de calcul dont on prouve mathématiquement l'équivalence. @@ -155,21 +153,23 @@ Par exemple : ```python def est_pair2(n): - - if (n % 2) == 0: - return("{0} est Pair".format(n)) + reste = n % 2 + if reste == 0: + return True else: - return("{0} est Impair".format(n)) + return False ``` ```python >>>est_pair2(113) ->>>'113 est Impair' +>>>False >>>est_pair2(42) ->>>'42 est Pair' +>>>True ``` +*Remarque : cette version renvoie bien un booléen, comme la première. Une fonction qui renverrait une chaîne de caractères comme `"42 est Pair"` ne serait pas un prédicat !* + Nous avons bien la preuve que le problème " Peut-on prouver qu'un nombre est pair" est bel et bien décidable. @@ -182,7 +182,7 @@ La question qui se pose à nous est de savoir comment reconnaitre un problème i Et à l'heure actuelle, nous ne disposons pas de machine magique permettant de nous donner cette information. -Pour déduire l'indécidabilité d'un programme, il faut un algorithme répondant à ce problème et également la preuve qu'il se termine. +Pour prouver qu'un problème est *décidable*, il suffit d'exhiber un algorithme qui le résout et qui se termine toujours. Mais pour prouver qu'un problème est *indécidable*, c'est bien plus difficile : il faut démontrer qu'**aucun** algorithme, même parmi ceux qu'on n'a pas encore inventés, ne pourra jamais le résoudre. En informatique, le plus célèbre de ces problèmes indécidables est le ***problème de l'arrêt***. diff --git a/Graphes/PARCOURS.md b/Graphes/PARCOURS.md index 3390dc8..392399e 100644 --- a/Graphes/PARCOURS.md +++ b/Graphes/PARCOURS.md @@ -43,7 +43,9 @@ def bfs(graphe, depart): ### Illustration du parcours en largeur -![parcours_largeur.gif](https://glassus.github.io/terminale_nsi/T1_Structures_de_donnees/1.4_Graphes/data/bfs.gif) +![parcours_largeur.gif](assets/bfs.gif) + +*Source : [Gilles Lassus](https://glassus.github.io/terminale_nsi/)* @@ -53,12 +55,11 @@ def bfs(graphe, depart): Le parcours en profondeur explore un chemin le plus loin possible avant de revenir en arrière. C’est une approche de type pile (LIFO). -#### Algorithme DFS : -1. Choisir un sommet de départ et l’empiler. -2. Marquer ce sommet comme visité. -3. Tant que la pile n’est pas vide : - - Retirer le sommet du sommet de la pile. - - Ajouter tous ses voisins non encore visités dans la pile et les marquer comme visités. +#### Algorithme DFS (version récursive) : +1. Marquer le sommet courant comme visité. +2. Pour chaque voisin non encore visité, relancer le parcours depuis ce voisin. + +> On peut aussi écrire DFS de manière itérative avec une pile explicite (en remplaçant la file du BFS par une pile). Dans la version récursive ci-dessous, c'est la **pile d'appels** de Python qui joue ce rôle : chaque appel récursif "empile" un sommet, chaque retour le "dépile". #### Implémentation en Python : ```python @@ -78,7 +79,9 @@ def dfs(graphe, depart, visite=None): ### Illustration -![Parcours_Profondeur](https://www.gaudry.be/img/math/graphe/graphes-dfs.gif) +![Parcours_Profondeur](assets/dfs.gif) + +*Source : [gaudry.be](https://www.gaudry.be/)* ---------- diff --git a/Graphes/README.md b/Graphes/README.md index 4d54266..c859b83 100644 --- a/Graphes/README.md +++ b/Graphes/README.md @@ -184,6 +184,39 @@ A = np.matrix(A) Ecrire la matrice d'adjacence du réseau social de l'introduction +### Liste d'adjacence + +La matrice n'est pas la seule représentation possible. On peut aussi associer à chaque sommet la **liste de ses voisins** (ou de ses **successeurs** dans le cas d'un graphe orienté). En Python, un dictionnaire est parfait pour cela : + +```python +adjacence = { + 'A': ['B', 'C', 'E'], + 'B': ['A', 'C', 'D'], + 'C': ['A', 'B', 'D'], + 'D': ['B', 'C'], + 'E': ['A'] +} +``` + +C'est cette représentation que nous utiliserons pour les parcours (voir [PARCOURS.md](PARCOURS.md)) et l'implémentation en POO (voir [POO.md](POO.md)). + +**Quelle représentation choisir ?** + +| | Matrice d'adjacence | Liste d'adjacence | +|---|---|---| +| Tester si deux sommets sont voisins | Immédiat (une case) | Parcours de la liste | +| Mémoire | n × n cases, même si peu d'arêtes | Proportionnelle au nombre d'arêtes | +| Usage naturel | Graphes denses (beaucoup d'arêtes) | Graphes creux (peu d'arêtes) | + +### Exercice 3: + +Le programme officiel demande de savoir **passer d'une représentation à l'autre**. + +1. Écrire à la main la liste d'adjacence correspondant à la matrice de l'exemple du cours. +2. Écrire une fonction `matrice_vers_liste(matrice, sommets)` qui prend la matrice (liste de listes) et la liste des noms de sommets, et renvoie le dictionnaire d'adjacence. +3. Écrire la fonction inverse `liste_vers_matrice(adjacence, sommets)`. +4. Vérifier vos deux fonctions : `matrice_vers_liste` suivie de `liste_vers_matrice` doit redonner la matrice de départ. + diff --git a/Modularité/Corrige_TP.md b/Modularité/Corrige_TP.md index 8d2348b..5c369b0 100644 --- a/Modularité/Corrige_TP.md +++ b/Modularité/Corrige_TP.md @@ -299,7 +299,7 @@ python arithmetique.py --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Modularité/DEBUG.md b/Modularité/DEBUG.md index eaae341..ded8bf6 100644 --- a/Modularité/DEBUG.md +++ b/Modularité/DEBUG.md @@ -127,7 +127,7 @@ Néanmoins, la postérité aura attribué ce mot à la développeuse, qui aurait ------ -Auteur : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster. +Auteur : Florian Mathieu, Enzo Frémeaux, Timothée Decoster. Licence CC BY NC diff --git a/Modularité/README.md b/Modularité/README.md index 6a6c27f..c10331a 100644 --- a/Modularité/README.md +++ b/Modularité/README.md @@ -26,7 +26,7 @@ Intéressons-nous au code Python ci-dessous. Ici, la structure compte plus que l ```python ## importations -from math import * +from math import sqrt import doctest ## variables @@ -77,7 +77,7 @@ Intéressons nous au programme vu précédemment : ```python ## importations -from math import * +from math import sqrt import doctest ``` @@ -169,6 +169,8 @@ def somme(n): >>> somme(5) 15 >>> somme(-1) + Traceback (most recent call last): + ... AssertionError: erreur """ assert type(n)==int, "erreur" @@ -187,7 +189,7 @@ L'attribut *verbose* de la fonction testmod nous permet de dire à ce dernier de ---------- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Modularité/TP_MiniPackage.md b/Modularité/TP_MiniPackage.md index ebf5e09..9f86381 100644 --- a/Modularité/TP_MiniPackage.md +++ b/Modularité/TP_MiniPackage.md @@ -562,7 +562,7 @@ def aire_cercle(rayon): --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Modularité/TP_Modules.md b/Modularité/TP_Modules.md index 72d0da3..8a7c04e 100644 --- a/Modularité/TP_Modules.md +++ b/Modularité/TP_Modules.md @@ -79,7 +79,7 @@ Question 10 - Ajouter la doctest de ces fonctions. ------- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/POO/README.md b/POO/README.md index e6e3ae3..85eec08 100644 --- a/POO/README.md +++ b/POO/README.md @@ -63,7 +63,7 @@ Le constructeur est une méthode(fonction) permettant d'initialiser votre type. ```python class Etudiant : - def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) : + def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) : self.nom = nom_etu self.prenom = prenom_etu self.spe1 = spe1_etu @@ -110,7 +110,7 @@ Supposons que l'étudiant change de spécialité. Bob voudrait arrêter de faire ```python def change_spe(self,nouvelle_spe) : - self.spe1 = nouvelle_spe + self.spe1 = nouvelle_spe ``` Pour appeler la méthode : @@ -126,9 +126,9 @@ On pourrait créer une méthode *anniversaire* par exemple : ```python def anniversaire(self) : - self.age = self.age + 1 - if self.age == 18 : - self.peut_avoir_son_permis = True + self.age = self.age + 1 + if self.age == 18 : + self.peut_avoir_son_permis = True ``` Si l'anniversaire de l'étudiant passe, alors il gagne 1 an et s'il a 18 ans alors il est éligible au permis de conduire. @@ -137,7 +137,7 @@ Imaginons maintenant qu'il soit possible d'avoir une nouvelle spécialité. ```python def nouvelle_spe(self,new_spe): - self.spe2 = new_spe + self.spe2 = new_spe ``` ```python @@ -169,7 +169,7 @@ Actuellement il est impossible de faire la même chose avec nos étudiants. C'es ```python def __eq__(self,obj2): - return self.spe1 == obj2.spe1 + return self.spe1 == obj2.spe1 ``` Cette méthode propre à python permet d'effectuer l'opération suivante. @@ -222,7 +222,7 @@ En utilisant des types privés il n'est plus possible d'accéder directement aux ```python class Etudiant : - def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) : + def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) : self.__nom = nom_etu self.__prenom = prenom_etu self.spe1 = spe1_etu @@ -238,10 +238,10 @@ Ici l'attribut \_\_nom et \_\_prenom sont privés. Pour accéder/modifier à leu ```python def get_nom(self): - return self.__nom + return self.__nom def set_nom(self,nouveau_nom): - self.__nom = nouveau_nom + self.__nom = nouveau_nom ``` Ces méthodes sont appelées des accesseurs et modificateurs. Elles sont optionnelles selon les cas. @@ -332,7 +332,7 @@ True ----------- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/POO/TP/Corrige_TP_POO.md b/POO/TP/Corrige_TP_POO.md index 6bd683f..b5327ae 100644 --- a/POO/TP/Corrige_TP_POO.md +++ b/POO/TP/Corrige_TP_POO.md @@ -244,7 +244,7 @@ def livres_par_auteur(self, nom_auteur): --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/POO/TP/TP_POO.md b/POO/TP/TP_POO.md index 93e4132..895115e 100644 --- a/POO/TP/TP_POO.md +++ b/POO/TP/TP_POO.md @@ -71,7 +71,7 @@ Il faut s'entraîner, essayer d'aller le plus loin possible. Alors essayez, test --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/POO/TP/TP_Pokemon.md b/POO/TP/TP_Pokemon.md index 70a4177..03603a8 100644 --- a/POO/TP/TP_Pokemon.md +++ b/POO/TP/TP_Pokemon.md @@ -536,7 +536,7 @@ print(sacha) --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Paradigmes/Corrige_TP_SpotifyWrapped.md b/Paradigmes/Corrige_TP_SpotifyWrapped.md index e56f7ed..38dbaaa 100644 --- a/Paradigmes/Corrige_TP_SpotifyWrapped.md +++ b/Paradigmes/Corrige_TP_SpotifyWrapped.md @@ -426,7 +426,7 @@ print(wrapped) --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Paradigmes/README.md b/Paradigmes/README.md index da4dfc6..81aaa3d 100644 --- a/Paradigmes/README.md +++ b/Paradigmes/README.md @@ -150,9 +150,11 @@ En Python, la fonction lambda se définit à l'aide du mot-clé **lambda** : ```python add_a_b = lambda a,b: a + b -entre_10_et_20 = lambda x : True if (x > 10 and x < 20) else False +entre_10_et_20 = lambda x: 10 < x < 20 ``` +*Remarque : inutile d'écrire `True if condition else False` - la condition **est** déjà un booléen, on la renvoie directement.* + Appelée aussi fonction anonyme, il ne faut pas en abuser en Python, elle : - est utile pour définir une fonction simple, proche d’une définition mathématique, en une ligne ; @@ -171,17 +173,21 @@ Appliquer une fonction à chaque élément d'une liste. ```python f = lambda x: x*5 liste = [2, 7, -1] -resultat = map(f, liste) +resultat = list(map(f, liste)) # [10, 35, -5] ``` +*Remarque : `map` renvoie un itérateur, pas une liste. Sans le `list()`, un `print(resultat)` afficherait ``.* + __La réduction__ Combiner les éléments d’une liste en appliquant une fonction à l’aide d’un accumulateur (à l’état initial, acc prend la première valeur de la liste et x la deuxième, le résultat est stocké dans acc). ```python +import functools + liste = [1, 3, 5, 6, 2] f_somme = lambda acc, x: acc + x -somme = functools.reduce(f_somme, liste) +somme = functools.reduce(f_somme, liste) # 17 ``` ```python @@ -197,7 +203,7 @@ Sélectionne les éléments d'une liste vérifiant un certain critère. ```python liste = [1, 3, 5, 6, 2] f_filtre = lambda x: x >= 3 -liste_filtree = filter(f_filtre, liste) +liste_filtree = list(filter(f_filtre, liste)) # [3, 5, 6] ``` #### Boucler en programmation fonctionnelle @@ -451,7 +457,7 @@ Voici une tâche simple : nous voulons faire cuire des pâtes. ------ -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Paradigmes/TP_SpotifyWrapped.md b/Paradigmes/TP_SpotifyWrapped.md index f547c0f..44b0cbc 100644 --- a/Paradigmes/TP_SpotifyWrapped.md +++ b/Paradigmes/TP_SpotifyWrapped.md @@ -406,7 +406,7 @@ print(f"Somme : {total}") # 15 --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Processus/CORRIGE.md b/Processus/CORRIGE.md index 59fdd9b..f7c3f3e 100644 --- a/Processus/CORRIGE.md +++ b/Processus/CORRIGE.md @@ -88,7 +88,7 @@ L'utilisateur a l'impression que les programmes s'exécutent simultanément grâ --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Processus/EXERCICES.md b/Processus/EXERCICES.md index a7e1128..ca367b9 100644 --- a/Processus/EXERCICES.md +++ b/Processus/EXERCICES.md @@ -49,7 +49,7 @@ --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Processus/HEUeaOHX0AA1EBP.jpeg b/Processus/HEUeaOHX0AA1EBP.jpeg new file mode 100644 index 0000000..95ccc48 Binary files /dev/null and b/Processus/HEUeaOHX0AA1EBP.jpeg differ diff --git a/Processus/README.md b/Processus/README.md index fd1601a..8353023 100644 --- a/Processus/README.md +++ b/Processus/README.md @@ -18,9 +18,16 @@ Tous ces programmes sont en réalité des lignes immenses de code et le processe ## 1. Notion de processus -Lorsqu'un programme est exécuté, il crée plusieurs processus. En effet, un programme est composé de diverses instructions (lignes de code) qui elles-mêmes forment diverses parties (processus) de celui-ci. +Un **processus** est un programme **en cours d'exécution** : lorsqu'on lance un programme, le système d'exploitation crée un processus, c'est-à-dire une instance vivante du programme avec tout ce dont elle a besoin (instructions chargées en mémoire, données, ressources allouées). -Ces processus sont donc stockés dans une file (tout cela est géré par l'OS [Rappel 1ère]) et sont exécutés un à un. +Il ne faut pas confondre les deux : + +- le **programme** est un fichier statique posé sur le disque (la recette de cuisine) ; +- le **processus** est son exécution en mémoire (le plat en train de cuire). + +Un même programme peut d'ailleurs être lancé plusieurs fois et donner plusieurs processus distincts (deux fenêtres du même navigateur, par exemple). Un processus peut aussi créer lui-même d'autres processus, appelés **processus fils**. + +Les processus prêts à s'exécuter sont placés dans une file (tout cela est géré par l'OS [Rappel 1ère]) et le processeur les traite à tour de rôle. *Exemple de répartition de deux programmes par l'OS :* @@ -57,6 +64,14 @@ Il existe aussi deux autres états : +### L'ordonnanceur + +C'est **l'ordonnanceur** (*scheduler* en anglais), un composant du système d'exploitation, qui décide quel processus prêt devient élu, et pour combien de temps. + +La politique la plus simple est le **tourniquet** (*round-robin*) : chaque processus reçoit à tour de rôle une petite tranche de temps processeur (quelques millisecondes), appelée **quantum**. Quand son quantum est écoulé, le processus élu repasse à l'état prêt et retourne dans la file. C'est cette alternance très rapide qui donne l'illusion que tout s'exécute en même temps. + +D'autres politiques existent (par priorité, par plus court travail d'abord...), c'est ce que vous manipulerez dans le TP Ordonnanceur. + ## 3. Interblocage : L'interblocage intervient lorsque plusieurs processus sont bloqués les uns par les autres. @@ -176,7 +191,7 @@ Pour voir les processus, ici, on utilisera plutôt **TOP** (dispo sous linux ég --------- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Recherche_textuelle/README.md b/Recherche_textuelle/README.md index 57bfa07..3a0052b 100644 --- a/Recherche_textuelle/README.md +++ b/Recherche_textuelle/README.md @@ -245,19 +245,22 @@ def traitement(motif): def morris_pratt(texte, motif): m = len(motif) n = len(texte) - i = 0 - j = 0 - sol = [] # Tableau pour stocker les solutions s = traitement(motif) # Pré-traitement du motif - while i < m and j < n: - if i >= 0 and motif[i] != texte[j]: - i = s[i] - else: + sol = [] # Tableau pour stocker les positions trouvées + i = 0 # indice dans le motif + j = 0 # indice dans le texte + while j < n: + if motif[i] == texte[j]: i += 1 j += 1 - if i >= m: # Si le motif est présent - sol.append(j - m) # La position dans le texte est ajoutée à la liste - i = 0 # Une nouvelle recherche commence après le motif trouvé + if i == m: # Le motif est présent + sol.append(j - m) # La position dans le texte est ajoutée à la liste + i = s[i - 1] + 1 # On poursuit la recherche (occurrences suivantes) + else: + if i == 0: + j += 1 # Échec dès le premier caractère : on avance dans le texte + else: + i = s[i - 1] + 1 # On reprend la comparaison au bon endroit du motif return sol ``` @@ -265,9 +268,7 @@ Ici, par rapport à recherche2, on modifie les instructions dans le cas où ***m Dans le programme naïf, les indices i et j sont modifiés par ***j = j - i + 1*** pour décaler le motif d'une unité et ***i = 0*** pour recommencer les comparaisons à partir du premier caractère du motif. -Dans ce nouveau programme, j n'est pas modifié. On reste donc sur le caractère posant problème, on ne revient pas en arrière. - -Pour la valeur de i, qui permet d'effectuer le bon décalage, on effectue une fois le traitement s = traitement (motif), s est alors un tableau, et s[i] est la nouvelle valeur de i. +Dans ce nouveau programme, j ne revient jamais en arrière : en cas d'échec à la position i du motif, ce sont les i premiers caractères du motif qui ont coïncidé. Le tableau s nous dit alors où reprendre : ***s[i - 1] + 1*** est la nouvelle valeur de i (la longueur du plus long bord du préfixe déjà reconnu). Si l'échec a lieu dès le premier caractère (i = 0), on avance simplement dans le texte. diff --git a/Routage/README.md b/Routage/README.md index 4f539d0..593ad45 100644 --- a/Routage/README.md +++ b/Routage/README.md @@ -127,7 +127,7 @@ Si un routeur (et donc un réseau) n'est plus accessible passé 3 minutes, il se - Au-delà de 15 sauts, on considère un routeur inaccessible. - Utilise l’algorithme à vecteur de distance de Bellman-Ford et est simple à configurer, mais limité en performance. - Convient aux petits réseaux -- Premier algorithme de routage de l'histoire +- L'un des premiers protocoles de routage déployés à grande échelle (années 1980) diff --git a/Réseau/README.md b/Réseau/README.md index adee729..d91f005 100644 --- a/Réseau/README.md +++ b/Réseau/README.md @@ -97,6 +97,8 @@ Exemple de masque de sous-réseau en IPv4 : - `255.255.0.0` (notation `/16`) → 65 536 adresses possibles - `255.0.0.0` (notation `/8`) → 16 777 216 adresses possibles +> **Attention** : parmi ces adresses, deux sont réservées et ne peuvent pas être attribuées à des machines : l'adresse du **réseau** (partie hôte à 0) et l'adresse de **diffusion** ou *broadcast* (partie hôte à 1). Un réseau en `/24` peut donc accueillir 256 - 2 = **254 machines**. C'est un calcul classique au bac ! + Chaque **bit à 1** dans le masque représente la partie réseau, et chaque **bit à 0** représente la partie hôte. #### Calcul d’un sous-réseau diff --git a/Soc/README.md b/Soc/README.md index 11badca..b80df08 100644 --- a/Soc/README.md +++ b/Soc/README.md @@ -232,9 +232,9 @@ Le recyclage des composants électroniques reste un défi : L'architecture des SoC connaît en 2025-2026 une rupture majeure : les puces ne sont plus seulement conçues pour le calcul généraliste ou le graphisme, mais pour **exécuter des modèles d'intelligence artificielle localement**, sans passer par le cloud. -### 6.1. Nvidia RTX Spark (2026) +### 6.1. Nvidia DGX Spark (2025) -Annoncé au Computex 2026, le **Nvidia RTX Spark** est un superchip qui illustre parfaitement l'évolution vers les SoC unifiés hautes performances. +Annoncé sous le nom « Project DIGITS » au CES de janvier 2025, puis rebaptisé au GTC de mars 2025, le **Nvidia DGX Spark** est un superchip qui illustre parfaitement l'évolution vers les SoC unifiés hautes performances. **Architecture :** @@ -243,27 +243,27 @@ Annoncé au Computex 2026, le **Nvidia RTX Spark** est un superchip qui illustre | CPU | 20 cœurs ARM Grace (Neoverse V2), co-développé avec MediaTek | | GPU | Blackwell - 6 144 CUDA cores, Tensor Cores Gen 5 | | Mémoire | Jusqu'à 128 Go de LPDDR5X **unifiée** (partagée CPU/GPU) | -| Bande passante | ~300 Go/s | +| Bande passante | 273 Go/s | | Interconnexion | NVLink-C2C (technologie issue des serveurs Nvidia) | -| Performances IA | 1 petaflop en FP4, modèles jusqu'à 120 milliards de paramètres | +| Performances IA | 1 petaflop en FP4, modèles jusqu'à 200 milliards de paramètres | -> **Lien avec le cours :** Le RTX Spark est un SoC au sens strict - CPU, GPU et mémoire sur la même puce, reliés par un bus interne ultra-rapide (NVLink-C2C). La mémoire unifiée signifie que CPU et GPU accèdent aux mêmes données sans copie, ce qui élimine un goulot d'étranglement classique. +> **Lien avec le cours :** Le DGX Spark est un SoC au sens strict - CPU, GPU et mémoire sur la même puce, reliés par un bus interne ultra-rapide (NVLink-C2C). La mémoire unifiée signifie que CPU et GPU accèdent aux mêmes données sans copie, ce qui élimine un goulot d'étranglement classique. **Ce qui est nouveau :** - **ARM + GPU Nvidia** : la convergence ARM/GPU, déjà amorcée par Apple (M-series), s'étend au monde PC et gaming. -- **IA locale** : exécuter un modèle de 120 milliards de paramètres sur un laptop (l'équivalent de GPT-3) sans connexion internet était impensable en 2023. +- **IA locale** : exécuter un modèle de 200 milliards de paramètres sur une machine de bureau compacte (plus grand que GPT-3 et ses 175 milliards) sans connexion internet était impensable en 2023. - **Usage prévu** : agents IA personnels, création de contenu (Adobe), gaming 1440p avec ray tracing et DLSS. -*Disponibilité : laptops et mini-PC prévus pour l'automne 2026.* +*Disponibilité : commercialisé depuis fin 2025 sous forme de mini-PC de bureau (15 cm × 15 cm).* ### 6.2. Contexte : la course aux puces IA -Le RTX Spark s'inscrit dans une tendance plus large : +Le DGX Spark s'inscrit dans une tendance plus large : | Fabricant | Puce | Spécialité | |-----------|------|------------| -| **Nvidia** | RTX Spark (2026) | IA + gaming, ARM + Blackwell, usage personnel | +| **Nvidia** | DGX Spark (2025) | IA locale, ARM + Blackwell, usage personnel | | **Apple** | M4 Pro/Max (2024) | SoC universel, efficacité énergétique, écosystème Apple | | **Qualcomm** | Snapdragon X Elite (2024) | PC Windows ARM, NPU 45 TOPS | | **AMD** | Strix Halo (2025) | x86 + GPU RDNA4, gaming portable | @@ -276,11 +276,11 @@ Le RTX Spark s'inscrit dans une tendance plus large : ### 6.3. Exercice d'actualité -Le RTX Spark intègre 20 cœurs ARM alors que les PC traditionnels utilisent du x86 (Intel/AMD). +Le DGX Spark intègre 20 cœurs ARM alors que les PC traditionnels utilisent du x86 (Intel/AMD). 1. En vous appuyant sur la section 3 (ARM vs x86), expliquer pourquoi Nvidia a choisi ARM plutôt que x86 pour ce superchip. -2. La mémoire du RTX Spark est dite "unifiée". En quoi cela diffère-t-il de l'architecture Von Neumann vue en Première, où CPU et GPU ont chacun leur propre mémoire ? -3. "1 petaflop = 10¹⁵ opérations par seconde." Un modèle d'IA de 120 milliards de paramètres nécessite environ 240 milliards d'opérations pour générer un seul token. Combien de tokens par seconde le RTX Spark peut-il théoriquement produire ? +2. La mémoire du DGX Spark est dite "unifiée". En quoi cela diffère-t-il de l'architecture Von Neumann vue en Première, où CPU et GPU ont chacun leur propre mémoire ? +3. "1 petaflop = 10¹⁵ opérations par seconde." Un modèle d'IA de 200 milliards de paramètres nécessite environ 400 milliards d'opérations pour générer un seul token. Combien de tokens par seconde le DGX Spark peut-il théoriquement produire ? --- diff --git a/Structures_lineaires/Pile_File/README.md b/Structures_lineaires/Pile_File/README.md index 998ea45..b779644 100644 --- a/Structures_lineaires/Pile_File/README.md +++ b/Structures_lineaires/Pile_File/README.md @@ -43,7 +43,7 @@ Une pile est une structure de données dans laquelle les derniers éléments ent ![image-20220729234146926](Images/Pile.png) -Ici seul le premier élément est accessible. +Ici, seul le **sommet** de la pile (le dernier élément empilé) est accessible. ### 3. 2. Interface @@ -95,7 +95,7 @@ La suite du chapitre se concentrera sur l'utilisation de ces structures et leurs --------- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md b/Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md index 781e8f8..b294f45 100644 --- a/Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md +++ b/Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md @@ -174,7 +174,7 @@ Enfile(8) --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Structures_lineaires/Pile_File/TD/TD_Pile_File.md b/Structures_lineaires/Pile_File/TD/TD_Pile_File.md index cbad183..ebb0b30 100644 --- a/Structures_lineaires/Pile_File/TD/TD_Pile_File.md +++ b/Structures_lineaires/Pile_File/TD/TD_Pile_File.md @@ -32,7 +32,7 @@ Le but du TD est de manipuler des piles et des files sans avoir d'implémentatio --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Structures_lineaires/Pile_File/TP/TP_File.md b/Structures_lineaires/Pile_File/TP/TP_File.md index 791dc59..f0ac136 100644 --- a/Structures_lineaires/Pile_File/TP/TP_File.md +++ b/Structures_lineaires/Pile_File/TP/TP_File.md @@ -73,7 +73,7 @@ Un fichier carte.py contient la classe carte et les fonctions suivantes : --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC diff --git a/Structures_lineaires/Pile_File/TP/TP_Pile.md b/Structures_lineaires/Pile_File/TP/TP_Pile.md index 9172451..f3108bf 100644 --- a/Structures_lineaires/Pile_File/TP/TP_Pile.md +++ b/Structures_lineaires/Pile_File/TP/TP_Pile.md @@ -100,7 +100,7 @@ Le but ici est de trier une pile. Pour cela nous utiliserons une autre pile temp --- -Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster +Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster Licence CC BY NC