예제 #1
0
def make_bom():
    """Generate a bill of materials and return the tt object."""

    finder = ModuleFinder()
    finder.run_script(sys.argv[0])
    tt = ttable()
    tt.add_option(LONGTABLE)
    tt.add_head(['name', 'ver', 'path', 'lines', 'bytes', 'sha-1'])
    tt.set_col_alignments("lllrrl")
    for inc in [False, True]:
        for name, mod in sorted(finder.modules.items()):
            if system_module(mod) != inc:
                continue  # don't use this one
            stats = file_stats(mod.__file__)
            ver = mod.globalnames.get('__version__', '---')
            if ver == 1 and name in sys.modules:
                # It has a version number; get it.
                try:
                    ver = sys.modules[name].__version__
                except AttributeError as e:
                    ver = '---'
            fname = mod.__file__
            if type(name) != str:
                name = ""
            if type(fname) != str:
                fname = ""
            tt.add_data([
                latex_escape(name), ver,
                latex_escape(fname), stats[0], stats[1], stats[2]
            ])
        tt.add_data(ttable.HR)
    return tt
예제 #2
0
def analyze_file(*,filename,mode=ttable.TEXT,verbose=False):
    """Analyze the named excel spreadsheet and return a string in the specified format."""
    NL = tytable.line_end(mode)
    ret = [NL]                   # an array of strings to be joined and returned
    if mode==ttable.TEXT:
        ret += [filename,'\n',"="*len(filename),NL]
    elif mode==ttable.LATEX:
        ret += [textbf(latex_escape(filename+":")),NL]
        
    if filename.lower().endswith(".csv"):
        wb = load_csv_workbook(filename=filename)
    elif filename.lower().endswith(".xlsx"):
        try:
            wb = load_workbook(filename=filename, read_only=True)
        except zipfile.BadZipFile:
            ret += ['Cannot read; badZipFile',NL]
            return "".join(ret)
        except TypeError:
            ret += ['Cannot read; bad Excel File',NL]
            return "".join(ret)
    else:
        return "Cannot read file type: {}".format(filename)

    tt = ttable()
    tt.add_head(['Worksheet Name','rows with data','columns with data',
                 'total numeric values','cells with $>4$ sigfigs'])
    
    ret_worksheets = []
    for ws in wb.worksheets:
        if verbose:
            print(f"  Analyzing {os.path.basename(filename)} worksheet {ws.title}")
        sf_ws = SigFigStats()              # for this worksheet
        
        empty_cells = 0
        for row in ws.iter_rows():
            for cell in row:
                if isinstance(cell,EmptyCell):
                    empty_cells += 1
                    continue
                val = get_number(cell.value)
                if val!=None:
                    sf_ws.add(val=val, row=cell.row, col=cell.column)
        ret_worksheets += ["Worksheet "+latex_escape(ws.title)]
        ret_worksheets += [sf_ws.typeset(mode=mode)]
        ret_worksheets += ["rows: {}  columns: {}  numbers: {}".format(sf_ws.max_row,sf_ws.max_col,sf_ws.count)]
        ret_worksheets += [""]
        tt.add_data([latex_escape(ws.title),sf_ws.max_row,sf_ws.max_col,sf_ws.count, sf_ws.improper_count()])
        # End of worksheet processing

    tt.set_col_totals([3,4])
    ret += [tt.typeset(mode=mode)] + [NL] + ret_worksheets

    # count the number of numbers and their precision
    return NL.join(ret)
예제 #3
0
def analyze_xlsx(*,filename,mode=TEXT):
    """Analyze the named excel spreadsheet and return a string in the specified format."""
    ret = []                    # an array of strings to be joined and returned
    NL = tytable.line_end(mode)
    if mode==TEXT:
        ret += [filename,'\n',"="*len(filename),NL]
    elif mode==LATEX:
        ret += [textbf(latex_escape(filename+":")),NL]
        
    try:
        wb = load_workbook(filename=filename, read_only=True)
    except zipfile.BadZipFile:
        ret += ['Cannot read; badZipFile',NL]
        return "".join(ret)
    except TypeError:
        ret += ['Cannot read; bad Excel File',NL]
        return "".join(ret)

    tt = ttable()
    tt.add_head(['','Worksheet Name','rows with data','columns with data',
                 'total numeric values','cells with $>4$ sigfigs'])
    
    sb = SigFigStats()              # for all the worksheets
    for i in range(len(wb.worksheets)):
        ws = wb.worksheets[i]
        wssb = SigFigStats()              # for this worksheet
        
        improper_count = 0
        for row in ws.iter_rows():
            for cell in row:
                if isinstance(cell,EmptyCell):
                    continue
                try:
                    if cell.value==None:
                        continue
                    val = float(cell.value)
                except (ValueError,TypeError,OverflowError) as e:
                    continue
                if improperly_rounded(val):
                    sb.add(val=val, row=cell.row+1, col=cell.column+1)
                    wssb.add(val=val, row=cell.row+1, col=cell.column+1)
                    improper_count += 1
        tt.add_data([i+1,latex_escape(ws.title),wssb.max_row,wssb.max_col,wssb.count, improper_count])
        # End of worksheet processing
    tt.add_data(tt.HR)
    tt.add_data(['total','--','--','--',sb.count])
    ret += [tt.typeset(mode=mode)]
    ret += [sb.typeset(mode=mode)]

    # count the number of numbers and their precision
    ret.append(NL)
    return "\n".join(ret)
