CoinAmt: improve columnar formatting

This commit is contained in:
The MMGen Project 2022-11-13 15:36:35 +00:00
commit 9c07442191
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
10 changed files with 43 additions and 34 deletions

View file

@ -38,7 +38,6 @@ class CoinAmt(Decimal,Hilite,InitErrors): # abstract class
max_prec = 0 # number of decimal places for this coin
max_amt = None # coin supply if known, otherwise None
units = () # defined unit names, e.g. ('satoshi',...)
amt_fs = '0.0' # format string for the fmt() method
def __new__(cls,num,from_unit=None,from_decimal=False):
if type(num) == cls:
@ -73,21 +72,18 @@ class CoinAmt(Decimal,Hilite,InitErrors): # abstract class
def fmtc(cls):
cls.method_not_implemented()
def fmt(self,fs=None,color=False,suf='',prec=1000):
if fs == None:
fs = self.amt_fs
def fmt(self,color=False,iwidth=1,prec=None): # iwidth: width of the integer part
s = self.__str__()
if '.' in fs:
p1,p2 = list(map(int,fs.split('.',1)))
ss = s.split('.',1)
if len(ss) == 2:
a,b = ss
ret = a.rjust(p1) + '.' + ((b+suf).ljust(p2+len(suf)))[:prec]
else:
ret = s.rjust(p1) + suf + (' ' * (p2+1))[:prec+1-len(suf)]
prec = prec or self.max_prec
if '.' in s:
a,b = s.split('.',1)
return self.colorize(
a.rjust(iwidth) + '.' + b.ljust(prec)[:prec], # truncation, not rounding!
color = color )
else:
ret = s.ljust(int(fs))
return self.colorize(ret,color=color)
return self.colorize(
s.rjust(iwidth).ljust(iwidth+prec+1),
color = color )
def hl(self,color=True):
return self.colorize(self.__str__(),color=color)
@ -165,7 +161,6 @@ class BTCAmt(CoinAmt):
max_amt = 21000000
satoshi = Decimal('0.00000001')
units = ('satoshi',)
amt_fs = '4.8'
class BCHAmt(BTCAmt):
pass
@ -177,7 +172,6 @@ class XMRAmt(CoinAmt):
max_prec = 12
atomic = Decimal('0.000000000001')
units = ('atomic',)
amt_fs = '4.12'
# Kwei (babbage) 3, Mwei (lovelace) 6, Gwei (shannon) 9, µETH (szabo) 12, mETH (finney) 15, ETH 18
class ETHAmt(CoinAmt):
@ -189,7 +183,6 @@ class ETHAmt(CoinAmt):
szabo = Decimal('0.000001')
finney = Decimal('0.001')
units = ('wei','Kwei','Mwei','Gwei','szabo','finney')
amt_fs = '4.18'
def toWei(self):
return int(Decimal(self) // self.wei)

View file

@ -1 +1 @@
13.3.dev19
13.3.dev20

View file

@ -48,7 +48,7 @@ Actions: [q]uit, r[e]draw, [D]elete address, add [l]abel:
'num': max(2,len(str(len(data)))+1),
'mmid': max(len(d.twmmid.disp) for d in data),
'used': 0,
'amt': self.disp_prec + 5,
'amt': self.amt_widths['amt'],
'date': 0,
'block': 0,
'date_time': 0,

View file

@ -75,8 +75,8 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
widths = { # fixed cols
'num': max(2,len(str(len(data)))+1),
'mmid': max(len(d.twmmid.disp) for d in data) if self.show_mmid else 0,
'amt': self.disp_prec + 5,
'amt2': self.disp_prec + 5 if self.has_amt2 else 0,
'amt': self.amt_widths['amt'],
'amt2': self.amt_widths.get('amt2',0),
'spc': (5 if self.show_mmid else 3) + self.has_amt2, # 5(3) spaces in fs
'txid': 0,
'vout': 0,

View file

@ -131,7 +131,7 @@ class TwAddresses(TwView):
'num': max(2,len(str(len(data)))+1),
'mmid': max(len(d.twmmid.disp) for d in data),
'used': 4,
'amt': self.disp_prec + 5,
'amt': self.amt_widths['amt'],
'date': self.age_w if self.has_age else 0,
'block': self.age_col_params['block'][0] if wide and self.has_age else 0,
'date_time': self.age_col_params['date_time'][0] if wide and self.has_age else 0,
@ -179,7 +179,7 @@ class TwAddresses(TwView):
u = yes if d.recvd else no,
a = d.addr.fmt( color=color, width=cw.addr ),
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ),
A = d.amt.fmt( color=color, prec=self.disp_prec ),
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
d = self.age_disp( d, self.age_fmt )
)
@ -208,7 +208,7 @@ class TwAddresses(TwView):
u = yes if d.recvd else no,
a = d.addr.fmt( color=color, width=cw.addr ),
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ),
A = d.amt.fmt( color=color, prec=self.disp_prec ),
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
b = self.age_disp( d, 'block' ),
D = self.age_disp( d, 'date_time' ),
).rstrip()

View file

@ -69,7 +69,7 @@ class TwGetBalance(MMGenObject,metaclass=AsyncInit):
return len(str(int(max(v[colname] for v in self.data.values())))) + iwidth_adj
def make_col(label,col):
return(self.data[label][col].fmt(fs=f'{iwidths[col]}.{add_w-1}',color=color))
return(self.data[label][col].fmt(iwidth=iwidths[col],color=color))
if color:
from ..color import red,green,yellow

View file

