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
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)
def make_runtime(): """Generate information about the runtime and return the tt object""" tt = ttable() tt.set_col_alignment(0, ttable.LEFT) tt.set_col_alignment(1, ttable.LEFT) tt.add_data(ttable.HR) for (k, v) in [["hostname", socket.gethostname()], ["uptime", shell("uptime")], ["time", datetime.datetime.now().isoformat()[0:19]]]: tt.add_data([k, v]) tt.add_data(ttable.HR) return tt
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)
def typeset(self,*,mode): if not self.count: return "" t = ttable() t.add_head(['Significant Digits','Cell count','Problem cells']) t.set_latex_colspec("rrl") t.set_col_alignment(1,ttable.CENTER) for (key,val) in sorted(self.sig_digits_histogram.items()): alerts = " ".join( str(alert) for alert in self.sig_digits_alerts[key][0:ALERT_VALUES]) if len(self.sig_digits_alerts[key]) >= ALERT_VALUES: alerts += r" \dots" t.add_data( (key,val,alerts) ) return t.typeset(mode=mode)
def typeset(self,*,mode): if not self.count: return "" t = ttable() t.add_head(['Significant Digits','Cell count','Problem cells']) t.set_latex_colspec("rrl") t.set_col_alignment(1,ttable.CENTER) for (sig_digs,vals) in sorted(self.sig_digits_alerts.items()): alert_cells = sorted(vals)[0:ALERT_VALUES] alerts = " ".join( [str(a) for a in alert_cells]) if len(alert_cells) >= ALERT_VALUES: alerts += r" . . . " t.add_data( (sig_digs,len(vals),alerts) ) if t.data: return t.typeset(mode=mode) else: return f"Cells: {self.count}; nothing improperly rounded."
count = 0 considered = 0 rows = [] for a in range(1,115): for b in range(a,115): for c in range(b,115): mean = statistics.mean([a,b,c]) median = statistics.median([a,b,c]) considered += 1 if median==MEDIAN and mean==MEAN: rows.append([a,b,c]) count += 1 # Now build a multicolumn table COLUMNS = 3 tt = tytable.ttable() tt.add_variable("mymedian",MEDIAN) tt.add_variable("mymean",MEAN) tt.add_head(['a','b','c'] * COLUMNS) total_rows = len(rows) for i in range(total_rows//COLUMNS): row = [] for col in range(0,3): offset = (total_rows * col)//COLUMNS + i if offset < len(rows): row += rows[offset] else: row += ['']*len(rows[0]) tt.add_data(row) tt.set_latex_colspec('@{\hspace{1pc}}|@{\hspace{1pc}}'.join(['rrr'] * COLUMNS))