Exercice de programmation orientée objet sous Python

a marqué ce sujet comme résolu.

Bonjour à tous!

Je dois implémenter un programme sous Python en utilisant la programmation orientée objet mais je me heurte à plusieurs difficultés, le sujet de mon exercice étant le suivant (en le résumant et simplifiant):

On dispose d’une base de données (fichier .csv que l’on doit donc importer sur Python) de produits alimentaires où chaque produit est caractérisé par son code-barre (info unique au produit), date d’ajout à la BdD, lieu(x) de fabrication, liste des ingrédients, etc…

A partir de cette base de données, on distingue 3 types de consultants différents:

-Le visiteur, qui peut:

 -Afficher un produit (ses caractéristiques citées plus haut)
 
 -Se créer un compte

-Le contributeur, qui peut:

 -Afficher lui aussi un produit
 
 -Créer/Modifier un produit
 
 -Se connecter/déconnecter 
 
 -Il ne peut se créer un compte car il en possède forcément déjà un (Un visiteur se créant un compte 
  devient nécessairement contributeur

-Enfin, l’administrateur, qui peut:

 -Afficher lui aussi un produit
 
 -Créer/Modifier lui aussi un produit
 
 -Supprimer un produit
 
 -Se connecter/déconnecter lui aussi
 
 -Valider/Supprimer un compte de contributeur (plus clairement: chaque visiteur se créant un compte doit 
  au préalable voir son compte validé par un administrateur avant de devenir contributeur)
 
 -Il ne peut lui non plus se créer un compte (même raison que pour le contributeur)

L’idée finale étant qu’une fois le programme lancé, il soit demandé au consultant son statut (visiteur/contributeur/administrateur), pour qu’on lui propose les tâches qu’il a le droit d’effectuer.

J’ai dans un premier temps du mal à établir les classes qu’il va falloir implémenter.

Faut-il implémenter par exemple les 5 classes Visiteur,Contributeur,Administrateur,Compte et Produit?

De plus je vois mal comment gérer les autorisations d’accès ainsi que les connections/ déconnections.

Merci par avance et n’hésitez pas à me demander si vous souhaitez d’autres précisions ! Alex :)

+0 -0

Salut !

Tout dépend de la finesse de gestion que tu veux avoir. Mais a priori, le plus simple serait probablement d’avoir une classe généraliste pour un compte enregistré en BDD, qui possèderait un attribut qui indiquerait si ce compte a des droits administrateurs ou non.

La gestion de base de données de Django est très pratique pour cela. Même si tu n’utilise pas Django pour ce projet, voir comment il marche pourrait surement t’inspirer pour ton projet. La gestion des permissions y est notamment très pratique. ;)

+0 -0

Salut et merci de m’avoir répondu !

Effectivement je n’utilise ici pas Django mais ayant fait quelques recherches sur internet j’avais cru comprendre que c’est assez pratique pour ce genre de problèmes.

Par contre tu pourrais un peu me développer ton idée de classes s’il te plaît? :)

Pour ce genre de choses, Django est en effet tout indiqué (si tu as le droit de l’utiliser) : il gère nativement les modèles en base de donnée (une classe représentant les données, concrètement), les utilisateurs, les permissions, et permet même de générer automatiquement les interfaces de base de création, modification et suppression (CRUD) grâce à l’administration embarquée.

Cela dit, vu qu’il mâche tout le travail (et pas qu’un peu), c’est très pratique mais moins bien pour apprendre, étant donné que tu ne le fais pas toi-même.

Concernant les classes je pense que l’idée de @rezemika est la bonne. On pourrait imaginer une classe User avec un attribut booléen is_admin (les visiteurs n’auraient pas de compte, donc pas d’instance User ; les contributeurs une instance avec is_admin = False et les administrateurs is_admin = True) et un is_active qui serait à False par défaut et passerait à True quand un administrateur le valide, en plus des champs classique mail/mot de passe.

Et une classe Product dont chaque instance représenterait une ligne du CSV (on transformerait le CSV en une liste d’instance de Product en chargeant le CSV), avec des attributs correspondant aux colonnes du fichier source.

Ensuite lors de la manipulation, le code vérifierait l’utilisateur actif (par exemple stocké dans une session — selon l’outil utilisé — et valant None si anonyme/visiteur) et autoriserait ou non en fonction du statut d’administrateur, de faire telle ou telle action.

Il y a plein d’autres façons de faire cela, bien sûr. Par exemple, celle de Django repose sur un système de permissions attribuées à des groupes de permissions eux-même attribués à des utilisateurs ; le code vérifiant qu’une permission (plutôt qu’un statut administrateur) est donnée. Par exemple, une permission pourrait ici être can_create_product, can_update_product, can_delete_product, can_validate_user, can_delete_user… L’inconvénient, c’est que c’est plus compliqué à mettre en place.

