126 lines
4.1 KiB
Python
126 lines
4.1 KiB
Python
import os, copy, io
|
|
from collections import OrderedDict
|
|
|
|
def try_float( sVal, dft=None ):
|
|
res = dft
|
|
try:
|
|
res = float( sVal )
|
|
except:
|
|
pass
|
|
return res
|
|
|
|
def mergeDict( dict1, dict2 ):
|
|
for key in dict2:
|
|
dict1[ key ] = dict2[ key ]
|
|
|
|
def addMapValues( dict1, dict2 ):
|
|
for key in dict2:
|
|
if key in dict1:
|
|
dict1[key] += dict2[key]
|
|
else:
|
|
dict1[key] = dict2[key]
|
|
|
|
class MatrixByStr: ### Matrix with string keys
|
|
def __init__( self,
|
|
rows, cols, ## each a list of tuples: (short, long) row/column names
|
|
defval = 0 ):
|
|
self.rows, self.cols = rows, cols
|
|
self.mbs = OrderedDict( (r[0],
|
|
OrderedDict( (c[0], copy.deepcopy(defval)) for c in cols )) for r in rows )
|
|
|
|
def __getitem__( self, k ):
|
|
return self.mbs[ k[0] ][ k[1] ]
|
|
|
|
def __setitem__( self, k, v ):
|
|
self.mbs[ k[0] ][ k[1] ] = v
|
|
|
|
def stringify2D( self ): ## compact 2D print
|
|
return MyTab().tabulate( [
|
|
[key] + list(row.values()) ## merge each row's key into the row
|
|
for key,row in self.mbs.items() ],
|
|
[""] + [ col[0] for col in self.cols ] )
|
|
|
|
## assumes each item is a list
|
|
def stringifyLists( self, title, rowIntro, colIntro ):
|
|
resIO = io.StringIO()
|
|
print( '#'*50, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( title, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( file=resIO )
|
|
|
|
for kr, r in self.mbs.items():
|
|
print( '#'*50, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( rowIntro, kr, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
print( file=resIO )
|
|
|
|
for kc, c in r.items():
|
|
print( '#'*50, file=resIO )
|
|
print( rowIntro, kr, file=resIO )
|
|
print( colIntro, " ", kc, " / ", len(c), file=resIO )
|
|
print( '#'*50, file=resIO )
|
|
|
|
for el in c:
|
|
print( el, file=resIO )
|
|
print( file=resIO )
|
|
|
|
return resIO.getvalue()
|
|
|
|
class MyTab:
|
|
def __init__( self ):
|
|
self.sColSep=' '
|
|
|
|
## Receive table row-wise (matr)
|
|
## hdr is a list of column headers
|
|
def tabulate( self, matr, hdr ):
|
|
res = ""
|
|
## Compute max width
|
|
nWMax = []
|
|
for iC in range( len( hdr ) ):
|
|
nWMax.append( len( str( hdr[ iC ] ) ) )
|
|
for iR in range( len( matr ) ):
|
|
if iC<len( matr[ iR ] ):
|
|
if nWMax[ iC ]<len( str( matr[iR][iC] ) ):
|
|
nWMax[ iC ] = len( str( matr[iR][iC] ) )
|
|
## Printing
|
|
res =( ("{0:<"+str(nWMax[0])+'}').format(hdr[0]) + self.sColSep )
|
|
for iC in range( 1, len( hdr ) ):
|
|
res += ( ("{0:"+str(nWMax[iC])+'}').format(hdr[iC])
|
|
+ ( self.sColSep if iC+1<len(hdr) else '\n' ) )
|
|
for iR in range( len( matr ) ):
|
|
res += ( ("{0:<"+str(nWMax[0])+'}').format(matr[iR][0] if 0<len( matr[ iR ] ) else '-') + self.sColSep )
|
|
for iC in range( 1, len( matr[iR] ) ):
|
|
res += ( ("{0:"+str(nWMax[iC])+'}').format(matr[iR][iC] if iC<len( matr[ iR ] ) else '-')
|
|
+ ( self.sColSep if iC+1<len(hdr) else '\n' ) )
|
|
return res
|
|
|
|
## change string to be abke to become a filename
|
|
def flnfy( sStr ):
|
|
keepcharacters = ('-','_')
|
|
return "".join(c if c.isalnum() or c in keepcharacters else 'I' for c in sStr).strip()
|
|
|
|
def makeDirname( sFln ):
|
|
sDir = os.path.dirname( sFln )
|
|
if 0<len(sDir):
|
|
try:
|
|
os.makedirs( sDir, exist_ok=True)
|
|
except:
|
|
print( "Failed to create dir '", sDir, "'.", sep='' )
|
|
return False
|
|
return True
|
|
|
|
def openFile_autoDir( sFln, sMode ):
|
|
makeDirname( sFln )
|
|
return open( sFln, sMode )
|
|
|
|
## stringify a container, inserting a given prefix before each element
|
|
def strNL( prf, cnt ):
|
|
return prf + prf.join( [ str( el ) for el in cnt ] )
|
|
|