예제 #4
0
 def typeset_cell(self, formatted_value, col_number):
     """Typeset a value for a given column number."""
     import math
     align = self.col_alignment.get(col_number, self.LEFT)
     if self.mode == self.HTML:
         return formatted_value
     if self.mode == self.LATEX:
         if self.OPTION_NO_ESCAPE in self.options:
             return formatted_value
         else:
             return latex_tools.latex_escape(formatted_value)
     if self.mode == self.TEXT:
         try:
             fill = (self.col_formatted_widths[col_number] -
                     len(formatted_value))
         except IndexError:
             fill = 0
         if align == self.RIGHT:
             return " " * fill + formatted_value
         if align == self.CENTER:
             return " " * math.ceil(
                 fill / 2.0) + formatted_value + " " * math.floor(
                     fill / 2.0)
         # Must be LEFT
         if col_number != self.cols - 1:  # not the last column
             return formatted_value + " " * fill
         return formatted_value  # don't indent last column
예제 #5
0
def analyze_csv(*,filename,mode=TEXT):
    """Analyze the numbers in a text file"""
    ret = []
    NL = tytable.line_end(mode)
    if mode==TEXT:
        ret += [filename,'\n',"="*len(filename),NL]
    elif mode==LATEX:
        ret += [textbf(latex_escape(filename+":")),NL]
    div = re.compile("[ ,]")
    sb = SigFigStats()
    with open(filename,"r") as f:
        row_number = 0
        for line in f:
            row_number += 1
            col_number = 0     
            for word in div.split(line):
                try:
                    val = float(word)
                    sb.add(val=val,row=row_number,col=col_number)
                except (ValueError,TypeError,OverflowError) as e:
                    pass
                col_number += 1
    ret += ["rows: {}  columns: {}  numbers: {}".format(sb.max_row,sb.max_col,sb.count),NL]
    ret += [sb.typeset(mode=mode)]
    return "\n".join(ret)
예제 #6
0
 def write_tail(doc, f, tail=None):
     if tail is None:
         tail = doc.tail
     if tail is not None:
         if hasattr(doc, 'option') and doc.option(OPTION_NO_ESCAPE):
             f.write(latex_escape(tail))
         else:
             f.write(tail)
예제 #7
0
 def write_text(doc, f, text=None):
     if text is None:
         text = doc.text
     if text is not None:
         if hasattr(doc, 'option') and doc.option(OPTION_NO_ESCAPE):
             f.write(latex_escape(text))
         else:
             f.write(text)
