Skip to content

Instantly share code, notes, and snippets.

@ultimatile
Last active January 22, 2020 08:48
Show Gist options
  • Save ultimatile/33c46177ba140ec0d00964fcd118f48b to your computer and use it in GitHub Desktop.
Save ultimatile/33c46177ba140ec0d00964fcd118f48b to your computer and use it in GitHub Desktop.
print values and errors with significant figures in python
#!/usr/bin/env python3
import numpy as np
def ve(x, xerror):
if abs(x) > xerror:
round_xerror = np.float("{:.1g}".format(xerror))
if round_xerror < 1:
exponent_xerror = np.int(np.floor(np.log10(round_xerror)))
mantissa_xerror = np.int(round_xerror / (10 ** exponent_xerror))
round_x = np.round(x, -exponent_xerror)
specifier_x = "." + str(-exponent_xerror) + "f"
return str(format(round_x, specifier_x) + "({})".format(mantissa_xerror))
else:
return str("{}({})".format(np.int(x), np.int(round_xerror)))
#return str("{}({})".format(np.int(x), np.int(xerror)))
else:
round_x = np.float("{:.1g}".format(abs(x)))
exponent_x = np.int(np.floor(np.log10(abs(round_x))))
round_xerror = np.round(xerror, -exponent_x)
mantissa_x = np.int(round_x / (10 ** exponent_x))
print("here")
if x < 0:
strh = "-"
else:
strh = ""
if round_xerror < 1:
vstr = strh + "0." + "0" * (-exponent_x - 1) + str(mantissa_x)
estr = str(np.int(round_xerror / (10 ** exponent_x)))
return vstr + "(" + estr + ")"
else:
#return str("{}({})".format(np.int(x), np.int(round_xerror)))
return str("{}({})".format(np.int(x), np.int(xerror)))
def case_ve(x, xerror):
if abs(x) > xerror:
round_xerror = np.float("{:.1g}".format(xerror))
if round_xerror < 1:
return "case abs(x) > xerror and round_xerror < 1"
else:
return "case abs(x) > xerror and round_xerror >= 1"
else:
round_x = np.float("{:.1g}".format(abs(x)))
exponent_x = np.int(np.floor(np.log10(abs(round_x))))
round_xerror = np.round(xerror, -exponent_x)
if round_xerror < 1:
return "case abs(x) <= xerror and round_xerror < 1"
else:
return "case abs(x) <= xerror and round_xerror >= 1"
def assertve(x, xerror, ans):
assert ve(x, xerror) == ans, "\nfailed; x={}, xerror={}\n showed: {}\n answer: {}\n{}".format(x, xerror, ve(x, xerror), ans, case_ve(x, xerror))
print("pass\n")
if __name__ == "__main__":
print("test 1")
x = -0.0123456
xerror = 0.00123456
ans = "-0.012(1)"
assertve(x, xerror, ans)
print("test 2")
x = 9.157422490306612e-05
xerror = 0.0001123
ans = "0.00009(11)"
assertve(x, xerror, ans)
print("test 3")
x = 0.00009157422490306612
xerror = 0.00000000001133813481973717
ans = "0.00009157422(1)"
assertve(x, xerror, ans)
print("test 4")
x = 1.23456789E5
xerror = 1.23456789E13
ans = "123456(12345678900000)"
assertve(x, xerror, ans)
print("test 5")
x = 12.3456789
xerror = 987.654321
ans = "12(987)"
assertve(x, xerror, ans)
print("test 6")
x = 0.00125421
xerror = 0.0235
ans = "0.001(24)"
assertve(x, xerror, ans)
#not yet pass following tests
print("test 7")
x = 123456.7891423362361
xerror = 1.23456789E-13
ans = "123456.7891423362361(1)"
assertve(x, xerror, ans)
print("test 8")
x = 1.23456789E10
xerror = 1.23456789E5
ans = "12345678900(123457)"
assertve(x, xerror, ans)
@zoome0215
Copy link

zoome0215 commented Dec 21, 2017

def finddot( numstr ):
    for i in range(0,len(numstr)):
        if numstr[i] == "." :
            return i
    return len(numstr)

def findnonzero( numstr ):
    for i in range(0,len(numstr)):
        if (numstr[i] != ".") and (numstr[i] != "0"):
            return i
    else :
        return len(numstr)

#input
x = -0.000000010123441
xe = 0.0110000

#reformat
xe=abs(xe)

#string
x_str = '{:.15f}'.format(abs(x))
xe_str = '{:.15f}'.format(xe)

#find decimal point
x_dp = finddot(x_str)
xe_dp = finddot(xe_str)

#find first digit
x_fp = findnonzero(x_str)
xe_fp = findnonzero(xe_str)

if xe_dp < xe_fp:


    if x_dp == len(x_str):
        x_str+="."

        for i  in range(0,xe_fp-xe_dp) :
            x_str+="0"

    else :

        if (x_fp - x_dp) < (xe_fp - xe_dp) :
            x_deci_num = (len(x_str)-1) - x_dp
            i = x_deci_num
            while i < (xe_fp-1):
                x_str += "0"
                i+=1
            xe_str = xe_str[xe_fp]
        else:
            xe_deci_num = (len(xe_str)-1) - xe_dp
            i = xe_deci_num
            while i < (x_fp-1):
                xe_str += "0"
                i+=1
            x_str = x_str[0:x_fp+1]
            xe_str = xe_str[x_dp+1:x_dp+x_fp-x_dp+1]


else:
    xe_int_num = xe_dp-xe_fp

    x_str = x_str[0:x_dp]
    xe_str = list(xe_str[0:xe_dp])

    if len(x_str) > len(xe_str) :
        i = xe_fp + 1
        while i < len(xe_str):
            xe_str[i] = '0'
            i+= 1

    else:
        i = 0
        while i < (len(x_str)-1):
            i += 1
            xe_str[len(xe_str)-i] = '0'

        if abs(x) < 1:
            x = abs(x)

    xe_str = "".join(xe_str)

if x<0:
    x_str = "-"+x_str

print "{}({})".format(x_str,xe_str)

numpy懐疑主義者用
3倍のコード量か。。。
gistの使い方わからないのでコメントで失礼します。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment