Merge pull request #11 from freezed/dico-ord
Fin du TP «Un dictionnaire ordonné»
This commit is contained in:
commit
9952eae898
|
@ -0,0 +1,202 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: freezed <freezed@users.noreply.github.com> 2018-01-25
|
||||
Version: 0.1
|
||||
Licence: `GNU GPL v3`: http://www.gnu.org/licenses/
|
||||
"""
|
||||
|
||||
|
||||
class DictionnaireOrdonne:
|
||||
|
||||
"""
|
||||
Dictionnaire ordonne
|
||||
====================
|
||||
|
||||
Objet ressemblant a un dict, avec des capacitees de tri.
|
||||
|
||||
Les cles et valeurs se trouvant dans des listes de meme
|
||||
taille, il suffira de prendre l'indice dans une liste pour
|
||||
savoir quel objet lui correspond dans l'autre. Par exemple,
|
||||
la cle d'indice 0 est couplee avec la valeur d'indice 0.
|
||||
|
||||
On doit pouvoir ajouter deux dictionnaires ordonnes
|
||||
(dico1 + dico2) ; les cles et valeurs du second dictionnaire
|
||||
sont ajoutees au premier.
|
||||
|
||||
:Example:
|
||||
>>> fruits = DictionnaireOrdonne()
|
||||
>>> fruits
|
||||
{}
|
||||
|
||||
>>> fruits["pomme"] = 52
|
||||
>>> fruits["poire"] = 34
|
||||
>>> fruits["prune"] = 128
|
||||
>>> fruits["melon"] = 15
|
||||
>>> fruits
|
||||
{'pomme': 52, 'poire': 34, 'prune': 128, 'melon': 15}
|
||||
|
||||
>>> fruits.sort()
|
||||
>>> print(fruits)
|
||||
{'melon': 15, 'poire': 34, 'pomme': 52, 'prune': 128}
|
||||
|
||||
>>> legumes = DictionnaireOrdonne(carotte = 26, haricot = 48)
|
||||
>>> print(legumes)
|
||||
{'carotte': 26, 'haricot': 48}
|
||||
|
||||
>>> len(legumes)
|
||||
2
|
||||
|
||||
#>>> legumes.reverse()
|
||||
#>>> fruits = fruits + legumes
|
||||
#>>> fruits
|
||||
#{'melon': 15, 'poire': 34, 'pomme': 52,
|
||||
#'prune': 128, 'haricot': 48, 'carotte':26}
|
||||
|
||||
#>>> del fruits['haricot']
|
||||
#>>> 'haricot' in fruits
|
||||
#False
|
||||
|
||||
#>>> legumes['haricot']
|
||||
#48
|
||||
|
||||
#>>> for cle in legumes:
|
||||
#... print(cle)
|
||||
#...
|
||||
#haricot
|
||||
#carotte
|
||||
|
||||
#>>> legumes.keys()
|
||||
#['haricot', 'carotte']
|
||||
|
||||
#>>> legumes.values()
|
||||
#[48, 26]
|
||||
|
||||
#>>> for nom, qtt in legumes.items():
|
||||
#... print("{0} ({1})".format(nom, qtt))
|
||||
#...
|
||||
#haricot (48)
|
||||
#carotte (26)
|
||||
"""
|
||||
|
||||
def __init__(self, **dico):
|
||||
"""
|
||||
On doit pouvoir creer le dictionnaire de plusieurs façons :
|
||||
- Vide: sans passer aucun parametre
|
||||
- Copie d'un dict(): parametre du constructeur un dict() que
|
||||
l'on copie par la suite dans notre objet. On peut ainsi
|
||||
ecrire constructeur(dictionnaire) et les cles et valeurs
|
||||
contenues dans le dictionnaire sont copiees dans l'objet
|
||||
construit.
|
||||
- Pre-rempli de cles/valeurs en parametre: comme les dict()
|
||||
usuels, on doit ici avoir la possibilite de pre-remplir
|
||||
notre objet avec des couples cles-valeurs passes en
|
||||
param (constructeur(cle1 = valeur1, cle2 = valeur2, …))
|
||||
Les cles et valeurs doivent etre couplees
|
||||
"""
|
||||
|
||||
self.kl = list()
|
||||
self.vl = list()
|
||||
|
||||
if len(dico) != 0:
|
||||
for k, v in dico.items():
|
||||
self.kl.append(k)
|
||||
self.vl.append(v)
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Affiche l'objet dans l'interpreteur ou grâce a la fonction
|
||||
print. L'affichage identique aux dict()
|
||||
({cle1: valeur1, cle2: valeur2, …}).
|
||||
"""
|
||||
content = list()
|
||||
|
||||
if len(self.kl) != 0:
|
||||
for i in range(0, len(self.kl)):
|
||||
content.append("'{}': {}".format(self.kl[i], self.vl[i]))
|
||||
|
||||
return "{0}{1}{2}".format(
|
||||
"{",
|
||||
", ".join(content),
|
||||
"}"
|
||||
)
|
||||
|
||||
def __setitem__(self, cle, valeur):
|
||||
"""
|
||||
Acces avec crochets pour modif (objet[cle] = valeur)
|
||||
Si la cle existe on ecrase l'ancienne valeur, si elle
|
||||
n'existe pas on ajoute le couple cle-valeur a la fin
|
||||
"""
|
||||
try:
|
||||
index = self.kl.index(cle)
|
||||
self.kl[index] = cle
|
||||
self.vl[index] = valeur
|
||||
|
||||
except ValueError:
|
||||
self.kl.append(cle)
|
||||
self.vl.append(valeur)
|
||||
|
||||
def sort(self, reverse=False):
|
||||
"""
|
||||
L'objet doit definir les methodes sort pour le trier et reverse
|
||||
pour l'inverser. Le tri de l'objet doit se faire en fonction
|
||||
des cles
|
||||
"""
|
||||
# pour trier on stocke les couples de cle & valeur sous forme
|
||||
# de tuple dans une liste temporaire
|
||||
liste_temporaire = list()
|
||||
|
||||
if len(self.kl) != 0: # Seulement si il y a des donnees
|
||||
for i in range(0, len(self.kl)): # on parcour chaque entee
|
||||
liste_temporaire.append((self.kl[i], self.vl[i]))
|
||||
|
||||
# Tri des tuples par la valeur par une comprension de liste
|
||||
liste_permute = [(val, cle) for cle, val in liste_temporaire]
|
||||
liste_triee = [(cle, val) for val, cle in sorted(liste_permute, reverse=reverse)]
|
||||
|
||||
# On range les donnees tries dans attributs de l'objet
|
||||
self.kl = [cle for cle, val in liste_triee]
|
||||
self.vl = [val for cle, val in liste_triee]
|
||||
|
||||
def __len__(self):
|
||||
""" Retourne la taille de l'objet grace a la fonction len """
|
||||
return len(self.kl)
|
||||
|
||||
#def __contains__():
|
||||
#""" Cherche une cle dans notre objet (cle in dictionnaire) """
|
||||
|
||||
#def __delattr__(self):
|
||||
#"""
|
||||
#Les cles et valeurs doivent etre couplees. Si on cherche
|
||||
#a supprimer une cle sa valeur doit etre supprimee.
|
||||
#"""
|
||||
|
||||
#def __getitem__():
|
||||
#""" Acces avec crochets pour recuperer une valeur (objet[cle]) """
|
||||
|
||||
#def __delitem__():
|
||||
#""" Acces avec crochets pour suppression (del objet[cle]) """
|
||||
|
||||
#def __setattr__():
|
||||
#""" Function doc """
|
||||
|
||||
#def generateur():
|
||||
#"""
|
||||
#L'objet doit pouvoir etre parcouru.
|
||||
#Quand on ecrit for cle in dictionnaire, on doit parcourir
|
||||
#la liste des cles contenues dans le dictionnaire. A l'instar
|
||||
#des dictionnaires, trois methodes keys() (renvoyant la liste
|
||||
#des cles), values() (renvoyant la liste des valeurs) et
|
||||
#items() (renvoyant les couples (cle, valeur)) doivent etre
|
||||
#mises en œuvre. Le type de retour de ces methodes est laisse
|
||||
#a votre initiative : il peut s'agir d'iterateurs ou de
|
||||
#generateurs (tant qu'on peut les parcourir).
|
||||
#"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
""" Active les doctests """
|
||||
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -0,0 +1,257 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: freezed <freezed@users.noreply.github.com> 2018-01-25
|
||||
Version: 0.1
|
||||
Licence: `GNU GPL v3`: http://www.gnu.org/licenses/
|
||||
"""
|
||||
|
||||
|
||||
class DictionnaireOrdonne:
|
||||
|
||||
"""
|
||||
|
||||
Dictionnaire ordonne
|
||||
====================
|
||||
|
||||
Notre dictionnaire ordonné. L'ordre des données est maintenu
|
||||
et il peut donc, contrairement aux dictionnaires usuels, être trié
|
||||
ou voir l'ordre de ses données inversées
|
||||
|
||||
|
||||
:Example:
|
||||
>>> fruits = DictionnaireOrdonne()
|
||||
>>> fruits
|
||||
{}
|
||||
|
||||
>>> fruits["pomme"] = 52
|
||||
>>> fruits["poire"] = 34
|
||||
>>> fruits["prune"] = 128
|
||||
>>> fruits["melon"] = 15
|
||||
>>> fruits
|
||||
{'pomme': 52, 'poire': 34, 'prune': 128, 'melon': 15}
|
||||
|
||||
>>> fruits.sort()
|
||||
>>> print(fruits)
|
||||
{'melon': 15, 'poire': 34, 'pomme': 52, 'prune': 128}
|
||||
|
||||
>>> legumes = DictionnaireOrdonne(carotte = 26, haricot = 48)
|
||||
|
||||
# Test possible seulement avec python 3.6,
|
||||
# voir: www.python.org/dev/peps/pep-0468/
|
||||
#>>> print(legumes)
|
||||
#{'carotte': 26, 'haricot': 48}
|
||||
|
||||
>>> len(legumes)
|
||||
2
|
||||
|
||||
>>> legumes.reverse()
|
||||
|
||||
>>> fruits = fruits + legumes
|
||||
>>> fruits
|
||||
{'melon': 15, 'poire': 34, 'pomme': 52, 'prune': 128, 'haricot': 48, 'carotte': 26}
|
||||
|
||||
>>> del fruits['haricot']
|
||||
|
||||
>>> 'haricot' in fruits
|
||||
False
|
||||
|
||||
>>> 'pomme' in fruits
|
||||
True
|
||||
|
||||
>>> legumes['haricot']
|
||||
48
|
||||
|
||||
>>> for cle in legumes:
|
||||
... print(cle)
|
||||
...
|
||||
haricot
|
||||
carotte
|
||||
|
||||
>>> fruits.keys()
|
||||
['melon', 'poire', 'pomme', 'prune', 'carotte']
|
||||
|
||||
>>> legumes.keys()
|
||||
['haricot', 'carotte']
|
||||
|
||||
>>> fruits.values()
|
||||
[15, 34, 52, 128, 26]
|
||||
|
||||
>>> legumes.values()
|
||||
[48, 26]
|
||||
|
||||
>>> for nom, qtt in legumes.items():
|
||||
... print("{0} ({1})".format(nom, qtt))
|
||||
...
|
||||
haricot (48)
|
||||
carotte (26)
|
||||
|
||||
>>> mots = {'olive': 51, 'identite': 43, 'mercredi': 25, 'prout': 218, 'assiette': 8, 'truc': 26}
|
||||
>>> mots_ordonne = DictionnaireOrdonne(mots)
|
||||
>>> mots_ordonne.sort()
|
||||
>>> mots_ordonne
|
||||
{'assiette': 8, 'identite': 43, 'mercredi': 25, 'olive': 51, 'prout': 218, 'truc': 26}
|
||||
"""
|
||||
|
||||
def __init__(self, base={}, **donnees):
|
||||
"""Constructeur de notre objet. Il peut ne prendre aucun paramètre
|
||||
(dans ce cas, le dictionnaire sera vide) ou construire un
|
||||
dictionnaire remplis grâce :
|
||||
- au dictionnaire 'base' passé en premier paramètre ;
|
||||
- aux valeurs que l'on retrouve dans 'donnees'."""
|
||||
|
||||
self._cles = [] # Liste contenant nos clés
|
||||
self._valeurs = [] # Liste contenant les valeurs correspondant à nos clés
|
||||
|
||||
# On vérifie que 'base' est un dictionnaire exploitable
|
||||
if type(base) not in (dict, DictionnaireOrdonne):
|
||||
raise TypeError( \
|
||||
"le type attendu est un dictionnaire (usuel ou ordonne)")
|
||||
|
||||
# On récupère les données de 'base'
|
||||
for cle in base:
|
||||
self[cle] = base[cle]
|
||||
|
||||
# On récupère les données de 'donnees'
|
||||
for cle in donnees:
|
||||
self[cle] = donnees[cle]
|
||||
|
||||
def __repr__(self):
|
||||
"""Représentation de notre objet. C'est cette chaîne qui sera affichée
|
||||
quand on saisit directement le dictionnaire dans l'interpréteur, ou en
|
||||
utilisant la fonction 'repr'"""
|
||||
|
||||
chaine = "{"
|
||||
premier_passage = True
|
||||
for cle, valeur in self.items():
|
||||
if not premier_passage:
|
||||
chaine += ", " # On ajoute la virgule comme séparateur
|
||||
else:
|
||||
premier_passage = False
|
||||
chaine += repr(cle) + ": " + repr(valeur)
|
||||
chaine += "}"
|
||||
return chaine
|
||||
|
||||
def __str__(self):
|
||||
"""Fonction appelée quand on souhaite afficher le dictionnaire grâce
|
||||
à la fonction 'print' ou le convertir en chaîne grâce au constructeur
|
||||
'str'. On redirige sur __repr__"""
|
||||
|
||||
return repr(self)
|
||||
|
||||
def __len__(self):
|
||||
"""Renvoie la taille du dictionnaire"""
|
||||
return len(self._cles)
|
||||
|
||||
def __contains__(self, cle):
|
||||
"""Renvoie True si la clé est dans la liste des clés, False sinon"""
|
||||
return cle in self._cles
|
||||
|
||||
def __getitem__(self, cle):
|
||||
"""Renvoie la valeur correspondant à la clé si elle existe, lève
|
||||
une exception KeyError sinon"""
|
||||
|
||||
if cle not in self._cles:
|
||||
raise KeyError( \
|
||||
"La clé {0} ne se trouve pas dans le dictionnaire".format( \
|
||||
cle))
|
||||
else:
|
||||
indice = self._cles.index(cle)
|
||||
return self._valeurs[indice]
|
||||
|
||||
def __setitem__(self, cle, valeur):
|
||||
"""Méthode spéciale appelée quand on cherche à modifier une clé
|
||||
présente dans le dictionnaire. Si la clé n'est pas présente, on l'ajoute
|
||||
à la fin du dictionnaire"""
|
||||
|
||||
if cle in self._cles:
|
||||
indice = self._cles.index(cle)
|
||||
self._valeurs[indice] = valeur
|
||||
else:
|
||||
self._cles.append(cle)
|
||||
self._valeurs.append(valeur)
|
||||
|
||||
def __delitem__(self, cle):
|
||||
"""Méthode appelée quand on souhaite supprimer une clé"""
|
||||
if cle not in self._cles:
|
||||
raise KeyError( \
|
||||
"La clé {0} ne se trouve pas dans le dictionnaire".format( \
|
||||
cle))
|
||||
else:
|
||||
indice = self._cles.index(cle)
|
||||
del self._cles[indice]
|
||||
del self._valeurs[indice]
|
||||
|
||||
def __iter__(self):
|
||||
"""Méthode de parcours de l'objet. On renvoie l'itérateur des clés"""
|
||||
return iter(self._cles)
|
||||
|
||||
def __add__(self, autre_objet):
|
||||
"""On renvoie un nouveau dictionnaire contenant les deux
|
||||
dictionnaires mis bout à bout (d'abord self puis autre_objet)"""
|
||||
|
||||
if type(autre_objet) is not type(self):
|
||||
raise TypeError( \
|
||||
"Impossible de concaténer {0} et {1}".format( \
|
||||
type(self), type(autre_objet)))
|
||||
else:
|
||||
nouveau = DictionnaireOrdonne()
|
||||
|
||||
# On commence par copier self dans le dictionnaire
|
||||
for cle, valeur in self.items():
|
||||
nouveau[cle] = valeur
|
||||
|
||||
# On copie ensuite autre_objet
|
||||
for cle, valeur in autre_objet.items():
|
||||
nouveau[cle] = valeur
|
||||
return nouveau
|
||||
|
||||
def items(self):
|
||||
"""Renvoie un générateur contenant les couples (cle, valeur)"""
|
||||
for i, cle in enumerate(self._cles):
|
||||
valeur = self._valeurs[i]
|
||||
yield (cle, valeur)
|
||||
|
||||
def keys(self):
|
||||
"""Cette méthode renvoie la liste des clés"""
|
||||
return list(self._cles)
|
||||
|
||||
def values(self):
|
||||
"""Cette méthode renvoie la liste des valeurs"""
|
||||
return list(self._valeurs)
|
||||
|
||||
def reverse(self):
|
||||
"""Inversion du dictionnaire"""
|
||||
# On crée deux listes vides qui contiendront le nouvel ordre des clés
|
||||
# et valeurs
|
||||
cles = []
|
||||
valeurs = []
|
||||
for cle, valeur in self.items():
|
||||
# On ajoute les clés et valeurs au début de la liste
|
||||
cles.insert(0, cle)
|
||||
valeurs.insert(0, valeur)
|
||||
# On met ensuite à jour nos listes
|
||||
self._cles = cles
|
||||
self._valeurs = valeurs
|
||||
|
||||
def sort(self):
|
||||
"""Méthode permettant de trier le dictionnaire en fonction de ses clés"""
|
||||
# On trie les clés
|
||||
cles_triees = sorted(self._cles)
|
||||
# On crée une liste de valeurs, encore vide
|
||||
valeurs = []
|
||||
# On parcourt ensuite la liste des clés triées
|
||||
for cle in cles_triees:
|
||||
valeur = self[cle]
|
||||
valeurs.append(valeur)
|
||||
# Enfin, on met à jour notre liste de clés et de valeurs
|
||||
self._cles = cles_triees
|
||||
self._valeurs = valeurs
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
""" Active les doctests """
|
||||
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: freezed <freezed@users.noreply.github.com> 2018-01-25
|
||||
Version: 0.1
|
||||
Licence: `GNU GPL v3`: http://www.gnu.org/licenses/
|
||||
"""
|
||||
|
||||
|
||||
class DictionnaireOrdonne:
|
||||
|
||||
"""
|
||||
Dictionnaire ordonne
|
||||
====================
|
||||
|
||||
Objet ressemblant a un dict, avec des capacitees de tri.
|
||||
|
||||
Les cles et valeurs se trouvant dans des listes de meme
|
||||
taille, il suffira de prendre l'indice dans une liste pour
|
||||
savoir quel objet lui correspond dans l'autre. Par exemple,
|
||||
la cle d'indice 0 est couplee avec la valeur d'indice 0.
|
||||
|
||||
:Example:
|
||||
>>> fruits = DictionnaireOrdonne()
|
||||
>>> fruits
|
||||
{}
|
||||
|
||||
>>> fruits["pomme"] = 52
|
||||
>>> fruits["poire"] = 34
|
||||
>>> fruits["prune"] = 128
|
||||
>>> fruits["melon"] = 15
|
||||
>>> fruits
|
||||
{'pomme': 52, 'poire': 34, 'prune': 128, 'melon': 15}
|
||||
|
||||
>>> fruits.sort()
|
||||
>>> print(fruits)
|
||||
{'melon': 15, 'poire': 34, 'pomme': 52, 'prune': 128}
|
||||
|
||||
>>> legumes = DictionnaireOrdonne(carotte = 26, haricot = 48)
|
||||
|
||||
# Test possible seulement avec python 3.6,
|
||||
# voir: www.python.org/dev/peps/pep-0468/
|
||||
#>>> print(legumes)
|
||||
#{'carotte': 26, 'haricot': 48}
|
||||
|
||||
>>> len(legumes)
|
||||
2
|
||||
|
||||
>>> legumes.reverse()
|
||||
|
||||
>>> fruits = fruits + legumes
|
||||
>>> fruits
|
||||
{'melon': 15, 'poire': 34, 'pomme': 52, 'prune': 128, 'haricot': 48, 'carotte': 26}
|
||||
|
||||
>>> del fruits['haricot']
|
||||
>>> del fruits['betterave']
|
||||
ValueError: «'betterave' is not in list»
|
||||
|
||||
>>> 'haricot' in fruits
|
||||
False
|
||||
|
||||
>>> 'pomme' in fruits
|
||||
True
|
||||
|
||||
>>> legumes['haricot']
|
||||
48
|
||||
>>> fruits['betterave']
|
||||
ValueError: «'betterave' is not in list»
|
||||
|
||||
>>> for cle in legumes:
|
||||
... print(cle)
|
||||
...
|
||||
haricot
|
||||
carotte
|
||||
|
||||
>>> fruits.keys()
|
||||
['melon', 'poire', 'pomme', 'prune', 'carotte']
|
||||
|
||||
>>> legumes.keys()
|
||||
['haricot', 'carotte']
|
||||
|
||||
>>> fruits.values()
|
||||
[15, 34, 52, 128, 26]
|
||||
|
||||
>>> legumes.values()
|
||||
[48, 26]
|
||||
|
||||
>>> for nom, qtt in legumes.items():
|
||||
... print("{0} ({1})".format(nom, qtt))
|
||||
...
|
||||
haricot (48)
|
||||
carotte (26)
|
||||
|
||||
>>> liste = [0,1,2,3]
|
||||
>>> tentative1 = DictionnaireOrdonne(liste)
|
||||
Un dict() est attendu en argument!
|
||||
|
||||
>>> dico_vide = {}
|
||||
>>> tentative2 = DictionnaireOrdonne(dico_vide)
|
||||
>>> tentative2
|
||||
{}
|
||||
|
||||
>>> mots = {'olive': 51, 'identite': 43, 'mercredi': 25, 'prout': 218, 'assiette': 8, 'truc': 26}
|
||||
>>> mots_ordonne = DictionnaireOrdonne(mots)
|
||||
>>> mots_ordonne.sort()
|
||||
>>> mots_ordonne
|
||||
{'assiette': 8, 'mercredi': 25, 'truc': 26, 'identite': 43, 'olive': 51, 'prout': 218}
|
||||
"""
|
||||
|
||||
def __init__(self, filled_dict={}, **kwargs):
|
||||
"""
|
||||
Peu prendre aucun parametre ou:
|
||||
- un dictionnaire 'filled_dict' en 1er argument
|
||||
- des valeurs nommees dans 'kwargs'
|
||||
"""
|
||||
# Creation des attributs qui stokeront les cles et valeurs
|
||||
self._keys_list = list()
|
||||
self._values_list = list()
|
||||
|
||||
# Si 'filled_dict' est un dict() non vide, ajout du contenu
|
||||
if type(filled_dict) not in (dict, DictionnaireOrdonne):
|
||||
#raise TypeError("Un dict() est attendu en argument!")
|
||||
print("Un dict() est attendu en argument!")
|
||||
else:
|
||||
for key, val in filled_dict.items():
|
||||
self._keys_list.append(key)
|
||||
self._values_list.append(val)
|
||||
|
||||
# Si les kwargs ne sont pas vide, ajout du contenu
|
||||
if len(kwargs) != 0:
|
||||
for key, val in kwargs.items():
|
||||
self._keys_list.append(key)
|
||||
self._values_list.append(val)
|
||||
|
||||
def __add__(self, other_dict_ord):
|
||||
"""
|
||||
On doit pouvoir ajouter deux dictionnaires ordonnes
|
||||
(dico1 + dico2) ; les cles et valeurs du second dictionnaire
|
||||
sont ajoutees au premier.
|
||||
"""
|
||||
i = 0
|
||||
while i < len(other_dict_ord):
|
||||
self._keys_list.append(other_dict_ord._keys_list[i])
|
||||
self._values_list.append(other_dict_ord._values_list[i])
|
||||
i += 1
|
||||
|
||||
return self
|
||||
|
||||
def __contains__(self, key_to_find):
|
||||
""" Cherche une cle dans notre objet (cle in dictionnaire) """
|
||||
return key_to_find in self._keys_list
|
||||
|
||||
def __delitem__(self, key_to_del):
|
||||
""" Acces avec crochets pour suppression (del objet[cle]) """
|
||||
try:
|
||||
index_to_del = self._keys_list.index(key_to_del)
|
||||
except ValueError as except_detail:
|
||||
print("ValueError: «{}»".format(except_detail))
|
||||
else:
|
||||
del self._keys_list[index_to_del]
|
||||
del self._values_list[index_to_del]
|
||||
|
||||
def __iter__(self):
|
||||
"""Parcours de l'objet, renvoi l'iterateur des cles"""
|
||||
return iter(self._keys_list)
|
||||
|
||||
def __getitem__(self, key_to_get):
|
||||
""" Acces aux crochets pour recuperer une valeur (objet[cle]) """
|
||||
try:
|
||||
find_key = self._keys_list.index(key_to_get)
|
||||
except ValueError as except_detail:
|
||||
print("ValueError: «{}»".format(except_detail))
|
||||
else:
|
||||
print(self._values_list[find_key])
|
||||
|
||||
def __len__(self):
|
||||
""" Retourne la taille de l'objet grace a la fonction len """
|
||||
return len(self._keys_list)
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Affiche l'objet dans l'interpreteur ou grâce a la fonction
|
||||
print: ({cle1: valeur1, cle2: valeur2, …}).
|
||||
"""
|
||||
# contiendra le txt a afficher
|
||||
object_repr = list()
|
||||
|
||||
# Si l'objet n'est pas vide
|
||||
if len(self._keys_list) != 0:
|
||||
for i in range(0, len(self._keys_list)):
|
||||
object_repr.append("'{}': {}".format(self._keys_list[i], self._values_list[i]))
|
||||
|
||||
return "{0}{1}{2}".format(
|
||||
"{",
|
||||
", ".join(object_repr),
|
||||
"}"
|
||||
)
|
||||
|
||||
def __setitem__(self, cle, valeur):
|
||||
"""
|
||||
Acces avec crochets pour modif (objet[cle] = valeur). Si la cle
|
||||
existe on ecrase l'ancienne valeur, sinon on ajoute le couple
|
||||
cle-valeur a la fin
|
||||
"""
|
||||
try:
|
||||
index = self._keys_list.index(cle)
|
||||
self._keys_list[index] = cle
|
||||
self._values_list[index] = valeur
|
||||
except ValueError:
|
||||
self._keys_list.append(cle)
|
||||
self._values_list.append(valeur)
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Methode pour afficher le dictionnaire avec «print()» ou pour
|
||||
le convertir en chaine grâce aec «str()». Redirige sur __repr__
|
||||
"""
|
||||
return repr(self)
|
||||
|
||||
def keys(self):
|
||||
"""
|
||||
La methode keys() (renvoyant la liste des cles) doit etre
|
||||
mises en œuvre. Le type de retour de ces methodes est laisse
|
||||
a votre initiative : il peut s'agir d'iterateurs ou de
|
||||
generateurs (tant qu'on peut les parcourir)
|
||||
"""
|
||||
return list(self._keys_list)
|
||||
|
||||
def sort(self, reverse=False):
|
||||
"""
|
||||
L'objet doit definir les methodes sort pour le trier et reverse
|
||||
pour l'inverser. Le tri de l'objet doit se faire en fonction
|
||||
des cles
|
||||
"""
|
||||
# Peut etre un peu overkill… voir methode dans la correction
|
||||
|
||||
# pour trier on stocke les couples de cle & valeur sous forme
|
||||
# de tuple dans une liste temporaire
|
||||
liste_temporaire = list()
|
||||
|
||||
if len(self._keys_list) != 0: # Seulement si il y a des donnees
|
||||
for i in range(0, len(self._keys_list)): # on parcour chaque entee
|
||||
liste_temporaire.append((self._keys_list[i], self._values_list[i]))
|
||||
|
||||
# Tri des tuples par la valeur par une comprension de liste
|
||||
liste_permute = [(val, cle) for cle, val in liste_temporaire]
|
||||
liste_triee = [(cle, val) for val, cle in sorted(liste_permute, reverse=reverse)]
|
||||
|
||||
# On range les donnees tries dans attributs de l'objet
|
||||
self._keys_list = [cle for cle, val in liste_triee]
|
||||
self._values_list = [val for cle, val in liste_triee]
|
||||
|
||||
def reverse(self):
|
||||
"""
|
||||
L'objet doit definir les methodes sort pour le trier et reverse
|
||||
pour l'inverser. Le tri de l'objet doit se faire en fonction
|
||||
des cles
|
||||
"""
|
||||
return self.sort(reverse=True)
|
||||
|
||||
def items(self):
|
||||
"""Renvoi un generateur contenant les couples (cle, valeur)"""
|
||||
for key, val in enumerate(self._keys_list):
|
||||
yield (val, self._values_list[key])
|
||||
|
||||
def values(self):
|
||||
"""
|
||||
La methode values() (renvoi la liste des valeurs) doit etre
|
||||
mises en œuvre. Le type de retour de ces methodes est laisse
|
||||
a votre initiative : il peut s'agir d'iterateurs ou de
|
||||
generateurs (tant qu'on peut les parcourir)
|
||||
"""
|
||||
return list(self._values_list)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
""" Active les doctests """
|
||||
|
||||
import doctest
|
||||
doctest.testmod()
|
Loading…
Reference in New Issue