Computing">
24 Nsij1an
24 Nsij1an
24 Nsij1an
SESSION 2024
JOUR 1
Dès que ce sujet vous est remis, assurez-vous qu’il est complet.
24-NSIJ1AN1 Page : 1 / 13
EXERCICE 1 (6 points)
Cet exercice porte sur la programmation Python, la programmation orientée objet, les
structures de données (file), l’ordonnancement et l’interblocage.
On veut simuler cet ordonnancement avec des objets. Pour ce faire, on dispose déjà
de la classe Processus dont voici la documentation :
Classe Processus:
p.execute_un_cycle()
Exécute le processus donné pendant un cycle.
p.est_fini()
Renvoie True si le processus est terminé, False sinon.
Pour simplifier, on ne s’intéresse pas aux ressources qu’un processus pourrait acquérir
ou libérer.
2. Citer les deux seuls états possibles pour un processus dans ce contexte.
Classe File
1 class File:
2 def __init__(self):
3 """ Crée une file vide """
4 self.contenu = []
5
6 def enfile(self, element):
7 """ Enfile element dans la file """
8 self.contenu.append(element)
9
10 def defile(self):
11 """ Renvoie le premier élément de la file et l'enlève de
la file """
12 return self.contenu.pop(0)
13
14 def est_vide(self):
24-NSIJ1AN1 Page : 2 / 13
15 """ Renvoie True si la file est vide, False sinon """
16 return self.contenu == []
Lors de la phase de tests, on se rend compte que le code suivant produit une erreur :
1 f = File()
2 print(f.defile())
3. Rectifier sur votre copie le code de la classe File pour que la function defile
renvoie None lorsque la file est vide.
On se propose d’ordonnancer les processus avec une méthode du type tourniquet telle
qu’à chaque cycle :
24-NSIJ1AN1 Page : 3 / 13
1 p1 = Processus("p1", 4)
2 p2 = Processus("p2", 3)
3 p3 = Processus("p3", 5)
4 p4 = Processus("p4", 3)
5 depart_proc = {0: p1, 1: p3, 2: p2, 3: p4}
Il s’agit d’une modélisation de la situation précédente où un seul processus
peut être créé lors d’un cycle donné.
4. Recopier et compléter sur votre copie le chronogramme ci-dessous pour les
processus p1, p2, p3 et p4.
24-NSIJ1AN1 Page : 4 / 13
À chaque appel de la méthode tourniquet, celle-ci renvoie soit le nom du processus
qui a été élu, soit None si elle n’a pas trouvé de processus en cours.
Dans la situation donnée en exemple (voir Figure 1), il s’avère qu’en fait les processus
utilisent des ressources comme :
24-NSIJ1AN1 Page : 5 / 13
EXERCICE 2 (6 points)
Le groupe est constitué de huit personnes (Anas, Emma, Gabriel, Jade, Lou, Milo,
Nina et Yanis) qui possèdent entre elles les relations suivantes :
24-NSIJ1AN1 Page : 6 / 13
On dispose de la liste suivante qui identifie les sommets du graphe :
Par exemple :
>>> nb_amis(graphe, 'L')
1
24-NSIJ1AN1 Page : 7 / 13
Milo s’est fâché avec Gabriel et Yanis tandis qu’Anas s’est fâché avec Yanis.
Le dictionnaire d’adjacence du graphe qui modélise cette nouvelle situation est donné
ci-dessous :
Pour établir la liste du cercle d’amis d’un sommet, on utilise un parcours en profondeur
du graphe à partir de ce sommet. On appelle cercle d’amis de Nom toute personne
atteignable dans le graphe à partir de Nom.
fonction parcours_en_profondeur(d, s)
ajouter s à la liste visités
pour tous les sommets voisins v de s :
si v n'est pas dans la liste visités :
parcours_en_profondeur(d, v)
retourner la liste visités
10. Recopier et compléter le code de la fonction parcours_en_profondeur(d, s)
qui prend en paramètres un dictionnaire d’adjacence d et un sommet s et qui
renvoie la liste des sommets issue du parcours en profondeur du graphe
modélisé par d à partir du sommet s.
1 def parcours_en_profondeur(d, s, visites = []):
2 ...
3 for v in d[s]:
4 ...
5 parcours_en_profondeur(d, v)
6 ...
24-NSIJ1AN1 Page : 8 / 13
EXERCICE 3 (8 points)
Cet exercice porte sur la programmation Python, la modularité, les bases de données
relationnelles et les requêtes SQL.
Une flashcard, autrement appelée carte de mémorisation, est une carte papier sur
laquelle se trouve au recto une question et au verso la réponse à cette question. On
les utilise en lisant la question du recto puis en vérifiant notre réponse à celle du verso.
Une étudiante souhaite réaliser des flashcards numériquement.
Partie A
L’étudiante souhaite stocker les questions/réponses de ses flashcards dans un fichier
au format csv. Ce format permet de stocker textuellement des données tabulaires. La
première ligne du fichier contient les descripteurs : les noms des champs renseignés
par la suite. Pour être en mesure de les identifier, chaque champ est séparé par un
caractère appelé séparateur. C’est la virgule qui est le plus couramment utilisée, mais
cela peut être d’autres caractères de ponctuation.
Le langage Python dispose d’un module natif nommé csv qui permet de traiter de tels
fichiers. La méthode DictReader de ce module prend en argument un fichier csv et
le séparateur utilisé. Elle permet d’extraire les données contenues dans le fichier. Voici
un exemple de fonctionnement.
fichier exemple.csv
champ1,champ2
a,7
b,8
c,9
code Python
import csv
with open('exemple.csv','r') as fichier:
donnees = list(csv.DictReader(fichier,delimiter=','))
print(donnees)
discipline;chapitre;question;réponse
histoire;crise de 1929;jeudi noir - date;24 octobre 1929
histoire;crise de 1929;jeudi noir - quoi;krach boursier
histoire;2GM;l’Axe;Allemagne, Italie, Japon
histoire;2GM;les Alliés;Chine, États-Unis, France, Royaume-Uni, URSS
24-NSIJ1AN1 Page : 9 / 13
histoire;2GM;Pearl Harbor - date;7 décembre 1941
philosophie;travail;Marx;aliénanation de l'ouvrier
philosophie;travail;Beauvoir;donne de la valeur à l'homme
philosophie;travail;Locke;permet de fonder le droit de propriété
philosophie;travail;Crawford;satisfaction et estime de soi
1 import csv
2 import time
3
4 def charger(nom_fichier):
5 with ...
6 donnees = ...
7 return ...
8
9 def choix_discipline(donnees):
10 disciplines = []
11 for i in range(len(donnees)):
12 disc = donnees[i]['discipline']
13 if not disc in disciplines:
14 disciplines.append(disc)
15 for i in range(len(disciplines)):
16 print(i + 1, disciplines[i])
17 num_disc = int(input('numéro de la discipline ? '))
18 return disciplines[num_disc - 1]
19
20 def choix_chapitre(donnees, disc):
21 chapitres = []
22 for i in range(len(donnees)):
23 if flashcard[i]['discipline'] == disc:
24 ch = flashcard[i]['chapitre']
25 if not ch in chapitres:
26 chapitres.append(ch)
27 for i in range(len(chapitres)):
28 print(i +1, chapitres[i])
29 num_ch = int(input('numéro du chapitre ? '))
30 return chapitres[num_ch - 1]
31
32 def entrainement(donnees, disc, ch):
33 for i in range(len(donnees)):
34 if donnees[i]['discipline'] == disc \
35 and donnees[i]['chapitre'] == ch:
36 print('QUESTION : ', donnees[i]['question'])
37 time.sleep(5)
38 print(donnees[i]['réponse'])
24-NSIJ1AN1 Page : 10 / 13
39 time.sleep(1)
40
41 flashcard = ...
42 d = ...
43 c = ...
44 entrainement(...)
Partie B
Pour améliorer sa mémorisation sur le long terme, l’étudiante décide de mettre en
œuvre le concept des boites de Leitner. Dans cette méthode, il s’agit d’espacer dans
le temps la révision des flashcards si l’étudiante répond correctement. Elle imagine
donc une base de données qui lui permettra de conserver pour chaque question la
date à laquelle elle doit de nouveau être posée. Elle décide que les questions seront
réparties en 5 boites. Initialement, tous les questions seront placées dans la boite 1.
Les questions de la boite 1 sont posées tous les jours, celles de la boite 2 tous les
deux jours, celles de la boite 3 tous les quatre jours, celles de la boite 4 tous les huit
jours et celles de la boite 5 tous les quinze jours. Si l’étudiante donne la bonne réponse
à une question et que la question n’appartient pas à la boite 5, son numéro de boite
est incrémenté (augmenté de 1). Si l’étudiante ne donne pas la bonne réponse, la
question revient dans la boite 1.
Elle met en œuvre une base de données relationnelle contenant 4 tables discipline,
chapitre, boite et question.
La table discipline contient la liste des disciplines étudiées. Elle a deux attributs :
• id, de type INT, l’identifiant de la discipline qui est une clé primaire pour cette
table ;
La table chapitre contient la liste des chapitres des disciplines étudiées. Elle a trois
attributs :
• id, de type INT, l’identifiant du chapitre qui est une clé primaire pour cette
table ;
24-NSIJ1AN1 Page : 11 / 13
• lib, de type TEXT, le libellé du chapitre ;
La table boite contient l’ensemble des cinq boites existantes. Elle a trois attributs :
• id, de type INT, l’identifiant numéro de la boite qui est une clé primaire pour
cette table ;
• id, de type INT, l’identifiant de la flashcard qui est une clé primaire pour cette
table ;
Table boite
Id lib frequence
7. Écrire une requête SQL qui complète la table boite et insère la boite 5 de
libellé ‘tous les quinze jours’ et de fréquence 15.
24-NSIJ1AN1 Page : 12 / 13
Une requête sur la table flashcard affiche l’enregistrement suivant :
8. Écrire une requête SQL pour mettre à jour la date de Pearl Harbor renvoyée.
La bonne date est le 7 décembre 1941.
9. Écrire une requête SQL qui permet d’obtenir la liste des libellés des disciplines.
10. Écrire une requête SQL qui permet d’obtenir la liste des libellés des chapitres
de la discipline ‘histoire’.
11. Écrire une requête SQL qui permet d’obtenir la liste des identifiants des
flashcards de la discipline ‘histoire’.
12. Écrire une requête SQL pour supprimer toutes les flashcards de la boite
d’identifiant 3.
24-NSIJ1AN1 Page : 13 / 13