예제 #8
0
    def typeset(self, *, mode=None, option=None, out=None):
        """ Returns the typeset output of the entire table. Builds it up in """

        if (self.OPTION_LONGTABLE in self.options) and (self.OPTION_TABULARX in self.options):
            raise RuntimeError("OPTION_LONGTABLE and OPTION_TABULARX conflict")

        if len(self.data) == 0:
            print("typeset: no rows")
            return ""

        if mode:
            self.set_mode(mode)

        if self.mode not in [self.TEXT, self.LATEX, self.HTML]:
            raise ValueError("Invalid typesetting mode " + self.mode)

        if option:
            self.add_option(option)
            print("add option", option)
        self.cols = self.ncols()  # cache
        if self.cols == 0:
            print("typeset: no data")
            return ""

        if self.mode not in [self.TEXT, self.LATEX, self.HTML]:
            raise ValueError("Invalid typesetting mode " + self.mode)

        if self.mode not in [self.TEXT, self.LATEX, self.HTML]:
            raise ValueError("Invalid typesetting mode " + self.mode)

        ret = [""]  # array of strings that will be concatenatted

        # If we need column totals, compute them
        if hasattr(self, "col_totals"):
            self.compute_and_add_col_totals()

        # Precalc any table widths if necessary 
        if self.mode == self.TEXT:
            self.calculate_col_formatted_widths()
            if self.title:
                ret.append(self.title + ":" + "\n")

        #
        # Start of the table 
        #
        if self.mode == self.LATEX:
            if self.fontsize:
                ret.append("{\\fontsize{%d}{%d}\\selectfont" % (self.fontsize, self.fontsize + 1))
            try:
                colspec = self.latex_colspec
            except AttributeError:
                colspec = "r" * self.cols
            if self.OPTION_LONGTABLE not in self.options:
                # Regular table
                if self.OPTION_TABLE in self.options:
                    ret.append("\\begin{table}")
                if self.OPTION_CENTER in self.options:
                    ret.append("\\begin{center}")
                if self.caption:
                    ret += ["\\caption{", self.caption, "}\n"]
                if self.label:
                    ret.append("\\label{")
                    ret.append(self.label)
                    ret.append("}")
                if self.OPTION_TABULARX in self.options:
                    ret += ["\\begin{tabularx}{\\textwidth}{", colspec, "}\n"]
                else:
                    ret += ["\\begin{tabular}{", colspec, "}\n"]
                ret += self.typeset_headings()
            if self.OPTION_LONGTABLE in self.options:
                # Longtable
                ret += ["\\begin{longtable}{", colspec, "}\n"]
                if self.caption:
                    ret += ["\\caption{", self.caption, "}\\\\ \n"]
                if self.label:
                    ret += ["\\label{", self.label, "}"]
                ret += self.typeset_headings()
                ret.append("\\hline\\endfirsthead\n")
                if self.label:
                    ret += [r'\multicolumn{', str(self.ncols()), r'}{c}{(Table \ref{', self.label, r'} continued)}\\', '\n']
                ret += self.typeset_headings()
                ret.append("\\hline\\endhead\n")
                ret += ['\\multicolumn{', str(self.ncols()), '}{c}{(Continued on next page)}\\\\ \n']
                ret.append(self.footer)
                ret.append("\\hline\\endfoot\n")
                ret.append(self.footer)
                ret.append("\\hline\\hline\\endlastfoot\n")
        elif self.mode == self.HTML:
            ret.append("<table>\n")
            ret += self.typeset_headings()
        elif self.mode == self.TEXT:
            if self.caption:
                ret.append("================ {} ================\n".format(self.caption))
            if self.header:
                ret.append(self.header)
                ret.append("\n")
            ret += self.typeset_headings()

        #
        # typeset each row.
        # computes the width of each row if necessary
        #
        for row in self.data:
            # See if we should omit this row
            if self.should_omit_row(row):
                continue

            # See if this row demands special processing
            if row.data == self.HR:
                ret.append(self.typeset_hr())
                continue

            ret.append(self.typeset_row(row))

        #
        # End of the table
        ##

        if self.mode == self.LATEX:
            if self.OPTION_LONGTABLE not in self.options:
                if self.OPTION_TABULARX in self.options:
                    ret.append("\\end{tabularx}\n")
                else:
                    ret.append("\\end{tabular}\n")
                if self.OPTION_CENTER in self.options:
                    ret.append("\\end{center}")
                if self.OPTION_TABLE in self.options:
                    ret.append("\\end{table}")
            else:
                ret.append("\\end{longtable}\n")
            if self.fontsize:
                ret.append("}")
            if self.footnote:
                ret.append("\\footnote{")
                ret.append(latex_tools.latex_escape(self.footnote))
                ret.append("}")
        elif self.mode == self.HTML:
            ret.append("</table>\n")
        elif self.mode == self.TEXT:
            if self.footer:
                ret.append(self.footer)
                ret.append("\n")

        # Finally, add any variables that have been defined
        for (name, value) in self.variables.items():
            if self.mode == self.LATEX:
                ret += latex_var(name, value)
            if self.mode == self.HTML:
                ret += "".join(["Note: ", name, " is ", value, "<br>"])

        outbuffer = "".join(ret)
        if out:
            out.write(outbuffer)
        return outbuffer
예제 #9
0
 def latex_cell_text(self, cell):
     if self.option(OPTION_NO_ESCAPE):
         return cell.text
     else:
         return latex_escape(cell.text)