私は今まで Python に列をフォーマットするためのソリューションがあることを知りませんでした - 組み込みのソリューション ( Lua ) を持たない別の言語用に独自のソリューションを既に作成していた場合に備えて、それを調べることにしました。 Logic は Universal であるため、数回のキー操作で Python に移植しました。
Python には独自のソリューションがあることを知っているので、それを現在のソリューションに統合することを検討します。
ただし、代替ソリューションを作成したので、ここにソリューションを投稿して、ソリューションがいかにユーザーフレンドリーであるかを確認できるようにします。Python に関する私の不満の 1 つは、三項演算子などの書式設定が直感的ではないことです。 False, True (正直なところ、True, False の方が、ステートメントを最初に持つことと一緒に並べたほうがよいでしょう) のほか、他のものは奇妙です...
サンプル関数は、使用中の Truncate を示しています (注: 一部のロジック コストは必要ありませんが、まだ移動中です - たとえば if _truncate ... など)。また、フォーマット列システムも示しています...
それはかなり基本的です-タブをスペースに変換し、列の長さを数え、スペースが多すぎる場合はスペースを追加します-テキストが多すぎる場合はそれを切り刻みます(私の他のソリューションには、使用できるバッファまたは境界があるため、境界文字が表示されます。そして、列間に最低1つの空白文字を強制する-私はまだPythonバリアントに追加する機会がありませんでした)など...
デバッグや出力に最適です..
いくつかの主要な関数があります... String.FormatColumn( [ _width, _text ], ... )、String.FormatSimpleColumn( _width, [ _text, ... ]、および String.FormatColumnEx( _empty_chars, [ _width, _text ], ... )..
String.FormatSimpleColumn は幅を 1 回取り、それをすべての列に使用し、テキストのみを繰り返します。
String.FormatColumn は、すべての列の幅とテキストを受け取ります...
String.FormatColumnEx は、スペースの代わりに使用する文字を指定できることを除いて、FormatColumn と同じです - 私は通常、インデックス行に小数または別の文字を使用します....
私のLua実装では、適切なスペースをトリミングするオプションもありましたが、スペースが不要な場合はヘルパー関数を使用してトリミングすることになりました...列を設定すると、単に何かを追加できるため、それらを残します必要に応じて関数呼び出しの外側の文字列に...そしてトリミングは簡単です..また、引数をチェーンする代わりに、まったく同じ結果を得るために関数呼び出しをチェーンすることができることも意味します..
##
## Sandbox - All Works, if public, are released under the ACL or Acecool Company License - Josh 'Acecool' Moser
##
##
## Declarations for Globals, CONSTants, ENUMeration, etc..
##
## Define the tab width in terms of how many space-chars are used per tab character - Pi uses 8, Windows uses 4, some use 2, etc..
CONST_TAB_WIDTH = 4
##
## String Library - This library only includes Format Column debugging output format system..
##
class String:
##
##
##
def FormatColumnStripR( _width = 25, _text ='', *_varargs ):
return String.FormatColumn( _width, _text, *_varargs ).rstrip( )
##
##
##
def FormatSimpleColumnStripR( _width = 25, *_varargs ):
return String.FormatSimpleColumn( _width, *_varargs ).rstrip( )
##
## Helper function which lets you define width for each text, and it repeats it for you so you can repeat text and all columns will be the same width
##
## Purpose:
## The purpose of the Format Column Helpers is to improve data output, primarily for debugging so output is easier to follow..
## Usage:
## String.FormatColumn( 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
## String.FormatColumn( 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
## String.FormatColumn( 25, 'Key', 15, 'Some', 15, 'Another', 50, 'Value' )
##
## Output:
## Text / Key Some Value Another Key Another Value <LINE END>
## Text / Key Some Value Another Key Another Value <LINE END>
## Key Some Another Value <LINE END>
##
def FormatColumn( _width = 25, _text = '', *_varargs ):
return String.FormatColumnEx( ' ', _width, _text, *_varargs )
##
## Helper function which lets you define width for each text, and it repeats it for you so you can repeat text and all columns will be the same width
##
## Purpose:
## The purpose of the Format Column Helpers is to improve data output, primarily for debugging so output is easier to follow..
## Usage:
## String.FormatColumnEx( '.', 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
## String.FormatColumnEx( ' ', 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
## String.FormatColumnEx( ' ', 25, 'Key', 15, 'Some', 15, 'Another', 50, 'Value' )
##
## Output:
## Text / Key...............Some Value.....Another Key....Another Value.....................................<LINE END>
## Text / Key Some Value Another Key Another Value <LINE END>
## Key Some Another Value <LINE END>
##
def FormatColumnEx( _empty_char = ' ', _width = 25, _text = '', *_varargs ):
## Make sure our text is a string
_text = str( _text )
## For each tab used, calculate how many spaces should be used with minimum of 1 and maximum of 4 being the range depending which snap-point is used.. Then strip that tab and add spaces in its place..
_text = _text.expandtabs( CONST_TAB_WIDTH )
## Count how many additional arguments we have
_count = len( _varargs )
## Since our Ex function, this, must use a paired-system, we make sure the rounded division is > 0
_more = ( round( _count / 2, 0 ) > 0 )
## How many repeating chars do we need to create?
_reps = ( _width - len( _text ) )
## Build a string to fill the empty column space with spaces so everything lines up - as long as the right font is used ( where all chars are the same size )
_empty = _empty_char * _reps
## Now we ensure our text is limited to the _width size - data going over is truncated...TernaryFunc( _reps > 0, _empty, _empty )
## _data = String.SubStr( _text + ( _empty ), 0, _width )
## _data = ( _text + ( _empty ) )[ : _width ]
_data = String.Truncate( _text + ( _empty ), _width )
## If we have more cars
if ( _more ):
## Recursive call by shifting our VarArgs left so they populate _width and _text - then add the result to the data var... This only stops when no more paired options are left...
_data = _data + String.FormatColumnEx( _empty_char, *_varargs )
## Return the data..
return _data
##
## Helper function which lets you define width once, and it repeats it for you so you can repeat text and all columns will be the same width
##
## Purpose:
## The purpose of the Format Column Helpers is to improve data output, primarily for debugging so output is easier to follow..
## Usage:
## String.FormatSimpleColumn( 15, 'Text / Key', 'Some Value', 'Another Key', 'Another Value' )
## String.FormatSimpleColumn( 15, 'Key', 'Some', 'Another', 'Value' )
##
## Output:
## Text / Key Some Value Another Key Another Value <LINE END>
## Key Some Another Value <LINE END>
##
def FormatSimpleColumn( _width = 25, *_varargs ):
## Count how many text elements we have...
_count = len( _varargs )
## Set up our return var
_data = ''
## If we have at least 1 text element to set-up into a column
if ( _count > 0 ):
## Then we loop through each vararg
for _text in _varargs:
## If width is negative, use the length of the string plus the absolute value of width as a buffer...
if ( _width < 0 ):
_data = _data + String.FormatColumn( len( str( _text ) ) + abs( _width ), str( _text ) )
else:
## And we use a pseudo recursive call on the FormatColumnEx function - extra args...
_data = _data + String.FormatColumn( _width, str( _text ) )
## Return the data..
return _data
##
## SubString replacement
##
## Usage:
## _data = String.SubStr( _text, 0, 10 )
##
def SubStr( _text, _start, _end ):
return _text[ _start : _end ]
##
## Truncate characters of a string after _len'nth char, if necessary... If _len is less than 0, don't truncate anything... Note: If you attach a suffix, and you enable absolute max length then the suffix length is subtracted from max length... Note: If the suffix length is longer than the output then no suffix is used...
##
## Usage: Where _text = 'Testing', _width = 4
## _data = String.Truncate( _text, _width ) == Test
## _data = String.Truncate( _text, _width, '..', True ) == Te..
##
## Equivalent Alternates: Where _text = 'Testing', _width = 4
## _data = String.SubStr( _text, 0, _width ) == Test
## _data = _text[ : _width ] == Test
## _data = ( _text )[ : _width ] == Test
##
def Truncate( _text, _max_len = -1, _suffix = False, _absolute_max_len = True ):
## Length of the string we are considering for truncation
_len = len( _text )
## Whether or not we have to truncate
_truncate = ( False, True )[ _len > _max_len ]
## Note: If we don't need to truncate, there's no point in proceeding...
if ( not _truncate ):
return _text
## The suffix in string form
_suffix_str = ( '', str( _suffix ) )[ _truncate and _suffix != False ]
## The suffix length
_len_suffix = len( _suffix_str )
## Whether or not we add the suffix
_add_suffix = ( False, True )[ _truncate and _suffix != False and _max_len > _len_suffix ]
## Suffix Offset
_suffix_offset = _max_len - _len_suffix
_suffix_offset = ( _max_len, _suffix_offset )[ _add_suffix and _absolute_max_len != False and _suffix_offset > 0 ]
## The truncate point.... If not necessary, then length of string.. If necessary then the max length with or without subtracting the suffix length... Note: It may be easier ( less logic cost ) to simply add the suffix to the calculated point, then truncate - if point is negative then the suffix will be destroyed anyway.
## If we don't need to truncate, then the length is the length of the string.. If we do need to truncate, then the length depends on whether we add the suffix and offset the length of the suffix or not...
_len_truncate = ( _len, _max_len )[ _truncate ]
_len_truncate = ( _len_truncate, _max_len )[ _len_truncate <= _max_len ]
## If we add the suffix, add it... Suffix won't be added if the suffix is the same length as the text being output...
if ( _add_suffix ):
_text = _text[ 0 : _suffix_offset ] + _suffix_str + _text[ _suffix_offset: ]
## Return the text after truncating...
return _text[ : _len_truncate ]
##
##
##
def __example__( self ):
##
## Truncate Example...
##
_col_key = 20
_col_eq = 10
_col_res = 15
_row_eq = '=='
_text = 'Testing'
print( '--------------------------------------------- 8' )
_width = 8
print( String.FormatColumn( _col_key, 'Testing', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, 'Testing', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 7' )
_width = 7
print( String.FormatColumn( _col_key, 'Testing', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, 'Testing', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 6' )
_width = 6
print( String.FormatColumn( _col_key, 'Testin', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, 'Test..', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 5' )
_width = 5
print( String.FormatColumn( _col_key, 'Testi', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, 'Tes..', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 4' )
_width = 4
print( String.FormatColumn( _col_key, 'Test', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, 'Te..', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 3' )
_width = 3
print( String.FormatColumn( _col_key, 'Tes', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, 'T..', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 2' )
_width = 2
print( String.FormatColumn( _col_key, 'Te', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, '..', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 1' )
_width = 1
print( String.FormatColumn( _col_key, 'T', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, '.', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '--------------------------------------------- 0' )
_width = 0
print( String.FormatColumn( _col_key, '', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width ) ) )
print( String.FormatColumn( _col_key, '', _col_eq, _row_eq, _col_res, String.Truncate( _text, _width, '..', True ) ) )
print( '---------------------------------------------' )