简体   繁体   English

如何使此Python代码更易用和可读?

[英]How Can I Make This Python Code More Usable And Readable?

Beginner in python, but been programming for about 5 years now. python的初学者,但是已经进行了大约5年的编程。 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? 您将如何做不同的事情?

PS This is just a simple script to take the problem from inside parenthesis, add it up, show the work, then evaluate the full problem. PS这只是一个简单的脚本,用于从括号内提取问题,将其加起来,显示工作,然后评估整个问题。

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)

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 . 当给定输入(1+2)/(3+4) ,它将尝试计算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". 我认为您应该在“查看答案”之前对此进行另一尝试。

If you want to make a simple calculator you could try implementing Shunting-yard algorithm . 如果您想制作一个简单的计算器,则可以尝试实现Shunting-yard算法

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. 如您所见,我还添加了很多评论来解释一些内容。

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) 您不会检查内容是否匹配,因此,如果将其传递给输入“(1”,则在尝试评估contents.group(0)时会出现异常。

Don't every use eval in a real program! 不要在实际程序中都使用eval

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! 您可以使用pyparsing来制作完整的解析器,但是我认为这是每个人至少应该一次尝试一次的练习!

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. 此外,对于嵌套的括号等,可以对括号选择算法进行一些改进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM