Introduction

Welcome to today's lesson on applying data filtering and aggregation in a real-world scenario using a user management system. We'll start by building a foundational structure that can handle basic user operations. Then, we'll expand it by introducing more advanced functionalities that allow filtering and aggregating user data.

Starter Task Methods

In our starter task, we will implement a class that manages basic operations on a collection of user data, specifically handling adding new users, retrieving user profiles, and updating user profiles.

Here are the starter task methods:

  • bool add_user(std::string user_id, int age, std::string country, bool subscribed) - adds a new user with the specified attributes. Returns true if the user was added successfully and false if a user with the same user_id already exists.
  • std::optional<UserProfile> get_user(std::string user_id) - returns the user's profile if the user exists; otherwise, returns std::nullopt.
  • bool update_user(std::string user_id, std::optional<int> age, std::optional<std::string> country, std::optional<bool> subscribed) - updates the user's profile based on non-optional parameters. Returns true if the user exists and was updated, false otherwise.

To store the user data, we will define a UserProfile custom struct.

Starter Task Implementation

Here is the implementation of our starter task in C++:

This implementation covers all our starter methods. Let's move forward and introduce more complex functionalities.

Introducing New Methods for Data Filtering and Aggregation

With our foundational structure in place, it's time to add functionalities for filtering user data and aggregating statistics.

Here are the new methods to implement:

  • std::vector<std::string> filter_users(std::optional<int> min_age, std::optional<int> max_age, std::optional<std::string> country, std::optional<bool> subscribed):
    • Returns the list of user IDs that match the specified criteria. Criteria can be std::nullopt, meaning that criterion should not be applied during filtering.
  • std::map<std::string, float> aggregate_stats() - returns statistics in the form of a map:
    • total_users: Total number of users (as a float)
    • average_age: Average age of all users (rounded down to the nearest integer)
    • subscribed_ratio: Ratio of subscribed users to total users (as a float with two decimals)
Step 1: Adding `filter_users` Method

This method filters users based on the criteria provided. Let's see how it works:

  • The filter_users method filters users based on min_age, max_age, country, and subscribed status criteria.
  • It iterates over the users map and checks each user's profile against the provided criteria.
  • Users who meet all the criteria are added to the filtered_users list, which is then returned.
  • The example usage shows how to add users and filter them based on different criteria.
Step 2: Adding `aggregate_stats` Method

This method aggregates statistics from the user profiles. Let's implement it:

This aggregate_stats method calculates and returns aggregate statistics about the users in the form of a map. It first determines total_users, the total number of users. If there are no users, it returns a dictionary with zeroed statistics. Otherwise, it calculates total_age by summing the ages of all users and counts subscribed_users who are subscribed. It then computes average_age by performing integer division of total_age by total_users and calculates subscribed_ratio by dividing subscribed_users by total_users and rounding to two decimal places. The resulting statistics dictionary includes total_users, average_age, and subscribed_ratio.

The Final Solution

Here's the complete UserManager class with all methods, including the new ones for filtering and aggregation:

Lesson Summary

Great job! Today, you've learned how to effectively handle user data by implementing advanced functionalities like filtering and aggregation on top of a basic system. This is a critical skill in real-life software development, where you often need to extend existing systems to meet new requirements.

I encourage you to practice solving similar challenges to solidify your understanding of data filtering and aggregation. Happy coding, and see you in the next lesson!

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