edit et corrections d'erreurs factuelles, de calculs et de mise en page

This commit is contained in:
2026-07-02 15:01:24 +02:00
parent 3067e1918e
commit 28d4a75c1b
32 changed files with 174 additions and 109 deletions

View File

@@ -14,10 +14,9 @@ Les enfants d'un noeud sont lus de **gauche à droite** et sont appelés **fils
![fig15.png](assets/fig15.png) ![fig15.png](assets/fig15.png)
### Exercice 1: ### Exercice 1 :
Parmi les arbres du cours précédent, lesquels sont binaires ? Parmi les arbres du cours précédent, lesquels sont binaires ?
Réponse
### Remarque: ### Remarque:
Les arbres binaires forment une structure de données qui peut se définir de façon récursive. 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.* *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 ? 1. Quelle est la taille du tableau qui permet de représenter cet arbre ?
![fig19.png](assets/fig19.png) ![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] ['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. 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 2. Ecrire une fonction qui retourne **True** si l'arbre est vide
3. Ecrire une fonction qui retourne les enfants d'un noeud. 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 5. Même question pour le fils droit
6. Ecrire une fonction qui renvoie **True** si le noeud est la racine de l'arbre 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 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.
**<u>Rappel : dans un tableau, si on note i l'indice d'un noeud, alors ses fils auront comme indice 2i +1 et 2i +2.</u>** **<u>Rappel : dans un tableau, si on note i l'indice d'un noeud, alors ses fils auront comme indice 2i +1 et 2i +2.</u>**
**<u>Inversement, pour trouver le parent d'un noeud, il faut vérifier : i - 1 //2</u>** **<u>Inversement, pour trouver le parent d'un noeud, il faut calculer : (i - 1) // 2</u>**
*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', [ ], [ ]]] ['r', ['a', [ ], [ ]], ['b', [ ], [ ]]]
### Exercice : ### Exercice 4 :
Ecrire le tableau représentant l'arbre ci-dessous et le stocker dans une variable **t** Ecrire le tableau représentant l'arbre ci-dessous et le stocker dans une variable **t**
![fig21.png](assets/fig21.png) ![fig21.png](assets/fig21.png)
@@ -194,7 +195,7 @@ print(arbre1)
['r', ['a', ['c', [], ['h', [], []]], ['d', ['i', [], []], ['j', ['m', [], []], []]]], ['b', ['e', ['k', [], []], []], ['f', [], []]]] ['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. 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) ![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. 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) ![fig25.png](assets/fig25.png)
### Exercice 7 ### Exercice 7 :
1. Rappeler les fonction permettant de définir une structure de file en python. 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. 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: Voici un algorithme permettant de réaliser ce parcours:
![fig26.png](assets/fig26.png) ![fig26.png](assets/fig26.png)
### Exercice ### Exercice 8 :
1. Proposer une fonction permettant de réaliser le parcours en profondeur d'un arbre 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. 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 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 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 * 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 1. Ecrire les sommets dans l'ordre d'un parcours infixe
@@ -298,12 +299,12 @@ Ce qui correspond à:
### Definition: ### Definition:
Dans un parcours **suffixe**, on note le noeud la dernière fois qu'on le rencontre. 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 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. 1. Voici trois algorithmes récursifs, dire pour chacun d'entre eux à quel parcours il correspond.
![fig27.png](assets/fig27.png) ![fig27.png](assets/fig27.png)
![fig28.png](assets/fig28.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 gauche (None par défaut) ou de type Noeud
* son fils droit (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 1. Implémentez cette classe Noeud
2. Stocker l'arbre comme étant l'objet de type "Noeud" correspondant à la racine. 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 3. Ecrire une méthode estFeuille qui renvoie True si le noeud est une feuille et False sinon

View File

@@ -56,8 +56,10 @@ On parle également de **hauteur d'un arbre** :
- Elle correspond à la **profondeur maximale** dun nœud dans larbre, cest-à-dire le **plus grand nombre darêtes** depuis la racine jusquà une feuille. - Elle correspond à la **profondeur maximale** dun nœud dans larbre, cest-à-dire le **plus grand nombre darêtes** depuis la racine jusquà une feuille.
- La hauteur est le nombre maximum de niveaux dans larbre, en partant de la racine jusquà la feuille la plus profonde. - La hauteur est le nombre maximum de niveaux dans larbre, en partant de la racine jusquà la feuille la plus profonde.
- Selon les points de vue, la hauteur est parfois définie différemment : - Selon les conventions, la hauteur est parfois définie différemment :
- On peut considérer la hauteur d'un arbre vide à 0, soit à 1. - 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 ?* **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 Licence CC BY NC

View File

@@ -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 : Ces derniers ont plusieurs fonctions dont 4 qui sont primordiales :

View File

@@ -105,9 +105,9 @@ Si lattribut `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é dappliquer la contrainte dinté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 !
--- ---

View File

@@ -29,7 +29,7 @@ On peut par exemple prendre des problèmes assez élémentaires :
- X est il un nombre pair ? - X est il un nombre pair ?
- Y est il une puissance de 3 ? - 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. 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. 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 ? » > **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.
>
> Question dont la réponse est bel et bien un prédicat.
### Définition : Décidabilité ### 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 ### 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. 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 ```python
def est_pair2(n): def est_pair2(n):
reste = n % 2
if (n % 2) == 0: if reste == 0:
return("{0} est Pair".format(n)) return True
else: else:
return("{0} est Impair".format(n)) return False
``` ```
```python ```python
>>>est_pair2(113) >>>est_pair2(113)
>>>'113 est Impair' >>>False
>>>est_pair2(42) >>>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. 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. 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***. En informatique, le plus célèbre de ces problèmes indécidables est le ***problème de l'arrêt***.

View File

@@ -43,7 +43,9 @@ def bfs(graphe, depart):
### Illustration du parcours en largeur ### 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. Cest une approche de type pile (LIFO). Le parcours en profondeur explore un chemin le plus loin possible avant de revenir en arrière. Cest une approche de type pile (LIFO).
#### Algorithme DFS : #### Algorithme DFS (version récursive) :
1. Choisir un sommet de départ et lempiler. 1. Marquer le sommet courant comme visité.
2. Marquer ce sommet comme visi. 2. Pour chaque voisin non encore visité, relancer le parcours depuis ce voisin.
3. Tant que la pile nest pas vide :
- Retirer le sommet du sommet de la pile. > 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".
- Ajouter tous ses voisins non encore visités dans la pile et les marquer comme visités.
#### Implémentation en Python : #### Implémentation en Python :
```python ```python
@@ -78,7 +79,9 @@ def dfs(graphe, depart, visite=None):
### Illustration ### 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/)*
---------- ----------

View File

@@ -184,6 +184,39 @@ A = np.matrix(A)
Ecrire la matrice d'adjacence du réseau social de l'introduction 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.

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -26,7 +26,7 @@ Intéressons-nous au code Python ci-dessous. Ici, la structure compte plus que l
```python ```python
## importations ## importations
from math import * from math import sqrt
import doctest import doctest
## variables ## variables
@@ -77,7 +77,7 @@ Intéressons nous au programme vu précédemment :
```python ```python
## importations ## importations
from math import * from math import sqrt
import doctest import doctest
``` ```
@@ -169,6 +169,8 @@ def somme(n):
>>> somme(5) >>> somme(5)
15 15
>>> somme(-1) >>> somme(-1)
Traceback (most recent call last):
...
AssertionError: erreur AssertionError: erreur
""" """
assert type(n)==int, "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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -63,7 +63,7 @@ Le constructeur est une méthode(fonction) permettant d'initialiser votre type.
```python ```python
class Etudiant : 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.nom = nom_etu
self.prenom = prenom_etu self.prenom = prenom_etu
self.spe1 = spe1_etu self.spe1 = spe1_etu
@@ -126,9 +126,9 @@ On pourrait créer une méthode *anniversaire* par exemple :
```python ```python
def anniversaire(self) : def anniversaire(self) :
self.age = self.age + 1 self.age = self.age + 1
if self.age == 18 : if self.age == 18 :
self.peut_avoir_son_permis = True 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. 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 ```python
def nouvelle_spe(self,new_spe): def nouvelle_spe(self,new_spe):
self.spe2 = new_spe self.spe2 = new_spe
``` ```
```python ```python
@@ -169,7 +169,7 @@ Actuellement il est impossible de faire la même chose avec nos étudiants. C'es
```python ```python
def __eq__(self,obj2): 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. 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 ```python
class Etudiant : 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.__nom = nom_etu
self.__prenom = prenom_etu self.__prenom = prenom_etu
self.spe1 = spe1_etu self.spe1 = spe1_etu
@@ -238,10 +238,10 @@ Ici l'attribut \_\_nom et \_\_prenom sont privés. Pour accéder/modifier à leu
```python ```python
def get_nom(self): def get_nom(self):
return self.__nom return self.__nom
def set_nom(self,nouveau_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. 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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -150,9 +150,11 @@ En Python, la fonction lambda se définit à l'aide du mot-clé **lambda** :
```python ```python
add_a_b = lambda a,b: a + b 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 : Appelée aussi fonction anonyme, il ne faut pas en abuser en Python, elle :
- est utile pour définir une fonction simple, proche dune définition mathématique, en une ligne ; - est utile pour définir une fonction simple, proche dune définition mathématique, en une ligne ;
@@ -171,17 +173,21 @@ Appliquer une fonction à chaque élément d'une liste.
```python ```python
f = lambda x: x*5 f = lambda x: x*5
liste = [2, 7, -1] 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 `<map object at 0x...>`.*
__La réduction__ __La réduction__
Combiner les éléments dune liste en appliquant une fonction à laide dun 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). Combiner les éléments dune liste en appliquant une fonction à laide dun 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 ```python
import functools
liste = [1, 3, 5, 6, 2] liste = [1, 3, 5, 6, 2]
f_somme = lambda acc, x: acc + x f_somme = lambda acc, x: acc + x
somme = functools.reduce(f_somme, liste) somme = functools.reduce(f_somme, liste) # 17
``` ```
```python ```python
@@ -197,7 +203,7 @@ Sélectionne les éléments d'une liste vérifiant un certain critère.
```python ```python
liste = [1, 3, 5, 6, 2] liste = [1, 3, 5, 6, 2]
f_filtre = lambda x: x >= 3 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 #### 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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

View File

@@ -18,9 +18,16 @@ Tous ces programmes sont en réalité des lignes immenses de code et le processe
## 1. Notion de processus ## 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 :* *Exemple de répartition de deux programmes par l'OS :*
@@ -57,6 +64,14 @@ Il existe aussi deux autres états :
<img src="assets/etat.png" style="zoom:50%;" /> <img src="assets/etat.png" style="zoom:50%;" />
### 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 : ## 3. Interblocage :
L'interblocage intervient lorsque plusieurs processus sont bloqués les uns par les autres. 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 Licence CC BY NC

View File

@@ -245,19 +245,22 @@ def traitement(motif):
def morris_pratt(texte, motif): def morris_pratt(texte, motif):
m = len(motif) m = len(motif)
n = len(texte) n = len(texte)
i = 0
j = 0
sol = [] # Tableau pour stocker les solutions
s = traitement(motif) # Pré-traitement du motif s = traitement(motif) # Pré-traitement du motif
while i < m and j < n: sol = [] # Tableau pour stocker les positions trouvées
if i >= 0 and motif[i] != texte[j]: i = 0 # indice dans le motif
i = s[i] j = 0 # indice dans le texte
else: while j < n:
if motif[i] == texte[j]:
i += 1 i += 1
j += 1 j += 1
if i >= m: # Si le motif est présent if i == m: # Le motif est présent
sol.append(j - m) # La position dans le texte est ajoutée à la liste 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é 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 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 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. 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.
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.

View File

@@ -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. - Au-delà de 15 sauts, on considère un routeur inaccessible.
- Utilise lalgorithme à vecteur de distance de Bellman-Ford et est simple à configurer, mais limité en performance. - Utilise lalgorithme à vecteur de distance de Bellman-Ford et est simple à configurer, mais limité en performance.
- Convient aux petits réseaux - 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)

View File

@@ -97,6 +97,8 @@ Exemple de masque de sous-réseau en IPv4 :
- `255.255.0.0` (notation `/16`) → 65 536 adresses possibles - `255.255.0.0` (notation `/16`) → 65 536 adresses possibles
- `255.0.0.0` (notation `/8`) → 16 777 216 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. Chaque **bit à 1** dans le masque représente la partie réseau, et chaque **bit à 0** représente la partie hôte.
#### Calcul dun sous-réseau #### Calcul dun sous-réseau

View File

@@ -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. 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 :** **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 | | CPU | 20 cœurs ARM Grace (Neoverse V2), co-développé avec MediaTek |
| GPU | Blackwell - 6 144 CUDA cores, Tensor Cores Gen 5 | | GPU | Blackwell - 6 144 CUDA cores, Tensor Cores Gen 5 |
| Mémoire | Jusqu'à 128 Go de LPDDR5X **unifiée** (partagée CPU/GPU) | | 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) | | 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 :** **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. - **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. - **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 ### 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é | | 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 | | **Apple** | M4 Pro/Max (2024) | SoC universel, efficacité énergétique, écosystème Apple |
| **Qualcomm** | Snapdragon X Elite (2024) | PC Windows ARM, NPU 45 TOPS | | **Qualcomm** | Snapdragon X Elite (2024) | PC Windows ARM, NPU 45 TOPS |
| **AMD** | Strix Halo (2025) | x86 + GPU RDNA4, gaming portable | | **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é ### 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. 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, CPU et GPU ont chacun leur propre mémoire ? 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, 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 ? 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 ?
--- ---

View File

@@ -43,7 +43,7 @@ Une pile est une structure de données dans laquelle les derniers éléments ent
![image-20220729234146926](Images/Pile.png) ![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 ### 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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC

View File

@@ -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 Licence CC BY NC