En effet ta solution est claire et modulable, contrairement à la mienne qui était plutôt archaïque..
Je ferais d'autres tests afin de voir plusieurs solutions possibles et de les comparer. Je vais aussi chercher d'autres exos sur la POO, celui-là était bien intéressant et formateur
# POO qui permet de gérer une pharmacie
################## CLASSES DU PROGRAMME QUI GÈRE LA PHARMACIE #################
class Pharmacie(object):
def __init__(self):
"""attributs de la classe Pharmacie() qui gère les clients et les
médicaments; les 4 dernières variables sont utilisés dans les
méthodes achat(), approvisionnement() et affichage()"""
self.client = Client()
self.medicament = Medicament()
self.clt = None
self.med = None
self.qte = None
self.money = None
def achat(self):
"""traiter un achat fait par un client. l'achat porte sur un
médicament donné dans une quantité donnée. Pour cette transaction le
client paie un certain prix. Une opération d'achat aura pour effet de
déduire la quantité achetée du stock du médicaments correspondant et
d'augmenter le crédit du client (d'un montant équivalent au montant
de l'achat moins la somme payée). Les noms du client et du médicament
sont lus depuis le terminal. Le programme boucle jusqu'à
introduction de noms connus aussi bien pour les clients que
les médicaments. Ces procédures de vérification sont prises en
charge par les méthodes lire_client() et lire_medicament()"""
self.clt = self.client.lire_client()
self.med = self.medicament.lire_medicament()
self.qte = self.medicament.stock_medicament()
while True:
try:
self.money = int(input("Combien payez-vous? "))
break
except ValueError:
print("Veuillez entrer un nombre!")
for k, v in self.medicament.identite_stock.items():
if self.med == k:
self.medicament.identite_stock[self.med] = v - self.qte
for k, v in self.client.compte.items():
if self.clt == k:
self.client.compte[self.clt] = v - self.money
def approvisionnement(self):
"""approvisionner le stock d'un médicament. Le nom du médicament à
approvisionner ainsi que la quantité à ajouter au stock sont lus
depuis le terminal. Lorsque le nom du médicament est introduit,
on vérifie s'il s'agit bien d'un nom connu dans la liste des
médicaments de la pharmacie. Le programme boucle jusqu'à
introduction d'un nom correct. Cette procédure de vérification est
prise en charge par la méthode lire_medicament()"""
self.med = self.medicament.lire_medicament()
self.qte = self.medicament.stock_medicament()
for k, v in self.medicament.identite_stock.items():
if self.med == k:
self.medicament.identite_stock[self.med] = v + self.qte
def affichage(self):
"""afficher les clients et leurs crédits respectifs ainsi
que les médicaments et leurs stocks respectifs"""
self.client.afficher_compte()
self.medicament.afficher_stock()
def quitter(self):
"""fin du programme"""
print("Programme terminé!")
class Client(object):
def __init__(self):
"""dictionnaire qui regroupe les clients et leurs credits respectifs"""
self.compte = {"bapetel": 200, "nasser": 300}
"""variables qui seront utilisés dans les méthodes de notre classe"""
self.nom = None
self.quantite = None
self.identite = None
def lire_client(self):
"""lire le nom du client depuis le terminal; la boucle se ferme
si et seulement si le nom du client est connu"""
while True:
self.nom = input("Entrez votre nom: ")
for k, v in self.compte.items():
if self.nom == k:
return self.nom
def afficher_compte(self):
"""afficher les clients et leurs credits respectifs"""
print("Clients et leurs crédits respectifs")
for k,v in self.compte.items():
print("{:<15}{:>15}".format(k, v))
class Medicament(object):
def __init__(self):
"""dictionnaire qui regroupe les médicaments et leurs stocks"""
self.identite_stock = {"aspirine": 50, "paracetamol": 60}
def stock_medicament(self):
"""lire le stock de médicament depuis le terminal; la boucle se ferme
si et seulement si le stock est un nombre entier"""
while True:
try:
self.quantite = int(input("Entrez la quantité : "))
break
except ValueError:
print("Veuillez entrez un nombre entier!")
return self.quantite
def lire_medicament(self):
"""lire le nom du médicament depuis le terminal; la boucle se ferme
si et seulement si le nom du médicament est connu"""
while True:
self.identite = input("Entrez le nom du médicament: ")
for k, v in self.identite_stock.items():
if self.identite == k:
return self.identite
def afficher_stock(self):
"""afficher les clients et leurs credits respectifs """
print("\nMédicaments et leurs stocks respectifs")
for k, v in self.identite_stock.items():
print("{:<15}{:>15}".format(k, v))
##################### PROGRAMME PRINCIPAL #####################################
p = Pharmacie()
# lire le choix depuis le terminal; la boucle se ferme
# si et seulement si le choix est un nombre entier
# compris entre 1 et 4
while True:
try:
choix = int(input("""\nQue voulez-vous faire?
1- Achat de médicament
2- Approvisionnement en médicament
3- Afficher l'état des stocks et des crédits
4- Quitter
"""))
if choix in range(1,5):
if choix == 1:
p.achat()
elif choix == 2:
p.approvisionnement()
elif choix == 3:
p.affichage()
elif choix == 4:
p.quitter()
break
except ValueError:
print("Veuillez choisir un nombre entre 1 et 4")
Ouf, c'est déjà plus lisible ! Es-tu sur que le code que tu as posté soit OK ? J'ai plusieurs erreurs de syntaxe (mauvaises indentations) et après correction, à l'exécution, il boucle sur 'Enter un nom" dans le choix 1 (achat) ...
Sur le fond, il me semble y avoir pas mal de confusion sur les classes et l'utilisation des variables associées.
Je m'explique sur l'exemple de la gestion des comptes clients (variable 'compte' dans ton code). Pour moi, cette base de données est associée à la pharmacie (et non à un client puisqu'elle contient plusieurs clients), ce qui traduit en Python veut dire que 'compte' doit être créé dans la classe Pharmacie (et pas dans la classe Client !).
Question subsidiaire : 'compte' dans Pharmacie, mais variable de classe ou variable d'instance (pour la différence entre les deux si c'est pas clair, voir un message ci-dessus) ? Ca dépend ! Si je suppose que je gère plusieurs pharmacies (facile avec la classe Pharmacie), la question devient : est-ce que je gère une base comptes clients commune (gestion type centralisée) ou une base pour chaque pharmacie (gestion décentralisée). Dans le premier cas, il me faut une variable de classe :
class Pharmacie :
compte = {'toto' : 100, ....}
def __init__(self):
....
Dans le deuxième cas, il me faut une variable d'instance :
class Pharmacie :
def __init__(self):
self.compte = {'toto' : 100, ....}
....
et chaque pharmacie aura sa propre base 'compte'
Remarque : du coup, on s'aperçoit que dans le cadre simplifié de l'exo, la classe Client devient inutile (elle serait utile si on gardait d'autres infos sur le client : adresse, téléphone etc).
Même type d'analyse pour la gestion des stocks. Tu peux voir le code de Ungoliat si c'est pas clair.
D'abord, je te remercie pour toutes tes remarques.
Vous vous rendez directement compte que je ne suis qu'un débutant, mais ce code fonctionne très bien chez moi. Sinon, je comprend pas pourquoi il y'a des erreurs de syntaxe. Je vais voir le code de Ungoliat pour mieux comprendre!
Bon c'est peut-être trop tard mais je poste ma solution. Je me suis mis au Python il y a une semaine environ et a la méthode objet. J'ai jamais fait d'objet après 10 ans d'informatique donc c'est pas évident de changer de manière de penser.
Je me demandais s'il était possible de faire des classes clients et medicaments qui héritent de la classe pharmacie. Je suis pas parti là dessus n'ayant pas trouvé de solution. A moins que ça ne soit pas réalisable.
class Client:
def __init__(self, nom, credit):
self.nom = nom
self.credit = credit
def affichage(self):
print("Credit du client {} : {}".format(self.nom, self.credit))
def approvisionnement(self, credit):
self.credit += credit
class Medicament:
def __init__(self, nom, prix, stock):
self.nom = nom
self.prix = prix
self.stock = stock
def affichage(self):
print("Stock du medicament {} : {}".format(self.nom, self.stock))
def approvisionnement(self, stock):
self.stock += stock
class Pharmacie:
def __init__(self, clients, medicaments):
self.medicaments = medicaments
self.clients = clients
def __lireClient(self):
trouve = False
while not trouve:
client = input("Nom du client? ")
for unclient in self.clients:
if unclient.nom == client:
trouve = True
break
if not trouve:
print("Client n'existe pas")
return unclient
def __lireMedicament(self):
trouve = False
while not trouve:
medicament = input("Nom du médicament? ")
for unmedicament in self.medicaments:
if unmedicament.nom == medicament:
trouve = True
break
if not trouve:
print("Medicament n'existe pas")
return unmedicament
def achat(self):
unclient = self.__lireClient()
unmedicament = self.__lireMedicament()
paiement = -1
while paiement == -1:
paiement = input("Quel le montant du paiement? ")
try:
paiement = int(paiement)
assert paiement >= 0
except ValueError:
print("Rentrer un montant valide")
except AssertionError:
print("Rentrer un montant positif")
paiement = -1
quantite = -1
while quantite == -1:
quantite = input("Quel est la quantité souhaité? ")
try:
quantite = int(quantite)
assert quantite >= 0
except AssertionError:
print("Rentrer une quantité positive")
quantite = -1
except ValueError:
print("Rentrer une quantité valide")
unmedicament.stock -= quantite
unclient.credit = unmedicament.prix * quantite - paiement
def approvisionnement(self):
unmedicament = self.__lireMedicament()
quantite = -1
while quantite == -1:
quantite = input("Donner la quantité? ")
try:
quantite = int(quantite)
assert quantite >= 0
except AssertionError:
print("Rentrer une quantité positive")
quantite = -1
except ValueError:
print("Rentrer une quantité valide")
unmedicament.stock += quantite
def affichage(self):
for elt in self.clients:
elt.affichage()
for elt in self.medicaments:
elt.affichage()
def quitter():
print("Programme terminé!")
exit(0)
def menu():
print("""1 : Achat de medicament
2 : Approvisionnement en medicaments
3 : Etats des stocks et des credits
4 : Quitter""")
while True:
try:
choix = int(input("Entrez votre choix: "))
if choix in range(1, 5):
break
except ValueError:
continue
return choix
Malfichu = Client("Malfichu",0.0)
Palichon = Client("Palichon",0.0)
Aspiron = Medicament("Aspiron", 20.40, 5)
Rhinoplexil = Medicament("Rhinoplexil", 19.15, 5)
clients = [Malfichu, Palichon]
medicaments = [Aspiron, Rhinoplexil]
pharma = Pharmacie(clients,medicaments)
while True:
choix = menu()
if choix == 1:
pharma.achat()
elif choix == 2:
pharma.approvisionnement()
elif choix == 3:
pharma.affichage()
elif choix == 4:
quitter()
else:
break
bon jour mes amis c'est mon premiers programme en python j'ai jamais travail avec python ou bien Poo juste si il y'a des remarque si vous plaît donné les . mon programme c'est tree débutant par ce que j'ai connais pas la Poo jusqu’à maintenant je commence a lire un peut de Poo
class Client:
def __init__(self,n,c):
self.nom=n
self.credit=c
def affichage(self,client):
print " le nom de client {} a un credit {}".format(self,client.nom,client.credit)
Après lecture (très) rapide, voici déjà quelques remarques :
Dans les méthodes affichage de tes deux classes, il n'y a aucune raison d'avoir un paramètre client/medicament. tu peux directement renvoyer les valeurs attendues grâce à self:
def affichage(self):
print "{} a un credit de {}€".format(self.nom, self.credit)
Ligne 7 à 9: À quoi sert la classe menu?
Ligne 12, 32, 33: tu appelles les fonctions mais tu ne récupères pas les valeurs. Ça ne sert donc à rien et ça force l'utilisateur à entrer deux fois les mêmes informations (ligne 14, 37, 38)
Ligne 13: À aucun moment tu ne fais la conversion de nvcontite en entier. Donc il y aura sûrement une erreur en ligne 15
Ligne 55: Il faut utiliser raw_input plutôt qu'input
Concernant des remarques de style/syntaxe:
Ligne 3 et 4: Il vaut mieux renommer tes fichiers en client.py et medicament.py car les majuscules sont réservées aux classes:
from client import Client
from medicament import Medicament
Ligne 3 et 4: De mon point de vue, il serait plus simple d'avoir un seul fichier pour l'ensemble des classes (pour cet exercice):
from cls_pharmacie import Client, Medicament
On ne met pas de majuscule dans le nom des fonctions/méthodes (oui je sais c'est l'énoncé mais au final ce n'est pas la bonne syntaxe):
Ce sujet est ancien, mais épinglé du coup voici mon code en trois fichiers:
pharmacie, variables, et... objets
"""Pharmacie ou programme principal"""
from objets import *
from variables import *
clear()
med=Medicament(1,2,3)
cli=Client(1)
while entree !="4":
clear()
entree = str()
print(' Menu principal \n 1-Etat des sotcks et crédits \n 2-Approvisionnement\
\n 3-Commercer \n 4-Quitter')
while entree != "1" and entree != "2" and entree != "3" and entree != "4":
print("Faites votre choix :")
entree = input()
if entree == "1":
clear()
med.affichage()
cli.affichage()
pause()# lambda qui fait pause en passant par le system os
if entree == "2":
clear()
a=med.lire_medicament()
med.approvisionnement(a)
if entree == "3":
clear()
a=cli.lire_client()
b=med.lire_medicament()
cli.achat(a,b)
pause()
Voic
from objets import *
entree=str()
lire_client=["Monsieur Latoue","Madame Lagoutoné", "Monsieur Palichon",\
"Mademoiselle Malorin", "Monsieur Malodeau"]
liste_clients=list()
i=0
while i !=5:
liste_clients.append(Client(lire_client[i]))
i +=1
i=0
while i !=5:
lire_client.append(liste_clients[i].nom)
i += 1
lire_medicament=list()
liste_de_medicaments=["Placebal", "Taplumal", "Truknazal", "Miracol", "Samarchol"]
liste_de_medicaments[0]=Medicament("Placebal",0,1.5)
liste_de_medicaments[1]=Medicament("Taplumal",0,2.5)
liste_de_medicaments[2]=Medicament("Truknazal",0,3)
liste_de_medicaments[3]=Medicament("Miracol",0,5)
liste_de_medicaments[4]=Medicament("Samarchol",0,15)
i=0
while i != 5:
lire_medicament.append(liste_de_medicaments[i].nom)
i += 1
i variables (en faite les listes)
Et bien sûr objets:
import os
clear = lambda: os.system('cls')# n'est-ce pas pratique une lambda? XD
pause = lambda: os.system('pause')# même chose qu'au dessus
class Client:
"""classe servant à définir les clients de la pharmacie.
ils seront caractérisés par:
-un nom.
-une ligne de crédit."""
def __init__(self,nom):
"""ici on définit les attributs du client"""
self.nom = nom
self.credit = 0
def affichage(self):
"""méthode servant à afficher:
les noms et crédits des clients"""
from variables import liste_clients
print('crédits des clients \n client {0} : {1}\
\n client {2} : {3} \n client {4} : {5} \
\n client {6} : {7} \n client {8} : {9} '\
.format(liste_clients[0].nom, liste_clients[0].credit,\
liste_clients[1].nom, liste_clients[1].credit,\
liste_clients[2].nom, liste_clients[2].credit,\
liste_clients[3].nom, liste_clients[3].credit,\
liste_clients[4].nom, liste_clients[4].credit))
def lire_client(self):
"""méthode servant à reconnaitre un client...
...entré par l'utilisateur depuis la liste...
de clients. La méthode bouclera temps que le...
client rentré n'est pas reconnu"""
clear()
from variables import liste_clients
entree = str()
while entree != liste_clients[0].nom and entree != liste_clients[1].nom and \
entree != liste_clients[2].nom and entree != liste_clients[3].nom and \
entree != liste_clients[4].nom:
print("Quel client allez vous servir?")
entree=input()
return entree
def achat(self, nom, med):
"""Méthode permetant de traiter l'achat d'un client
Le crédit du client correspond à la quantité acquise
multipliée par le prix du médicament moins la somme payée.
un crédit positif correspond à un client qui doit de l'argent;
un crédit négatif correspond à un trop perçu de la part de la pharmacie
"""
self.nom=nom
self.med=med
quantite=-1
montant=-1
from variables import lire_medicament, liste_clients,\
liste_de_medicaments, lire_client#importation des listes utiles
#ici on trouve quel medicament à quel indice
for posmed, nommed in enumerate(lire_medicament):
if self.med == nommed:
break#quand on trouve on s'arrête gardant l'indice dans "posmed"
#ici on trouve quel client à quel indice
for poscli, nomcli in enumerate(lire_client):
if self.nom == nomcli:
break#quand on trouve on s'arrête gardant l'indice dans "poscli"
#a partir d'ici les indices découverts deviennent utiles:
while quantite < 0 or quantite > liste_de_medicaments[posmed].stock:
print("Entrez une quantité:")
quantite=input()
try:
quantite=int(quantite)
except Exception as ValueError:
print("SVP saisissez une valeur correcte")
quantite = -1
continue
while montant < 0:
print("Saisissez un montant:")
montant=input()
try:
montant=float(montant)
except Exception as ValueError:
montant = -1
continue
liste_de_medicaments[posmed].stock -= quantite
liste_clients[poscli].credit-=montant-(quantite*liste_de_medicaments[posmed].prix)
pause()
class Medicament:
"""Voici l'objet médicament qui comporte se caractérise par:
-un nom
-un stock (nombre entier)
-un prix."""
def __init__(self, nom, stock, prix):
self.nom = nom
self.stock=stock
self.prix=prix
def affichage(self):
"""méthode servant à écrire:
les noms et stocks de chaque médicament"""
from variables import liste_de_medicaments
print('Stoques de médicaments: \n {0} : {1} \
\n {2} : {3} \n {4} : {5} \n {6} : {7} \n {8} : {9} '\
.format(liste_de_medicaments[0].nom, liste_de_medicaments[0].stock,\
liste_de_medicaments[1].nom, liste_de_medicaments[1].stock,\
liste_de_medicaments[2].nom, liste_de_medicaments[2].stock,\
liste_de_medicaments[3].nom, liste_de_medicaments[3].stock,\
liste_de_medicaments[4].nom, liste_de_medicaments[4].stock))
def approvisionnement(self,entree):
"""méthode servant à approvisionner la pharmacie en médicaments.
elle permet d'afficher les nom des médicaments
l'état de leurs stock
d'entrer un nom de médicament
de vérifier qu'il existe bien
et s'il exite d'augmenter le stock"""
from variables import liste_de_medicaments
self.entree=entree
quantite = -1
while quantite <= 0:
print("saisissez une quantité :")
quantite=input()
try:
quantite=int(quantite)
except Exception as ValueError:
print("Il faut insérer un chiffre supérieur à 0 !")
quantite= -1
continue
for posmed, nommed in enumerate(lire_medicament):
if self.entree == nommed:
brek
liste_de_medicaments[posmed].stock += quantite
def lire_medicament(self):
"""méthode servant à vérifier si un medicament...
...entré par l'utilisateur existe bel et bien...
cette méthode bouclera temps que le nom n'est pas...
reconnu depuis la liste des noms de médicaments."""
from variables import liste_de_medicaments
entree=str()
print("Entrez un nom de médicament : ")
entree=input()
while entree != liste_de_medicaments[0].nom and\
entree != liste_de_medicaments[1].nom and\
entree != liste_de_medicaments[2].nom and\
entree != liste_de_medicaments[3].nom and\
entree != liste_de_medicaments[4].nom:
print("Ce nom est invalide, SVP vérifiez l'orthographe")
entree=input()
return entree
en lisant l'énoncé j'ai remarqué qu'il n'y avait rien au sujet des achats de la pharmacie, que rien ne la caractérise, ni stock, ni fonds de commerce, ni actions, ni rien, du coup je n'en ait pas fait un objet. Je n'en voyait pas l'utilité.
from Client import Client
from Medicament import Medicament
class Pharmacie:
def __init__(self):
self.__clients = list()
self.__medicaments = list()
@property
def clients(self):
return self.__clients
@property
def medicaments(self):
return self.__medicaments
def ajouter_client(self, client: Client):
self.__clients.append(client)
def ajouter_medicament(self, medicament: Medicament):
self.__medicaments.append(medicament)
def prix_medicament(self, nom: str):
for medicament in self.__medicaments:
if medicament.nom == nom:
return medicament.prix
def vendre_medicament(self):
while True:
nom_client = input("Qui est le client? ")
client = self.client(nom_client)
if client is not None:
break
nom_medicament = self.lire_medicament()
while True:
try:
qte = int(input("Quelle quantité achetez-vous? "))
break
except ValueError:
pass
montant_a_payer = qte * self.prix_medicament(nom_medicament)
while True:
try:
montant_paye = float(input(f"Le prix à payer est de {montant_a_payer}. Combien payez-vous?"))
break
except ValueError:
pass
for medicament in self.medicaments:
if medicament.nom == nom_medicament:
medicament.stock -= qte
break
client.credit += montant_a_payer - montant_paye
def approvisionnement(self):
nom = self.lire_medicament()
while True:
try:
qte = int(input("Quelle quantité à approvisionner? "))
break
except ValueError:
pass
for medicament in self.__medicaments:
if nom == medicament.nom:
medicament.stock += qte
break
def affichage(self):
text = "État des stocks de médicaments:"
print(text, end="\n" + "-" * len(text) + "\n")
for medicament in self.__medicaments:
print(f"{medicament.nom}, stock: {medicament.stock}, prix: {medicament.prix}")
print()
text = "État des comptes client:"
print(text, end="\n" + "-" * len(text) + "\n")
for client in self.__clients:
print(f"{client.nom}: {client.credit}")
def lire_client(self):
while True:
nom = input("Quel est le nom du client? ")
if nom in [client.nom for client in self.__clients]:
return nom
def lire_medicament(self):
while True:
nom = input("Quel est le nom du medicament? ")
if nom in [medicament.nom for medicament in self.__medicaments]:
return nom
def client(self, nom: str):
for client in self.clients:
if client.nom == nom:
return client
return None
def medicament(self, nom: str):
for medicament in self.medicaments:
if medicament.nom == nom:
return medicament
return None
def entrer_pharmacie(self):
while True:
while True:
try:
print("Menu:\n-----")
print("1. Etat des stocks et comptes clients")
print("2. Approvisionement de médicament")
print("3. Achat client")
print("4. Quitter")
choix = int(input("> "))
if choix in range(1, 5):
break
except ValueError:
pass
if choix == 1:
self.affichage()
elif choix == 2:
self.approvisionnement()
elif choix == 3:
self.vendre_medicament()
elif choix == 4:
self.sortir_pharmacie()
def sortir_pharmacie(self):
print("Merci et au revoir.")
print("Programme terminé!")
exit()
Je fais au plus simple, créer une classe Pharmacie n'a aucun intérêt vu que le programme n’interagit qu'avec une seul pharmacie (on peut supposer alors que ce programme servira à ladite pharmacie).
Concernant la réponse de KongkeoXayavongkeo, ça ne sert à rien d'encapsuler tes propriétés comme ça, on est en Python pas en Java, tes propriétés sont toujours accessibles.
À mon sens "exotique" n'est pas le terme approprié !
@Raidez,
Le programme crée une seule pharmacie pour le test, mais il pourrait très bien en créer plusieurs.
Créer une classe n'a pas que pour objectif de créer plusieurs objets, ça peut être aussi un moyen d'organiser son code, gérer la portée des variables, en hériter, etc...
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
La doc est la bible du développeur !
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)