【问题标题】:Python counting significant digitsPython计算有效数字
【发布时间】:2011-11-15 20:23:47
【问题描述】:

我将这个问题标记为 javascript,因为即使我目前用 Python 编写了这个问题,如果用 Javascript 更容易实现,我可以很容易地用 Javascript 实现它。

我的任务是为化学系做一个重要的数字计算检查器。这意味着学生将他们的数据输入到字段中,网络应用程序将对他们的字段执行预定义的操作并跟踪有效数字,并查看他们的答案是否具有正确数量的有效数字。

当我将问题分解为我认为是一个良好的工作流程时,我意识到我需要一种用于 Python(后端,因为这是一个用 Django 制作的网络应用程序)或 Javascript(因为你总是可以在前端验证它没问题)以确定有效位数。我做了一些研究,发现了this question,它告诉我我需要使用 python 字符串而不是浮点数。我目前的 python 代码感觉几乎完成了,但我仍然面临一个重大挑战

import re
def find_sigfigs(x):
    # change the 'E' to lower case if the student typed it in as uppercase
    x = x.lower()
    if ('e' in x):
        myStr = x.split('e')
        # this function assumes that the number on the left of the 'e' is
        # the number of sigfigs. That would be true for user input but not
        # true when python converts a float to scientific notation
        return len( (re.search('[0-9]+', myStr[0])).group() )
    else:
        # put it in e format and return the result of that
        ### problem: python makes me hard code the number of sigfigs as '2'
        ### without the 2 there it always defaults to 6
        return find_sigfigs('%.*e' %(2,float(x)))

>>> find_sigfigs('1.3e-4')
>>> 2
>>> find_sigfigs('1234')
>>> 3
>>> find_sigfigs('123456')
>>> 3
>>> find_sigfigs('1.2345e3')
>>> 5

然后没有 2

return find_sigfigs('%.e' %(float(x)))

#Because it changes it to 1.234000e3
>>> find_sigfigs('1234')
>>> 7

#Because it changes it to 1.234560e5
>>> find_sigfigs('123456')
>>> 7

简单地说,我的问题是我需要一种简单的方法来计算学生没有明确声明的 sigfigs(也就是科学记数法)。有没有一些简单的方法可以让我在“e”之前删除每个零,直到它到达第一个非零数字。我想,我需要从拆分字符串的后面开始,并删除零,直到它到达一个非零数字?

编辑:所以在稍微摆弄之后,我希望这是解决问题的适当方法。我测试了好几次,但不太严格(也可能有效,但谁知道呢!我不太擅长 sigfigs...)

def find_sigfigs(x):
    '''Returns the number of significant digits in a number. This takes into account
       strings formatted in 1.23e+3 format and even strings such as 123.450'''
    # change all the 'E' to 'e'
    x = x.lower()
    if ('e' in x):
        # return the length of the numbers before the 'e'
        myStr = x.split('e')
        return len( myStr[0] ) - 1 # to compenstate for the decimal point
    else:
        # put it in e format and return the result of that
        ### NOTE: because of the 8 below, it may do crazy things when it parses 9 sigfigs
        n = ('%.*e' %(8, float(x))).split('e')
        # remove and count the number of removed user added zeroes. (these are sig figs)
        if '.' in x:
            s = x.replace('.', '')
            #number of zeroes to add back in
            l = len(s) - len(s.rstrip('0'))
            #strip off the python added zeroes and add back in the ones the user added
            n[0] = n[0].rstrip('0') + ''.join(['0' for num in xrange(l)])
        else:
            #the user had no trailing zeroes so just strip them all
            n[0] = n[0].rstrip('0')
        #pass it back to the beginning to be parsed
    return find_sigfigs('e'.join(n))

【问题讨论】:

  • 感谢您的解决方案 :)

标签: javascript python


【解决方案1】:

我认为有一个不需要递归的更简单的解决方案。此外,上述解决方案仅在传入字符串时有效。要求字符串中的有效数字对我来说似乎很奇怪,所以感觉函数应该在内部进行这种转换,或者至少支持传递字符串和数字。

这是我想出的:

def find_sigfigs(number):
    """Returns the number of significant digits in a number"""

    # Turn it into a float first to take into account stuff in exponential
    # notation and get all inputs on equal footing. Then number of sigfigs is
    # the number of non-zeros after stripping extra zeros to left of whole
    # number and right of decimal
    number = repr(float(number))

    tokens = number.split('.')
    whole_num = tokens[0].lstrip('0')

    if len(tokens) > 2:
        raise ValueError('Invalid number "%s" only 1 decimal allowed' % (number))

    if len(tokens) == 2:
        decimal_num = tokens[1].rstrip('0')
        return len(whole_num) + len(decimal_num)

    return len(whole_num)

我错过了一些边缘情况吗?

【讨论】:

  • 注意repr()的使用,所以这在Python 2和3中是一样的。str()在python 2和3中改变了:stackoverflow.com/questions/25898733/…
  • 看起来如果你传入像1e-5 这样的数字,这将不起作用,因为str(float(1e-5)) 是如何工作的。需要找到一种方法来用适当的零扩展负指数。
【解决方案2】:

我认为正则表达式在这里有点矫枉过正,但是您的方法应该可以工作,而且我确信这不是性能问题。

我认为你在最后描述的内容是正确的。我会使用split('e'),后跟rstrip('0'),这将删除“尾随零”。然后,如果您想保留递归调用,可以将字符串重新组合在一起。

【讨论】:

  • 感谢rstrip() 的提示,这让我走上了正轨
猜你喜欢
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 2023-01-10
相关资源
最近更新 更多