#1 Le 20/04/2010, à 15:29
- Pork Pie Hat
[résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Salut à tous.
Bon, j'ai fini la lecture de l'ouvrage de Swaroop, A Byte of Python - et je tente de faire son exercice de fin.
Avant toute chose, je ne demande pas la solution toute faite, mais plutôt des conseils (sur la qualité du code (*s'étrangle*), ou du genre, "Là, tu te plantes gravement !!!") - car pour l'instant, mon programme marche une fois sur deux. Donc, il ne marche pas (il fonctionne correctement si j'entre une première valeur, mais si je décide de supprimer directement une valeur, ça plante).
Bref, j'oubliais de dire le sujet de son TP : créer un address-book (avec possibilité d'ajout, de modif, de recherche et de suppression).
Il conseille (même si nous ne devons pas le lire) d'utiliser une classe, les dictionnaires, etc...
Je vous livre mon code actuel :
#!/usr/bin/python3
# -*- coding:Utf-8 -*-
# nom de fichier : address_book.py
import sys
import pickle
#class Person():
# '''Représente une personne, avec nom, adresse mail, téléphone'''
#
# def __init__(self, name, email, phone):
# "Initialise les données."
# self.name = name
# self.email = email
# self.phone = phone
#
# def tell(self):
# "Donner des détails."
# print("Nom : {0} *** Email : {1} ***\
# Téléphone : {2}".format(self.name, self.email, self.phone))
#Création d'un dictionnaire
adr_book = dict()
#Création du fichier de stockage
adr_bookfile = 'address_book.data'
#Initialisation de la variable de boucle
running = True
#Affichage du Menu
print("*************************************")
print("* Address-book made by Pork Pie Hat *")
print("*************************************")
#Boucle du Programme
while running:
print("\nQue voulez-vous faire ?\n")
print("1. Ajouter un contact")
print("2. Modifier un contact")
print("3. Rechercher un contact")
print("4. Supprimer un contact")
print("5. Voir la liste des contacts")
print("6. Quitter")
#saisie du choix
rep = eval(input("\nChoix : "))
#Conditions
#Ajout d'un contact
if rep == 1:
print("\nAjout d'un contact")
n = input("Son nom : ")
e = input("Son email : ")
p = input("Son téléphone : ")
adr_book[n] = e,p
f = open(adr_bookfile, 'wb')
pickle.dump(adr_book, f)
f.close()
#Modifier un contact
elif rep == 2:
print("\nModification d'un contact")
mod = input("Quel contact voulez-vous modifier ? ")
adr_book[mod] = input("Nouvel email : "), input("Nouveau téléphone : ")
f = open(adr_bookfile, 'wb')
pickle.dump(adr_book, f)
f.close()
#Rechercher un contact
elif rep == 3:
f = open(adr_bookfile, 'rb')
storedab = pickle.load(f)
r = input("Son nom : ")
if r in storedab:
print(r,storedab[r])
else:
print("Absent")
f.close()
#Supprimer un contact
elif rep == 4:
f = open(adr_bookfile, 'wb')
print("\nSuppression d'un contact")
supp = input("Entrez le nom du contact à supprimer : ")
del adr_book[supp]
print(supp," a été supprimé(e)")
pickle.dump(adr_book, f)
f.close()
#Liste des contacts
elif rep == 5:
f = open(adr_bookfile, 'rb')
storedab = pickle.load(f)
print("\nIl y a {0} contacts dans l'address-book\n".format(len(storedab)))
for name, info in storedab.items():
print("Nom : {0} *** Email/Téléphone : {1}".format(name,info))
f.close()
#Quitter
else:
f.close()
sys.exit()
Je n'utilise pas la classe que j'ai créée, mais je la laisse comme exemple d'une idée. Je ne vois pas vraiment comment l'utiliser dans le cas des dictionnaires.
J'attends avec impatience vos critiques - et vous remercie d'avance.
Dernière modification par Pork Pie Hat (Le 22/04/2010, à 13:48)
Hors ligne
#2 Le 20/04/2010, à 16:18
- jde3
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Salut à toi,
Je ne suis pas expert de bonnes manières, mais je te dis juste ce que tout ça m'inspire.
Déjà, si tu veux utiliser les dictionnaires et ton objet Python, je pense que l'intérêt serait alors de faire en sorte que la clé utilisée pour ton dictionnaire soit forcément unique, même si deux personnes de ton annuaire ont le même nom. Du coup, la gestion des homonymes serait OK, reste plus qu'à choisir comment tu définis la clé.
Ensuite, pour ta classe Person, je pense que tu es sur la bonne piste. Si tu veux jouer les cadors, il est de coutume en Pyton de faire une méthode __str__ qui remplacerait ta classe tell (http://docs.python.org/reference/datamo … ct.__str__) avantageusement.
Enfin, pour faire plus propre, à ta place, j'aurais même une classe AddressBook et le code de ton programme ne ferait qu'appeler des méthodes de cette classe, selon le choix entré par l'utilisateur.
Dernière modification par jde3 (Le 20/04/2010, à 16:19)
Hors ligne
#3 Le 20/04/2010, à 16:24
- redo_fr
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Salut,
créer un objet facilite la manipulation de tes données.
Un exemple:
Tu crées un objet AddrBook
Tu lui ajoutes un dictionnaire pour stocker tes données
Tu ajoutes des méthodes pour accéder à ces données
class AddrBook:
"""Classe du carnet d'adresse"""
def __init__(self,addrFile):
""" Initialisation du carnet d'adresses"""
self.addrFile = addrFile
self.adresses = {}
self.chargeCarnet()
def ajoutPersonne(self):
""" Ajout d'une personne dans le carnet d'adresses"""
nom = raw_input('Nom: ')
prenom = raw_input('Prénom: ')
telephone = raw_input('Téléphone: ')
infos = (prenom,telephone)
self.adresses[nom] = infos
def chargeCarnet(self):
"""Charge le carnet d'adresse depuis le disque dur"""
f = open(self.addrFile., 'rb')
self.adresses = pickle.load(f)
f.close()
def sauveCarnet(self)
"""Sauve le carnet d'adresse sur le disque dur"""
f = open(self.addrFile,'wd')
pickle.dump(self.adresses,f)
f.close()
def recherchePersonne(self):
"""Recherche d'une personne dans le carnet d'adresses"
rec = raw_input('Nom: ')
if self.adresses.has_key(rec):
print 'prénom:', (self.adresses[rec][0],)
print 'Telephone: ', (self.adresses[rec][1],)
else:
print "Cette personne n'existe pas."
Tu initialises ton carnet avec
carnet = AddrBook('address_book.data')
Maintenant pour accéder à tes données, tu peux appeler les méthodes
par exemple
carnet.ajoutPersonne()
L'autre avantage est que tu peux créer plusieurs carnets distincts:
carnetPerso = AddrBook('address_book_perso.data')
carnetTravail = AddrBook('address_book_work.data')
et faire des manipulations indépendantes
carnetPerso.recherchePersonne()
carnetTravail.ajoutPersonne()
etc...
Dernière modification par redo_fr (Le 20/04/2010, à 16:25)
Il n'y a pas de mauvais outils, il n'y a que de mauvais ouvriers
- papy -
Personnellement, je crois que faire des procès est un signe que les affaires vont mal. Je ne dis pas que Microsoft va mal, ce n'est qu'un signe, pas un indicateur...
- Linus Torvalds -
Hors ligne
#4 Le 20/04/2010, à 22:25
- Pork Pie Hat
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Merci de ces réponses. Je vais me pencher dessus dès demain.
J'avais commencé le TP avec les classes, mais je trouvais une certaine redondance entre l'emploi d'une classe et celle d'un dictionnaire.
Je n'avais pas bien compris comment intégrer les deux.
Merci de ces éclaircissements.
Hors ligne
#5 Le 21/04/2010, à 10:07
- brulouni
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Les objets c'est comme les antibiotiques c'est pas automatique !
A ta place je testerai les deux implémentations : une avec objet, l'autre avec seulement des dictionnaires (deux a priori) et des fonctions.
Une ébauche possible avec juste des fonctions :
def loadAdressBook(adressBook, file_name):
pass
def saveAdressBook(adressBook, file_name):
pass
def createContact(name, phone, email):
contact = {'name': name, 'phone': phone, 'email': email}
return contact
def addContact(adressBook, contact)
adressBook.update(contact)
def main():
adressBook = dict()
ab_path = 'default.ab'
if len(sys.argv) > 1:
loadAdressBook(adressBook, sys.argv[1])
ab_path = sys.argv[1]
while True:
print("\nQue voulez-vous faire ?\n")
print("1. Ajouter un contact")
print("2. Sauver")
print("6. Quitter")
#saisie du choix
rep = input("\nChoix : "))
if rep == 1:
n = input("Son nom : ")
e = input("Son email : ")
p = input("Son téléphone : ")
addContact(adressBook, createContact(n, p, e))
elif rep == 2:
saveAdressBook(adressBook, ab_path)
elif rep == 6:
exit(0)
"Tout ce qui est simple est faux, tout ce qui est compliqué est inutile."
~ Paul Valery
Hors ligne
#6 Le 21/04/2010, à 12:49
- Pork Pie Hat
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Merci de votre aide.
Bon, je me suis replongé dans le code en m'inspirant de ce que vous m'avez dit.
Je cherche encore le moyen d'afficher proprement le contenu du dictionnaire.
(j'ai tenté le fameux __str__, ça marche, mais je ne suis pas satisfait pour l'heure du résultat).
En ce qui concerne le choix d'une classe, c'est uniquement à cause de l'intitulé du TP qui demandait d'en utiliser (ça m'exerce - mais je suis d'accord avec l'utilisation de fonctions à la place).
Voici le code actuel, qui est fonctionnel (en grande partie, je pense):
#!/usr/bin/python3
# -*- coding:Utf-8 -*-
import sys
import pickle
class AdrBook:
'''Classe du carnet d'adresse'''
def __init__(self, adbook):
'''initialisation du carnet d'adresse'''
self.adbook = adbook
self.adr_book = {}
def addPerson(self):
'''Ajout d'un contact'''
print("\nAjout d'un contact")
n = input("Son nom : ")
e = input("Son email : ")
t = input("Son téléphone : ")
self.adr_book[n] = e,t
self.saveAdBook()
def modPerson(self):
'''Modifier un contact'''
print("\nModification d'un contact")
mod = input("Quel contact voulez-vous modifier ? ")
self.adr_book[mod] = input("Nouvel email : "), input("Nouveau Téléphone : ")
self.saveAdBook()
def rechPerson(self):
'''Rechercher un contact'''
print("\nRecherche d'un contact")
self.loadAdBook()
rech = input("Son nom : ")
if rech in self.adr_book:
print("Nom : ",rech," *** Email : ",self.adr_book[rech][0],\
" *** Téléphone : ",self.adr_book[rech][1])
else:
print("Contact inexistant.")
def suppPerson(self):
'''Suppression d'un contact'''
self.loadAdBook()
print("\nSuppression d'un contact")
supp = input("Entrez le nom du contact à supprimer : ")
del self.adr_book[supp]
print(supp," a été supprimé(e) du carnet.")
self.saveAdBook()
def affAdrBook(self):
'''Afficher le carnet d'adresse'''
try:
self.loadAdBook()
print("\nIl y a {0} contact(s) dans le carnet\n".format(len(self.adr_book)))
for name, info in self.adr_book.items():
print("Nom : {0} *** Email/Téléphone : {1}".format(name,info))
except IOError:
print("Votre carnet n'est pas encore créé.")
print("Veuillez ajouter un contact pour le créer.")
def loadAdBook(self):
'''Charge le carnet d'adresse'''
file = open(self.adbook, 'rb')
self.adr_book = pickle.load(file)
file.close()
def saveAdBook(self):
'''Sauve le carnet d'adresse'''
file = open(self.adbook, 'wb')
pickle.dump(self.adr_book, file)
file.close()
def eraseAdBook(self):
'''Suppression de la totalité des contacts'''
self.loadAdBook()
print("\nSuppression de la totalité des contacts.")
a = input("Prêt(e)? O/N : ")
if a == 'O':
self.adr_book.clear()
print("Le carnet a été effacé.")
self.saveAdBook()
#####################
#Programme Principal#
#####################
#Création du carnet d'adresses
carnet = AdrBook('adbook.data')
#Initialisation de la variable de boucle
running = True
#Affichage du Menu
print("*************************************")
print("* Address-book made by Pork Pie Hat *")
print("*************************************")
#Boucle du Programme
while running:
print("\nQue voulez-vous faire ?\n")
print("1. Ajouter un contact")
print("2. Modifier un contact")
print("3. Rechercher un contact")
print("4. Supprimer un contact")
print("5. Voir la liste des contacts")
print("6. Effacer l'ensemble des contacts")
print("7. Quitter")
#saisie du choix
rep = eval(input("\nChoix : "))
#Conditions
#Ajout d'un contact
if rep == 1:
carnet.addPerson()
#Modifier un contact
elif rep == 2:
carnet.modPerson()
#Rechercher un contact
elif rep == 3:
carnet.rechPerson()
#Supprimer un contact
elif rep == 4:
carnet.suppPerson()
#Liste des contacts
elif rep == 5:
carnet.affAdrBook()
elif rep == 6:
carnet.eraseAdBook()
#Quitter
else:
sys.exit()
Merci de vos critiques (à ce soir ^^).
Dernière modification par Pork Pie Hat (Le 21/04/2010, à 20:46)
Hors ligne
#7 Le 21/04/2010, à 21:02
- Pork Pie Hat
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Je coince un peu.
Comment pourrais-je avoir le même affichage avec la fonction def affAdrBook(self) que celle que j'obtiens avec la fonction def rechPerson(self)?
def affAdrBook(self):
'''Afficher le carnet d'adresse'''
try:
self.loadAdBook()
print("\nIl y a {0} contact(s) dans le carnet\n".format(len(self.adr_book)))
for name, info in self.adr_book.items():
print("Nom : {0} *** Email/Téléphone : {1}".format(name,info))
except IOError:
print("Votre carnet n'est pas encore créé.")
print("Veuillez ajouter un contact pour le créer.")
def rechPerson(self):
'''Rechercher un contact'''
print("\nRecherche d'un contact")
self.loadAdBook()
rech = input("Son nom : ")
if rech in self.adr_book:
print("Nom : ",rech," *** Email : ",self.adr_book[rech][0],\
" *** Téléphone : ",self.adr_book[rech][1])
else:
print("Contact inexistant.")
Je ne trouve pas le moyen de "scinder" les éléments dans l'affichage de l'ensemble du carnet d'adresses.
Hors ligne
#8 Le 22/04/2010, à 09:13
- jde3
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
info est un tuple à deux éléments, tu peux donc y accéder tout naturellement :
print("Nom : " + name + " *** Email : " + info[0] + " *** Téléphone : " + info[1])
Sinon, tant qu'on y est, je te conseille de lire ça :http://docs.python.org/library/functions.html#input. Tout ça pour dire que ton code ne marche pas chez moi (version de python sûrement) alors qu'en remplaçant tes input par des raw_input, ça roule.
Dernière modification par jde3 (Le 22/04/2010, à 09:14)
Hors ligne
#9 Le 22/04/2010, à 09:36
- Pork Pie Hat
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Merci beaucoup.
C'était tellement évident... J'étais parti chercher midi à quatorze heures...
Cela marche nickel.
Il ne me reste plus maintenant qu'à fignoler le tout, gérer les exceptions possibles et suivre ton idée (@jde3) sur la gestion des homonymes.
En ce qui concerne l'incompatibilité du programme, c'est en effet à cause de la version de Python.
J'ai codé en python3.1 - et une des nouveautés du 3, c'est la refonte de l'input() qui traite directement en str.
Et comme je ne souhaite manipuler que des chaînes de caractères - sauf pour le choix du menu : avec eval(input()).
Dernière modification par Pork Pie Hat (Le 22/04/2010, à 09:37)
Hors ligne
#10 Le 22/04/2010, à 13:47
- Pork Pie Hat
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Voilà la forme finale de mon code concernant ce TP.
Peut-être y apporterai-je quelques améliorations plus tard lorsque je saurai comment améliorer ^^.
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# nom de fichier : address_book.py
__author__="Pork Pie Hat"
__date__ ="23 avr. 2010"
#Importation des modules
import sys
import pickle
#Création de la classe nécessaire
class AdrBook:
'''Classe du carnet d'adresse'''
def __init__(self, adbook):
'''initialisation du carnet d'adresse'''
self.adbook = adbook
self.adr_book = {}
def addPerson(self):
'''Ajout d'un contact'''
print("\nAjout d'un contact")
try :
self.loadAdBook()
n = input("Son nom et prénom\
(Attention : programme sensible à la casse): ")
if n in self.adr_book:
print("Ce contact existe déjà.")
print("Voulez-vous le modifier ou est-ce un contact homonyme ?")
print("Conseil : donnez une clé unique pour chaque contact")
else:
e = input("Son email : ")
t = input("Son téléphone : ")
self.adr_book[n] = e,t
self.saveAdBook()
except IOError:
'''Carnet non créé : vérification impossible'''
n = input("Son nom et prénom\
(Attention : programme sensible à la casse): ")
e = input("Son email : ")
t = input("Son téléphone : ")
self.adr_book[n] = e,t
self.saveAdBook()
def modPerson(self):
'''Modifier un contact'''
print("\nModification d'un contact")
self.loadAdBook()
print("Quel contact voulez-vous modifier ? ")
mod = input("Entrez son nom et son prénom\
(Attention : programme sensible à la casse): ")
if mod in self.adr_book:
self.adr_book[mod] = input("Nouvel email : "),\
input("Nouveau Téléphone : ")
self.saveAdBook()
else:
print("Contact inexistant - ou erreur de saisie.")
def rechPerson(self):
'''Rechercher un contact'''
print("\nRecherche d'un contact")
self.loadAdBook()
rech = input("Son nom et prénom : ")
if rech in self.adr_book:
print("Nom : ",rech," *** Email : ", self.adr_book[rech][0],\
" *** Téléphone : ", self.adr_book[rech][1])
else:
print("Contact inexistant - ou erreur de saisie.")
def suppPerson(self):
'''Suppression d'un contact'''
try:
self.loadAdBook()
print("\nSuppression d'un contact")
supp = input("Entrez le nom et le prénom du contact à supprimer : ")
del self.adr_book[supp]
print(supp," a été supprimé(e) du carnet.")
self.saveAdBook()
except KeyError:
print("Veuillez saisir correctement le nom et prénom(s) du contact à supprimer.")
def affAdrBook(self):
'''Afficher le carnet d'adresse'''
try:
self.loadAdBook()
print("\nIl y a {0} contact(s) dans le carnet\n".format(len(self.adr_book)))
for name, info in self.adr_book.items():
print("Nom : ", name, " *** Email : ",\
info[0], " *** Téléphone : ", info[1])
except IOError:
print("Votre carnet n'est pas encore créé.")
print("Veuillez ajouter un contact pour le créer.")
def loadAdBook(self):
'''Charge le carnet d'adresse'''
file = open(self.adbook, 'rb')
self.adr_book = pickle.load(file)
file.close()
def saveAdBook(self):
'''Sauve le carnet d'adresse'''
file = open(self.adbook, 'wb')
pickle.dump(self.adr_book, file)
file.close()
def eraseAdBook(self):
'''Suppression de la totalité des contacts'''
try:
self.loadAdBook()
print("\nSuppression de la totalité des contacts.")
print("\nIl y a {0} contact(s) dans le carnet\n".format(len(self.adr_book)))
a = input("Prêt(e)? Toute réponse autre que 'oui' annule l'opération : ")
if a == 'oui':
self.adr_book.clear()
print("Le carnet a été effacé.")
self.saveAdBook()
else:
print("Opération annulée.")
except IOError:
print("Il n'y a pas encore de carnet à effacer (carnet inexistant).")
#####################
#Programme Principal#
#####################
#Versions du programme
__version__='1.0.1' #Ajout d'une exception IOError lors de l'ajout d'un contact
#__version__='1.0' #Programme fonctionnel en mode console
#Vérification de la version Python, amélioration de l'affichage
#__version__='0.4' #Gestion des exceptions
#__version__='0.3' #Possibilité de supprimer l'ensemble des contacts
#__version__='0.2' #Création de la classe AdrBook à l'instar du dictionnaire
#__version__='0.1' #Address_book sous forme de dictionnaire
#Vérification de la version Python
if sys.version_info[0] < 3:
sys.exit("Une version de Python 3.0 (au minimum) est requise pour ce programme.")
#Création du carnet d'adresses
carnet = AdrBook('adbook.data')
#Initialisation de la variable de boucle
running = True
#Affichage du Menu
print("*************************************")
print("* Simple Address-book *")
print("*************************************")
print("Version : ",__version__)
print("Auteur : {0} - Date de création : {1}".format(__author__,__date__))
#Boucle du Programme
while running:
print("\nQue voulez-vous faire ?\n")
print("1. Ajouter un contact")
print("2. Modifier un contact")
print("3. Rechercher un contact")
print("4. Supprimer un contact")
print("5. Voir la liste des contacts")
print("6. Effacer l'ensemble des contacts")
print("7. Quitter")
try:
#saisie du choix
rep = eval(input("\nChoix : "))
#Conditions
#Ajout d'un contact
if rep == 1:
carnet.addPerson()
#Modifier un contact
elif rep == 2:
carnet.modPerson()
#Rechercher un contact
elif rep == 3:
carnet.rechPerson()
#Supprimer un contact
elif rep == 4:
carnet.suppPerson()
#Liste des contacts
elif rep == 5:
carnet.affAdrBook()
#Effacer l'ensemble du carnet
elif rep == 6:
carnet.eraseAdBook()
#Quitter
elif rep == 7:
sys.exit()
#Clause petit malin
else :
print("Veuillez entrer un choix valide")
except NameError:
print("Veuillez entrer un choix valide.")
continue
except SyntaxError:
print("Veuillez entrer un choix valide.")
continue
except EOFError:
print("\nVeuillez entrer 7 comme choix pour quitter le programme.")
continue
except KeyboardInterrupt:
print("\nVeuillez entrer 7 comme choix pour quitter le programme.")
continue
Merci de m'avoir aidé, aiguillé, conseillé.
A bientôt.
PS : s'il y a des choses encore à dire, n'hésitez pas hein ^^
Dernière modification par Pork Pie Hat (Le 23/04/2010, à 11:23)
Hors ligne
#11 Le 18/12/2013, à 09:21
- haffoudhi
Re : [résolu] - [python]Conseils pour un TP (cf. A Byte of Python)
Voulez vous donner le fichier que vous avez travaille car j'arrive pas à tester le programme.merci
Hors ligne