def geopolitical_units(draw: _DrawType): """ Generates a `GeopoliticalUnit` object. :param draw: Hidden argument, used by Hypothesis. """ return GeopoliticalUnit( object_id=str(draw(uuids())), name=draw(emails()), type=draw(reporting_unit_types()), contact_information=draw(contact_infos()), )
def get_fake_election(self) -> ElectionDescription: """ Get a single Fake Election object that is manually constructed with default values """ fake_ballot_style = BallotStyle("some-ballot-style-id") fake_ballot_style.geopolitical_unit_ids = ["some-geopoltical-unit-id"] fake_referendum_ballot_selections = [ # Referendum selections are simply a special case of `candidate` in the object model SelectionDescription("some-object-id-affirmative", "some-candidate-id-1", 0), SelectionDescription("some-object-id-negative", "some-candidate-id-2", 1), ] sequence_order = 0 number_elected = 1 votes_allowed = 1 fake_referendum_contest = ReferendumContestDescription( "some-referendum-contest-object-id", "some-geopoltical-unit-id", sequence_order, VoteVariationType.one_of_m, number_elected, votes_allowed, "some-referendum-contest-name", fake_referendum_ballot_selections, ) fake_candidate_ballot_selections = [ SelectionDescription("some-object-id-candidate-1", "some-candidate-id-1", 0), SelectionDescription("some-object-id-candidate-2", "some-candidate-id-2", 1), SelectionDescription("some-object-id-candidate-3", "some-candidate-id-3", 2), ] sequence_order_2 = 1 number_elected_2 = 2 votes_allowed_2 = 2 fake_candidate_contest = CandidateContestDescription( "some-candidate-contest-object-id", "some-geopoltical-unit-id", sequence_order_2, VoteVariationType.one_of_m, number_elected_2, votes_allowed_2, "some-candidate-contest-name", fake_candidate_ballot_selections, ) fake_election = ElectionDescription( election_scope_id="some-scope-id", type=ElectionType.unknown, start_date=datetime.now(), end_date=datetime.now(), geopolitical_units=[ GeopoliticalUnit( "some-geopoltical-unit-id", "some-gp-unit-name", ReportingUnitType.unknown, ) ], parties=[Party("some-party-id-1"), Party("some-party-id-2")], candidates=[ Candidate("some-candidate-id-1"), Candidate("some-candidate-id-2"), Candidate("some-candidate-id-3"), ], contests=[fake_referendum_contest, fake_candidate_contest], ballot_styles=[fake_ballot_style], ) return fake_election
def _contest_name_to_description( self, name: str, contest_uid_maker: UidMaker, gp_uid_maker: UidMaker, ) -> Tuple[ContestDescription, List[Candidate], GeopoliticalUnit, Dict[ str, str]]: selections: List[SelectionDescription] = [] candidates: List[Candidate] = [] # We're collecting the candidates at the same time that we're collecting the selections # to make sure that the object_id's are properly synchronized. Consider the case where # we ended up with two candidates with identical names. In the Dominion CSV, we'd have # no way to tell if they were actually the same person running in two separate contests, # or whether they were distinct. This solution ensures that we create a fresh Candidate # one-to-one with every SelectionDescription. # This method will be called separately for every contest name, and the resulting lists # of candidates should be merged to make the complete list that goes into an # ElectionDescription. candidate_to_column: Dict[str, str] = {} for c in self.metadata.contest_map[name]: id_str = c.object_id id_number = int( id_str[1:]) # total hack: stripping off the first char candidate = Candidate( object_id=id_str, ballot_name=_str_to_internationalized_text_en(c.choice_name), party_id=c.party_name if c.party_name != "" else None, image_uri=None, ) # To make our lives easier, we're going to use identical object_ids for selections # and candidates, and hopefully this won't break anything. candidates.append(candidate) selections.append( SelectionDescription( object_id=candidate.object_id, candidate_id=candidate.object_id, sequence_order=id_number, )) candidate_to_column[candidate.object_id] = c.to_string() gp = GeopoliticalUnit( object_id=gp_uid_maker.next(), name=name, type=ReportingUnitType.unknown, ) id_number, id_str = contest_uid_maker.next_int() number_elected = self.metadata.max_votes_for_map[name] vote_variation_type = (VoteVariationType.one_of_m if number_elected == 1 else VoteVariationType.n_of_m) vote_allowed = None if number_elected < 2 else number_elected return ( ContestDescription( object_id=id_str, electoral_district_id=gp.object_id, sequence_order=id_number, vote_variation=vote_variation_type, number_elected=number_elected, votes_allowed=vote_allowed, name=name, ballot_selections=selections, ballot_title=_str_to_internationalized_text_en(name), ), candidates, gp, candidate_to_column, )