Introduction

Welcome to today's lesson, where we will tackle a common challenge in software engineering: the introduction of complex features while preserving backward compatibility. Our focus will be on a Potluck Dinner organization system, where we will manage participants and their respective dishes for each round. Get ready for an exciting journey through Ruby programming, step-by-step analysis, and strategic thinking. Let's dive into our adventure!

Starter Task Review

Initially, our Potluck Dinner organization system allows us to add and remove participants and manage their respective dishes for each round. There are three essential methods:

  • add_participant(member_id): This method adds a participant. If a participant with the given member_id already exists, it won't create a new one but will return false. Otherwise, it will add the member and return true.
  • remove_participant(member_id): This method removes a participant with the given member_id. If the participant exists, the system will remove them and return true. Otherwise, it will return false. When removing a participant, you need to remove their dish if they brought one.
  • add_dish(member_id, dish_name): This method enables each participant to add their dishes for every round. If a participant has already added a dish for this round OR if the member_id isn't valid, the method will return false. Otherwise, it will add the dish for the respective participant's round and return true.

Let's write our Ruby code, which implements the functions as per our initial state:

In this code, we employed Ruby hashes to store unique participant IDs and their respective dish names. With this foundation laid, let's introduce some advanced functionalities.

Introducing Advanced Functionalities

Our Potluck Dinner organization system is currently simple but practical. To make it even more exciting, we're going to introduce a "Dish of the Day" feature. This feature will enable participants to vote, and the dish receiving the most votes will be declared the "Dish of the Day."

To add this feature, we will define two new methods:

  • vote(member_id, vote_id): This method will allow a participant to cast a vote for a dish. Each participant can cast a vote only once per round. If a participant tries to vote again or if the member_id isn't valid, it should return false.
  • dish_of_the_day: This method will calculate and return the "Dish of the Day" based on the votes received. If multiple dishes tie for the highest number of votes, the dish brought by the participant who joined first acquires precedence. If there are no votes, the function returns nil.
Step 1: Constructor and Updating Existing Methods

First, we update our Potluck class to store the participant's joining time directly in the participants hash, and ensure compatibility across other methods.

Constructor Update:

Updating Methods to Incorporate Join Time and Consistent Removal:

By storing a join_time in the participants hash, we keep track of who joined first. We also ensure removal from all related structures (@dishes and @votes) for consistency.

Step 2: Implementing the vote Method

Next, we add a method to allow participants to vote for the dishes:

This ensures each participant can only vote once per round, returning false if the participant has already voted or if the participant doesn't exist.

Step 3: Implementing the dish_of_the_day Method

Finally, we implement the logic to determine the "Dish of the Day":

If there are no votes, the method returns nil. In case of a tie, the participant with the earliest join time wins.

Ensuring Backward Compatibility
  • Participants Data Structure Change: By using a hash for participant details, we ensure each participant remains uniquely identifiable while enabling additional functionality like join time.
  • Method Signature Consistency: All method signatures remain unchanged to ensure existing interactions remain unaffected.
Final Implementation

Combining all our steps, this is the final implementation of our Potluck class with all the required methods:

Lesson Summary

Bravo! You've successfully completed the task of introducing complex features while preserving backward compatibility using Ruby. This skill is invaluable in real-life software engineering scenarios, where maintaining existing functionality while enhancing systems is crucial. Strengthen this ability with even more practice and explore similar challenges. I'll see you in the next lesson! Happy coding with Ruby!

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