RÉPUBLIQUE DU SÉNÉGAL
Un peuple, Un but, Une foi
Ministère de l’Enseignement Supérieur, de la Recherche et de l’Innovation
École Centrale des logiciels Libres et de Télécommunications
Guichet Automatique Bancaire
Présenté par : Prof:
Amadou Bory DIALLO
Winnie Edgard NDASSIMBA
M. Latyr N’DIAYE
Projet d’API
Ce projet consiste à écrire un programme python utilisant une base de données SQLITE qui se
comporterai exactement comme un GAB (Guichet Automatique Bancaire).
Nous avons déjà à notre actif des fichiers CSV qui contiennent des informations sur des comptes de
clients d’une banque.
Exercice 1
Création de la base de données, les tables et importation des fichiers CSV
Les prérequis
# apt update
# apt install python3
# apt install sqlite3
# apt install sqlitebrowser
Code 1
Voici le code permettant de créer la base de données banque et les trois tables associées !
Le fichier aura pour nom : [Link]
Puisque ces trois tables doivent fonctionner en symbiose, elle doivent forcement être liées à travers
les histoires de clés étrangères comme sur le code suivant :
# nano [Link]
#-*-coding:utf8-*-
import sqlite3
conn = [Link]('[Link]')
print ("Base de données ouverte avec succès !");
#La table clients
[Link]('CREATE TABLE Clients (idClient INTEGER PRIMARY KEY,nom TEXT,
prenom TEXT,adresse TEXT, codePostal TEXT, ville TEXT, telephoneFixe TEXT,
telephonePortable TEXT)')
#La table comptes
[Link]('CREATE TABLE Comptes (idCompte INTEGER PRIMARY KEY,idClient
INTEGER,typeCompte TEXT,codePIN TEXT,solde REAL, FOREIGN KEY(idClient)
REFERENCES Clients(idClient))')
#La table Opérations
[Link]('CREATE TABLE Operations (idOperation INTEGER PRIMARY
KEY,dateOperation TEXT,idCompte INTEGER,libelleOperation TEXT,Montant REAL,
FOREIGN KEY(idCompte) REFERENCES Comptes(idCompte))')
print ("les tables ont été créées avec succès, les relations ont aussi été faites !");
[Link]()
Exécution du code comme suit :
# python3 [Link]
Les tables ont été créées avec succès !
La conséquence de l’exécution de cette commande est la génération d’un fichier nommé [Link]
Le voici d’ailleurs :
Affichons notre base de données et la structure des différentes tables :
# sqlitebrowser [Link]&
Et voici le résultat
Nous voyons clairement que les trois tables on été générées !
Importation des fichiers CSV
Nous avons remarqué que nos tables sont encore vides, elles ne contiennent aucune information
pour le moment. Nous allons les alimenter avec des fichiers EXCEL (en format CSV).
Note : Puisque nous avons déjà créé les tables avec les différentes colonnes, pour éviter la doublure
de colonnes, nous allons modifier les fichiers CSV comme suit :
Retirer juste le nom des colonnes
Nous vennons d’enlever les entêtes car elle existent déjà dans les tables déjà créées !
Nous ferons la même chose pour les deux autres fichiers restant.
Maintenant nous allons importer le contenu des fichiers CSV dans cette base de données :
Le fichier [Link]
Pour importer les fichiers CSV, il faut tout d’abord lancer la base de données avec sqlitebrowser
# sqlitebrowser banque &
L’importation des fichiers se fait comme suit :
Se positionner sur la table
Cliquer sur l’onglet Fichier > importer > Table depuis un fichier CSV…
Parcourir notre arborescence pour sélectionner le fichier en question.
Ouvrir le fichier
Valider
Cliquer sur Oui
Le fichier est importé avec succès !
Voici le contenu de la table Clients
La table Clients contient enfin du contenu grâce au fichier CSV que nous venons importer !
Nous ferons la même chose pour les deux autres fichiers !
Note : Toujours commencer par retirer le nom des colonnes sur les fichiers CSV avant de les
importer, car la table contient déjà ces entêtes !
Après importation des fichiers, Voici le contenu de la table Comptes
La table Operations
Toutes nos tables ont désormais du contenu !
Exercice 2
Écrivons le programme du serveur central de la banque écoutant sur le port 50000.
# nano [Link]
#!/usr/bin/env python3
import sqlite3
import threading
threadsClients = []
import socket
##La fonction de connexion à la base de données
def connexionBaseDeDonnees():
baseDeDonnees = [Link]("[Link]")
curseur = [Link]()
return baseDeDonnees, curseur
##La fonction de test du code PIN
def testpin(numCompte, pinUtilisateur):
baseDeDonnees, curseur = connexionBaseDeDonnees()
[Link]("SELECT codePIN FROM Comptes WHERE idCompte = ?",
(numCompte,))
pincompte = [Link]()[0]
[Link]()
if pincompte == pinUtilisateur:
return True
else:
return False
##La fonction de consultation de solde
def solde(numCompte):
baseDeDonnees, curseur = connexionBaseDeDonnees()
[Link]("SELECT solde FROM Comptes WHERE idCompte = ?",
(numCompte,))
soldeCompte = [Link]()[0]
[Link]()
return soldeCompte
##La fonction de retrait
def retrait(numCompte, montant):
#Le montant est négatif
baseDeDonnees, curseur = connexionBaseDeDonnees()
montant = float(montant)
soldeCompte = solde(numCompte)
if soldeCompte < montant or montant >= 0:
[Link]()
return False
else:
nouveauSolde = soldeCompte+montant
[Link]("UPDATE Comptes SET solde = ? WHERE idCompte = ?",
(nouveauSolde,numCompte))
[Link]("INSERT INTO Operations (dateOperation, idCompte,
libelleOperation, montant) VALUES (DATE('NOW'), ?, ?, ?)",(numCompte, "Retrait",
montant))
[Link]()
[Link]()
return True
## Fonction de transfert d'argent
def transfert(numCompteSource, numCompteDestination, montant):
#Pour un montant positif
baseDeDonnees, curseur = connexionBaseDeDonnees()
montant = float(montant)
soldeCompteSource = solde(numCompteSource)
if soldeCompteSource < montant or montant <= 0:
[Link]()
return False
else:
nouveauSoldeSource = soldeCompteSource-montant
[Link]("UPDATE Comptes SET solde = ? WHERE idCompte = ?",
(nouveauSoldeSource,numCompteSource))
[Link]("INSERT INTO Operations (dateOperation, idCompte,
libelleOperation, montant) VALUES (DATE('NOW'), ?, ?, ?)",(numCompteSource,
"Virement", -montant))
soldeCompteDestination = solde(numCompteDestination)
nouveauSoldeDestination = soldeCompteDestination+montant
[Link]("UPDATE Comptes SET solde = ? WHERE idCompte = ?",
(nouveauSoldeDestination,numCompteDestination))
[Link]("INSERT INTO Operations (dateOperation, idCompte,
libelleOperation, montant) VALUES (DATE('NOW'), ?, ?, ?)",(numCompteDestination,
"Virement", montant))
[Link]()
[Link]()
return True
## Fonction de depôt d'argent
def depot(numCompte, montant):
#Pour un montant positif
baseDeDonnees, curseur = connexionBaseDeDonnees()
montant = float(montant)
soldeCompte = solde(numCompte)
nouveauSolde = soldeCompte+montant
[Link]("UPDATE Comptes SET solde = ? WHERE idCompte = ?",
(nouveauSolde,numCompte))
[Link]("INSERT INTO Operations (dateOperation, idCompte,
libelleOperation, montant) VALUES (DATE('NOW'), ?, ?, ?)",(numCompte, "Dépôt",
montant))
[Link]()
[Link]()
return True
##Fonction de Consultation de l'historique
def historique(numCompte):
baseDeDonnees, curseur = connexionBaseDeDonnees()
[Link]("SELECT dateOperation, libelleOperation, montant FROM
Operations WHERE idCompte = ? ORDER BY dateOperation DESC LIMIT 10;",
(numCompte,))
historiqueCSV = "\"dateOperation\";\"libelleOperation\";\"montant\"\n"
for ligne in [Link]():
historiqueCSV += "\"" + ligne[0] + "\";\"" + ligne[1] + "\";\"" + str(ligne[2]) +
"\"\n"
return historiqueCSV
def instanceServeur (client, infosClient):
adresseIP = infosClient[0]
port = str(infosClient[1])
print("Instance de serveur prêt pour " + adresseIP + ":" + port)
actif = True
while actif:
message = [Link](255).decode("utf-8").upper().split(" ")
pret = False
if message[0] == "TESTPIN":
if testpin(message[1], message[2]):
[Link]("TESTPIN OK".encode("utf-8"))
message = [Link](255).decode("utf-8").upper().split(" ")
if message[0] == "RETRAIT":
if retrait(message[1], message[2]):
[Link]("RETRAIT OK".encode("utf-8"))
else:
[Link]("RETRAIT NOK".encode("utf-8"))
elif message[0] == "DEPOT":
depot(message[1], message[2])
[Link]("DEPOT OK".encode("utf-8"))
elif message[0] == "SOLDE":
soldeCompte = solde(message[1])
[Link](("SOLDE " + str(soldeCompte)).encode("utf-
8"))
elif message[0] == "TRANSFERT":
if transfert(message[1], message[2], message[3]):
[Link]("TRANSFERT OK".encode("utf-8"))
else:
[Link]("TRANSFERT NOK".encode("utf-8"))
elif message[0] == "HISTORIQUE":
historiqueCSV = historique(message[1])
[Link](("HISTORIQUE " +
historiqueCSV).encode("utf-8"))
else:
[Link]("ERROPERATION".encode("utf-8"))
else:
[Link]("TESTPIN NOK".encode("utf-8"))
else:
[Link]("ERROPERATION".encode("utf-8"))
print("Connexion fermée avec " + adresseIP + ":" + port)
[Link]()
serveur = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](('', 50000)) # Écoute sur le port 50000
[Link](5)
while True:
client, infosClient = [Link]()
[Link]([Link](None, instanceServeur, None, (client,
infosClient), {}))
threadsClients[-1].start()
[Link]()
Exercice 3
Écrivons le programme des distributeurs automatiques de la banque.
# nano [Link]
#!/usr/bin/env python3
import socket
adresseIP = "[Link]"
port = 50000 # le port 50000
while True:
client = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link]((adresseIP, port))
print("Bienvenue dans la banque Python")
nocompte = input("Entrez votre numéro de compte : ")
pin = input("Entrez votre code PIN : ")
[Link](("TESTPIN " + nocompte + " " + pin).encode("utf-8"))
reponse = [Link](255).decode("utf-8")
if reponse == "TESTPIN OK":
print("Bienvenue ! ")
print(" Opérations : ")
print("1 - Dépôt")
print("2 - Retrait")
print("3 - Transfert")
print("4 - Historique des opérations")
print("5 - Solde du compte")
operation = input("Entrez l'opération que vous souhaitez : ")
if operation == "1":
montant = input("Entrez le montant à déposer : ")
[Link](("DEPOT " + nocompte + " " + montant).encode("utf-8"))
reponse = [Link](255).decode("utf-8")
print("Dépot effectué")
elif operation == "2":
montant = input("Entrez le montant à retirer : ")
montant = str(- float(montant)) # Le montant doit être négatif
[Link](("RETRAIT " + nocompte + " " + montant).encode("utf-8"))
reponse = [Link](255).decode("utf-8")
if reponse == "RETRAIT OK":
print("Retrait effectué")
else:
print("Retrait refusé")
elif operation == "3":
montant = input("Entrez le montant à transferer : ")
nocompteDestination = input("Entrez le numéro de compte du
bénéficiaire : ")
[Link](("TRANSERT " + nocompte + " " + nocompteDestination +
" " + montant).encode("utf-8"))
reponse = [Link](255).decode("utf-8")
if reponse == "TRANSERT OK":
print("Transfert effectué")
else:
print("Transfert refusé")
elif operation == "4":
[Link](("HISTORIQUE " + nocompte).encode("utf-8"))
historique = [Link](4096).decode("utf-8").replace("HISTORIQUE
","") # On transfert un grand volume de données
print(historique)
elif operation == "5":
[Link](("SOLDE " + nocompte).encode("utf-8"))
solde = [Link](4096).decode("utf-8").replace("SOLDE ","")
print("Le solde du compte est de " + solde)
else:
print("Vos identifiants sont incorrects")
print("Au revoir !")
[Link]()
Après mise en place d’un service, le test de fonctionnement doit être un reflex.
Place au test
Il faut tout d’abord lancer le serveur afin qu’il écoute les requête
# python3 [Link]
Nous allons maintenant lancer le client. Dans un autre SHELL
# python3 [Link]
Saisir le numéro du compte, ensuite le code PIN et nous aurons la liste des Opérations
disponibles :
Mettre le numéro de l’opération à effectuer.
Consultation de solde :
Retrait d’argent
Vérifions le solde après ce retrait :
Nous voyons clairement que le compte a été débité !
Consultation de l’historique
Nous avons écrit le code de telle sorte qu’il affiche l’historique des 10 dernières transactions.
Nous voyons clairement les dates et le libellé des dix dernières transactions. La dernière se trouve
en tête de liste.
Voici l’information sur la base de données elle-même
Dépôt d’argent
Le compte numéro 1 vient d’effectuer un dépôt de 8000
Consultation du solde pour voir s’il y a changement
Son compte a été crédité de 8000.
Consultation de l’historique des opérations
Le solde sur la base de données
L’historique dans la base de données
Vous pouvez vous amuser à faire des transferts d’argent !
Nous constatons que les scripts travaillent de concert avec la base de données. Ce qui est tout à fait
normal car toutes les requêtes des clients sont traitées par ladite base de données !
Notre guichet automatique bancaire fonctionne à merveille !