Welcome to today’s lesson on applying data filtering and aggregation in a real-world scenario through a user management system. We’ll start by building a foundational structure that can handle basic user operations, then gradually expand it by introducing more advanced functionalities to allow filtering and aggregating user data.
In our starter task, we’ll implement a class to manage basic operations on a collection of user data, specifically handling the addition of new users, retrieving user profiles, and updating existing user profiles. Here are the methods we’ll begin with:
- add_user(user_id, age, country, subscribed) — Adds a new user with specified attributes. Returns
trueif the user is added successfully; returnsfalseif a user with the sameuser_idalready exists. - get_user(user_id) — Retrieves the user’s profile as a hash if the user exists; returns
nilif the user does not exist. - update_user(user_id, age = nil, country = nil, subscribed = nil) — Updates the user’s profile with provided parameters. Returns
trueif the user exists and was updated, andfalseotherwise.
Let’s begin by creating a UserManager class that manages user data within a hash structure, @users, where each key is a user_id and each value is a hash representing the user’s profile.
The initialize method sets up an empty hash, @users, which will store all user profiles.
The add_user and get_user methods handle adding new users and retrieving existing user profiles.
In add_user, we check if a user with the specified user_id already exists. If not, we create a new entry in @users with the user’s details and return true. If the user already exists, it returns false. The get_user method retrieves a user’s profile from @users, returning the profile if found or nil if the user does not exist.
The update_user method allows updating the details of an existing user.
In update_user, we first check if the specified user_id exists in @users. If it does, we update the user’s details based on the provided arguments. Each attribute is only updated if a value is passed in. This method returns true if the user is updated, and false if the user does not exist.
With our basic structure in place, let’s add two additional methods to handle more advanced operations, such as filtering user data based on criteria and aggregating user statistics.
- filter_users(min_age = nil, max_age = nil, country = nil, subscribed = nil) — Filters and returns a list of user IDs that match the specified criteria. Any criterion can be omitted by setting it to
nil, meaning that criterion will be ignored. - aggregate_stats — Returns statistics as a hash, including:
total_users: Total number of usersaverage_age: Average age of all users (rounded down to the nearest integer)subscribed_ratio: Ratio of subscribed users to total users (as a float rounded to two decimals)
Here’s the filter_users method using Ruby’s select to efficiently filter users based on specified criteria.
This method filters @users by applying each criterion only if it’s not nil. Using select, we return a filtered hash containing only users who meet all specified conditions. Calling .keys on the result gives an array of user IDs that match the criteria.
The aggregate_stats method calculates and returns aggregate statistics from the user data.
In aggregate_stats, we calculate total_users by finding the size of @users. If there are no users, we return a hash with zeroed statistics. Otherwise, we calculate total_age by summing the ages of all users, and subscribed_users by counting users with subscribed set to true. We compute average_age by dividing total_age by total_users, and subscribed_ratio by dividing subscribed_users by total_users, rounding to two decimal places.
Below is the complete UserManager class, incorporating all the methods we’ve discussed. This final implementation allows you to add, retrieve, update, filter, and aggregate user data in a flexible and efficient way.
This complete UserManager class now provides all the functionality required for managing a collection of user profiles with robust filtering and aggregation capabilities.
To see this class in action, let’s look at a few example usage scenarios.
In these examples, we first add a few users to our UserManager instance and then demonstrate filtering them based on various criteria. We also use to view statistical data on the users.
Great job! Today, you learned how to manage user data by implementing essential functionalities such as adding, retrieving, and updating profiles. Building on this foundation, you added advanced filtering and aggregation features, making the code versatile and effective for real-world applications. Practicing these techniques on similar challenges will further solidify your understanding of data filtering and aggregation. Keep up the great work, and see you in the next lesson!