@ -12,6 +12,8 @@
tw.txhistory: Tracking wallet transaction history class for the MMGen suite
"""
from collections import namedtuple
from ..util import fmt
from ..objmethods import MMGenObject
from ..obj import NonNegativeInt
@ -49,6 +51,10 @@ class TwTxHistory(TwView):
def filter_data(self):
return (d for d in self.data if d.confirmations > 0 or self.show_unconfirmed)
def set_amt_widths(self,data):
amts_tuple = namedtuple('amts_data',['amt'])
return super().set_amt_widths([amts_tuple(d.amt_disp(self.show_total_amt)) for d in data])
def get_column_widths(self,data,wide=False):
# var cols: inputs outputs comment [txid]
@ -77,7 +83,7 @@ class TwTxHistory(TwView):
widths = { # fixed cols
'num': max(2,len(str(len(data)))+1),
'date': self.age_w,
'amt': self.disp_prec + 5,
'amt': self.amt_widths['amt'],
'spc': 6 + self.show_txid, # 5(6) spaces between cols + 1 leading space in fs
}
@ -109,7 +115,7 @@ class TwTxHistory(TwView):
t = d.txid_disp( width=cw.txid, color=color ) if hasattr(cw,'txid') else None,
d = d.age_disp( self.age_fmt, width=self.age_w, color=color ),
i = d.vouts_disp( 'inputs', width=cw.inputs, color=color ),
A = d.amt_disp(self.show_total_amt).fmt( prec=self.disp_prec, color=color ),
A = d.amt_disp(self.show_total_amt).fmt( iwidth=cw.iwidth, prec=self.disp_prec, color=color ),
o = d.vouts_disp( 'outputs', width=cw.outputs, color=color ),
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ) ).rstrip()

View file

@ -132,8 +132,8 @@ class TwUnspentOutputs(TwView):
'num': max(2,len(str(len(data)))+1),
'vout': 4,
'mmid': max(len(d.twmmid.disp) for d in data) if self.show_mmid else 0,
'amt': self.disp_prec + 5,
'amt2': 0,
'amt': self.amt_widths['amt'],
'amt2': self.amt_widths.get('amt2',0),
'block': self.age_col_params['block'][0] if wide else 0,
'date_time': self.age_col_params['date_time'][0] if wide else 0,
'date': self.age_w,
@ -177,8 +177,8 @@ class TwUnspentOutputs(TwView):
m = (MMGenID.fmtc( '.'*cw.mmid, color=color ) if d.skip == 'addr'
else d.twmmid.fmt( width=cw.mmid, color=color )) if cw.mmid else None,
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ) if cw.comment else None,
A = d.amt.fmt( color=color, prec=self.disp_prec ),
B = d.amt2.fmt( color=color, prec=self.disp_prec ) if cw.amt2 else None,
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
B = d.amt2.fmt( color=color, iwidth=cw.iwidth2, prec=self.disp_prec ) if cw.amt2 else None,
d = self.age_disp(d,self.age_fmt),
)
@ -203,8 +203,8 @@ class TwUnspentOutputs(TwView):
v = ' ' + d.vout.fmt( width=cw.vout-1, color=color ) if cw.vout else None,
a = d.addr.fmt( width=cw.addr, color=color ),
m = d.twmmid.fmt( width=cw.mmid, color=color ),
A = d.amt.fmt( color=color, prec=self.disp_prec ),
B = d.amt2.fmt( color=color, prec=self.disp_prec ) if cw.amt2 else None,
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
B = d.amt2.fmt( color=color, iwidth=cw.iwidth2, prec=self.disp_prec ) if cw.amt2 else None,
b = self.age_disp(d,'block'),
D = self.age_disp(d,'date_time'),
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ),

View file

@ -121,6 +121,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
if self.has_wallet:
from .ctl import TrackingWallet
self.wallet = await TrackingWallet(proto,mode='w')
self.amt_keys = {'amt':'iwidth','amt2':'iwidth2'} if self.has_amt2 else {'amt':'iwidth'}
@property
def age_w(self):
@ -225,10 +226,12 @@ class TwView(MMGenObject,metaclass=AsyncInit):
def do_ret(freews):
widths.update({k:minws[k] + freews.get(k,0) for k in minws})
widths.update({ikey: widths[key] - self.disp_prec - 1 for key,ikey in self.amt_keys.items()})
return namedtuple('column_widths',widths.keys())(*widths.values())
def do_ret_max():
widths.update({k:max(minws[k],maxws[k]) for k in minws})
widths.update({ikey: widths[key] - self.disp_prec - 1 for key,ikey in self.amt_keys.items()})
return namedtuple('column_widths',widths.keys())(*widths.values())
def get_freews(cols,varws,varw,minw):
@ -308,6 +311,12 @@ class TwView(MMGenObject,metaclass=AsyncInit):
self.proto.dcoin
) if hasattr(self,'total') else ''
def set_amt_widths(self,data):
# width of amts column: min(7,width of integer part) + len('.') + width of fractional part
self.amt_widths = {k:
min(7,max(len(str(getattr(d,k).to_integral_value())) for d in data)) + 1 + self.disp_prec
for k in self.amt_keys}
async def format(self,display_type,color=True,cached=False,interactive=False):
if not cached:
@ -322,6 +331,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
data = self.disp_data = list(self.filter_data()) # method could be a generator
if data and dt.need_column_widths:
self.set_amt_widths(data)
cw = self.get_column_widths(data,wide=dt.detail)
cwh = cw._asdict()
fp = self.fs_params

View file

@ -276,7 +276,7 @@ class MoneroWalletOps:
uarg_info = xmrwallet_uarg_info
def fmt_amt(amt):
return self.proto.coin_amt(amt,from_unit='atomic').fmt(fs='5.12',color=True)
return self.proto.coin_amt(amt,from_unit='atomic').fmt( iwidth=5, prec=12, color=True )
def hl_amt(amt):
return self.proto.coin_amt(amt,from_unit='atomic').hl()