scripts: Added support for SI-prefixes as iI punescape modifiers
This adds %i and %I as punescape modifiers for limited printing of integers with SI prefixes: - %(field)i - base-10 SI prefixes - 100 => 100 - 10000 => 10K - 0.01 => 10m - %(field)I - base-2SI prefixes - 128 => 128 - 10240 => 10Ki - 0.125 => 128mi These can also easily include units as a part of the punescape string: - %(field)iops/s => 10Kops/s - %(field)IB => 10KiB This is particularly useful in plotmpl.py for adding explicit x/yticklabels without sacrificing the automatic SI-prefixes.
This commit is contained in:
+73
-3
@@ -56,6 +56,38 @@ CODE_PATH = ['./scripts/code.py']
|
|||||||
STACK_PATH = ['./scripts/stack.py']
|
STACK_PATH = ['./scripts/stack.py']
|
||||||
CTX_PATH = ['./scripts/ctx.py']
|
CTX_PATH = ['./scripts/ctx.py']
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# open with '-' for stdin/stdout
|
# open with '-' for stdin/stdout
|
||||||
def openio(path, mode='r', buffering=-1):
|
def openio(path, mode='r', buffering=-1):
|
||||||
@@ -405,6 +437,38 @@ class CsvAttr:
|
|||||||
|
|
||||||
return len(self.keyed)
|
return len(self.keyed)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
# attrs can override __getitem__ for lazy attr generation
|
# attrs can override __getitem__ for lazy attr generation
|
||||||
@@ -415,7 +479,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -435,10 +499,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
@@ -456,7 +526,7 @@ def psplit(s):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+72
-2
@@ -58,6 +58,38 @@ CODE_PATH = ['./scripts/code.py']
|
|||||||
STACK_PATH = ['./scripts/stack.py']
|
STACK_PATH = ['./scripts/stack.py']
|
||||||
CTX_PATH = ['./scripts/ctx.py']
|
CTX_PATH = ['./scripts/ctx.py']
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# open with '-' for stdin/stdout
|
# open with '-' for stdin/stdout
|
||||||
def openio(path, mode='r', buffering=-1):
|
def openio(path, mode='r', buffering=-1):
|
||||||
@@ -267,6 +299,38 @@ class CsvAttr:
|
|||||||
|
|
||||||
return len(self.keyed)
|
return len(self.keyed)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
# attrs can override __getitem__ for lazy attr generation
|
# attrs can override __getitem__ for lazy attr generation
|
||||||
@@ -277,7 +341,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -297,10 +361,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
|
|||||||
+75
-2
@@ -24,6 +24,38 @@ import os
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# various field types
|
# various field types
|
||||||
|
|
||||||
@@ -1274,6 +1306,37 @@ class CsvExpr:
|
|||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
sys.exit(3)
|
sys.exit(3)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
@@ -1285,7 +1348,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -1305,10 +1368,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
@@ -1330,6 +1399,10 @@ def punescape_help():
|
|||||||
'%Uaaaaaaaa', 'A character with the hex value aaaaaaaa'))
|
'%Uaaaaaaaa', 'A character with the hex value aaaaaaaa'))
|
||||||
print(' %-21s %s' % (
|
print(' %-21s %s' % (
|
||||||
'%(field)s', 'An existing field formatted as a string'))
|
'%(field)s', 'An existing field formatted as a string'))
|
||||||
|
print(' %-21s %s' % (
|
||||||
|
'%(field)i', 'An field formatted with a base-10 SI prefix'))
|
||||||
|
print(' %-21s %s' % (
|
||||||
|
'%(field)I', 'An field formatted with a base-2 SI prefix'))
|
||||||
print(' %-21s %s' % (
|
print(' %-21s %s' % (
|
||||||
'%(field)[dboxX]', 'An existing field formatted as an integer'))
|
'%(field)[dboxX]', 'An existing field formatted as an integer'))
|
||||||
print(' %-21s %s' % (
|
print(' %-21s %s' % (
|
||||||
|
|||||||
+73
-3
@@ -114,6 +114,38 @@ CHARS_BRAILLE = (
|
|||||||
'⠉⢉⡉⣉⠩⢩⡩⣩⠍⢍⡍⣍⠭⢭⡭⣭' '⠙⢙⡙⣙⠹⢹⡹⣹⠝⢝⡝⣝⠽⢽⡽⣽'
|
'⠉⢉⡉⣉⠩⢩⡩⣩⠍⢍⡍⣍⠭⢭⡭⣭' '⠙⢙⡙⣙⠹⢹⡹⣹⠝⢝⡝⣝⠽⢽⡽⣽'
|
||||||
'⠋⢋⡋⣋⠫⢫⡫⣫⠏⢏⡏⣏⠯⢯⡯⣯' '⠛⢛⡛⣛⠻⢻⡻⣻⠟⢟⡟⣟⠿⢿⡿⣿')
|
'⠋⢋⡋⣋⠫⢫⡫⣫⠏⢏⡏⣏⠯⢯⡯⣯' '⠛⢛⡛⣛⠻⢻⡻⣻⠟⢟⡟⣟⠿⢿⡿⣿')
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# some ways of block geometry representations
|
# some ways of block geometry representations
|
||||||
# 512 -> 512
|
# 512 -> 512
|
||||||
@@ -4023,6 +4055,38 @@ class CsvAttr:
|
|||||||
|
|
||||||
return len(self.keyed)
|
return len(self.keyed)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
# attrs can override __getitem__ for lazy attr generation
|
# attrs can override __getitem__ for lazy attr generation
|
||||||
@@ -4033,7 +4097,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -4053,10 +4117,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
@@ -4074,7 +4144,7 @@ def psplit(s):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+72
-2
@@ -133,6 +133,38 @@ HEIGHT = 350
|
|||||||
FONT = ['sans-serif']
|
FONT = ['sans-serif']
|
||||||
FONT_SIZE = 10
|
FONT_SIZE = 10
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# open with '-' for stdin/stdout
|
# open with '-' for stdin/stdout
|
||||||
def openio(path, mode='r', buffering=-1):
|
def openio(path, mode='r', buffering=-1):
|
||||||
@@ -3911,6 +3943,38 @@ class CsvAttr:
|
|||||||
|
|
||||||
return len(self.keyed)
|
return len(self.keyed)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
# attrs can override __getitem__ for lazy attr generation
|
# attrs can override __getitem__ for lazy attr generation
|
||||||
@@ -3921,7 +3985,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -3941,10 +4005,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
|
|||||||
+73
-3
@@ -64,6 +64,38 @@ CHARS_BRAILLE = (
|
|||||||
'⠉⢉⡉⣉⠩⢩⡩⣩⠍⢍⡍⣍⠭⢭⡭⣭' '⠙⢙⡙⣙⠹⢹⡹⣹⠝⢝⡝⣝⠽⢽⡽⣽'
|
'⠉⢉⡉⣉⠩⢩⡩⣩⠍⢍⡍⣍⠭⢭⡭⣭' '⠙⢙⡙⣙⠹⢹⡹⣹⠝⢝⡝⣝⠽⢽⡽⣽'
|
||||||
'⠋⢋⡋⣋⠫⢫⡫⣫⠏⢏⡏⣏⠯⢯⡯⣯' '⠛⢛⡛⣛⠻⢻⡻⣻⠟⢟⡟⣟⠿⢿⡿⣿')
|
'⠋⢋⡋⣋⠫⢫⡫⣫⠏⢏⡏⣏⠯⢯⡯⣯' '⠛⢛⡛⣛⠻⢻⡻⣻⠟⢟⡟⣟⠿⢿⡿⣿')
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# open with '-' for stdin/stdout
|
# open with '-' for stdin/stdout
|
||||||
def openio(path, mode='r', buffering=-1):
|
def openio(path, mode='r', buffering=-1):
|
||||||
@@ -413,6 +445,38 @@ class CsvAttr:
|
|||||||
|
|
||||||
return len(self.keyed)
|
return len(self.keyed)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
# attrs can override __getitem__ for lazy attr generation
|
# attrs can override __getitem__ for lazy attr generation
|
||||||
@@ -423,7 +487,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -443,10 +507,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
@@ -464,7 +534,7 @@ def psplit(s):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -614,7 +614,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -634,10 +634,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
@@ -655,7 +661,7 @@ def psplit(s):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -498,7 +498,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -518,10 +518,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
|
|||||||
+73
-3
@@ -48,6 +48,38 @@ CHARS_BRAILLE = (
|
|||||||
'⠉⢉⡉⣉⠩⢩⡩⣩⠍⢍⡍⣍⠭⢭⡭⣭' '⠙⢙⡙⣙⠹⢹⡹⣹⠝⢝⡝⣝⠽⢽⡽⣽'
|
'⠉⢉⡉⣉⠩⢩⡩⣩⠍⢍⡍⣍⠭⢭⡭⣭' '⠙⢙⡙⣙⠹⢹⡹⣹⠝⢝⡝⣝⠽⢽⡽⣽'
|
||||||
'⠋⢋⡋⣋⠫⢫⡫⣫⠏⢏⡏⣏⠯⢯⡯⣯' '⠛⢛⡛⣛⠻⢻⡻⣻⠟⢟⡟⣟⠿⢿⡿⣿')
|
'⠋⢋⡋⣋⠫⢫⡫⣫⠏⢏⡏⣏⠯⢯⡯⣯' '⠛⢛⡛⣛⠻⢻⡻⣻⠟⢟⡟⣟⠿⢿⡿⣿')
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# open with '-' for stdin/stdout
|
# open with '-' for stdin/stdout
|
||||||
def openio(path, mode='r', buffering=-1):
|
def openio(path, mode='r', buffering=-1):
|
||||||
@@ -478,6 +510,38 @@ class CsvAttr:
|
|||||||
|
|
||||||
return len(self.keyed)
|
return len(self.keyed)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
# attrs can override __getitem__ for lazy attr generation
|
# attrs can override __getitem__ for lazy attr generation
|
||||||
@@ -488,7 +552,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -508,10 +572,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
@@ -529,7 +599,7 @@ def psplit(s):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
return [m.group() for m in re.finditer(pattern.pattern + '|.', s)]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+72
-2
@@ -50,6 +50,38 @@ HEIGHT = 350
|
|||||||
FONT = ['sans-serif']
|
FONT = ['sans-serif']
|
||||||
FONT_SIZE = 10
|
FONT_SIZE = 10
|
||||||
|
|
||||||
|
SI_PREFIXES = {
|
||||||
|
18: 'E',
|
||||||
|
15: 'P',
|
||||||
|
12: 'T',
|
||||||
|
9: 'G',
|
||||||
|
6: 'M',
|
||||||
|
3: 'K',
|
||||||
|
0: '',
|
||||||
|
-3: 'm',
|
||||||
|
-6: 'u',
|
||||||
|
-9: 'n',
|
||||||
|
-12: 'p',
|
||||||
|
-15: 'f',
|
||||||
|
-18: 'a',
|
||||||
|
}
|
||||||
|
|
||||||
|
SI2_PREFIXES = {
|
||||||
|
60: 'Ei',
|
||||||
|
50: 'Pi',
|
||||||
|
40: 'Ti',
|
||||||
|
30: 'Gi',
|
||||||
|
20: 'Mi',
|
||||||
|
10: 'Ki',
|
||||||
|
0: '',
|
||||||
|
-10: 'mi',
|
||||||
|
-20: 'ui',
|
||||||
|
-30: 'ni',
|
||||||
|
-40: 'pi',
|
||||||
|
-50: 'fi',
|
||||||
|
-60: 'ai',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# open with '-' for stdin/stdout
|
# open with '-' for stdin/stdout
|
||||||
def openio(path, mode='r', buffering=-1):
|
def openio(path, mode='r', buffering=-1):
|
||||||
@@ -339,6 +371,38 @@ class CsvAttr:
|
|||||||
|
|
||||||
return len(self.keyed)
|
return len(self.keyed)
|
||||||
|
|
||||||
|
# SI-prefix formatter
|
||||||
|
def si(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 3*mt.floor(mt.log(abs(x), 10**3))
|
||||||
|
p = min(18, max(-18, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (10.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI_PREFIXES[p])
|
||||||
|
|
||||||
|
# SI-prefix formatter for powers-of-two
|
||||||
|
def si2(x):
|
||||||
|
if x == 0:
|
||||||
|
return '0'
|
||||||
|
# figure out prefix and scale
|
||||||
|
p = 10*mt.floor(mt.log(abs(x), 2**10))
|
||||||
|
p = min(30, max(-30, p))
|
||||||
|
# format with 3 digits of precision
|
||||||
|
s = '%.3f' % (abs(x) / (2.0**p))
|
||||||
|
s = s[:3+1]
|
||||||
|
# truncate but only digits that follow the dot
|
||||||
|
if '.' in s:
|
||||||
|
s = s.rstrip('0')
|
||||||
|
s = s.rstrip('.')
|
||||||
|
return '%s%s%s' % ('-' if x < 0 else '', s, SI2_PREFIXES[p])
|
||||||
|
|
||||||
# parse %-escaped strings
|
# parse %-escaped strings
|
||||||
#
|
#
|
||||||
# attrs can override __getitem__ for lazy attr generation
|
# attrs can override __getitem__ for lazy attr generation
|
||||||
@@ -349,7 +413,7 @@ def punescape(s, attrs=None):
|
|||||||
'|' '%u....'
|
'|' '%u....'
|
||||||
'|' '%U........'
|
'|' '%U........'
|
||||||
'|' '%\((?P<field>[^)]*)\)'
|
'|' '%\((?P<field>[^)]*)\)'
|
||||||
'(?P<format>[+\- #0-9\.]*[sdboxXfFeEgG])')
|
'(?P<format>[+\- #0-9\.]*[siIdboxXfFeEgG])')
|
||||||
def unescape(m):
|
def unescape(m):
|
||||||
if m.group()[1] == '%': return '%'
|
if m.group()[1] == '%': return '%'
|
||||||
elif m.group()[1] == 'n': return '\n'
|
elif m.group()[1] == 'n': return '\n'
|
||||||
@@ -369,10 +433,16 @@ def punescape(s, attrs=None):
|
|||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = int(v)
|
v = int(v)
|
||||||
elif f[-1] in 'fFeEgG':
|
elif f[-1] in 'iIfFeEgG':
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
v = dat(v, 0)
|
v = dat(v, 0)
|
||||||
v = float(v)
|
v = float(v)
|
||||||
|
if f[-1] in 'iI':
|
||||||
|
v = (si if 'i' in f[-1] else si2)(v)
|
||||||
|
f = f.replace('i', 's').replace('I', 's')
|
||||||
|
if '+' in f and not v.startswith('-'):
|
||||||
|
v = '+'+v
|
||||||
|
f = f.replace('+', '').replace('-', '')
|
||||||
else:
|
else:
|
||||||
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
f = ('<' if '-' in f else '>') + f.replace('-', '')
|
||||||
v = str(v)
|
v = str(v)
|
||||||
|
|||||||
Reference in New Issue
Block a user