2009-11-15 11 views
1

Débutant en python, mais programmé depuis environ 5 ans maintenant. Je soupçonne que j'ai beaucoup à apprendre à faire les choses de manière orientée objet, mais je connais les bases. J'ai prévu de programmer une calculatrice qui montre que c'est un travail pour le défi et les connaissances que je vais en tirer. Je viens de commencer et c'est ce que j'ai, et ça me semble vraiment moche. Comment l'auriez-vous fait différemment?Comment puis-je rendre ce code Python plus utilisable et lisible?

P.S. Ceci est juste un script simple pour prendre le problème de l'intérieur de la parenthèse, l'ajouter, montrer le travail, puis évaluer le problème complet.

import re 

def EvalParenths(problem): 
    contents = "" 
    if re.match("\(", problem): 
     contents = re.match("(\(.*\))", problem) 
     parenthsAnswer = contents.group(0) 
     problem = problem.replace(parenthsAnswer, '') 
     print " \ \n " + str(eval(parenthsAnswer)) + problem 
     problem = problem.replace(parenthsAnswer, '') 
     answer = eval(parenthsAnswer+problem) 
     print " \ \n " + str(answer) 
    else: 
     print "Didn't Find Parenthesis" 

def ProblemHasParenths(problem): 
    return re.match("\(", problem) 

""""" 
Example Problem: (12/4)*2 

""""" 

problem = raw_input() 

if ProblemHasParenths: 
    EvalParenths(problem) 
+2

Il est très lisible pour moi, et je ne connais pas un peu de Python. – Konamiman

+0

Merci :) Je me sens parfois comme si je faisais tout mal depuis que j'ai toujours codé par moi-même, et ne me sens pas comme si j'en savais assez sur OOP et autres. – Codygman

Répondre

2

Si vous voulez faire une simple calculatrice, vous pouvez essayer d'implémenter Shunting-yard algorithm.

Mais si vous voulez aller avec l'approche regex je serais toujours le faire un peu différemment:

import re 

#In python functions/methods usually are lowercase 
#and words are seperated by _ while classes use CamelCasing 
def eval_step_by_step(expression): 
    """Evaluates math expression. Doesn't do any error checking. 
     expression (string) - math expression""" 

    print expression 
    #For pretty formating. 
    expr_len = len(expression) 
    #While there's parentheses in the expression. 
    while True: 
     #re.match checks for a match only at the beginning of the string, 
     #while re.search checks for a match anywhere in the string. 

     #Matches all numbers, +, -, *,/and whitespace within parentheses 
     #lazily (innermost first). 
     contents = re.search("\(([0-9|\*|/|\+|\-|\s]*?)\)", expression) 
     #If we didn't find anything, print result and break out of loop. 
     if not contents: 
      #string.format() is the Python 3 way of formating strings 
      #(Also works in Python 2.6). 

      #Print eval(expression) aligned right in a "field" with width 
      #of expr_len characters. 
      print "{0:{1}}".format(eval(expression), expr_len) 
      break 

     #group(0) [match] is everything matching our search, 
     #group(1) [parentheses_text] is just epression withing parentheses. 
     match, parentheses_text = contents.group(0), contents.group(1) 
     expression = expression.replace(match, str(eval(parentheses_text))) 
     #Aligns text to the right. Have to use ">" here 
     #because expression is not a number. 
     print "{0:>{1}}".format(expression, expr_len) 

#For example try: (4+3+(32-1)*3)*3 
problem = raw_input("Input math problem: ") 

eval_step_by_step(problem) 

Il ne fonctionne pas exactement la même chose que votre fonction, mais vous pouvez facilement mettre en œuvre des modifications dans votre fonction pour correspondre à la mienne. Comme vous pouvez le voir, j'ai aussi ajouté beaucoup de commentaires pour expliquer certaines choses.

+0

Merci pour la recommandation algo. Je suis sur le point d'aller au lit de toute façon :) Je suis en train de lire sur l'algo de triage en ce moment! – Codygman

+0

BTW, la raison pour laquelle je veux faire une calculatrice qui montre les étapes est que je crois qu'il va m'aider dans la programmation de type intelligence artificielle – Codygman

+0

J'ai mis à jour avec du code, désolé pour le retard quelque chose est venu. –

5

Quelques problèmes:

contents = re.match("(\(.*\))", problem) 

Quand il a donné l'entrée (1+2)/(3+4), il va essayer d'évaluer 1+2)/(3+4.

Il ne va pas aussi bien dans les parenthèses imbriquées, pour cela vous devrez utiliser la récursivité.

Je pense que vous devriez faire une autre tentative avant de "regarder les réponses". Pourquoi ne correspondez-vous pas seulement aux doubles parenthèses et aux parenthèses correspondantes?

+0

Je ferai quand je me lève le matin! Merci pour le conseil – Codygman

0

Le premier match pour un seul ( n'est pas vraiment nécessaire car si la correspondance pour les doubles échoue, cela signifie qu'il n'y a pas d'expression à évaluer.

import re 

def eval_parentheses(problem): 
    contents = re.match("(\(.*\))", problem) 
    if contents: 
    ... 
    else: 
     print "Couldn't find parentheses!" 

En outre, l'algorithme de sélection entre parenthèses pourrait être améliorée un peu pour parens imbriqués etc.

2

Je remplacerai probablement les occurrences de

re.match("\(", problem) 

avec

problem.startswith("(") 

En

contents = re.match("(\(.*\))", problem) 
parenthsAnswer = contents.group(0) 

vous ne cochez pas pour voir si le contenu correspond à ou pas si vous passez l'entrée « (1 » vous obtiendrez une exception lorsque vous essayez d'évaluer contents.group (0)

Don » t chaque utilisation eval dans un vrai programme!

Vous pouvez utiliser pyparsing pour faire un analyseur complet, mais je pense que c'est le genre de chose que tout le monde devrait essayer lui-même comme un exercice au moins une fois!