Partage
  • Partager sur Facebook
  • Partager sur Twitter

PEP sur la POO ?

Gestionnaire de tournoi / appareillement Suisse sur le Elo.

14 février 2017 à 10:21:06

Bonjour à tous,

J'aurai aimé savoir comment organiser un programme en Programmation Orientée Objet (POO). Je ne suis qu'un autodidacte en python, mais j'aime ça.

Or, en regardant le code des autres, je me rends compte que je suis très séquentiel dans ma manière de programmer et je vois bien que la POO pourrait apporter beaucoup de choses. Mais j'ai du mal à comprendre  comment formuler mes class et comment elles interagissent entres elles. Ça m'aiderai à comprendre le code des autres également.

Si je comprends bien, mon programme, c'est une usine, mes class, ce sont des personnes de l'usine qui font leur boulot dans leur coin (des sous programmes autonomes ?) et qui travaillent sur des objets qui circulent (oui je sais... On conceptualise comme on peut).

Mais en même temps, on voit beaucoup de class "statiques" qui ne font rien, qui contiennent juste des flags de programmation.

Dans mon cas, je m'intéresse à la programmation d'un logiciel d'organisation de tournoi Suisse (type échecs).

La séquence réelle vue de l'arbitre utilisateur du logiciel est la suivante:

1) gestion des inscriptions pour dresser une liste des participants.

2) ordonner la liste (du plus fort au moins fort) et attribuer un numéro

3) organiser une ronde

... a) mettre en place les adversaires en suivant les règles d'appareillement automatiques ou forcées

... b) enregistrer les résultats des joueurs

... c) mettre à jour la grille américaine (la grille de synthèse des rencontres avec le calcul des critères de départage)

4) on recommence (3) autant de fois que prévue

5) publication des résultats définitifs.

Ma question dans ce cas est la suivante. Quels objets faut-il créer ?

Si j'ai bien compris, on va avoir une class "tournoi", une class "joueur", une class "ronde" et une class "grille américaine", parce que ces objets "existent". Mais la class joueur est complètement passive, alors que la class "ronde" calcule des choses. Ça ne pose pas de problème ? Existe-t-il une PEP sur ce sujet ?

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
14 février 2017 à 10:40:09

Bonjour,

Déjà faut savoir que la POO est une manière de coder qui n'avantage pas l'optimisation de code dans le sens 'vitesse d'exécution', mais optimisera dans le sens lisibilité et maintenabilité (mais là encore faut pas faire de la POO à toutes les sauces).

Une classe est un dessin de construction, un genre de patron, qui permettra par la suite (comme une usine) de construire autant d'objets que tu le souhaites.

Pour la suite tu demandes quel objet créer, seulement tu ne peux avoir de réponse sans avoir une idée précise de la façon dont tu vas régler ta problématique.  Dans tous les cas cette solution doit être suffisamment complexe pour que la POO se justifie, car elle apporte un plus dans ton organisation.

Dans ton cas, j'ai du mal à voir l'intérêt de la POO, mais c'est un avis... peut-être vois-je mal le problème !

  • Partager sur Facebook
  • Partager sur Twitter
14 février 2017 à 11:12:03

lelorrain7 a écrit:

Si j'ai bien compris, on va avoir une class "tournoi", une class "joueur", une class "ronde" et une class "grille américaine", parce que ces objets "existent" Mais la class joueur est complètement passive, alors que la class "ronde" calcule des choses. Ça ne pose pas de problème ? Existe-t-il une PEP sur ce sujet ?


Je ne comprends pas "passive" ; ta classe Player ne contiendra pas que des informations immuables ?

class Player:
    def __init__(self, name, elo):
        """
        les instances de Player seraient créées via l'inscription
        """
		
        self.name = name
	self.elo = elo      # va évoluer
	self.victories = 0  # idem
	self.draws = 0      # idem
	self.losses = 0     # idem


Et l'intérêt dans ce cas d'utiliser des classes c'est de passer des objets à d'autres objets, exemple une classe Game (ou Rencontre, Partie...)

