def collect_rows(): q1 = ''' prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> SELECT DISTINCT ?s ?lat ?lng ?title ?ended ?year WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:brewing-ended ?ended. OPTIONAL { ?s tb:year ?year. } } ''' return [ (s, lat, lng, title, convert(ended), convert(dated)) for (s, lat, lng, title, ended, dated) in sparqllib.query_for_rows(q1) ]
def make_thing_map(query, symbols, filename, legend=False): global lat, lng # symbols: [(uri, color, name), ...] themap = config.make_map_from_cli_args() symbols = { uri: (themap.add_symbol(random_id(), color, '#000000', 1, title=pick_name(name)), pick_name(name)) for (uri, color, name) in symbols } other = themap.add_symbol(random_id(), '#000000', '#000000', 1, title='Other') unclassified = {} for (s, title, thing, lat, lng) in sparqllib.query_for_rows(query): try: (symbol, name) = symbols[thing] except KeyError: unclassified[thing] = unclassified.get(thing, 0) + 1 symbol = other name = thing themap.add_marker(lat, lng, title + ': ' + name, symbol) for (thing, count) in unclassified.items(): print 'Unclassified: %s %s' % (thing, count) themap.set_legend(legend) themap.render_to(config.get_file() or filename)
def make_table(filename, query, get_column_label, label, caption, min_accounts=0, format='html', get_row_label=default_row_label, row_type_name='Country'): table = CountryTable(min_accounts, row_label=row_type_name) # v=value, c=country, s=uri of account for (v, c, s) in sparqllib.query_for_rows(query): table.add_account(v, c, s) if format == 'html': writer = HtmlWriter(codecs.open(filename, 'w', 'utf-8')) elif format == 'latex': writer = LatexWriter(codecs.open(filename, 'w', 'utf-8'), label=label, caption=caption, columns=len(table.get_columns()) + 2) else: assert False, 'Unknown format %s' % format write_table(writer, table, get_column_label, get_row_label) if len(sys.argv) > 1: os.system('open %s' % filename)
def property_table(outf, query, properties): objects = {} for (s, p, o) in sparqllib.query_for_rows(query): if s in objects: k = objects[s] else: k = {} #{'number' : rdfutils.get_number_from_uri(str(s))} objects[s] = k k[str(p)] = o outf.write('<table>\n') outf.write('<tr>\n') for (url, label, func, help) in properties: if not help: outf.write('<th>%s\n' % label) else: outf.write('<th><span title="%s">%s</span>' % (help, label)) for k in objects.values(): outf.write('<tr>') #out.write('<tr><td><a href="#kv%s">%s</a>' % (k['number'], k['number'])) for (url, label, func, help) in properties: v = k.get(url) if v: v = func(v) v = (v or ' ').encode('utf-8') outf.write('<td>%s' % v) outf.write('\n') outf.write('</table>\n')
def color_scale_map(query, outfile, max_value=1000000, legend=False, symbol_count=10, value_mapper=value_mapper, label_formatter=lambda y, x: '%s-%s' % (y, x)): data = [(lat, lng, title, value_mapper(min(float(ratio), max_value))) for (lat, lng, title, ratio) in sparqllib.query_for_rows(query)] color_scale_map_data(data, outfile, legend, symbol_count, label_formatter)
def make_term_map(termprop, symbols, filename, usemap=None, scale=None, language='en'): global lat, lng # symbols: [(regex, color, name), ...] stroke = '#000000' themap = usemap or config.make_map_from_cli_args() symbols = [(regex, themap.add_symbol(random_id(), color, stroke, strokeweight=1, title=name, scale=scale)) for (regex, color, name) in symbols] othername = { 'en': 'Other', 'no': 'Annet', }[language] OTHER = themap.add_symbol('black', '#000000', stroke, strokeweight=1, title=othername, scale=scale) unmatched = [] for (title, lat, lng, term) in sparqllib.query_for_rows(query % termprop): symbol = OTHER for (regex, s) in symbols: if matches(regex, term): symbol = s break themap.add_marker(lat, lng, title + ': ' + term, symbol) if symbol == OTHER: unmatched.append(term) themap.set_legend(True) themap.render_to(filename) unmatched.sort() for term in unmatched: print term
def make_boolean_map(query, filename, labels=None): themap = config.make_map_from_cli_args() if labels: themap.set_legend(True) labels = labels or {'borderline': '', 'true': '', 'false': ''} gray = themap.add_symbol('gray', '#999999', title=labels['borderline']) symbols = { 'true': themap.add_symbol('white', '#FFFF00', title=labels['true']), 'false': themap.add_symbol('black', '#000000', title=labels['false']), 'http://www.garshol.priv.no/2014/neg/both': gray, 'http://www.garshol.priv.no/2014/neg/borderline': gray } for (s, lat, lng, title, value) in sparqllib.query_for_rows(query): symbol = symbols[value] themap.add_marker(lat, lng, title, symbol) themap.render_to(filename)
def get_data(country): query = ''' prefix dc: <http://purl.org/dc/elements/1.1/> prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix neu: <http://www.garshol.priv.no/2015/neu/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix uff: <http://www.garshol.priv.no/2015/uff/> SELECT DISTINCT ?h ?c ?s WHERE { ?s dc:title ?title; tb:part-of ?c; tb:brew-frequency ?h. ?c a dbp:Country. FILTER (?c = dbp:%s) }''' % country return [float(t) for (t, c, s) in sparqllib.query_for_rows(query)]
?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:pitch-temperature ?t. OPTIONAL { ?s tb:own-yeast ?yeast } }''' accounts = set() own = 0 unknown = 0 other = 0 for (s, lat, lng, t, yeast) in sparqllib.query_for_rows(query): if not pitch.get_temp(t): continue if s in accounts: print 'DUPLICATE', s accounts.add(s) if yeast == 'true': own += 1 elif yeast == 'false': other += 1 else: unknown += 1 total = own + unknown + other
SELECT DISTINCT ?s ?dry ?wood WHERE { ?s dc:title ?title; tb:malt-drying ?dry; tb:malt-drying-wood ?wood. }''' def get_name(h): return tablelib.get_last_part(str(h)) MALT = 'http://www.garshol.priv.no/2014/trad-beer/malt-drying/' simplify = { MALT + 'a-shaped-kiln': MALT + 'soinn', } filename = 'kiln-wood-table.html' table = tablelib.CountryTable(min_accounts=1) for (s, dry, wood) in sparqllib.query_for_rows(query): dry = simplify.get(dry, dry) table.add_account(wood, dry, s) writer = tablelib.HtmlWriter(open(filename, 'w')) tablelib.write_table(writer, table, get_name) if len(sys.argv) > 1: os.system('open %s' % filename)
import sys, codecs import tablelib, sparqllib import pitch tab = tablelib.HtmlWriter(codecs.open('pitch-temperature-qa-table.html', 'w', 'utf-8')) tab.start_table() tab.header_row('URI', 'LAT', 'LONG', 'TEMP TEXT', 'TEMP', 'CAT', 'COUNTRY') seen = set() for (s, lat, lng, t, c) in sparqllib.query_for_rows(pitch.query): temp = pitch.get_temp(t) tab.row(s, lat, lng, t, temp, pitch.get_category(t, quiet = True), c) if s in seen: print 'DUPLICATE', s else: seen.add(s) tab.end_table()
title=l['either']) blue = themap.add_symbol('blue', '#0000FF', '#000000', strokeweight=1, title=l['men']) NEG = 'http://www.garshol.priv.no/2014/neg/' MALE = NEG + 'male' FEMALE = NEG + 'female' BOTH = NEG + 'both' symbol_map = {MALE: blue, FEMALE: red, BOTH: pink} query = ''' prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> SELECT ?s ?lat ?lng ?sex ?title WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:malter-sex ?sex. }''' for (s, lat, lng, sex, title) in sparqllib.query_for_rows(query): symbol = symbol_map[sex] themap.add_marker(lat, lng, title, symbol) themap.set_legend(True) themap.render_to(config.get_file() or 'malter-sex-map')
'From bottom of beer cask': green, } query = ''' prefix dc: <http://purl.org/dc/elements/1.1/> prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix yeast: <http://www.garshol.priv.no/2017/trad-beer/yeast-keeping/> SELECT DISTINCT ?s ?lat ?lng ?proc ?procname ?title WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:yeast-keeping ?proc. ?proc rdfs:label ?procname. }'''# FILTER( ?proc in (yeast:log, yeast:yeast-ring)) for (s, lat, lng, proc, procname, title) in sparqllib.query_for_rows(query): symbol = symbols.get(procname, black) if symbol == black: print 'UNMAPPED', repr(procname) themap.add_marker(lat, lng, title, symbol, procname) themap.set_legend(True) themap.render_to(config.get_file() or 'yeast-keeping-map')
SELECT DISTINCT ?s ?lat ?lng ?t ?c ?time WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:fermentation-time ?time; tb:pitch-temperature ?t. ?s tb:part-of ?c. ?c a dbp:Country. }''' temps = [] times = [] for (s, lat, lng, t, c, time) in sparqllib.query_for_rows(query): temp = pitch.get_temp(t) if not temp: continue temps.append(temp) times.append(float(time)) from matplotlib import pyplot as plt plt.scatter(times, temps) plt.title('Pitch temperature vs fermentation time') plt.xlabel('Fermentation time') plt.ylabel('Pitch temperature') plt.show()
NEG + 'either' : EITHER, NEG + 'both' : EITHER } query = ''' prefix dc: <http://purl.org/dc/elements/1.1/> prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix eu: <http://www.garshol.priv.no/2017/eu/> prefix r: <http://www.garshol.priv.no/2014/trad-beer/recipe/> SELECT DISTINCT ?s ?lat ?lng ?title ?harvest WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:yeast-harvest ?harvest. }''' for (s, lat, lng, title, harvest) in sparqllib.query_for_rows(query): try: symbol = symbols[harvest] except KeyError: print 'KeyError:', s, harvest raise themap.add_marker(lat, lng, title, symbol) themap.set_legend(True) themap.render_to(config.get_file() or 'yeast-harvest')
def average(numbers): return sum(numbers) / len(numbers) # ===== ALL IN ONE DATA SET singles = [] ranges = [] milks = 0 bodies = 0 other = 0 unreadable = 0 temperatures = [] q = pitch.make_query(country=config.get_country()) for (s, lat, lng, t, c) in sparqllib.query_for_rows(q): temp = pitch.get_temp(t) if temp: cat = pitch.get_category(t) temperatures.append(temp) if cat == 'single': singles.append(temp) elif cat == 'range': ranges.append(temp) elif cat == 'milkwarm': milks += 1 elif cat == 'body': bodies += 1 else:
data = {} # url -> (title, lat, lng, [v1, v2, ...]) query = ''' prefix dc: <http://purl.org/dc/elements/1.1/> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> SELECT ?s ?t ?lat ?lng ?hops WHERE { ?s dc:title ?t; geo:lat ?lat; geo:long ?lng; tb:hops ?hops. }''' for (s, t, lat, lng, v) in sparqllib.query_for_rows(query): hops = [] if data.has_key(s): hops = data[s][3] hops.append(strip_uri(v)) data[s] = (t, lat, lng, hops) # ----- STEP 2: MAKE THE MAP themap = config.make_map_from_cli_args() if OAT_BELT: geojson = open('/Users/larsga/data/privat/trad-beer/works/map-data/hasund-line.json').read() themap.add_line_string(geojson = geojson, color = '#0000FF', width = 3)
prefix dc: <http://purl.org/dc/elements/1.1/> prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix neu: <http://www.garshol.priv.no/2015/neu/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix uff: <http://www.garshol.priv.no/2015/uff/> SELECT DISTINCT ?h ?c ?s WHERE { ?s dc:title ?title; tb:part-of ?c; tb:hop-wort-ratio ?h. ?c a dbp:Country. }''' # FILTER( ?c = dbp:Denmark ) values = [float(h) for (h, c, s) in sparqllib.query_for_rows(query)] # PLOT A HISTOGRAM # http://matplotlib.org/1.2.1/examples/pylab_examples/histogram_demo.html from matplotlib import pyplot pyplot.style.use('ggplot') (n, bins, patches) = pyplot.hist(values, 10) pyplot.title('Hopping rates in farmhouse ale') pyplot.ylabel('Number of accounts') pyplot.xlabel('Grams per liter') pyplot.show()
black = themap.add_symbol('black', '#000000', '#000000', strokeweight=1, title="Don't remove") query = ''' prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix neg: <http://www.garshol.priv.no/2014/neg/> SELECT ?s ?lat ?lng ?remove ?title WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; neg:remove-sprout ?remove. }''' for (s, lat, lng, remove, title) in sparqllib.query_for_rows(query): if remove == 'true': symbol = yellow elif remove == 'false': symbol = black else: assert 0, 'Bad remove: ' + remove themap.add_marker(lat, lng, title, symbol) themap.set_legend(True) themap.render_to('remove-sprout-map')
}''' def decade(year): return (int(year) / 10) * 10 def bicade(year): bic = int(year) / 10 bic = bic - (bic % 2) return bic * 10 def label(v): if v == 'http://www.garshol.priv.no/2014/neg/borderline': return 'borderline' elif v == 'true': return 'Own malts' else: return 'Bought malts' def sort_rows(): rows = list(set(table._country.values())) rows.sort() return rows table = tablelib.CountryTable(0, sort_rows = sort_rows, row_label = 'Decade') for (s, year, yeast) in sparqllib.query_for_rows(query): table.add_account(yeast, decade(year), s) writer = tablelib.HtmlWriter(open('own-malts-by-decade.html', 'w')) tablelib.write_table(writer, table, label)
smallest = 0 biggest = 250 increment = (biggest - smallest) / symbol_count if themap.get_color(): colorfunc = maputils.color else: colorfunc = maputils.bwcolor symbols = [ themap.add_symbol('id%s' % ix, '#' + colorfunc(ix, symbol_count), '#000000', strokeweight=1, scale=10, title='%s-%s' % (smallest + increment * ix, smallest + increment * (ix + 1))) for ix in range(symbol_count) ] for (s, title, h, lat, lng) in sparqllib.query_for_rows(query): hours = float(h) index = (int((hours - smallest) / increment)) symbol = symbols[min(index, symbol_count - 1)] print hours, min(index, symbol_count - 1), symbol.get_color() themap.add_marker(lat, lng, '%s' % title, symbol) themap.set_legend(True) themap.render_to('fermentation-time-map')
prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix uff: <http://www.garshol.priv.no/2015/uff/> SELECT DISTINCT ?s ?title ?y WHERE { ?s a ?type; dc:title ?title; tb:year ?y. ?type rdfs:subClassOf tb:Account. }''' # tb:pitch-temperature ?pt; years = [] for (s, title, y) in sparqllib.query_for_rows(query): #print s, title, y if int(y) < 0: print s, title years.append(int(y)) years.sort() print years[0], '-', years[-1] from matplotlib import pyplot pyplot.style.use(config.get_plot_style()) (n, bins, patches) = pyplot.hist(years, BINS, alpha=0.5,
query = ''' prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> SELECT ?s ?title ?lat ?lng ?inf WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:juniper-infusion ?inf. }''' accounts = { s: (title, lat, lng, number(inf)) for (s, title, lat, lng, inf) in sparqllib.query_for_rows(query) } query = ''' prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> SELECT ?s ?title ?lat ?lng ?herbs WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:herbs ?herbs. }'''
prefix neu: <http://www.garshol.priv.no/2015/neu/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix uff: <http://www.garshol.priv.no/2015/uff/> SELECT DISTINCT ?h ?c ?s WHERE { ?s dc:title ?title; tb:part-of ?c; tb:brew-frequency ?h. ?c a dbp:Country. }''' # FILTER( ?c = dbp:Norway ) values = [float(t) for (t, c, s) in sparqllib.query_for_rows(query)] # PLOT A HISTOGRAM # http://matplotlib.org/1.2.1/examples/pylab_examples/histogram_demo.html from matplotlib import pyplot (n, bins, patches) = pyplot.hist(values, 10) pyplot.title('Brews per year') pyplot.xlabel('Brews') pyplot.ylabel('Number of accounts') pyplot.show() # =========================================================================== # NORWAY vs DENMARK def get_data(country):
?s tb:adjuncts ?a } ''' # ===== HERBS BY COUNTRY query = ''' prefix dc: <http://purl.org/dc/elements/1.1/> prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix neu: <http://www.garshol.priv.no/2015/neu/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix uff: <http://www.garshol.priv.no/2015/uff/> SELECT DISTINCT ?h ?c ?s WHERE { ?s dc:title ?title; tb:part-of ?c; tb:adjuncts ?h. ?c a dbp:Country. }''' table = tablelib.CountryTable(min_accounts = 2) for (a, c, s) in sparqllib.query_for_rows(query): table.add_account(a, c, s) out = tablelib.HtmlWriter(open('adjunct-table.html', 'w')) tablelib.write_table(out, table, tablelib.get_last_part)
?s dc:title ?title; tb:part-of ?c; tb:yeast-keeping ?proc. ?c a dbp:Country. }''' q2 = ''' prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix yeast: <http://www.garshol.priv.no/2017/trad-beer/yeast-keeping/> select ?s ?l where { ?s a tb:YeastKeepingMethod; rdfs:label ?l. } ''' labels = {uri : label for (uri, label) in sparqllib.query_for_rows(q2)} def get_method_name(uri): if uri == 'Other': return 'Other' return labels[uri] format = tablelib.get_format() tablelib.make_table('yeast-keeping-table.html', query, get_method_name, label = 'yeast_keeping', caption = 'Methods for yeast preservation', min_accounts = MIN_ACCOUNTS, format = format)
prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix uff: <http://www.garshol.priv.no/2015/uff/> SELECT DISTINCT ?s ?lat ?lng ?t ?type WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:pitch-temperature ?t; tb:yeast-type ?type. }''' groups = {} for (s, lat, lng, t, group) in sparqllib.query_for_rows(query): temp = pitch.get_temp(t) if temp: if group not in groups: groups[group] = [] groups[group].append(temp) import numpy from matplotlib import pyplot ix = 0 for groupname in GROUPS.keys(): temperatures = [] for grpid in GROUPS[groupname]: temperatures += groups.get(grpid, [])
prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix sproc: <http://www.garshol.priv.no/2014/trad-beer/simple-process/> SELECT DISTINCT ?s ?malts WHERE { ?s dc:title ?title; tb:malt-wort-ratio ?malts; geo:lat ?lat; geo:long ?lng. }''' # tb:process ?proc. # ?proc neg:variant-of ?sproc. # ?sproc neg:variant-of ?ssproc. # FILTER (?ssproc = sproc:complex-mash) ratios = [float(ratio) for (s, ratio) in sparqllib.query_for_rows(query)] from matplotlib import pyplot #pyplot.style.use('grayscale') (n, bins, patches) = pyplot.hist(ratios, BINS, alpha=0.5, label='Malt/wort ratios') pyplot.title('Farmhouse ale strength') pyplot.xlabel('Kilos of malt pr liter') pyplot.ylabel('Number of accounts') pyplot.show()
import maplib import sparqllib themap = config.make_map_from_cli_args() symbols = { '1' : themap.add_symbol('white', '#FFFFFF', '#000000'), '0' : themap.add_symbol('black', '#000000', '#000000'), 'true' : themap.add_symbol('white', '#FFFFFF', '#000000'), 'false' : themap.add_symbol('black', '#000000', '#000000') } query = ''' prefix dc: <http://purl.org/dc/elements/1.1/> prefix neg: <http://www.garshol.priv.no/2014/neg/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> SELECT DISTINCT ?s ?lat ?lng ?title ?mead WHERE { ?s dc:title ?title; geo:lat ?lat; geo:long ?lng; tb:strong-beer ?mead. }''' for (s, lat, lng, title, mead) in sparqllib.query_for_rows(query): themap.add_marker(lat, lng, title, symbols[mead]) themap.render_to('strong-beer')
prefix tb: <http://www.garshol.priv.no/2014/trad-beer/> prefix dbp: <http://dbpedia.org/resource/> prefix uff: <http://www.garshol.priv.no/2015/uff/> SELECT DISTINCT ?h ?s WHERE { ?s dc:title ?title; tb:part-of ?c; tb:herbs ?h. ?c a dbp:Country. FILTER( ?c = dbp:%s ) }''' % country # FILTER (?h != neg:alder-branches && ?h != neg:straw ) rows = [(herb, account) for (herb, account) in sparqllib.query_for_rows(query)] accounts = set([account for (herb, account) in rows]) herb_count = {} for (herb, account) in rows: herb_count[herb] = herb_count.get(herb, 0) + 1 herb_rows = herb_count.items() herb_rows.sort(key=lambda pair: pair[1] * -1) filename = 'herbs-single-country.html' if format == 'html': writer = tablelib.HtmlWriter(open(filename, 'w')) else: writer = tablelib.LatexWriter(open(filename, 'w'),