[Git][NTPsec/ntpsec][wip-ntpq-peers-display] mreadlist now properly displays units.
Ian Bruene
gitlab at mg.gitlab.com
Wed Mar 29 00:21:57 UTC 2017
Ian Bruene pushed to branch wip-ntpq-peers-display at NTPsec / ntpsec
Commits:
f8143746 by Ian Bruene at 2017-03-28T19:20:20-05:00
mreadlist now properly displays units.
- - - - -
1 changed file:
- pylib/util.py
Changes:
=====================================
pylib/util.py
=====================================
--- a/pylib/util.py
+++ b/pylib/util.py
@@ -89,14 +89,45 @@ def portsplit(hostname):
def filtcooker(data):
"Cooks the string of space seperated numbers with units"
parts = data.split()
- cooked = []
+ floatyparts = []
+ oomcount = {}
+ # Find out what the 'natural' unit of each value is
for part in parts:
part = float(part)
- cooked.append(unitformatter(part, UNITS_SEC, UNIT_MS))
- rendered = "".join(cooked)
+ floatyparts.append(part)
+ value, oom = scaleforunit(part)
+ oomcount[oom] = oomcount.get(oom, 0) + 1
+ # Find the most common unit
+ mostcommon = None
+ highestcount = 0
+ for key in oomcount.keys():
+ count = oomcount[key]
+ if count > highestcount:
+ mostcommon = key
+ highestcount = count
+ newunit = mostcommon + UNIT_MS
+ # Shift all values to the new unit
+ cooked = []
+ for part in floatyparts:
+ fmt = formatdigitsplit(part, 7)
+ temp = fmt % rescaleunit(part, mostcommon)
+ cooked.append(temp)
+ rendered = " ".join(cooked) + " " + UNITS_SEC[newunit]
return rendered
+def rescaleunit(f, ooms):
+ "Rescale a number by enough orders of magnitude for N units"
+ count = abs(ooms)
+ shiftup = (True if (f > 0.0) else False) # up or down the unit list?
+ for i in range(count):
+ if shiftup:
+ f /= 1000.0
+ else:
+ f *= 1000.0
+ return f
+
+
def scaleforunit(f):
"Scales a number by units to keep it in the range 0.000-999.9"
if f == 0.0: # guard against looping forever
@@ -111,9 +142,28 @@ def scaleforunit(f):
return (f, unitsmoved)
+def formatdigitsplit(f, fieldsize):
+ "Create a format string for a float without adding fake precision."
+ if f.is_integer(): # This also catches f == 0.0
+ return "%" + str(fieldsize) + "d"
+ af = abs(f)
+ if af >= 100.0:
+ maxdigits = fieldsize - 4 # xxx.
+ elif af >= 10.0:
+ maxdigits = fieldsize - 3 # xx.
+ elif af >= 1.0:
+ maxdigits = fieldsize - 2 # x.
+ if f < 0.0:
+ maxdigits -= 1 # need to fit a negative symbol
+ sig = len(str(f).split(".")[1]) # count digits after the decimal point
+ subdigits = min(sig, maxdigits) # use min so we don't add fake data
+ formatter = "%" + str(fieldsize) + "." + str(subdigits) + "f"
+ return formatter
+
+
def unitformatter(f, unitgroup, startingunit, baseunit=None,
strip=False, width=8):
- "Formatting for unit associated values in 8 characters."
+ "Formatting for unit associated values in N characters."
if width is not None: # For padding to n characters
padder = (lambda x: (" " * (width - len(x))) + x)
else:
@@ -130,35 +180,14 @@ def unitformatter(f, unitgroup, startingunit, baseunit=None,
f, unitsmoved = scaleforunit(f)
unitget = startingunit + unitsmoved
if (0 <= unitget < len(unitgroup)):
- # CATCH HERE: width==None, then render at full size
unit = unitgroup[unitget]
if width is None:
rendered = repr(f) + unit
return rendered
displaysize = width - len(unit)
af = abs(f)
- if af.is_integer():
- # No decimal places, so don't show any.
- formatstring = "%" + str(displaysize) + "d"
- rendered = (formatstring % f) + unit
- if not strip:
- rendered = padder(rendered)
- return rendered
- # Ok, not zero, not int, and in unit range. Can finally format
- # We need to know how many chars are taken by the point and what
- # is above it. Hence, maxdigits.
- if af >= 100.0:
- maxdigits = displaysize - 4 # xxx.
- elif af >= 10.0:
- maxdigits = displaysize - 3 # xx.
- elif af >= 1.0:
- maxdigits = displaysize - 2 # x.
- if f < 0.0:
- maxdigits -= 1 # need to fit a negative symbol
- # How many sub-decimal digits do we have / need?
- sigdigits = len(str(af).split(".")[1]) # count digits after point
- formatdigits = min(sigdigits, maxdigits) # don't add fake data
- formatter = "%" + str(displaysize) + "." + str(formatdigits) + "f"
+ # Ok, not zero, and in unit range. Can finally format
+ formatter = formatdigitsplit(f, displaysize)
rendered = (formatter % f) + unit
if strip:
rendered = rendered.strip()
@@ -354,7 +383,7 @@ def cook(variables, showunits=False):
longestspecial = len(max(specials, key=len))
for (name, value) in variables.items():
if name in specials: # need special formatting for column alignment
- formatter = "%" + str(longestspecial) + "s="
+ formatter = "%" + str(longestspecial) + "s ="
item = formatter % name
else:
item = "%s=" % name
@@ -371,7 +400,7 @@ def cook(variables, showunits=False):
item += ("00", "01", "10", "11")[value]
elif name == "reach":
item += "%03lo" % value
- elif name in ("filtdelay", "filtoffset", "filtdisp", "filterror"):
+ elif name in specials:
if showunits:
item += filtcooker(value)
else:
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/f814374635458e87c749b1edbe66aebc665c0d8a
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20170329/930f4449/attachment.html>
More information about the vc
mailing list