Skip to content

Instantly share code, notes, and snippets.

@hogjonny
Last active December 22, 2015 20:59
Show Gist options
  • Save hogjonny/6530283 to your computer and use it in GitHub Desktop.
Save hogjonny/6530283 to your computer and use it in GitHub Desktop.
Some simple formatting for nicely logging blocks of data (takes string block, or iterable data type ... fallback is the attrs on object passed in.)
#!/usr/bin/env python
#coding:utf-8
# -- This line is 75 characters -------------------------------------------
# headerFooter.py
# author: hogjonny [at] gmail [dot] com
# -------------------------------------------------------------------------
'''
Some string formatting and generator functions,
useful for logging, etc.
Takes a string [using .splitlines()], otherwise works on .iteritems() for
for itterating data passed in.
usage:
from bp_stringformatting import headerString, footerString
>> print headerString('INFO')
#### -- INFO:: ---------------------------------------------------------- #
'''
import types
import inspect
###########################################################################
## Header and Foot formatting functions
## bigHeader(), genHeaderString(), genFooterString(), oneShotHandF()
# -------------------------------------------------------------------------
def bigHeader(headerString, padder='-', length=75):
'''
Generates a custom header, for a header with a long string.
'''
if not isinstance(headerString, basestring):
raise TypeError("headerString must be a string")
if len(headerString) > length:
wordList = headerString.split(' ')
output = ''
line = ''
for word in wordList:
if len(line+word) < length:
line += '{0} '.format(word)
else:
output += '{0}\n'.format(line)
line = ''
line += '{0} '.format(word)
output += line
return ('{0}\n'
'{1}\n'
'{2}\n'.format( genHeaderString(headerString='HEADER',
endreturn=''),
output,
padder*length) )
# -------------------------------------------------------------------------
def genHeaderString(headerString='INFO', length=75, footer='', endreturn='\n'):
'''
A basic 75 character length header.
You can overload the headerString= and length= values.
if len(headerString) is > 75, a bigHeader is returned.
'''
dash = '-'
endCap = ' #'
dashbar = ''
if len(headerString) > length:
header = bigHeader(headerString=headerString, length=length)
else:
header = '#### -- {0}:: {1}'.format(headerString, footer)
dashbar = dash*(length - len(header) - len(endCap))
header = '{0}{1}{2}{3}'.format(header, dashbar, endCap, endreturn)
return header
# -------------------------------------------------------------------------
def genFooterString(footerString='INFO', length=75, footer='END : '):
'''
calls the headerString, overloading the header, with a new footer.
'''
return genHeaderString(headerString=footerString,
length=length,
footer=footer)
# -------------------------------------------------------------------------
def oneShotHandF(itterableData=None, typeStr=None, length=75):
'''
Formats a string block, or any itterable item into a nice looking block.
'''
usedataType = False
dataInType = '{0}\n'.format(type(itterableData))
try:
# see if it's a string object
dataList = [line for line in itterableData.splitlines(0)]
itterableData = dataList
pass
# fallback, other types
except:
# next, let's try to build a common itterable
try:
def references(itterableData):
try:
return itterableData.iteritems()
except AttributeError:
return enumerate(itterableData)
itterableData = references(itterableData)
pass
except:
# and if that fails, check my object attrs, etc.
# if I am passed a callable, like a function, do this:
if isinstance(itterableData, (types.ObjectType,
types.FunctionType,
types.BuiltinFunctionType,
types.MethodType,
types.BuiltinMethodType,
types.UnboundMethodType)):
usedataType = True
# if no typeStr is set, we can try to generate one for the object
if typeStr is None:
typeStr = None
frame = inspect.currentframe().f_back
tmp = dict(frame.f_globals.items() + frame.f_locals.items())
for k, var in tmp.items():
if isinstance(var, itterableData.__class__):
if hash(itterableData) == hash(var):
typeStr = k
attr_and_values = ((attr, getattr(itterableData, attr))
for attr in dir(itterableData)
if not attr.startswith("_"))
dataList = [(attr, value) for attr, value in attr_and_values]
itterableData = dataList
pass
# start building the string with header
output = genHeaderString(typeStr, length)
if usedataType:
output += dataInType
# format the lines into the output
for item in itterableData:
if isinstance(item, basestring) or len(item) is 1:
item = item
elif len(item) is 2:
item = ('{0} = {1}'.format(item[0], item[1]) )
output += ('- {0}\n'.format(item))
# add the footer
if len(typeStr) <= length:
output = ('{0}{1}'.format(output, genFooterString(typeStr, length) ) )
else:
output = ('{0}{1}'.format(output, genFooterString('', length) ) )
return output
# -------------------------------------------------------------------------
# direct call for testing functions
if __name__ == "__main__" :
typeString = 'INFO'
print genHeaderString(typeString)
infoString = 'Do not eat junkfood,\nIt is not good for you!\n'
print oneShotHandF(infoString, typeString)
infoDict = {'Cheetos': 'Very tasty and crunchy...',
'Nutritional value': 'Not good for you!'}
print oneShotHandF(infoDict, typeString)
print oneShotHandF(oneShotHandF)
class Foo(object):
def __init__(self, value=None):
self.xFoo = None
if value is not None:
self.xFoo = value
def print_xFoo(self):
print self.xFoo
return self.xFoo
foo = Foo()
print oneShotHandF(foo)
fool = Foo('Fool')
print oneShotHandF(fool)
reallyBigStringHeader = ('I am a really big string of data that I want '
'to use as a header, it is so long, that I am '
'going to build a different header')
print oneShotHandF(fool, reallyBigStringHeader)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment