Python:让这段代码更紧凑?

时间:2013-04-11 23:30:50

标签: python python-2.7 while-loop physics performance

如何摆脱此代码中过多的重复?

代码:http://pastebin.com/13e2nWM9

程序根据用户提供的数据计算运动方程(SUVAT方程)。

我所指的部分是:

while True:
        a = raw_input("What is the value of a? Make sure it is in standard units, however, do not include the unit.")
        try:
            float(a)
            print "a is " + str(a) + " ms^-2"
            break
        except:
            print"You must enter a number. Don't include units!"

重复多次,除了变量'a'和重复块时更改的单位。

非常感谢。

4 个答案:

答案 0 :(得分:3)

这是一个选项,将以下函数定义放在模块的顶部:

def get_float(name, units):
    prompt = "What is the value of {0}? Make sure it is in standard units, however, do not include the unit.".format(name)
    while True:
        val = raw_input(prompt)
        try:
            val = float(val)
            print '{0} is {1} {2}'.format(name, val, units)
            return val
        except Exception:
            print "You must enter a number. Don't include units!"

以下是如何使用它的示例,以下代码可以替换第72行到第100行的所有内容:

name_units_pairs = [('v', 'ms^-1'), ('a', 'ms^-2'), ('t', 's'),]
vals = {}
for name, units in name_units_pairs:
    vals[name] = get_float(name, units)
u = vals['v'] - vals['a'] * vals['t']

答案 1 :(得分:1)

不要使用原始的例外,并封装测试,这就是全部。 而不是

while True:
        a = raw_input("What is the value of a? Make sure it is in standard units, however, do not include the unit.")
        try:
            float(a)
            print "a is " + str(a) + " ms^-2"
            break
        except:
            print"You must enter a number. Don't include units!"

a = my_input(valuename='a', unit='m^-2', unitformat=float)

并在my_input中执行测试(和提示)。

my_input可能类似于:

def my_input(valuename, unit, unitformat=float):
  while True:
    val = raw_input("What is the value of %s? Make sure it is in standard units"+
                    "(%s), however, do not include the unit." % (valuename, unit))
    try:
        unitformat(val)
    except ValueError:
        print"You must enter a number. Don't include units!"
    else:
        print "%s is %s %s" % (valuename, val, unit)
        return val

答案 2 :(得分:0)

我认为没有理由认为这段代码有任何需要,或者实际上是任何用途,以提高效率。这里的限制因素是控制台输出的速度。

但是...

如果它节省的额外几纳秒真的,真的非常重要,不知何故,你可以加速它的最大方式(我认为,虽然它实际上可能因为解释而减慢速度)是单独输出打印的东西,在不同的打印语句中,因此它不必在内存中构造2个额外的字符串来表示"a is " + str(a)"a is " + str(a) + " ms^-2"的值。为了节省另外几纳​​秒,用一种编译成机器代码的语言编写程序。

或者,如果您的意思是使用较少的代码来执行相同的操作,请像其他人所说的那样封装输入。

答案 3 :(得分:0)

您可以使用循环自动输入,将值存储在字典中,然后在最后完成所有数学运算。

import math

units = {'s': 'm', 'u': 'ms^-1', 'v': 'ms^-1', 'a': 'ms^-2', 't': 's'}
variables = ['s', 'u', 'v', 'a', 't']
suvat = dict((k, None) for k in variables)
input_variables = []

def pick_from_list(prompt, L):
    while True:
        pick = raw_input(prompt % str(L))
        if pick in L:
            print "You have chosen", pick
            return pick
        print """Sorry, I didn't understand that, try again. Make sure your spelling is
            correct (Case Sensitive), and that you did not inlcude the quotation marks."""

aim = pick_from_list("""Welcome to Mattin's SUVAT Simulator! Choose the value you are
                    trying to find. You can pick from variables %s""",
                     variables)

for order in 'first', 'second', 'third':
    prompt = 'Please choose which variable to input %s. You can pick from %%s' % order
    choices = [k for k in variables if not (k is aim or k in input_variables)]
    input_variables.append(pick_from_list(prompt, choices))

for v in input_variables:
    while True:
        raw_input("""What is the value of %s? Make sure it is in standard
units, however, do not include the unit.""" % v)
        try:
            suvat[v] = float(val)
            print "%s is %s%s" % (v, val, units[v])
            break
        except:
            print "You must enter a number. Don't include units!"

# for readability of the maths, turn dictionary into variables
s, u, v, a, t = [suvat[k] for k in variables]

# (not tested)
if s is None:
    if t is None:
        t = (v - u) / a
    if v is None:
        s = u * t + .5 * a * t * t
    elif a is None:
        s = .5 * (u + v) * t
    else:
        s = v * t - .5 * a * t * t
if v is None:
    if u is None:
        u = s / t - .5 * a * t * t
    if t is None:
        v = math.sqrt(u * u + 2 * a * s)
    else:
        v = 2 * s / t - u
if u is None:
    if a is None:
        a = 2 * v / t - s / (t * t)
    u = math.sqrt(v * v - 2 * a * s)
if a is None:
    a = (v * v - u * u) / (2 * s)
if t is None:
    t = (v - u) / a

# turn the set of variables back into a dictionary
solutions = dict(zip(variables, [s, u, v, a, t]))
print 'Solution: %s=%s%s' % (aim, solutions[aim], units[aim])