Mais je me pose une question. Où seraient stockés les utilisateurs ? Dans une base de données ? Ou alors en faisant simplement confiance pour que chacun dise « je suis X » sans vérification (possible si c’est juste un exercice) ?

Et quel genre de support utilises-tu ? Web ? Console ? Autre chose ?

+1 -0

Edit : grillé par @Amaury.

Hum, j’avais mal lu. Je dois préciser qu’en plus de ta base de produits, tu devra aussi créer une base d’utilisateurs. Puisque tu utilise du CSV pour la première, tu ne pourra pas faire une gestion sous forme de tables ou utiliser des champs avec des relations comme on en trouve dans les bases de données SQL. Tu peux cependant t’en rapprocher, si chaque produit et chaque utilisateur contiennent un champ unique qui leur servira d’ID.

Ensuite, en lisant chaque ligne du CSV, tu récupère probablement un tuple. Tu peux alors le passer au constructeur d’une classe Python qui aura diverses méthodes pour réaliser les actions que tu veux.

# Colonnes : "nom", "prix_ht", "fabricant"
csv_line = ("Fromage", "5.50", "Fromager X")

class Product:
    def __init__(self, nom, prix, fabricant):
        self.nom = nom
        self.prix = float(prix)  # Ici, il vaudrait mieux utiliser le module "money" : https://github.com/carlospalol/money
        self.fabricant = fabricant
    
    def prix_ttc(self):
        return self.prix * 1.2

# Voir http://sametmax.com/operateur-splat-ou-etoile-en-python/
product = Product(*csv_line)

Naturellement, il faudra aussi (ou en tout cas, ce serait bien plus pratique) créer une classe qui aura à gérer les interactions avec ta base CSV, notamment pour récupérer les données et les mettre à jour.

Si c’est possible pour toi et que ton projet est destiné à avoir une vie longue, il serait d’ailleurs sans doute bien plus pratique d’avoir une base de données SQL pour gérer tout ça (dans laquelle tu n’aurais qu’à faire une grosse importation la première fois, depuis le CSV).

+1 -0

Grillé par Amaury mais ton message a l’avantage de contenir un exemple concret ^^

(+1 pour l’avantage d’utiliser un vrai SGBD si c’est un projet à long terme, et si c’est possible bien sûr — p.ex. SQLite pour les petites quantités de données portables et stockées dans un fichier, ou MySQL pour des trucs plus gros ou performants)

+0 -0

Merci @Amaury !

Pour te répondre (et réagir) un peu dans le désordre:

J’utilise Python 2.7 sous Spyder 3.

Quant au stockage des utilisateurs:

Contrairement à la base de données des produits qui, elle, existe déjà (via le .csv), rien n’indique dans le sujet qu’il y a déjà des utilisateurs. (Cela dit, pour une question de cohérence, on pourrait envisager qu’il existe déjà ne serait-ce qu’un seul admin, parce qu’a priori la BDD ne s’est pas créée toute seule, mais ce n’est pas le coeur du problème :)).

Donc en fait mon idée c’est de créer un contributeur et un admin afin de tester le programme, càd montrer que mon contributeur va devoir se connecter, pourra effectuer certaines tâches et d’autres non, tandis que mon admin pourra effectuer toutes les tâches requises (sauf créer un autre compte). Pas besoin de créer un visiteur simple car il n’a pas de compte, on est d’accord?

Au passage, dans le sujet un compte c’est pseudo (unique) +mot de passe, donc on doit pouvoir stocker tous ces couples dans un dictionnaire ou une liste de liste je suppose?

L’idée du sujet c’est simplement quand on lance le programme, la console nous demande quel type de consultant on est, du style:

Quel type d’utilisateur êtes-vous?

1: Visiteur

2: Contributeur

3: Administrateur

Puis si j’entre 1 dans la console, on va m’afficher la liste des tâches que je peux faire, toujours associées à un entier qui sera mon input dans la console (aussi à un moment donné on va me proposer de créer un compte pour passer contributeur).

Si j’entre 2 ou 3 on va me demander de me connecter, évidemment pour le contributeur ça va fonctionner que si un admin a validé mon compte.

Petite précision:

Du coup si j’ai entré 2, pour contributeur, et que ma connection se soit bien déroulée (bon pseudo+MdP + compte validé), on ne va pas me proposer derrière de valider un compte car seuls les administrateurs peuvent le faire.

