Avis sur un plus ou moins

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

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')

Édité par neo2500

+0 -0
Staff

Cette réponse a aidé l'auteur du sujet

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.

Édité par nohar

I was a llama before it was cool

+7 -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. :-)

Édité par Ozmox

Éternel curieux

+0 -0
Auteur du sujet

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.

+0 -0
Staff

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.

Édité par nohar

I was a llama before it was cool

+2 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

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