[Tutor] Simple bank account oriented object
Steven D'Aprano
steve at pearwood.info
Tue Apr 6 01:15:29 CEST 2010
On Tue, 6 Apr 2010 06:31:30 am Marco Rompré wrote:
> Hi im doin a programmin course at university and in one on my
> exercise i have to do that
>
> I had to define a class CompteBancaire(CompteBancaire is bankaccount
> in french), that would allow me to create objects Compte1,
> Compte2,etc.
[...]
I do not understand French, so if I have misunderstood something, please
excuse me. My comments are added in between yours.
> #Exercice 3,2 - Gestion d'un compte bancaire pour étudiant avec marge
> de crédit disponible de 1000$CDN
>
> class CompteBancaire:
> "définition d'un compte bancaire"
This docstring is not very useful. The reader already knows that you are
defining a CompteBancaire. What else can you tell them? How about basic
usage?
class CompteBancaire:
"""définition d'un compte bancaire
Example: create a cheque account with $1000 balance.
>>> compte = CompteBancaire('cheque', 1000)
Deposit $100, then withdraw $80:
>>> compte.depot(100)
>>> compte.retrait(80)
"""
> def __init__(self,nom,solde,interet): #Nous allons
> instancier et initialiser les objets à la classe
> self.nom, self.solde, self.interet = nom,solde,interet
It is not clear to me whether interet (French for interest?) is meant to
be a percentage rate, or an amount. I will assume it is an amount (how
much interest the bank has paid you). Every new account will always
start with interet = 0, so we should write this:
def __init__(self, nom, solde):
self.nom, self.solde = nom, solde
self.interet = 0
It is not clear to me what nom (name?) is for, but I have left it in.
> def depot(self,somme=0): #Méthode pour
> additionner les dépôts au compte
> self.solde=self.solde+somme
Do you need the default value for deposits? Will it ever be useful for
the user to call compte.depot() without an amount?
I would think it would be more useful to add the default values to the
initialiser __init__:
def __init__(self, nom='', solde=0):
...
and take it away from the depot and retrait methods:
def depot(self, somme):
...
def retrait(self,somme):
...
But this is just my opinion.
> def retrait(self,somme=0): #Méthode pour
> soustraire les retraits au compte
> if self.nom == 'Sandon':
> if self.solde-somme<0:
> print "Les fonds sont insuffisants. Essayez un autre
> montant pour votre retrait!"
> else:
> self.solde=self.solde-somme
This comment might be more advanced than you have learned. If so, you
can safely ignore this part. If you have not learned about exceptions
yet, you can safely ignore this.
When programming, you should separate the "back-end" from
the "front-end". The back-end should report errors using exceptions, in
a form which is useful to the programmer, and the front-end should
catch those exceptions and print an error message in a form which is
useful to the user.
So we should write:
def retrait(self, somme):
if somme > self.solde:
raise ValueError('fonds sont insuffisants')
else:
self.solde = self.solde - somme
> elif self.nom =='Étudiant': #Vérifie s'il s'agit
> d'un compte étudiant
This part is not good. The CompteBancaire class MUST NOT know anything
about the CompteEtudiant subclass. Each class should only know about
itself, and superclasses (parent classes).
So all the code dealing with the Étudiant account must go inside the
CompteEtudiant class, not the CompteBancaire.
> if self.solde - somme < -self.margeCre: # Vérifie si
> le retrait dépasse la marge de crédit maximum
> print "Désolé, votre retrait dépasse la marge de
> crédit autorisé"
> else: # sinon déuit le
> montant retirer de la marge de crédit
> self.margeCre = self.solde - somme
> self.solde = 0
> def calculInteret(self,calculInteret=0): #Méthode qui calcule
> les intérêts et le solde résiduel
> self.interet=self.solde*calculInteret/100
> self.solde=(self.solde*calculInteret/100)+self.solde
There is a small problem with Python here, depending on what version you
are using. In older versions of Python, division is "integer division",
so that:
1/2 -> 0
9/4 -> 2
and so forth. This will give you the wrong result for calculating
interest. In newer versions of Python (version 3.0 and better) division
is "true division":
1/2 -> 0.5
9/4 -> 2.5
The easiest way to make your code work correctly is to change 100 to
100.0 (a float instead of an int) and then it will calculate as you
expect in all versions.
> def affiche_solde(self): #Méthode qui affiche
> le solde et le montant d'intérêt accumulé
> print "Le solde du compte bancaire de %s est de %d $CAD"
> %(self.nom,self.solde)
> print "Vous avez récolté %d $CDN en intérêt"%(self.interet)
Now we look at the Étudiant account, and add the extra functionality.
> class CompteEtudiant(CompteBancaire):
> "définition du compte bancaire pour étudiant dérivé du compte
> bancaire standard"
> def __init__(self, nom='', solde=0, margeCre=0):
> CompteBancaire.__init__(self, nom='Nom', solde=0, interet=0)
> self.nom, self.solde, self.margeCre = nom, solde, margeCre
The CompteEtudiant class can let the CompteBancaire do some of the work.
This is called "inheritance" -- the subclass inherits code from the
parent class.
def __init__(self, nom='', solde=0, margeCre=0):
# Call the parent class method.
CompteBancaire.__init__(self, nom, solde)
# Do the extra work this class needs.
self.margeCre = margeCre
Calling CompteBancaire.__init__ does everything the CompteBancaire
understands. It sets nom, solde and interet, but not margeCre because
CompteBancaire does not know anything about margeCre. Then the subclass
sets margeCre itself.
> def affiche_solde(self, somme=0): #Méthode constructeur
> qui redéfini la fonction affiche_solde pour le compte étudiant
> print "%s--Votre solde bancaire est de %d $CAD"
> %(self.nom,self.solde)
> print "Le solde de votre marge de crédit est de %d $CAD"
> %(self.margeCre)
The CompteEtudiant should print the same information as the
CompteBancaire class, plus extra. Again, inheritance makes it easy:
def affiche_solde(self):
# Display everything the super class understands.
CompteBancaire.affiche_soldeafficheself)
# Display the parts that only the subclass understands.
print "Le solde de votre marge de crédit est de %d $CAD" %
(self.margeCre)
And one more method needs to be defined: we have to change the retrait
method to allow negative balance, but only up to a maximum of margeCre.
def retrait(self, somme):
if somme > self.solde + self.margeCre:
raise ValueError('fonds sont insuffisants')
else:
self.solde = self.solde - somme
--
Steven D'Aprano
More information about the Tutor
mailing list