Submit
Path:
~
/
/
proc
/
thread-self
/
root
/
proc
/
self
/
root
/
opt
/
alt
/
python27
/
lib
/
python2.7
/
site-packages
/
File Content:
lprettytable.py
#!/usr/bin/env python # # PrettyTable 0.5 # Copyright (c) 2009, Luke Maurits <luke@maurits.id.au> # All rights reserved. # With contributions from: # * Chris Clark # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import cgi import copy import cPickle import sys FRAME = 0 ALL = 1 NONE = 2 class PrettyTable: def __init__(self, fields=None, caching=True, padding_width=1, left_padding=None, right_padding=None): """Return a new PrettyTable instance Arguments: fields - list or tuple of field names caching - boolean value to turn string caching on/off padding width - number of spaces between column lines and content""" # Data self.fields = [] if fields: self.set_field_names(fields) else: self.widths = [] self.aligns = [] self.set_padding_width(padding_width) self.rows = [] self.cache = {} self.html_cache = {} # Options self.hrules = FRAME self.caching = caching self.padding_width = padding_width self.left_padding = left_padding self.right_padding = right_padding self.vertical_char = "|" self.horizontal_char = "-" self.junction_char = "+" def __getslice__(self, i, j): """Return a new PrettyTable whose data rows are a slice of this one's Arguments: i - beginning slice index j - ending slice index""" newtable = copy.deepcopy(self) newtable.rows = self.rows[i:j] return newtable def __str__(self): return self.get_string() ############################## # ATTRIBUTE SETTERS # ############################## def set_field_names(self, fields): """Set the names of the fields Arguments: fields - list or tuple of field names""" # We *may* need to change the widths if this isn't the first time # setting the field names. This could certainly be done more # efficiently. if self.fields: self.widths = [len(field) for field in fields] for row in self.rows: for i in range(0,len(row)): if len(unicode(row[i])) > self.widths[i]: self.widths[i] = len(unicode(row[i])) else: self.widths = [len(field) for field in fields] self.fields = fields self.aligns = len(fields)*["c"] self.cache = {} self.html_cache = {} def set_field_align(self, fieldname, align): """Set the alignment of a field by its fieldname Arguments: fieldname - name of the field whose alignment is to be changed align - desired alignment - "l" for left, "c" for centre and "r" for right""" if fieldname not in self.fields: raise Exception("No field %s exists!" % fieldname) if align not in ["l","c","r"]: raise Exception("Alignment %s is invalid, use l, c or r!" % align) self.aligns[self.fields.index(fieldname)] = align self.cache = {} self.html_cache = {} def set_padding_width(self, padding_width): """Set the number of empty spaces between a column's edge and its content Arguments: padding_width - number of spaces, must be a positive integer""" try: assert int(padding_width) >= 0 except AssertionError: raise Exception("Invalid value for padding_width: %s!" % unicode(padding_width)) self.padding_width = padding_width self.cache = {} self.html_cache = {} def set_left_padding(self, left_padding): """Set the number of empty spaces between a column's left edge and its content Arguments: left_padding - number of spaces, must be a positive integer""" try: assert left_padding == None or int(left_padding) >= 0 except AssertionError: raise Exception("Invalid value for left_padding: %s!" % unicode(left_padding)) self.left_padding = left_padding self.cache = {} self.html_cache = {} def set_right_padding(self, right_padding): """Set the number of empty spaces between a column's right edge and its content Arguments: right_padding - number of spaces, must be a positive integer""" try: assert right_padding == None or int(right_padding) >= 0 except AssertionError: raise Exception("Invalid value for right_padding: %s!" % unicode(right_padding)) self.right_padding = right_padding self.cache = {} self.html_cache = {} def set_border_chars(self, vertical="|", horizontal="-", junction="+"): """Set the characters to use when drawing the table border Arguments: vertical - character used to draw a vertical line segment. Default is | horizontal - character used to draw a horizontal line segment. Default is - junction - character used to draw a line junction. Default is +""" if len(vertical) > 1 or len(horizontal) > 1 or len(junction) > 1: raise Exception("All border characters must be strings of length ONE!") self.vertical_char = vertical self.horizontal_char = horizontal self.junction_char = junction self.cache = {} ############################## # DATA INPUT METHODS # ############################## def add_row(self, row): """Add a row to the table Arguments: row - row of data, should be a list with as many elements as the table has fields""" if len(row) != len(self.fields): raise Exception("Row has incorrect number of values, (actual) %d!=%d (expected)" %(len(row),len(self.fields))) self.rows.append(row) for i in range(0,len(row)): if len(unicode(row[i])) > self.widths[i]: self.widths[i] = len(unicode(row[i])) self.html_cache = {} def add_column(self, fieldname, column, align="c"): """Add a column to the table. Arguments: fieldname - name of the field to contain the new column of data column - column of data, should be a list with as many elements as the table has rows align - desired alignment for this column - "l" for left, "c" for centre and "r" for right""" if len(self.rows) in (0, len(column)): if align not in ["l","c","r"]: raise Exception("Alignment %s is invalid, use l, c or r!" % align) self.fields.append(fieldname) self.widths.append(len(fieldname)) self.aligns.append(align) for i in range(0, len(column)): if len(self.rows) < i+1: self.rows.append([]) self.rows[i].append(column[i]) if len(unicode(column[i])) > self.widths[-1]: self.widths[-1] = len(unicode(column[i])) else: raise Exception("Column length %d does not match number of rows %d!" % (len(column), len(self.rows))) ############################## # MISC PRIVATE METHODS # ############################## def _get_sorted_rows(self, start, end, sortby, reversesort): # Sort rows using the "Decorate, Sort, Undecorate" (DSU) paradigm rows = copy.deepcopy(self.rows[start:end]) sortindex = self.fields.index(sortby) # Decorate rows = [[row[sortindex]]+row for row in rows] # Sort rows.sort(reverse=reversesort) # Undecorate rows = [row[1:] for row in rows] return rows def _get_paddings(self): if self.left_padding is not None: lpad = self.left_padding else: lpad = self.padding_width if self.right_padding is not None: rpad = self.right_padding else: rpad = self.padding_width return lpad, rpad ############################## # ASCII PRINT/STRING METHODS # ############################## def printt(self, start=0, end=None, fields=None, header=True, border=True, hrules=FRAME, sortby=None, reversesort=False): """Print table in current state to stdout. Arguments: start - index of first data row to include in output end - index of last data row to include in output PLUS ONE (list slice style) fields - names of fields (columns) to include sortby - name of field to sort rows by reversesort - True or False to sort in descending or ascending order border - should be True or False to print or not print borders hrules - controls printing of horizontal rules after each row. Allowed values: FRAME, ALL, NONE""" print self.get_string(start, end, fields, header, border, hrules, sortby, reversesort) def get_string(self, start=0, end=None, fields=None, header=True, border=True, hrules=FRAME, sortby=None, reversesort=False): """Return string representation of table in current state. Arguments: start - index of first data row to include in output end - index of last data row to include in output PLUS ONE (list slice style) fields - names of fields (columns) to include sortby - name of field to sort rows by reversesort - True or False to sort in descending or ascending order border - should be True or False to print or not print borders hrules - controls printing of horizontal rules after each row. Allowed values: FRAME, ALL, NONE""" if self.caching: key = cPickle.dumps((start, end, fields, header, border, hrules, sortby, reversesort)) if key in self.cache: return self.cache[key] hrule = hrules or self.hrules bits = [] if not self.fields: return "" if not header: # Recalculate widths - avoids tables with long field names but narrow data looking odd old_widths = self.widths[:] self.widths = [0]*len(self.fields) for row in self.rows: for i in range(0,len(row)): if len(unicode(row[i])) > self.widths[i]: self.widths[i] = len(unicode(row[i])) if header: bits.append(self._stringify_header(fields, border, hrules)) elif border and hrules != NONE: bits.append(self._stringify_hrule(fields, border)) if sortby: rows = self._get_sorted_rows(start, end, sortby, reversesort) else: rows = self.rows[start:end] for row in rows: bits.append(self._stringify_row(row, fields, border, hrule)) if border and not hrule: bits.append(self._stringify_hrule(fields, border)) string = "\n".join(bits) if self.caching: self.cache[key] = string if not header: # Restore previous widths self.widths = old_widths for row in self.rows: for i in range(0,len(row)): if len(unicode(row[i])) > self.widths[i]: self.widths[i] = len(unicode(row[i])) return string def _stringify_hrule(self, fields=None, border=True): if not border: return "" lpad, rpad = self._get_paddings() padding_width = lpad+rpad bits = [self.junction_char] for field, width in zip(self.fields, self.widths): if fields and field not in fields: continue bits.append((width+padding_width)*self.horizontal_char) bits.append(self.junction_char) return "".join(bits) def _stringify_header(self, fields=None, border=True, hrules=FRAME): lpad, rpad = self._get_paddings() bits = [] if border: if hrules != NONE: bits.append(self._stringify_hrule(fields, border)) bits.append("\n") bits.append(self.vertical_char) for field, width in zip(self.fields, self.widths): if fields and field not in fields: continue bits.append(" " * lpad + field.center(width) + " " * rpad) if border: bits.append(self.vertical_char) if border and hrules != NONE: bits.append("\n") bits.append(self._stringify_hrule(fields, border)) return "".join(bits) def _stringify_row(self, row, fields=None, border=True, hrule=False): lpad, rpad = self._get_paddings() bits = [] if border: bits.append(self.vertical_char) for field, value, width, align in zip(self.fields, row, self.widths, self.aligns): if fields and field not in fields: continue if align == "l": bits.append(" " * lpad + unicode(value).ljust(width) + " " * rpad) elif align == "r": bits.append(" " * lpad + unicode(value).rjust(width) + " " * rpad) else: bits.append(" " * lpad + unicode(value).center(width) + " " * rpad) if border: bits.append(self.vertical_char) if border and hrule == ALL: bits.append("\n") bits.append(self._stringify_hrule(fields, border)) return "".join(bits) ############################## # HTML PRINT/STRING METHODS # ############################## def print_html(self, start=0, end=None, fields=None, sortby=None, reversesort=False, format=True, header=True, border=True, hrules=FRAME, attributes=None): """Print HTML formatted version of table in current state to stdout. Arguments: start - index of first data row to include in output end - index of last data row to include in output PLUS ONE (list slice style) fields - names of fields (columns) to include sortby - name of field to sort rows by format - should be True or False to attempt to format alignmet, padding, etc. or not header - should be True or False to print a header showing field names or not border - should be True or False to print or not print borders hrules - include horizontal rule after each row attributes - dictionary of name/value pairs to include as HTML attributes in the <table> tag""" print self.get_html_string(start, end, fields, sortby, reversesort, format, header, border, hrules, attributes) def get_html_string(self, start=0, end=None, fields=None, sortby=None, reversesort=False, format=True, header=True, border=True, hrules=FRAME, attributes=None): """Return string representation of HTML formatted version of table in current state. Arguments: start - index of first data row to include in output end - index of last data row to include in output PLUS ONE (list slice style) fields - names of fields (columns) to include sortby - name of border - should be True or False to print or not print borders format - should be True or False to attempt to format alignmet, padding, etc. or not header - should be True or False to print a header showing field names or not border - should be True or False to print or not print borders hrules - include horizontal rule after each row attributes - dictionary of name/value pairs to include as HTML attributes in the <table> tag""" if self.caching: key = cPickle.dumps((start, end, fields, format, header, border, hrules, sortby, reversesort, attributes)) if key in self.html_cache: return self.html_cache[key] if format: tmp_html_func=self._get_formatted_html_string else: tmp_html_func=self._get_simple_html_string string = tmp_html_func(start, end, fields, sortby, reversesort, header, border, hrules, attributes) if self.caching: self.html_cache[key] = string return string def _get_simple_html_string(self, start, end, fields, sortby, reversesort, header, border, hrules, attributes): bits = [] # Slow but works table_tag = '<table' if border: table_tag += ' border="1"' if attributes: for attr_name in attributes: table_tag += ' %s="%s"' % (attr_name, attributes[attr_name]) table_tag += '>' bits.append(table_tag) # Headers bits.append(" <tr>") for field in self.fields: if fields and field not in fields: continue bits.append(" <th>%s</th>" % cgi.escape(unicode(field))) bits.append(" </tr>") # Data if sortby: rows = self._get_sorted_rows(stard, end, sortby, reversesort) else: rows = self.rows for row in self.rows: bits.append(" <tr>") for field, datum in zip(self.fields, row): if fields and field not in fields: continue bits.append(" <td>%s</td>" % cgi.escape(unicode(datum))) bits.append(" </tr>") bits.append("</table>") string = "\n".join(bits) return string def _get_formatted_html_string(self, start, end, fields, sortby, reversesort, header, border, hrules, attributes): bits = [] # Slow but works table_tag = '<table' if border: table_tag += ' border="1"' if hrules == NONE: table_tag += ' frame="vsides" rules="cols"' if attributes: for attr_name in attributes: table_tag += ' %s="%s"' % (attr_name, attributes[attr_name]) table_tag += '>' bits.append(table_tag) # Headers lpad, rpad = self._get_paddings() if header: bits.append(" <tr>") for field in self.fields: if fields and field not in fields: continue bits.append(" <th style=\"padding-left: %dem; padding-right: %dem; text-align: center\">%s</th>" % (lpad, rpad, cgi.escape(unicode(field)))) bits.append(" </tr>") # Data if sortby: rows = self._get_sorted_rows(start, end, sortby, reversesort) else: rows = self.rows for row in self.rows: bits.append(" <tr>") for field, align, datum in zip(self.fields, self.aligns, row): if fields and field not in fields: continue if align == "l": bits.append(" <td style=\"padding-left: %dem; padding-right: %dem; text-align: left\">%s</td>" % (lpad, rpad, cgi.escape(unicode(datum)))) elif align == "r": bits.append(" <td style=\"padding-left: %dem; padding-right: %dem; text-align: right\">%s</td>" % (lpad, rpad, cgi.escape(unicode(datum)))) else: bits.append(" <td style=\"padding-left: %dem; padding-right: %dem; text-align: center\">%s</td>" % (lpad, rpad, cgi.escape(unicode(datum)))) bits.append(" </tr>") bits.append("</table>") string = "\n".join(bits) return string def main(): x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"]) x.set_field_align("City name", "l") # Left align city names x.add_row(["Adelaide",1295, 1158259, 600.5]) x.add_row(["Brisbane",5905, 1857594, 1146.4]) x.add_row(["Darwin", 112, 120900, 1714.7]) x.add_row(["Hobart", 1357, 205556, 619.5]) x.add_row(["Sydney", 2058, 4336374, 1214.8]) x.add_row(["Melbourne", 1566, 3806092, 646.9]) x.add_row(["Perth", 5386, 1554769, 869.4]) print x if len(sys.argv) > 1 and sys.argv[1] == "test": # This "test suite" is hideous and provides poor, arbitrary coverage. # I'll replace it with some proper unit tests Sometime Soon (TM). # Promise. print "Testing field subset selection:" x.printt(fields=["City name","Population"]) print "Testing row subset selection:" x.printt(start=2, end=5) print "Testing hrules settings:" print "FRAME:" x.printt(hrules=FRAME) print "ALL:" x.printt(hrules=ALL) print "NONE:" x.printt(hrules=NONE) print "Testing lack of headers:" x.printt(header=False) x.printt(header=False, border=False) print "Testing lack of borders:" x.printt(border=False) print "Testing sorting:" x.printt(sortby="City name") x.printt(sortby="Annual Rainfall") x.printt(sortby="Annual Rainfall", reversesort=True) print "Testing padding parameter:" x.set_padding_width(0) x.printt() x.set_padding_width(5) x.printt() x.set_left_padding(5) x.set_right_padding(0) x.printt() x.set_right_padding(20) x.printt() x.set_left_padding(None) x.set_right_padding(None) x.set_padding_width(2) print "Testing changing characters" x.set_border_chars("*","*","*") x.printt() x.set_border_chars("!","~","o") x.printt() x.set_border_chars("|","-","+") print "Testing everything at once:" x.printt(start=2, end=5, fields=["City name","Population"], border=False, hrules=True) print "Rebuilding by columns:" x = PrettyTable() x.add_column("City name", ["Adelaide", "Brisbane", "Darwin", "Hobart", "Sydney", "Melbourne", "Perth"]) x.add_column("Area", [1295, 5905, 112, 1357, 2058, 1566, 5385]) x.add_column("Population", [1158259, 1857594, 120900, 205556, 4336374, 3806092, 1554769]) x.add_column("Annual Rainfall", [600.5, 1146.4, 1714.7, 619.5, 1214.8, 646.9, 869.4]) x.printt() print "Testing HTML:" x.print_html() x.print_html(border=False) x.print_html(border=True) x.print_html(format=False) x.print_html(attributes={"name": "table", "id": "table"}) if __name__ == "__main__": main()
Submit
FILE
FOLDER
Name
Size
Permission
Action
Babel-1.3-py2.7.egg-info
---
0755
Beaker-1.5.4-py2.7.egg-info
---
0755
Jinja2-2.7.2-py2.7.egg-info
---
0755
Mako-0.7.3-py2.7.egg-info
---
0755
Paste-1.7.5.1-py2.7.egg-info
---
0755
Tempita-0.5.1-py2.7.egg-info
---
0755
_dummy_thread
---
0755
_markupbase
---
0755
_thread
---
0755
alembic
---
0755
alembic-0.8.3-py2.7.egg-info
---
0755
argparse-1.2.1-py2.7.egg-info
---
0755
babel
---
0755
beaker
---
0755
builtins
---
0755
chardet
---
0755
chardet-2.3.0-py2.7.egg-info
---
0755
clquota
---
0755
clselect
---
0755
clselector
---
0755
contextlib2-0.5.4-py2.7.egg-info
---
0755
copyreg
---
0755
dateutil
---
0755
docopt-0.6.2-py2.7.egg-info
---
0755
future
---
0755
future-0.17.0-py2.7.egg-info
---
0755
html
---
0755
http
---
0755
jinja2
---
0755
jsonschema
---
0755
jsonschema-2.6.0-py2.7.egg-info
---
0755
libfuturize
---
0755
libpasteurize
---
0755
lvemanager
---
0755
lvestats
---
0755
mako
---
0755
nose
---
0755
nose-1.3.4-py2.7.egg-info
---
0755
past
---
0755
paste
---
0755
pip
---
0755
pip-20.2.4.dist-info
---
0755
pkg_resources
---
0755
python_dateutil-1.4.1-py2.7.egg-info
---
0755
python_editor-0.4-py2.7.egg-info
---
0755
pytz
---
0755
queue
---
0755
raven
---
0755
raven-6.3.0-py2.7.egg-info
---
0755
repoze
---
0755
repoze.lru-0.6-py2.7.egg-info
---
0755
reprlib
---
0755
requests
---
0755
requests-2.10.0-py2.7.egg-info
---
0755
schema-0.3.1-py2.7.egg-info
---
0755
setuptools
---
0755
setuptools-36.3.0.post20231113.dist-info
---
0755
socketserver
---
0755
svgwrite
---
0755
svgwrite-1.1.5-py2.7.egg-info
---
0755
tempita
---
0755
tkinter
---
0755
urllib3
---
0755
urllib3-1.15.1-py2.7.egg-info
---
0755
winreg
---
0755
xmlrpc
---
0755
Paste-1.7.5.1-py2.7-nspkg.pth
304 bytes
0644
PySocks-1.5.7-py2.7.egg-info
322 bytes
0644
argparse.py
87791 bytes
0644
argparse.pyc
67763 bytes
0644
argparse.pyo
67598 bytes
0644
clhooklib.pyc
3126 bytes
0644
contextlib2.py
14828 bytes
0644
contextlib2.pyc
16009 bytes
0644
contextlib2.pyo
16009 bytes
0644
docopt.py
19946 bytes
0644
docopt.pyc
24666 bytes
0644
docopt.pyo
24447 bytes
0644
easy_install.py
126 bytes
0644
easy_install.pyc
328 bytes
0644
easy_install.pyo
328 bytes
0644
editor.py
2550 bytes
0755
editor.pyc
3577 bytes
0644
editor.pyo
3577 bytes
0644
lprettytable.py
23849 bytes
0644
lprettytable.pyc
19697 bytes
0644
lprettytable.pyo
19558 bytes
0644
pyparsing-1.5.6-py2.7.egg-info
670 bytes
0644
pyparsing.py
155429 bytes
0644
pyparsing.pyc
153536 bytes
0644
pyparsing.pyo
153536 bytes
0644
pytz-2012d-py2.7.egg-info
23309 bytes
0644
repoze.lru-0.6-py2.7-nspkg.pth
307 bytes
0644
schema.py
6206 bytes
0644
schema.pyc
8532 bytes
0644
schema.pyo
8443 bytes
0644
six-1.9.0-py2.7.egg-info
1419 bytes
0644
six.py
29664 bytes
0644
six.pyc
30722 bytes
0644
six.pyo
30722 bytes
0644
socks.py
29952 bytes
0644
socks.pyc
25688 bytes
0644
socks.pyo
25688 bytes
0644
sockshandler.py
2913 bytes
0644
sockshandler.pyc
4737 bytes
0644
sockshandler.pyo
4737 bytes
0644
typing-3.5.3.0-py2.7.egg-info
1484 bytes
0644
typing.py
64895 bytes
0644
typing.pyc
79068 bytes
0644
typing.pyo
78407 bytes
0644
N4ST4R_ID | Naxtarrr