Exemple #1
0
    def process_ballot(self, ballot):
        """Prints out each ballot item and allows user to select and verify a choice for each"""
        for item in ballot.items:
            # skip BallotItems that cannot be filled out any more
            if item.max_choices_selected():
                continue

            choice_num = 1
            print(item.description)
            for choice in item.choices:
                choice_str_list = [str(choice_num), ':', choice.description]
                if choice.chosen:
                    choice_str_list.append('SELECTED')
                print(" ".join(choice_str_list))
                choice_num = choice_num + 1

            candidate_selection = utils.get_input_of_type(
                "Please enter the number of the candidate to bubble in your optical scan ballot: ",
                int, list(range(1,
                                len(item.choices) + 1)))
            candidate_index = candidate_selection - 1
            confirmed = utils.get_input_of_type(
                "Enter 'y' to confirm selection or 'n' to reject. " +
                item.choices[candidate_index].description + ": ", str,
                ['y', 'n'])
            if confirmed == 'y':
                item.choices[candidate_index].select()
            else:
                # prompt user to re-select
                # item.clear()  # clear the BallotItem so it can be filled all at once (for simplicity)
                pass
    def fill_out(self, selections=None, **kwargs):
        """
        selections  pre-determined selections (used by simulation/adversaries)
                      ex: {'President': [0], 'Vice President': [1]}

        Returns whether or not ballot was filled out. This determines whether or not
        a transaction will be created. 

        Future enhancement: Implement retry mechanism, allowing ballots to be invalidated.
        To do this, we would have to support invalidating claim tickets and allowing the
        voter to claim another ticket in its stead.
        """

        if selections:
            for position in selections:
                self.select(position, selections[position])
            return True

        print("Ballot for {}".format(self.election))
        for position in self.items:
            metadata = self.items[position]
            print("{}: {}".format(position, metadata['description']))
            for num, choice in enumerate(metadata['choices']):
                print("{}. {}".format(num + 1, choice))

            max_choices = metadata['max_choices']
            if max_choices > 1:
                msg = "Please enter your choice numbers, separated by commas (no more than {} selections): ".format(
                    max_choices)
            else:
                msg = "Please enter your choice number: "

            user_input = input(msg)
            user_input = user_input.split(
                ",")[:max_choices]  # cap at max_choices
            selection_indexes = []
            for selection in user_input:
                try:
                    candidate = metadata['choices'][int(selection) - 1]
                    selection_indexes.append(int(selection) - 1)
                except (IndexError, ValueError):
                    retry = True

            # no valid selections were made
            if not selection_indexes:
                retry = True

            selections = [metadata['choices'][i] for i in selection_indexes]
            print("Your valid selections: {}".format(selections))
            confirmation = utils.get_input_of_type(
                "Enter 'y' to confirm choices or 'n' to invalidate ballot ",
                str,
                allowed_inputs=['y', 'n', 'Y', 'N']).lower()
            print()
            if confirmation == 'n':
                retry = True
                return False
            else:
                self.select(position, selection_indexes)
        return True
Exemple #3
0
    def lookup_voter_id(self):
        name = utils.get_input_of_type("Type in your full name: ", str).lower()
        matches = self.get_voter_by_name(name)

        if not matches:
            print("No matches found")
        else:
            print("Matching ID(s) found: {}".format(
                [voter.id for voter in matches]))
Exemple #4
0
    def begin_voting_process(self):
        for voter in self.voter_roll:
            print(voter.id, voter.name)

        # Allow user to self-authenticate
        voter_id = utils.get_input_of_type("Please enter your voter ID: ", str)
        voter = self.get_voter_by_id(voter_id)
        if not voter:
            print("Incorrect ID entered.")
            return

        # check that voter has not voted before
        voter_computer = random.choice(self.voter_computers)
        voted = voter_computer.has_voter_voted(voter)
        if voted:
            print('You have already voted!')
            return

        # voter has not voted; retrieve a ballot from the ballot generator
        ballot = self.ballot_generator.retrieve_ballot(
        )  # this will create a transaction for the ballot as well
        print('your ballot id: ' + str(ballot.id))

        # create transaction on voter computer indicating that voter has retrieved ballot (we say that they voted)
        print('Creating transaction on voter blockchain')
        voter_computer.create_transaction(voter)

        # voter visits random voting computer
        voting_computer = random.choice(self.voting_computers)
        print('Now at voting booth')

        # voter fills out ballot and confirms choice
        self.process_ballot(ballot)
        ballot_filled = ballot.is_filled()

        # ensures that ballot is filled
        while not ballot_filled:
            self.process_ballot(ballot)
            ballot_filled = ballot.is_filled()
        input("Press enter to submit your ballot")

        # submit ballot to paper trail
        self.paper_trail.append(ballot)

        # simulation does not offer the chance for voter to omit ballot not change it; maybe request a new one?

        # TODO: handle state of select/chosen for multi-choice options

        # self.paper_trail.append(ballot)

        # create a transaction with the ballot
        voting_computer.create_transaction(ballot)
        print("Created a transaction with the ballot and the ballot state.")
Exemple #5
0
 def begin_election(self):
     """Main entry point to begin the election program"""
     exit = False
     print('Start of election!')
     ballots_available = True
     while not exit and ballots_available:
         self.clear_screen()
         self.print_menu()
         menu_choice = utils.get_input_of_type("Please enter choice:", int)
         exit = self.handle_input(menu_choice)
         ballots_available = False if not self.ballot_generator.are_ballots_available(
         ) else True
     print('Election Over!')
Exemple #6
0
    def _authenticate_voter(self, voter_auth_booth, **kwargs):
        """Authenticates voter and returns voter object (None if voter cannot vote)."""
        voter_name = utils.get_input_of_type(
            "Please authenticate yourself by typing in your full name.\n",
            str).lower()
        voter_id = None
        voter = None

        voters = self.get_voter_by_name(voter_name)
        if len(voters) > 1:
            voter_id = utils.get_input_of_type(
                "Multiple matches found for {}. Please enter in your voter id.\n"
                .format(voter_name), str)
            for v in voters:
                if v.id == voter_id:
                    voter = v
                    break
            if not voter:
                print("Please look up your ID and try again.")
                return None
        elif len(voters) == 1:
            voter = voters[0]
            voter_id = voters[0].id
        return voter
Exemple #7
0
 def get_menu_choice(self):
     return utils.get_input_of_type('Enter in an option: ', int)