Domain: Business Operations & Analytics

Perform a multi-stage retail cohort analysis using only the CSV files in the current task folder:

- `customer_data(1)(1).csv`
- `product_data(1)(1).csv`
- `sales_data(1)(1).csv`
- `store_data(1)(1).csv`

### 1. Data Preparation
* **Date Parsing**: Convert the `date` column to a `YYYY-MM` period.

### 2. Metric Calculations
* **Net Revenue**: Calculate as $net\_units \times list\_price \times (1 - discount)$, where $net\_units$ is `quantity` if `returned == 0`, and `-quantity` otherwise. Treat missing `discount` values as `0.0`.
* **Anomaly**: A transaction is an anomaly if `cost_price > list_price`.
* **Cohort**: Group the transactions by `region`, `category`, and `gender`. Qualify cohorts that have at least 500 transactions.
* **Volatility Index**: For each qualified cohort, calculate:

$$Vol = \frac{\sigma}{\mu_{abs}} \times \frac{\ln(1 + txn\_count)}{1 + anomaly\_rate}$$

Where $\sigma$ is the population standard deviation (`ddof=0`) of the monthly net revenue, and $\mu_{abs}$ is the mean of the absolute monthly net revenue values for that cohort.

### 3. Output Requirements
Return a Python list with exactly 8 elements:

1. Literal string `'RS'`.
2. Literal integer `10`.
3. The top 10 cohorts represented as a list of lists: `[rank, region, category, gender, transactions, anomalies, rate_str, vol_str]`. Sort the qualified cohorts by `Vol` descending, then `rate` descending, and finally `region` ascending. Round `rate` and `vol` to 6 decimal places and represent them as strings.
4. The MD5 hash of the compact JSON representation of the top 10 list using separators `(',', ':')`.
5. The sum of `round(Vol * 10^6)` for all qualified cohorts.
6. The sum of anomalies for all qualified cohorts.
7. The sum of transactions for all qualified cohorts.
8. A derived integer value: `Element[4] + (Element[5] * 1000) + Element[6]`.


Grading rubric:
criterion: The final answer is a Python list with exactly 8 top-level elements.
weight: 10
criterion: The first two elements in the list are exactly 'RS' and 10.
weight: 5
criterion: The first ranked cohort in the top 10 list is 'Lisbon', 'Dresses', 'Male' with a volatility of '3.194202'.
weight: 15
criterion: The tenth ranked cohort in the top 10 list is 'Coimbra', 'Dresses', 'Other' with a volatility of '2.949429'.
weight: 15
criterion: The MD5 hash of the top 10 list matches exactly '259491af160d7dfd6619ef9097adaa0c'.
weight: 15
criterion: The total sum of the scaled volatility across all qualified cohorts is exactly 194013943.
weight: 10
criterion: [Discriminative] The total anomaly count across all qualified cohorts is exactly 8064.
weight: 10
criterion: [Discriminative] The total transaction count across all qualified cohorts is exactly 46753.
weight: 10
criterion: The derived value is correctly calculated as exactly 202124696.
weight: 10

Golden answer:
**Reasoning**
The analysis loads the four retail CSV files from the current task folder and merges them into one transaction table. It fills missing `discount` values with `0.0`, converts `date` to monthly periods, computes `net_revenue` using negative quantity for returned items, and flags anomalies where `cost_price > list_price`.

It then groups by `region`, `category`, and `gender`, keeps only cohorts with at least 500 transactions, computes the monthly-revenue volatility index for each qualified cohort, sorts the cohorts by the required ranking rules, and returns the requested 8-element list including the top 10 cohort table and checksum values.

**Final Answer**
```python
import hashlib
import json
import math
from pathlib import Path

import numpy as np
import pandas as pd


BASE = Path(__file__).resolve().parent


def solve():
    cust = pd.read_csv(BASE / "customer_data(1)(1).csv")
    prod = pd.read_csv(BASE / "product_data(1)(1).csv")
    sales = pd.read_csv(BASE / "sales_data(1)(1).csv")
    store = pd.read_csv(BASE / "store_data(1)(1).csv")

    df = (
        sales.merge(prod, on="product_id")
        .merge(cust, on="customer_id")
        .merge(store, on="store_id")
    )
    df["discount"] = df["discount"].fillna(0.0)
    df["date"] = pd.to_datetime(df["date"])
    df["month"] = df["date"].dt.to_period("M")

    df["net_units"] = np.where(df["returned"] == 0, df["quantity"], -df["quantity"])
    df["net_revenue"] = df["net_units"] * df["list_price"] * (1.0 - df["discount"])
    df["is_anomaly"] = (df["cost_price"] > df["list_price"]).astype(int)

    qualified = []
    for name, group in df.groupby(["region", "category", "gender"]):
        if len(group) < 500:
            continue
        anom = group["is_anomaly"].sum()
        rate = anom / len(group)
        m_rev = group.groupby("month")["net_revenue"].sum()
        vol = (m_rev.std(ddof=0) / m_rev.abs().mean()) * (
            math.log(1 + len(group)) / (1 + rate)
        )
        qualified.append(
            {
                "region": name[0],
                "category": name[1],
                "gender": name[2],
                "transactions": len(group),
                "anomalies": anom,
                "rate": rate,
                "vol": vol,
            }
        )

    q_df = (
        pd.DataFrame(qualified)
        .sort_values(["vol", "rate", "region"], ascending=[False, False, True])
        .reset_index(drop=True)
    )

    top_10 = [
        [
            i + 1,
            r["region"],
            r["category"],
            r["gender"],
            int(r["transactions"]),
            int(r["anomalies"]),
            f"{r['rate']:.6f}",
            f"{r['vol']:.6f}",
        ]
        for i, r in q_df.head(10).iterrows()
    ]

    md5 = hashlib.md5(json.dumps(top_10, separators=(",", ":")).encode()).hexdigest()

    s_vol = int(sum(round(x["vol"] * 1000000) for x in qualified))
    s_anom = int(sum(x["anomalies"] for x in qualified))
    s_trans = int(sum(x["transactions"] for x in qualified))

    return [
        "RS",
        10,
        top_10,
        md5,
        s_vol,
        s_anom,
        s_trans,
        s_vol + (s_anom * 1000) + s_trans,
    ]


print(solve())
```

Verified result:

```python
['RS', 10, [[1, 'Lisbon', 'Dresses', 'Male', 636, 104, '0.163522', '3.194202'], [2, 'Online', 'Accessories', 'Other', 606, 93, '0.153465', '3.081312'], [3, 'Porto', 'Dresses', 'Other', 609, 101, '0.165846', '3.040916'], [4, 'Coimbra', 'Shoes', 'Male', 608, 112, '0.184211', '3.030399'], [5, 'Online', 'Bottoms', 'Other', 583, 97, '0.166381', '3.012131'], [6, 'Online', 'Bottoms', 'Female', 633, 103, '0.162717', '2.999410'], [7, 'Porto', 'Shoes', 'Other', 670, 105, '0.156716', '2.971117'], [8, 'Coimbra', 'Tops', 'Female', 595, 117, '0.196639', '2.958421'], [9, 'Online', 'Dresses', 'Female', 618, 93, '0.150485', '2.950499'], [10, 'Coimbra', 'Dresses', 'Other', 575, 91, '0.158261', '2.949429']], '259491af160d7dfd6619ef9097adaa0c', 194013943, 8064, 46753, 202124696]
```