Mostly Linux & Python syntax notes and hyperlinks.
Sunday, August 17, 2014
Tuesday, August 12, 2014
python : write a message with a dashed line of the same length above &/or below
testdash.py
def writeWithDashedLine(space_before,msg,before=False,after=True,dash='-'):
string = ""
dashes = dash * len(msg)
if before:
string += "%s%s\n" % (space_before,dashes)
string += "%s%s\n" % (space_before,msg)
if after:
string += "%s%s\n" % (space_before,dashes)
return string
output:mystring = writeWithDashedLine(' ','Hi this is a test')
print mystring
mystring = writeWithDashedLine(' ','Here is another',True,True,'=')
print mystring
$ python testdash.py
Hi this is a test
-----------------
===============
Here is another
===============
Sunday, August 10, 2014
python code moved to github
Um, OK, sensible thing is to move the code over to a website already set up to store versions of code.
The python for my PyGotham talk "Building flexible tools to store sums and report on CSV data" is now in: https://github.com/pargery/csv_utilities
The python for my PyGotham talk "Building flexible tools to store sums and report on CSV data" is now in: https://github.com/pargery/csv_utilities
python: Newer version of ReportWithLevels class
"""
ReportWithLevels
__author__ = 'Margery Harrison'
__license__ = "Public Domain"
__version__ = "1.1"
To use this:
1) create an object of this class
2) if you don't want to report to stdout, then call open_outfile()
--> pass to open_outfile the path to the output file
3) Call write_line() to write header lines or any other explanations
4) For each set of messages and sums,
call print_level(level,message,sum)
level indicates amount to indent
message is the part that explains the sum
sum is right justified as a numeric field.
"""
import sys
class ReportWithLevels():
def __init__(self):
"""
Sets the default values for the class
"""
self.fdout=sys.stdout #default - writes report to stdout
self.number_width=10
self.level_indent=2
self.total_width=30
self.debug = False
self.min_level = 1
self.max_level = 4
#levels before which to print a newline
self.newline_before = [1]
# open the input path as file to write to
def open_outfile(self,path):
try:
self.fdout = open(path,'w')
except IOError:
msg="{0:s} Can't open and write to {1:s}".format(self.__class__.__name__,path)
sys.stderr.write(msg)
# print debug statement if debugging turned on
def debug_print(self,message):
if self.debug:
print(message)
def write_indent(self,message,level):
if level > 0:
indent=' ' * (level * self.level_indent)
else:
indent=' '
self.fdout.write('{0:s}{1:s}'.format(indent,message))
# Write a line out to the output file with newline at end
# adding indentation level for beginning
def write_line(self,message,lev=0):
if lev==0:
self.fdout.write(message + '\n')
else:
self.write_indent(message,lev)
self.fdout.write('\n')
# for printing msg,sum pairs when report is getting dense
def print_on_same_line(self,message,total,level=0):
"""
:param message: string to go with the total sum
:param total: total sum to go with the message
:param level: OPTIONAL - begins message at level-appropriate indendation
"""
#create a string of spaces called 'indent'
if level > 0:
indent=' ' * (level * self.level_indent)
else:
indent=' '
self.fdout.write('{0:s}{1:s}: {2:d} '.format(indent,message,total))
# Print message and total with indentation set by input level
# default sort of print-message
def print_on_new_line(self, level, message, total):
"""
:type level: int indicating indentation level
:type message: str that goes with int total
:type total: int sum that goes with message
"""
lev=int(level)
#skip a space before level 1 statements
if lev in self.newline_before:
self.write_line('')
#s1 and s2 are number of spaces for formatting
s1 = lev * self.level_indent
s2 = self.total_width - s1
#initialize fstr to the correct number of spaces
fstr='{{0:{0:d}s}} {{1:{1:d}s}}'.format(s1,s2)
# Number format string is right justified within number_width
number_format='{{2:-{0:d}d}}'.format(self.number_width)
fstr+=number_format
self.debug_print('level {0:d} format str= {1:s}'.format(lev,fstr))
self.write_line(fstr.format(' ', message, int(total)))
# Print message and total with indentation set by input level
# dispatches printing to either print_on_same_line or print_on_new_line
def print_level(self, level, message, total):
"""
:type level: int
:type message: str
:type total: int
"""
lev=int(level)
#assert lev >= self.min_level and lev <= self.max_level,\
# "input level not within current limits"
if lev > self.max_level:
self.print_on_same_line(message,total)
else:
self.print_on_new_line(level,message,total)
if __name__ == '__main__':
print "Testing ReportWithLevels.printLevel()"
pl=ReportWithLevels()
pl.open_outfile("testout.txt")
pl.write_line("This is my report")
pl.number_width=12
tot=7
for level in [1,2,3,2,2,3,4,3,1]: #range(1,4):
msg='level {0:d} msg'.format(level)
tot=tot * 12
pl.print_level(level,msg,tot)
ReportWithLevels
__author__ = 'Margery Harrison'
__license__ = "Public Domain"
__version__ = "1.1"
To use this:
1) create an object of this class
2) if you don't want to report to stdout, then call open_outfile()
--> pass to open_outfile the path to the output file
3) Call write_line() to write header lines or any other explanations
4) For each set of messages and sums,
call print_level(level,message,sum)
level indicates amount to indent
message is the part that explains the sum
sum is right justified as a numeric field.
"""
import sys
class ReportWithLevels():
def __init__(self):
"""
Sets the default values for the class
"""
self.fdout=sys.stdout #default - writes report to stdout
self.number_width=10
self.level_indent=2
self.total_width=30
self.debug = False
self.min_level = 1
self.max_level = 4
#levels before which to print a newline
self.newline_before = [1]
# open the input path as file to write to
def open_outfile(self,path):
try:
self.fdout = open(path,'w')
except IOError:
msg="{0:s} Can't open and write to {1:s}".format(self.__class__.__name__,path)
sys.stderr.write(msg)
# print debug statement if debugging turned on
def debug_print(self,message):
if self.debug:
print(message)
def write_indent(self,message,level):
if level > 0:
indent=' ' * (level * self.level_indent)
else:
indent=' '
self.fdout.write('{0:s}{1:s}'.format(indent,message))
# Write a line out to the output file with newline at end
# adding indentation level for beginning
def write_line(self,message,lev=0):
if lev==0:
self.fdout.write(message + '\n')
else:
self.write_indent(message,lev)
self.fdout.write('\n')
# for printing msg,sum pairs when report is getting dense
def print_on_same_line(self,message,total,level=0):
"""
:param message: string to go with the total sum
:param total: total sum to go with the message
:param level: OPTIONAL - begins message at level-appropriate indendation
"""
#create a string of spaces called 'indent'
if level > 0:
indent=' ' * (level * self.level_indent)
else:
indent=' '
self.fdout.write('{0:s}{1:s}: {2:d} '.format(indent,message,total))
# Print message and total with indentation set by input level
# default sort of print-message
def print_on_new_line(self, level, message, total):
"""
:type level: int indicating indentation level
:type message: str that goes with int total
:type total: int sum that goes with message
"""
lev=int(level)
#skip a space before level 1 statements
if lev in self.newline_before:
self.write_line('')
#s1 and s2 are number of spaces for formatting
s1 = lev * self.level_indent
s2 = self.total_width - s1
#initialize fstr to the correct number of spaces
fstr='{{0:{0:d}s}} {{1:{1:d}s}}'.format(s1,s2)
# Number format string is right justified within number_width
number_format='{{2:-{0:d}d}}'.format(self.number_width)
fstr+=number_format
self.debug_print('level {0:d} format str= {1:s}'.format(lev,fstr))
self.write_line(fstr.format(' ', message, int(total)))
# Print message and total with indentation set by input level
# dispatches printing to either print_on_same_line or print_on_new_line
def print_level(self, level, message, total):
"""
:type level: int
:type message: str
:type total: int
"""
lev=int(level)
#assert lev >= self.min_level and lev <= self.max_level,\
# "input level not within current limits"
if lev > self.max_level:
self.print_on_same_line(message,total)
else:
self.print_on_new_line(level,message,total)
if __name__ == '__main__':
print "Testing ReportWithLevels.printLevel()"
pl=ReportWithLevels()
pl.open_outfile("testout.txt")
pl.write_line("This is my report")
pl.number_width=12
tot=7
for level in [1,2,3,2,2,3,4,3,1]: #range(1,4):
msg='level {0:d} msg'.format(level)
tot=tot * 12
pl.print_level(level,msg,tot)
Wednesday, August 6, 2014
Linux: find and print the contents of files matching a pattern
find . -iname foo* -exec cat '{}' \; | more
To print the name before the printing the file contents:
find . -iname foo* -print -exec more '{}' \; | more
Subscribe to:
Posts (Atom)