Physique-Chimie & NSI

Cours complets et originaux de Physique-Chimie & NSI

Devoir n°4
Dictionnaires, POO et bases de données
1h25

Cet exercice est composé de trois parties indépendantes.

On veut créer une application permettant de stocker et de traiter des informations sur des livres de science-fiction. On désire stocker les informations suivantes :

Voici un extrait des informations que l’on cherche à stocker :

Livres de science-fiction
id titre auteur ann_pub note
1 1984 Orwell 1949 10
2 Dune Herbert 1965 8
14 Fondation Asimov 1951 9
4 Ubik K.Dick 1953 9
8 Blade Runner K.Dick 1968 8
7 Les Robots Asimov 1950 10
15 Ravage Barjavel 1943 6
17 Chroniques martiennes Bradbury 1950 7
9 Dragon déchu Hamilton 2003 8
10 Fahrenheit 451 Bradbury 1953 8

Partie A

Dans cette première partie, on utilise un dictionnaire Python. On considère le programme suivant :


		dico_livres = {
			'id' : [1, 2, 14, 4, 5, 8, 7, 15, 9, 10],
			'titre' : ['1984', 'Dune', 'Fondation', 'Ubik', 'Blade Runner',
			'Les Robots', 'Ravage', 'Chroniques martiennes',
			'Dragon déchu', 'Fahrenheit 451'],
			'auteur' : ['Orwell', 'Herbert', 'Asimov', 'K.Dick', 'K.Dick', 'Asimov',
			'Barjavel', 'Bradbury', 'Hamilton', 'Bradbury'],
			'ann_pub' : [1949, 1965, 1951, 1953,1968, 1950, 1943, 1950, 2003, 1953],
			'note' : [10, 8, 9, 9, 8, 10, 6, 7, 8, 8]
		}
		a = dico_livres['note']
		b = dico_livres['titre'][2]
	

1. Déterminer les valeurs des variables a et b après l’exécution de ce programme.

La fonction titre_livre prend en paramètre un dictionnaire (de même structure que dico_livres) et un identifiant, et renvoie le titre du livre qui correspond à cet identifiant. Dans le cas où l’identifiant passé en paramètre n’est pas présent dans le dictionnaire, la fonction renvoie None.


		def titre_livre(dico, id_livre):
			for i in range(len(dico['id'])):
				if dico['id'][i] == ... :
					return dico['titre'][...]
			return ...
	

2. Recopier et compléter les lignes 3, 4 et 5 de la fonction titre_livre.

3. Écrire une fonction note_maxi qui prend en paramètre un dictionnaire dico (de même structure que dico_livres) et qui renvoie la note maximale.

4. Écrire une fonction livres_note qui prend en paramètre un dictionnaire dico (de même structure que dico_livres) et une note n, et qui renvoie la liste des titres des livres ayant obtenu la note n (on rappelle que t.append(a) permet de rajouter l’élément a à la fin de la liste t).

5. Écrire une fonction livre_note_maxi qui prend en paramètre un dictionnaire dico (de même structure que dico_livres) et qui renvoie la liste des titres des livres ayant obtenu la meilleure note sous la forme d’une liste Python.

Partie B

Dans cette partie, on utilise le paradigme orientée objet (POO). On propose deux classes : Livre et Bibliotheque.


		class Livre:
			def __init__(self, id_livre, titre, auteur, ann_pub, note):
				self.id = id_livre
				self.titre = titre
				self.auteur = auteur
				self.ann_pub = ann_pub
				self.note = note
			def get_id(self):
				return self.id
			def get_titre(self):
				return self.titre
			def get_auteur(self):
				return self.auteur
			def get_ann_pub(self):
				return self.ann_pub
		
		class Bibliotheque:
			def __init__(self):
				self.liste_livre = []
			def ajout_livre(self, livre):
				self.liste_livre.append(livre)
			def titre_livre(self, id_livre):
				for livre in self.liste_livre :
					if ... == id_livre :
						return ...
				return ...
	

6. Citer un attribut et une méthode de la classe Livre.

7. Écrire la méthode get_note de la classe Livre. Cette méthode devra renvoyer la note d’un livre.

8. Écrire le programme permettant d’ajouter le livre Blade Runner à la fin de la « bibliothèque » en utilisant la classe Livre et la classe Bibliotheque (voir le tableau en début d’exercice).

9. Recopier et compléter la méthode titre_livre de la classe Bibliotheque. Cette méthode prend en paramètre l’identifiant d’un livre et renvoie le titre du livre si l’identifiant existe, ou None si l’identifiant n’existe pas.

Partie C.

On utilise maintenant une base de données relationnelle. Les commandes nécessaires ont été exécutées afin de créer une table livres. Cette table livres contient toutes les données sur les livres. On obtient donc la table suivante :

livres
id titre auteur ann_pub note
1 1984 Orwell 1949 10
2 Dune Herbert 1965 8
14 Fondation Asimov 1951 9
4 Ubik K.Dick 1953 9
8 Blade Runner K.Dick 1968 8
7 Les Robots Asimov 1950 10
15 Ravage Barjavel 1943 6
17 Chroniques martiennes Bradbury 1950 7
9 Dragon déchu Hamilton 2003 8
10 Fahrenheit 451 Bradbury 1953 8

L’attribut id est la clé primaire pour la table livres.

10. Expliquer pourquoi l’attribut auteur ne peut pas être choisi comme clé primaire.

11. Donner le résultat renvoyé par la requête SQL suivante :

SELECT titre FROM livres WHERE auteur = 'K.Dick';

12. Écrire une requête SQL permettant d’obtenir les titres des livres écrits par Asimov publiés après 1950.

13. Écrire une requête SQL permettant de modifier la note du livre Ubik en la passant de 9/10 à 10/10.

On souhaite proposer plus d’informations sur les auteurs des livres. Pour cela, on crée une seconde table auteurs avec les attributs suivants :

  • id de type INT ;
  • nom de type TEXT ;
  • prenom de type TEXT ;
  • annee_naissance de type INT (année de naissance).
auteurs
id nom prenom annee_naissance
1 Orwell George 1903
2 Herbert Franck 1920
3 Asimov Isaac 1920
4 K.Dick Philip 1928
5 Bradbury Ray 1920
6 Barjavel René 1911
7 Hamilton Peter 1960

La table livres est aussi modifiée comme suit :

livres
id titre id_auteur ann_pub note
1 1984 1 1949 10
2 Dune 2 1965 8
14 Fondation 3 1951 9
4 Ubik 4 1953 9
8 Blade Runner 4 1968 8
7 Les Robots 3 1950 10
15 Ravage 6 1943 6
17 Chroniques martiennes 5 1950 7
9 Dragon déchu 7 2003 8
10 Fahrenheit 451 5 1953 8

14. Expliquer l’intérêt d’utiliser deux tables (livres et auteurs) au lieu de regrouper toutes les informations dans une seule table.

15. Expliquer le rôle de l’attribut id_auteur de la table livres.

16. Écrire une requête SQL qui renvoie le nom et le prénom des auteurs des livres publiés après 1960.

17. Décrire par une phrase en français le résultat de la requête SQL suivante :


		SELECT titre
		FROM livres
		JOIN auteurs ON id_auteur = auteurs.id
		WHERE ann_pub - annee_naissance < 30;
	

Un élève décide de créer une application d’annuaire pour sa classe. On pourra retrouver, grâce à cette application, différentes informations sur les élèves de la classe : nom, prénom, date de naissance, numéro de téléphone, adresse email, etc.

18. Expliquer en quoi la réalisation de ce projet pourrait être problématique.

Correction

Partie A

1. a = [10, 8, 9, 9, 8, 10, 6, 7, 8, 8] et b = 'Fondation'.

Remarque : utiliser un dictionnaire de cette manière est totalement absurde et contre-intuitive. Il aurait été beaucoup plus logique d’avoir une liste de livres qui, eux, aurait été des dictionnaires. 🙄

B si Dune au lieu de Foundation

[1]

2. Fonction titre_livres :


				# lignes à compléter
						if dico['id'][i] == id_livre:
							return dico['titre'][i]
					return None
			

B si return dico['titre'][id_livre] au lieu de return dico['titre'][i]

[2]

3. Fonction note_maxi :


				def note_maxi(dico):
					note_maxi = 0
					for n in dico['note']:
						if n > note_maxi:
							note_maxi = n
					return note_maxi
					
				# ou beaucoup plus court 🤓
				def note_maxi(dico):
					return max(dico['notes'])
			
[2]

4. Fonction livres_note


					def livres_notes(dico, n):
						livres = []
						for i in range(len(dico['notes'])):
							if dico['note'][i] == n : livres.append(dico['titre'][i])
						return livres
			

25 % pour initialisation tableau vide
50 % pour boucle cohérente (for i in range(len(dico)))
20 % pour le append correct

[2]

5. Fonction livre_note_maxi


					def livre_note_maxi(dico):
						note_maxi = note_maxi(dico)
						livres = livres_notes(dico, note_maxi)
						return livres
			
[1]

Partie B

6. Un seul exemple est attendu dans chaque cas.

  • attributs : id, titre, auteur, ann_pub, note
  • methode : get_id, get_titre, get_auteur, get_ann_pub
[1]

7. Méthode get_note


					# à placer à l’intérieur de la classe
					def get_note(self):
						return self.note
			
[1]

8. Ajout d’un livre à une bibliothèque. On suppose que la bibliothèque a déjà été créée (variable bibal)


					bladerunner = Livre(8, "Blade Runner", "K.Dick", 1968, 8)
					bibal.ajout_livre(bladerunner)
			
[2]

9. Méthode titre_livre


					def titre_livre(self, id_livre):
						for livre in self.liste_livre :
							if livre.id == id_livre :
								return livre.titre
						return None
			

25 % pour livre in self.liste_livre

[2]

Partie C

10. Parce qu’un même auteur peut être associé à plusieurs livres, et une clé primaire doit être unique.

[1]

11. Résultat requête SQL


				Ubik
				Blade Runner
			
[1]

12. Requête SQL


				SELECT titre FROM livres WHERE auteur = 'Asimov' AND ann_pub > 1950;
			

C si WHERE à la place du AND

[1]

13. Requête SQL type UPDATE


				UPDATE livres SET note = 10 WHERE titre = 'Ubik';
			

D si seule la clause WHERE est correcte

[1]

14. Évite la redondance des données.

0 si l’idée d’éviter la redondance des données est absente.

[1]

15. Il s’agit d’une clé étrangère permettant de lier un livre à un auteur.

D si « clé étrangère » sans autre explication

[1]

16. Requête SQL avec JOIN


				SELECT auteurs.nom, auteurs.prenom
				FROM auteurs
				JOIN livres ON livres.id_auteur = auteurs.id
				WHERE livres.ann_pub > 1960;
			

-25 % si ambigüité sur origine des attributs (id est à la fois dans auteurs et dans livres)

[1,5]

17. Titre des livres écrits avant les 30 ans de l’auteur.

[1]

18. Le recueil de données personnelles est encadré par la loi (RGPD).

[0,5]