def render_cutoff_paths(self, output_port, xmax=None, ymax=None): print(latex.subsection("Paths with cutoff"), file=output_port) # Build a lattice for each cluster size {1 .. num_modules-1} print("Building lattice for %s" % self.project_name) lattice = self.make_lattice(transitivity=self.get_num_modules()) # xmax = max((e[2]["weight"] for e in lattice.edges_iter(data=True))) untyped_config = "0" * self.get_num_modules() untyped_mean = self.stats_of_config(untyped_config)["mean"] typed_config = "1" * self.get_num_modules() typed_mean = self.stats_of_config(typed_config)["mean"] rows = [] for group_size in range(1, self.get_num_modules()): # For each group size (freedom to type exactly N modules at once) # make a histogram of max overhead edges along each path # (Shows the number of paths that have 'really bad' overhead) print("Computing paths for group size '%s'" % group_size) cutoff = 1 + (self.get_num_modules() - group_size) paths = networkx.all_simple_paths(lattice, source=untyped_config, target=typed_config, cutoff=cutoff) weights = [self.max_weight(lattice, path) for path in paths if len(path) == 1 + cutoff] num_release_u = sum((1 for x in weights if x < (untyped_mean * constants.DELIVERABLE))) num_dev_u = sum((1 for x in weights if x < (untyped_mean * constants.USABLE))) num_x_u = sum((1 for x in weights if x < (untyped_mean * 15))) num_release_t = sum((1 for x in weights if x < (typed_mean * constants.DELIVERABLE))) num_dev_t = sum((1 for x in weights if x < (typed_mean * constants.USABLE))) num_x_t = sum((1 for x in weights if x < (typed_mean * 15))) num_paths = len(weights) rows.append( [str(cutoff), str(num_paths)] + [ "%s (%s\\%%)" % (x, round((x / num_paths) * 100, 2)) for x in [num_release_u, num_dev_u, num_x_u, num_release_t, num_dev_t, num_x_t] ] ) print( latex.table( [ "Path length", "Total", "$<$ 2x untyped", "$<$ 4x untyped", "$<$ 15x untyped", "$<$ 2x typed", "$<$ 4x typed", "$<$ 15x typed", ], rows, ), file=output_port, )
def render_all_paths(self, output_port, transitivity=[1]): """ Options: - transitivity : How many transitive edges to include. By default, edges are only between consecutive levels. If argument is a list, analyzes one graph of each transitivity """ print(latex.subsection("Lattices+Freedom"), file=output_port) typed_mean = self.stats_of_config("1" * self.get_num_modules())["mean"] untyped_mean = self.stats_of_config("0" * self.get_num_modules())["mean"] rows = [] for trans in transitivity: print("Building lattice for %s with transitivity %s" % (self.project_name, trans)) lattice = self.make_lattice(transitivity=trans) untyped_config = "0" * self.get_num_modules() typed_config = "1" * self.get_num_modules() paths = networkx.all_simple_paths(lattice, source=untyped_config, target=typed_config) weights = [self.max_weight(lattice, path) for path in paths] num_release_u = sum((1 for x in weights if x < (untyped_mean * constants.DELIVERABLE))) num_dev_u = sum((1 for x in weights if x < (untyped_mean * constants.USABLE))) num_x_u = sum((1 for x in weights if x < (untyped_mean * 15))) num_release_t = sum((1 for x in weights if x < (typed_mean * constants.DELIVERABLE))) num_dev_t = sum((1 for x in weights if x < (typed_mean * constants.USABLE))) num_x_t = sum((1 for x in weights if x < (typed_mean * 15))) num_paths = len(weights) rows.append( [str(trans), str(num_paths)] + [ "%s (%s\\%%)" % (x, round((x / num_paths) * 100, 2)) for x in [num_release_u, num_dev_u, num_x_u, num_release_t, num_dev_t, num_x_t] ] ) print( latex.table( [ "Fuel", "Total", "$<$ 2x untyped", "$<$ 4x untyped", "$<$ 15x untyped", "$<$ 2x typed", "$<$ 4x typed", "$<$ 15x typed", ], rows, ), file=output_port, )
def render_sample_results(self, output_port): print(latex.subsection("Notes"), file=output_port) num_sampled = sum((1 for v in self.stats_by_config.values() if v)) print("Sampled %s of %s configurations." % (num_sampled, self.get_num_configurations()), file=output_port) print(latex.table(["\# Typed", "\# Configs", "\# Samples", "Sample Mean", "Sample Variance", "95\% CI", "Standard Error", "Jarque-Bera"] ,[self.sample_stats((lambda cfg, nt=n: config.num_typed_modules(cfg) == n), n) for n in range(self.get_num_modules())]), file=output_port)
def main(): parser = argparse.ArgumentParser(description="Generate maps comparing the actual and theoretical proportional representation in a given year.") parser.add_argument('year', action='store', default='2016', type=int) parser.add_argument('--latex', dest='latex', action='store_true') args = parser.parse_args() year = args.year try: a = YEAR_DATA[year] except Exception as e: print("No data available for {}. Note that the analysis only works in presidential years.".format(year)) return -1 with open(YEAR_DATA[year]['house'], "r") as house: reader = csv.DictReader(house) states = dict() for row in reader: curState = row['state'].title().strip() if row['is_winner'].upper() == 'TRUE': try: states[curState].delegation += 1 except: states[curState] = State(curState, 1) rep = Representative(row['name'], util.party_str(row['individual_party'])) states[curState].reps.append(rep) with open(YEAR_DATA[year]['pres']) as pres: reader = csv.DictReader(pres) for row in reader: curState = row['state'].title().strip() if curState in states: states[curState].voteshare[util.party_str(row['individual_party'])] += float(row['vote_pct'])/100 totals = {util.Party.DEM: 0, util.Party.GOP: 0, util.Party.OTHER: 0} for k in states: state=states[k] print(state) for r in state.reps: print(r) print("Pres. share:") for s in state.voteshare: print("{}: {:.1%}".format(s, state.voteshare[s])) state.calculate_prop() print("Rep. share:") print("D: {:.1%}".format(state.prop_rep[util.Party.DEM]/(state.delegation*2))) print("R: {:.1%}".format(state.prop_rep[util.Party.GOP]/(state.delegation*2))) print("I: {:.1%}".format(state.prop_rep[util.Party.OTHER]/(state.delegation*2))) print(state.prop_rep) totals[util.Party.DEM] += state.prop_rep[util.Party.DEM] totals[util.Party.GOP] += state.prop_rep[util.Party.GOP] totals[util.Party.OTHER] += state.prop_rep[util.Party.OTHER] print(state.check_prop()) print("Total seats: D: {}, R: {}, I: {}".format(totals[util.Party.DEM],totals[util.Party.GOP],totals[util.Party.OTHER])) old_colors = {} prop_colors = {} for s in states: state = states[s] try: old_colors[s] = mapwriter.lean_to_color(state.rep_shares(), state.voteshare, state.delegation) prop_colors[s] = mapwriter.lean_to_color({p: state.prop_rep[p]/(2*state.delegation) for p in list(util.Party)}, state.voteshare, state.delegation*2) except: print("Error on {}".format(str(state))) exit() oldmap = mapwriter.MapWriter(old_colors) oldmap.generate() oldmap.write("out/{}_old_map.svg".format(year)) prop_map = mapwriter.MapWriter(prop_colors) prop_map.generate() prop_map.write("out/{}_prop_map.svg".format(year)) if (args.latex): header = [['\\textbf{State}', '\\multicolumn{3}{c}{\\textbf{Single Member Districts}}', '\\multicolumn{4}{c}{\\textbf{Mixed Member Prop.}}'], ['', 'GOP', 'Dem', 'Badness', 'GOP', 'Dem', 'Other', 'Badness']] data = [] total_seats = {'gop_old': 0, 'dem_old': 0, 'gop_prop': 0, 'dem_prop': 0, 'other_prop': 0} for s in states: state = states[s] vote_share = state.voteshare rep_share = state.rep_shares() prop_share = {p: state.prop_rep[p]/(2*state.delegation) for p in list(util.Party)} def countreps(p): i=0 for r in state.reps: if r.party == p: i+=1 return i rep_dist = {p: countreps(p) for p in list(util.Party)} prop_dist = state.prop_rep total_seats['gop_old'] += rep_dist[util.Party.GOP] total_seats['dem_old'] += rep_dist[util.Party.DEM] total_seats['gop_prop'] += prop_dist[util.Party.GOP] total_seats['dem_prop'] += prop_dist[util.Party.DEM] total_seats['other_prop'] += prop_dist[util.Party.OTHER] data.append([state.name,'{}'.format(rep_dist[util.Party.GOP]), '{}'.format(rep_dist[util.Party.DEM]), '{:.1f}\\%'.format(vote_badness(rep_share, vote_share)*100.0), '{}'.format(prop_dist[util.Party.GOP]), '{}'.format(prop_dist[util.Party.DEM]), '{}'.format(prop_dist[util.Party.OTHER]), '{:.1f}\\%'.format(vote_badness(prop_share, vote_share)*100.0)]) footer = [['Totals', str(total_seats['gop_old']), str(total_seats['dem_old']), '{:.1f}\\%'.format(vote_badness({util.Party.GOP: total_seats['gop_old']/435.0, util.Party.DEM: total_seats['dem_old']/435.0}, YEAR_DATA[year]['results'])*100.0), str(total_seats['gop_prop']), str(total_seats['dem_prop']), str(total_seats['other_prop']), '{:.1f}\\%'.format(vote_badness({util.Party.GOP: total_seats['gop_prop']/870.0, util.Party.DEM: total_seats['dem_prop']/870.0}, YEAR_DATA[year]['results'])*100.0)]] with open("out/{}_table.tex".format(year), "w") as tfile: tfile.write(latex.table(header, data, footer, 8))