class Game:
    def __init__(self, white, black):
	"""
	white et black sont des instances de Player
	"""
	self.white = white
	self.black = black

	# résultat à mettre à jour à la fin du match
	# (avec gestion de la perf elo ?)
	self.result = None

Ton objet Player existe bien, et il est utile à d'autres objets

Un Match utilise une paire d'instances de Player

Une Ronde "contient"n Match

Une Grille "contient" n Ronde

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
14 février 2017 à 20:07:43 - Message modéré pour le motif suivant : Message complètement hors sujet


14 février 2017 à 20:25:06

Crée ton propre sujet et présente correctement ton code.....
  • Partager sur Facebook
  • Partager sur Twitter
15 février 2017 à 15:36:46

Bonour,

lelorrain7 a écrit:

J'aurai aimé savoir comment organiser un programme en Programmation Orientée Objet (POO). Je ne suis qu'un autodidacte en python, mais j'aime ça.

Vaste question, mais très intéressante. Je me suis retrouvé tout comme toi un peu bloqué devant ce problème à l'époque.

lelorrain7 a écrit:

Si je comprends bien, mon programme, c'est une usine, mes class, ce sont des personnes de l'usine qui font leur boulot dans leur coin (des sous programmes autonomes ?) et qui travaillent sur des objets qui circulent (oui je sais... On conceptualise comme on peut).

L'analogie semble indiquer que tu confonds class et **instance de classe*. Le premier c'est la définition de l'objet de ce type. Le deuxième c'est un de ces objets. Si je reprends alors ton analogie, je dirais plutôt que ton usine a des ouvriers (instances de classes) qui manipulent des objets (instances d'autres classes). L'analogie reste bancale car l'usine peut créer des ouvriers, les détruire, etc. :)

Pour determiner tes classes, ça peut t'aider te regarder la description du projet et de traduire les noms par des classes et les actions / verbes par des méthodes de ces classes. Il faut aussi bien penser pour une méthode : qui est responsable pour faire ça ?

lelorrain7 a écrit:

1) gestion des inscriptions pour dresser une liste des participants.

On aurait déjà une classe Participant qui contiendrait leur nom, adresse et tout ce qui est nécessaire à connaître sur eux. Il y a aussi la liste des participants qui est ... une liste. :) Il te faudra probablement les actions suivantes (communément appelées CRUD)

  • Create
  • Read
  • Update
  • Delete

Ainsi que des méthodes de sérialisations. Autrement dit un :

  • Load
  • Save

On se rend compte que toutes ces méthodes ne sont pas la responsabilité du Participant, mais de la liste qui les contient. Le participant semble n'être qu'une série de variables. Dans ce cas, on pourrait faire de Participant un namedtuple et il faut trouver un nom pour la liste des participants ; mettons ListeParticipants.

lelorrain7 a écrit:

2) ordonner la liste (du plus fort au moins fort) et attribuer un numéro

Une responsabilité de notre ListeParticipants. Ca fait deux méthodes de plus.

lelorrain7 a écrit:

3) organiser une ronde

  1. mettre en place les adversaires en suivant les règles d'appareillement automatiques ou forcées
  2. enregistrer les résultats des joueurs
  3. mettre à jour la grille américaine (la grille de synthèse des rencontres avec le calcul des critères de départage)

On a un nouveau nom : une Ronde ou Tournoi. Elle met en place (action => méthode) les adversaires selon des règles. Il s'agit probablement des matches. Donc il faudrait une classe Match. Je ne sais pas si les adversaires sont les participants ou seulement un sous-ensemble. Selon il faudra une autre classe qui s'occupe de sélectionner des participants dans la liste des participants pour en faire des joueurs.

Pour le point 2 c'est une action et c'est la responsabilité du Tournoi.

Pour le 3, comme je ne sais pas de quoi on parle, je te laisse faire l'exercice par toi-même. :)

  • Partager sur Facebook
  • Partager sur Twitter