#!/usr/bin/python import sys import ezt COLS = 28 ROWS = 25 def plot(fp, table): ezt.Template('wines.ezt', True, ezt.FORMAT_HTML).generate(fp, {'wines': table}) def extract_wines(wines): table = [_item([_item() for c in range(COLS)]) for r in range(ROWS)] for row in wines: bin = row[6] if bin.startswith('AA'): bin_c = 26 bin_r = int(bin[2:]) elif bin.startswith('AB'): bin_c = 26 bin_r = int(bin[2:]) elif not bin: # whoops!! continue else: bin_c = ord(bin[0]) - ord('A') bin_r = int(bin[1:]) item = table[bin_r].row[bin_c] item.bin = bin item.color = row[0] item.vintage = row[1] item.wine = row[2] item.locale = row[3] item.winery = row[4] item.varietal = row[5] item.start_year = _convert_year(row[7]) item.end_year = _convert_year(row[8]) item.my_score = row[9] if row[10]: item.score = format(float(row[10]), '.1f') else: item.score = None return table def _convert_year(y): if y == '9999': return None return int(y) class _item(object): # two types of items. one with a single 'row' attr, and all others def __init__(self, row=None): self.row = row self.wine = None # detect empty cells def _check_data(wines): assert wines[0] == [ 'Color', 'Vintage', 'Wine', 'Locale', 'Producer', 'Varietal', 'Bin', 'BeginConsume', 'EndConsume', 'PScore', 'CScore', ] def run_plot(out_fn, wines_fn): if out_fn is None or out_fn == '-': out_fp = sys.stdout else: out_fp = open(out_fn, 'w') if wines_fn is None or wines_fn == '-': wines_fp = sys.stdin else: wines_fp = open(wines_fn) wines = [line.rstrip('\r\n').split('\t') for line in wines_fp.readlines()] _check_data(wines) table = extract_wines(wines[1:]) plot(out_fp, table) if __name__ == '__main__': if len(sys.argv) > 1: wines_fn = sys.argv[1] if len(sys.argv) > 2: out_fn = sys.argv[2] else: out_fn = None else: wines_fn = None out_fn = None run_plot(out_fn, wines_fn)