예제 #1
0
def get_targets_by_chamber(chamber):
    if chamber not in targets_by_chamber:
        # Get all current representatives or all senators.
        role_type = RoleType.representative if chamber == "house" else RoleType.senator
        targets = PersonRole.objects.filter(
         current=True,
         role_type=role_type)\
         .exclude(phone=None)\
         .select_related('person')

        # Create a priority score for each. We prefer to first call
        # legislators in the middle of the ideology spectrum because
        # they are least predictable, and also we prefer to call leaders
        # because they are more important.
        analysis = load_sponsorship_analysis2(settings.CURRENT_CONGRESS,
                                              role_type, None)
        target_priorities = {}

        all_ideology_scores = [float(p["ideology"]) for p in analysis["all"]]
        mean_ideology = sum(all_ideology_scores) / float(len(analysis["all"]))
        absmax_ideology = max(abs(max(all_ideology_scores) - mean_ideology),
                              abs(min(all_ideology_scores) - mean_ideology))

        for p in analysis["all"]:
            score = float(
                p["leadership"]) - abs(float(p["ideology"]) -
                                       mean_ideology) / absmax_ideology
            target_priorities[p["id"]] = score

        targets_by_chamber[chamber] = [
            (target, target_priorities.get(target.person.id, 0.0))
            for target in targets
        ]

    return targets_by_chamber[chamber]
예제 #2
0
def get_targets_by_chamber(chamber):
	if chamber not in targets_by_chamber:
		# Get all current representatives or all senators.
		role_type = RoleType.representative if chamber == "house" else RoleType.senator
		targets = PersonRole.objects.filter(
			current=True,
			role_type=role_type)\
			.exclude(phone=None)\
			.select_related('person')

		# Create a priority score for each. We prefer to first call
		# legislators in the middle of the ideology spectrum because
		# they are least predictable, and also we prefer to call leaders
		# because they are more important.
		analysis = load_sponsorship_analysis2(settings.CURRENT_CONGRESS, role_type, None)
		target_priorities = { }

		all_ideology_scores = [float(p["ideology"]) for p in analysis["all"]]
		mean_ideology = sum(all_ideology_scores) / float(len(analysis["all"]))
		absmax_ideology = max(abs(max(all_ideology_scores)-mean_ideology), abs(min(all_ideology_scores)-mean_ideology))

		for p in analysis["all"]:
			score = float(p["leadership"]) - abs(float(p["ideology"]) - mean_ideology)/absmax_ideology
			target_priorities[p["id"]] = score

		targets_by_chamber[chamber] = [
			(target, target_priorities.get(target.person.id, 0.0))
			for target in targets
		]

	return targets_by_chamber[chamber]
예제 #3
0
 def make_chart_series(role_type):
     data = load_sponsorship_analysis2(CURRENT_CONGRESS, role_type, None)
     if not data: return None
     
     ret = { }
     for p in data["all"]:
         ret.setdefault(p["party"], {
             "type": "party",
             "party": p["party"],
             "data": [],
         })["data"].append({
             "x": float(p["ideology"]),
             "y": float(p["leadership"]),
             "name": p["name"],
         })
     ret = list(ret.values())
     ret.sort(key = lambda s : len(s["data"]), reverse=True)
     
     data = dict(data) # clone before modifying, just in case
     data["series"] = json.dumps(ret)
     
     return data
예제 #4
0
    def make_chart_series(role_type):
        data = load_sponsorship_analysis2(CURRENT_CONGRESS, role_type, None)
        if not data: return None

        ret = {}
        for p in data["all"]:
            ret.setdefault(p["party"], {
                "type": "party",
                "party": p["party"],
                "data": [],
            })["data"].append({
                "x": float(p["ideology"]),
                "y": float(p["leadership"]),
                "name": p["name"],
            })
        ret = list(ret.values())
        ret.sort(key=lambda s: len(s["data"]), reverse=True)

        data = dict(data)  # clone before modifying, just in case
        data["series"] = json.dumps(ret)

        return data
