Avis sur un plus ou moins

Le problème exposé dans ce sujet a été résolu.

Bonjour à tous,

J'essaie de me mettre à python et j'ai codé un petit "plus ou moins".

J'aimerais savoir si mon code est "pythonic" ou non et comment l'améliorer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# -*- coding: utf-8 -*-

import random
from enum import Enum

class POM(Enum):
    TOO_BIG = 1
    TOO_SMALL = -1
    FOUND = 0
    
class PlusOuMoins:
    def __init__(self, max_number=100):
        self.__max_number = 100
        self.__guessed_number = random.randint(0,max_number)
    
    def ask_for(self, number):
        if(number<self.__guessed_number):
            return POM.TOO_SMALL
        elif(number>self.__guessed_number):
            return POM.TOO_BIG
        else:
            return POM.FOUND

def plus_ou_moins(max_number=100):
    pom = PlusOuMoins(max_number)
    while True:
        user_number = ask_a_number(max_number)
        res = pom.ask_for(user_number)
        if(res == POM.TOO_SMALL):
            print('Too small')
        elif(res == POM.TOO_BIG):
            print('Too big')
        else:
            print('Found')
            break

def ask_a_number(max_number):
    try:
        user_number = int(input('Enter a number between 0 and {}: '.format(max_number)))
        if(user_number<0 or user_number>max_number):
            return ask_a_number(max_number)
        else:
            return user_number
    except ValueError:
        print('Please enter a number')
        return ask_a_number(max_number)

def try_to_guess_number(max_number=100):
    pom = PlusOuMoins(max_number)
    max_guess = max_number
    min_guess = 0
    while True:
        guess = (max_guess-min_guess)//2+min_guess
        print(guess)
        res = pom.ask_for(guess)
        if(res == POM.TOO_SMALL):
            min_guess = guess+1
        elif(res == POM.TOO_BIG):
            max_guess = guess-1
        else:
            break
        
if __name__ == "__main__":
    try:
        user_input = int(input('Enter 0 to play or 1 to let the compulter play: '))
    except ValueError:
        print('Please enter a number')
    if(user_input == 0):
        plus_ou_moins(100)
    elif(user_input == 1):
        try_to_guess_number(100)
    else:
        print('Plesae enter 0 or 1')

+0 -0

Au-delà du fait que ce soit over-engineered (la classe ne sert à rien, l'enum ne factorise pas grand chose) :

  • Les parenthèses ne servent à rien à côté d'un if.
  • L'encadrement se teste avec if not 0 <= user_number <= max_number:
  • Tu fais une conversion inutile en int dans ton menu,
  • Tu gères un cas d'erreur par un appel récursif dans ask_a_number, en Python on utiliserait plutôt une boucle,
  • C'est mal nommé : je vois au moins 4 occurrences de plus_ou_moins, PlusOuMoins, POM ou pom. Ça devrait te donner un indice : si tu n'es pas en mesure de donner un nom unique, explicite et sans ambiguïté à un objet, c'est que la conception n'est pas claire dans ta tête et que tu peux probablement faire beaucoup plus simple que ça.

Pythonique, ça veut dire respecter le zen de Python (import this dans une console), dont la règle d'or serait ici Simple is better than complex.

+4 -0

Salut!

J'ai masqué mes deux précédents messages car ils ne servaient à rien, si ce n'est troller. Effectivement, je ne suis pas expert en python mais ton code comporte pas mal d'incohérences… :-°

En revanche, quand tu aura corrigé tes erreurs, tu pourras regarder de ce coté. ;-)

Je pense que l'on apprend de ses erreurs en les acceptants puis en les humiliants. :-)

+0 -0

Salut,

Effectivement mon code est over-engineered. J'aurai dû directement poser ma question …

En fait, j’essaie de comprendre un peu plus le langage Python et de rendre mon code "moins C++". Par ex, cette vidéo sur l'EAFP est typiquement ce qui m'intéresse (notamment l’exemple très intéressant pour accéder à un tableau en vérifiant de ne pas dépasser). Ma question était débile, sorry :-°

@Ozmox J'ai vu ton deuxième message (celle avec l'image) et ça m'a plutôt fait sourire ;) Et je suis parfaitement d'accord avec ta dernière phrase.

En fait, une astuce pour ne pas coder en Python à-la-C++, c'est de se forcer au départ faire le maximum de trucs dans un shell interactif quand tu codes.

Au bout d'un moment, tu verras que tu vas coder 90% de tes fonctionnalités dans des fonctions hyper courtes et simples. Tu n'auras plus qu'à les mettre en forme dans un fichier et rajouter des docstrings et le tour sera joué.

Il faudra aussi que tu passes énormément de temps à tricher sur ce que tu connais du système de types de C++ : en Python, tu prends une tétrachiée de raccourcis pour en faire 10 fois plus avec 5 fois moins de code.

À ce point de vue, je suis tombé il n'y a pas très longtemps sur bpython que j'installe systématiquement chaque fois que je crée un virtualenv, parce qu'il a toutes les features qui m'intéressent (et qui manquent au shell standard), sans la lourdeur d'ipython :

  • coloration syntaxique,
  • complétion automatique, avec affichage de la doc des fonctions en temps réel,
  • spawning d'un éditeur de texte quand tu veux écrire du code multi-ligne,
  • tu peux utiliser ton éditeur de texte pour revenir dans le passé, récrire des lignes, et réinterpréter totalement ta session,
  • tu peux effacer des lignes que tu as tapées en te gourant.

C'est super pratique pour l'usage que j'ai de mon interpréteur, parce que j'utilise énormément celui-ci, non seulement pour tester mon code ou explorer des modules tiers, mais aussi pour faire du code de démo que je colle ensuite dans mes posts sur le forum ou dans des tutoriels.

+1 -0
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