English 中文(简体)
How Can I Make This Python Code More Usable And Readable?
原标题:

Beginner in python, but been programming for about 5 years now. I suspect I have a lot to learn about doing things the object oriented way, but I know the basics. I planned on programming a calculator that shows it s work for the challenge and knowledge i ll gain from it. I just started and this is what i ve got, and it just looks really ugly to me. How would you have done it differently?

P.S. This is just a simple script to take the problem from inside parenthesis, add it up, show the work, then evaluate the full problem.

import re

def EvalParenths(problem):
    contents = ""
    if re.match( "(", problem):
        contents = re.match("((.*))", problem)
        parenthsAnswer = contents.group(0)
        problem = problem.replace(parenthsAnswer,   )
        print "    
   "  + str(eval(parenthsAnswer)) + problem
        problem = problem.replace(parenthsAnswer,   )
        answer = eval(parenthsAnswer+problem)
        print "     
    " + 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)
最佳回答

If you want to make a simple calculator you could try implementing Shunting-yard algorithm.

But if you want to go with regex approach I d still do it a little differently:

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)

It doesn t exactly work the same as your function, but you could easily implement modifications into your function to match mine. As you can see, I ve also added a lot of comments to explain some stuff.

问题回答

Some problems:

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

When it s given the input (1+2)/(3+4), it s going to try to evaluate 1+2)/(3+4.

It also doesn t go all the way into nested parentheses, for this you would need to use recursion.

I think you should make another attempt at this before you "look at the answers".

I d probably replace occurrences of

re.match( "(", problem)

with

problem.startswith("(")

In

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

you don t check to see whether contents matches or not so if you pass it the input "(1" you ll get an exception when you try to evaluate contents.group(0)

Don t every use eval in a real program!

You could use pyparsing to make a full parser, but I think it is the kind of thing everyone should try on their own as an exercise at least once!

Why don t you match only for the double and matching parentheses? The first match for a single ( is not really necessary because if the match for the doubles fail, this means there are no expression for you to evaluate.

import re

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

Also, the parentheses selection algorithm could be improved a bit for nested parens etc.





相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签