Skip to content

S2Q1 · Sales Analysis by Product

⚡ Quick Reference

Function: analyze_sales(data: list, threshold: int) -> dict

Core idea: for each product, compute aggregations, include only if total >= threshold.

def analyze_sales(data: list, threshold: int) -> dict:
    result = {}
    for record in data:
        product = record["product"]
        sales   = record["sales"]
        if not sales:
            continue
        total = sum(sales)
        if total >= threshold:
            result[product] = {
                "total":   total,
                "count":   len(sales),
                "average": total / len(sales),
                "max":     max(sales),
            }
    return result

Key rules: - Skip products with no sales (avoid division by zero) - Include only if total >= threshold - average = total / count as a float - max = largest single sale value


Template Code

def analyze_sales(data: list, threshold: int) -> dict:
    '''
    Analyze sales records by product and return stats for products
    meeting the total sales threshold.

    Args:
        data (list): List of dicts with keys "product" and "sales"
        threshold (int): Minimum total sales to include a product

    Returns:
        dict: {product: {"total", "count", "average", "max"}}
              Only products with total >= threshold are included.

    Example:
    >>> analyze_sales([
    ...   {"product": "P1", "sales": [100, 150]},
    ...   {"product": "P2", "sales": [40]}
    ... ], 200)
    {"P1": {"total": 250, "count": 2, "average": 125.0, "max": 150}}
    '''
    ...

Problem Statement

Problem

Write a function analyze_sales(data, threshold) that computes total, count, average, and max sales per product, returning only those with total ≥ threshold.

Example:

Input
data=[{"product":"P1","sales":[100,150]},
      {"product":"P2","sales":[40]}],
threshold=200
Output
{"P1": {"total": 250, "count": 2, "average": 125.0, "max": 150}}

P1 total = 250 ≥ 200 → included. P2 total = 40 < 200 → excluded.


Tracing the example

Product Sales Total Count Average Max Total ≥ 200?
P1 [100, 150] 250 2 125.0 150 ✅ included
P2 [40] 40 1 40.0 40 ❌ excluded

Solution approaches

def analyze_sales(data: list, threshold: int) -> dict:
    result = {}
    for record in data:
        sales = record["sales"]
        if not sales:
            continue
        total = sum(sales)
        if total >= threshold:
            result[record["product"]] = {
                "total":   total,
                "count":   len(sales),
                "average": total / len(sales),
                "max":     max(sales),
            }
    return result
def analyze_sales(data: list, threshold: int) -> dict:
    result = {}
    for record in data:
        product = record["product"]
        sales   = record["sales"]

        if len(sales) == 0:
            continue

        total   = 0
        maximum = sales[0]
        for s in sales:
            total += s
            if s > maximum:
                maximum = s

        if total >= threshold:
            result[product] = {
                "total":   total,
                "count":   len(sales),
                "average": total / len(sales),
                "max":     maximum,
            }
    return result
def analyze_sales(data: list, threshold: int) -> dict:
    def make_stats(sales):
        if not sales:
            return None
        total = sum(sales)
        if total < threshold:
            return None
        return {"total": total, "count": len(sales),
                "average": total / len(sales), "max": max(sales)}

    return {
        r["product"]: stats
        for r in data
        if (stats := make_stats(r["sales"])) is not None
    }
def analyze_sales(data: list, threshold: int) -> dict:
    get_sales = lambda r: r["sales"]
    valid = filter(lambda r: get_sales(r) and sum(get_sales(r)) >= threshold, data)

    def make_agg(r):
        sales = r["sales"]
        total = sum(sales)
        return (r["product"], {
            "total":   total,
            "count":   len(sales),
            "average": total / len(sales),
            "max":     max(sales),
        })

    return dict(map(make_agg, valid))

Key takeaways

01

Compute sales once, reuse everywhere

Extract sales = record["sales"] and compute total = sum(sales) once. Then use total, len(sales), and max(sales) - no repeated iteration over the same list.

02

Guard against empty sales lists

if not sales: continue skips records with no transactions before any computation. Without this, sum([])/len([]) raises a ZeroDivisionError.

03

This is the same pattern as process_orders (S3Q1 Set 3)

Both problems: extract values, compute aggregations, filter by threshold. The structure is identical - only the field names differ. Recognising the pattern saves time in an exam setting.