import collections import csv from collections import namedtuple from dataclasses import dataclass @dataclass class DataClassRow: __slots__ = ['route', 'date', 'daytype', 'rides'] route: str date: str daytype: str rides: int class BasicRow: def __init__(self, route, date, daytype, rides): self.route = route self.date = date self.daytype = daytype self.rides = rides class SlotsRow: __slots__ = ['route', 'date', 'daytype', 'rides'] def __init__(self, route, date, daytype, rides): self.route = route self.date = date self.daytype = daytype self.rides = rides TupleRow = namedtuple('Row', ['route', 'date', 'daytype', 'rides']) def read_rides(filename, readfunc): """Read the bus ride data using a conversion function.""" with open(filename) as f: rows = csv.reader(f) next(rows) return [readfunc(row) for row in rows] def read_rides_as_tuples(filename): return read_rides(filename, row_to_tuple) def read_rides_as_dicts(filename): return read_rides(filename, row_to_dict) def read_rides_as_namedtuples(filename): return read_rides(filename, row_to_namedtuple) def read_rides_as_classes(filename): return read_rides(filename, row_to_class) def read_rides_as_slotsclasses(filename): return read_rides(filename, row_to_slotsclass) def read_rides_as_dataclasses(filename): return read_rides(filename, row_to_dataclass) class RideData(collections.abc.Sequence): def __init__(self): self.routes = [] self.dates = [] self.daytypes = [] self.numrides = [] def __len__(self): return len(self.routes) def __getitem__(self, index): if not isinstance(index, slice): return dict(route=self.routes[index], date=self.dates[index], daytype=self.daytypes[index], rides=self.numrides[index]) value = RideData() value.routes = self.routes[index] value.dates = self.dates[index] value.daytypes = self.daytypes[index] value.numrides = self.numrides[index] return value def append(self, d): self.routes.append(d['route']) self.dates.append(d['date']) self.daytypes.append(d['daytype']) self.numrides.append(d['rides']) def read_rides_as_columns(filename): """Read the bus ride data into 4 lists, one per column.""" data = RideData() with open(filename) as f: rows = csv.reader(f) next(rows) for row in rows: data.append(dict(route=row[0], date=row[1], daytype=row[2], rides=int(row[3]))) return data def row_to_tuple(row): return (row[0], row[1], row[2], int(row[3])) def row_to_dict(row): return dict(route=row[0], date=row[1], daytype=row[2], rides=int(row[3])) def row_to_namedtuple(row): return TupleRow(row[0], row[1], row[2], int(row[3])) def row_to_class(row): return BasicRow(row[0], row[1], row[2], int(row[3])) def row_to_slotsclass(row): return SlotsRow(row[0], row[1], row[2], int(row[3])) def row_to_dataclass(row): return DataClassRow(route=row[0], date=row[1], daytype=row[2], rides=int(row[3])) if __name__ == '__main__': import sys import tracemalloc method = sys.argv[1] methods = { 'tuple': row_to_tuple, 'dict': row_to_dict, 'namedtuple': row_to_namedtuple, 'class': row_to_class, 'slots': row_to_slotsclass, 'dataclass': row_to_dataclass, } if method not in methods: print("unknown method") sys.exit(-1) tracemalloc.start() rows = read_rides('Data/ctabus.csv', methods[method]) print('Memory Use: Current %d, Peak %d;' % tracemalloc.get_traced_memory(), 'Method:', method)