NEANMOINS, il faut quand même faire en sorte que si je suis un contributeur et que dans la liste suivante je choisis "créer/modifier un produit" (ce qui est possible d’après le sujet donc moi je vais faire en sorte de l’afficher dans ladite liste), le programme fasse une vérification pour s’assurer que j’en ai (ici le contributeur donc) le droit.

J’ai bien conscience que ce que j’explique est pas forcément hyper clair haha !

Sinon, merci beaucoup pour ton explication de ta classe User :) :)

Mais du coup à part tes classes User et Product, lesquelles tu créerais?

Alex

@Necros211 Je viens de re-vérifier et je ne m’étais pas trompé, c’est bien Python 2.7 :)

Alexouu

Hum, ça risque de te poser problème à long terme, Python 2.7 ne sera plus maintenu à partir de 2020, et de moins en moins de modules sont compatibles avec Python 2.7. À moins qu’un impératif technique absolu ne t’en empêche, il serait bien plus aisé de penser à migrer vers Python 3.

Contrairement à la base de données des produits qui, elle, existe déjà (via le .csv), rien n’indique dans le sujet qu’il y a déjà des utilisateurs. (Cela dit, pour une question de cohérence, on pourrait envisager qu’il existe déjà ne serait-ce qu’un seul admin, parce qu’a priori la BDD ne s’est pas créée toute seule, mais ce n’est pas le coeur du problème :)). Donc en fait mon idée c’est de créer un contributeur et un admin afin de tester le programme, càd montrer que mon contributeur va devoir se connecter, pourra effectuer certaines tâches et d’autres non, tandis que mon admin pourra effectuer toutes les tâches requises (sauf créer un autre compte). Pas besoin de créer un visiteur simple car il n’a pas de compte, on est d’accord?

Je ne suis pas sur de comprendre. Tu as une base de données d’utilisateurs ou pas encore ? Si oui, elle se base sur quelle technologie ? C’est là aussi du CSV, c’est du SQL, ou encore autre chose ?

Au passage, dans le sujet un compte c’est pseudo (unique) +mot de passe, donc on doit pouvoir stocker tous ces couples dans un dictionnaire ou une liste de liste je suppose?

En effet, mais il faudra de toute façon stocker ces données dans un fichier quelconque. Aussi, je te rappelle qu’il est largement conseillé (pour ne pas dire quasi indispensable) de stocker les hashs des mots de passe, et pas les mots de passe eux-mêmes. Aussi, si tu veux qu’il y ait un statut admin, il te faudra aussi stocker ce statut avec les identifiants.

Si j’entre 2 ou 3 on va me demander de me connecter, évidemment pour le contributeur ça va fonctionner que si un admin a validé mon compte.

Une solution plus simple serait de proposer d’emblée une fenêtre de connexion avec un bouton "Mode visiteur" (par exemple), et quand l’utilisateur se connecte, vérifier s’il a le statut d’administrateur ou non.

Mais du coup à part tes classes User et Product, lesquelles tu créerais?

Eh bien tout dépend des technologies utilisées pour les différentes bases de données. Est-ce que l’import de ton CSV vers une base de données SQL est envisageable ? Comment stocke-tu les utilisateurs ?

Si tu reste sur du CSV pour tout, alors tu peux aussi faire une classe qui accède à un CSV et qui se charge de la lecture et de l’écriture, pour ne pas avoir à réécrire des open() partout dans ton code.

+1 -0

Pardon pour ma réaction tardive @rezemika et merci !

Pour la version de Python je comprends bien qu’il falloir passer à Python 3, c’est simplement qu’on utilise la 2.7 pour ce projet :)

Pour les utilisateurs: Non il n’y a pas de base de données utilisateurs qui existe déjà. Mais tu as raison, il va certainement falloir stocker ces données quelque part ! (Encore une fois c’est moi qui vais créer 2–3 comptes à la main juste pour montrer que mon programme tourne bien)

Pour ce qui est des hashs, je comprends que dans la réalité on devrait vraiment s’en pré-occuper mais pour ce projet-là il n’y a pas besoin de s’embêter avec ça mais merci du tuyau :)

En ce qui concerne le CSV, je pensais faire comme tu dis à la fin de ton message, à savoir créer spécialement une classe qui load le CSV et se charge de la lecture et de l’écriture (pas le droit d’utiliser SQL ici :))

En ce qui concerne le CSV, je pensais faire comme tu dis à la fin de ton message, à savoir créer spécialement une classe qui load le CSV et se charge de la lecture et de l’écriture (pas le droit d’utiliser SQL ici :))

Alexouu

Oui, ou pourquoi pas juste un module avec les fonctions nécessaires à l’utilisation du fichier csv ?

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte