Enhancing Functionality in a Voting System While Ensuring Backward Compatibility

Introduction

Welcome back to a fascinating session where we will learn about enhancing existing functionality without causing regressions. Our scenario today involves designing a voting system. We'll start with the basic implementation of the voting system and gradually introduce additional elements of complexity.

Starter Task Review

In our initial task, we create a simple voting system in Python with a set of basic functionalities:

  • register_candidate(self, candidate_id: str) -> bool:: This method is used for adding new candidates to our system.
  • vote(self, timestamp: int, voter_id: str, candidate_id: str) -> bool:: This method is designed to facilitate users casting their votes. Each vote is given a timestamp.
  • get_votes(self, candidate_id: str) -> int | None:: This method retrieves the total number of votes for a given candidate.
  • top_n_candidates(self, n: int) -> list[str]:: We also want to add a leaderboard functionality to our system. This method returns the top 'n' candidates sorted by the number of votes.

Initial Solution Development

Let's jump into the Python code and begin the implementation of our starter task. Here, we use Python's built-in defaultdict as the core of our design. This dictionary-like object allows us to have dynamic lists keyed based on candidate IDs and voter IDs, which will greatly simplify our design.

from collections import defaultdict

class VotingSystem:
    def __init__(self):
        self.candidates = {}  # Stores candidate_id as key and votes as value
        self.voters = defaultdict(lambda: {'votes': [], 'timestamps': []})  # Tracks each voter's voting history

    def register_candidate(self, candidate_id: str) -> bool:
        if candidate_id in self.candidates:
            return False  # Candidate is already registered
        self.candidates[candidate_id] = 0  # Initialize candidates with 0 votes
        return True

    def vote(self, timestamp: int, voter_id: str, candidate_id: str) -> bool:
        if candidate_id not in self.candidates:
            return False  # Returns False if candidate is not registered
        self.voters[voter_id]['votes'].append(candidate_id)  # Record the vote
        self.voters[voter_id]['timestamps'].append(timestamp)  # Record the time of the vote
        self.candidates[candidate_id] += 1  # Increment vote count for the candidate
        return True

    def get_votes(self, candidate_id: str) -> int | None:
        return self.candidates.get(candidate_id)  # Retrieve vote count for a candidate or None if not found

    def top_n_candidates(self, n: int) -> list[str]:
        return sorted(self.candidates, key=self.candidates.get, reverse=True)[:n]  # Return top n candidates based on votes
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal