Welcome to our lesson on mastering data aggregation and data streams with C++. In this lesson, you'll learn to build a basic sales records aggregator using C++'s standard library containers. Then, we'll extend its functionality to handle more complex operations such as filtering, data aggregation, and formatting. By the end of this session, you'll be proficient in managing and formatting data streams efficiently in C++.
To get started, we'll create a simple sales record aggregator in C++. Here are the methods we'll focus on:
-
void add_sale(const std::string& sale_id, double amount, const std::string& date);
- Adds or updates a sale record with a unique identifiersale_id
,amount
, and adate
in the format "YYYY-MM-DD". -
std::optional<double> get_sale(const std::string& sale_id) const;
- Retrieves the sale amount associated with thesale_id
. If the sale does not exist, it returns an empty optional. -
bool delete_sale(const std::string& sale_id);
- Deletes the sale record with the givensale_id
. Returnstrue
if the sale was deleted andfalse
if the sale does not exist.
Are these methods clear so far? Great! Let's now look at how we would implement them.
Here is the complete code for the starter task:
Explanation:
- The
sales
map stores sale records withsale_id
as the key and a pair ofamount
anddate
as the value. add_sale
adds a new sale or updates an existing sale ID.get_sale
retrieves the amount for a given sale ID or returnsstd::nullopt
if the sale does not exist.delete_sale
removes the sale record for the given sale ID or returnsfalse
if the sale does not exist.
Now that we have our basic aggregator, let's extend it to include more advanced functionalities.
To add complexity and usefulness to our sales aggregator, we'll introduce some additional methods for advanced data aggregation, filtering, and formatting functionalities.
-
std::pair<int, double> aggregate_sales(double min_amount = 0) const;
- Returns the total number of sales and the total sales amount where the sale amount is abovemin_amount
. -
std::string format_sales(double min_amount = 0) const;
- Returns the sales data, filtered bymin_amount
, formatted as a plain text string. Includes sales statistics in the output. -
std::vector<std::tuple<std::string, double, std::string>> get_sales_in_date_range(const std::string& start_date, const std::string& end_date) const;
- Retrieves all sales that occurred within the given date range, inclusive. Each sale includessale_id
,amount
, anddate
.
Let's implement these methods step by step.
We'll create the aggregate_sales
method:
This method iterates through the sales and sums those that exceed the min_amount
.
Next, we create the format_sales
method to output data in plain text format.
In this method, std::ostringstream
is used, which is a stream class to operate on strings. It allows you to format strings in a way similar to using std::cout
. We append formatted data to the stream using the insertion operators (<<
), then use the str()
method to retrieve the final concatenated string. This approach is beneficial for creating large and complex strings safely and efficiently.
Let's implement get_sales_in_date_range
, which relies on parsing dates and comparing them to filter sales records.
In this implementation, parse_date
is a helper lambda function that converts a date string into a std::chrono::system_clock::time_point
, allowing you to compare dates. This involves reading the date into a std::tm
structure with std::get_time
and then converting it to a time_point
using std::chrono::system_clock::from_time_t
. This functionality is fundamental when working with date ranges to ensure accurate filtering of sales records.
Congratulations! You've extended a basic C++ sales aggregator to an advanced aggregator capable of filtering, aggregating, and formatting data, using custom structures for data handling. These skills are crucial for efficiently managing data streams, especially with large datasets in C++. Feel free to experiment with similar challenges to reinforce your understanding. Well done!