예제 #5
0
def fetch_statements(bill):
    from person.models import Person
    from person.views import http_rest_json
    from parser.processor import Processor

    # load statements from ProPublica API, ignoring any network errors
    try:
        statements = http_rest_json(
            "https://api.propublica.org/congress/v1/{congress}/bills/{bill}/statements.json"
            .format(
                congress=bill.congress,
                bill=bill.bill_type_slug + str(bill.number),
            ),
            headers={
                'X-API-Key': settings.PROPUBLICA_CONGRESS_API_KEY,
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            })
        if statements["status"] != "OK": raise Exception()
        statements = statements["results"]
    except:
        return []

    # bulk-fetch all legislators mentioned and make a mapping from bioguide ID to Person object
    legislators = {
        p.bioguideid: p
        for p in Person.objects.filter(
            bioguideid__in=[s['member_id'] for s in statements])
    }

    # make simplified statements records
    statements = [{
        "date": Processor.parse_datetime(s["date"]).date(),
        "person": legislators.get(s["member_id"]),
        "type": s["statement_type"],
        "title": s["title"],
        "url": s["url"],
    } for s in statements if s["date"]]

    # downcase all-caps titles
    for s in statements:
        if s["title"] != s["title"].upper(): continue
        s["title"] = s["title"].lower()
        if s["person"]:
            s["title"] = s["title"].replace(
                s["person"].lastname.lower(),
                s["person"].lastname)  # common easy case fix

    # sort by date because we want to give a diversity of viewpoints by showing only one
    # statement per legislator
    statements.sort(key=lambda s: s["date"], reverse=True)

    # Put all of the statements that are the most recent for the legislator first, then all of the second-most-recent, and so on.
    # Since sort is stable, it will remain in reverse-date order within each group.
    seen = {}
    for s in statements:
        seen[s["person"]] = seen.get(s["person"], 0) + 1
        s["legislator_ordinal"] = seen[s["person"]]
    statements.sort(key=lambda s: s["legislator_ordinal"])

    # bulk-fetch ideology & leadership scores
    from person.models import RoleType
    from person.analysis import load_sponsorship_analysis2
    scores = load_sponsorship_analysis2(
        bill.congress,
        RoleType.representative, None)["all"] + load_sponsorship_analysis2(
            bill.congress, RoleType.senator, None)["all"]
    leadership_scores = {s["id"]: float(s["leadership"]) for s in scores}
    ideology_scores = {s["id"]: float(s["ideology"]) for s in scores}

    # Tag relevance of the person making the press statement. (We'd love to prioritize relevant
    # committee chairs but we only have current committee info so we couldn't do it for
    # past bills.)
    cosponsors = set(bill.cosponsors.all())
    for s in statements:
        if s["person"] == bill.sponsor:
            s["relevance"] = "Sponsor"
            s["priority"] = (0, -leadership_scores.get(s["person"].id, 0))
        elif s["person"] in cosponsors:
            s["relevance"] = "Co-sponsor"
            s["priority"] = (1, -leadership_scores.get(
                s["person"].id if s["person"] else 0, 0))

    # Get the prioritized statements to show.
    ret = []

    # For up to the first two, show the sponsor and the cosponsor with the highest leadership
    # score (or if there is no sponsor statement, the two top cosponsors), but prioritizing
    # the most recent statements for each legislator
    statements.sort(
        key=lambda s: (s["legislator_ordinal"], s.get("priority", (2, ))))
    while statements and statements[0].get("priority") and statements[0][
            "legislator_ordinal"] == 1 and len(ret) < 2:
        ret.append(statements.pop(0))

    # For the third statement, take the legislator with the ideology score furthest from
    # the sponsor's score, to hopefully get an opposing viewpoint.
    if bill.sponsor and bill.sponsor.id in ideology_scores:
        statements.sort(key=lambda s: (
            s["legislator_ordinal"
              ],  # most recent statements by legislators first
            not (s["person"] and s["person"].id in ideology_scores
                 ),  # people with ideology scores first
            "relevance" in s,  # people who aren't a sponsor/cosponsor first
            -abs(
                ideology_scores.get(s["person"].id if s["person"] else 0, 0) -
                ideology_scores[bill.sponsor.id])))
        while statements and len(ret) < 3:
            ret.append(statements.pop(0))

    return ret