Domain: Business Operations & Analytics

You are given two local CSV files in the current task folder:

- `Orders.csv`
- `Details.csv`

Your task is to identify the three `normalized_order_id` values with the highest `data_quality_risk_index` after fully linking eligible header rows and detail rows.

Definitions:

1. `normalized_order_id`
   - Extract the numeric key from `Order ID` by concatenating all digit characters in the string.
   - If at least one digit exists, the normalized id is `B-` followed by the key left-padded to 5 digits.
   - If no digit exists, the identifier is malformed.

2. Header-row retention rule
   - Work from `Orders.csv`.
   - For each numeric key, retain exactly one header row using this order:
     1. earliest valid day-first parsed `Order Date`
     2. lexicographically smallest `CustomerName`
     3. lexicographically smallest `State`
     4. lexicographically smallest `City`
     5. earliest source row

3. Detail-row retention rule
   - Work from `Details.csv`.
   - Coerce `Amount`, `Profit`, and `Quantity` to numeric.
   - Any coercion failure maps that field to `0` and contributes to `null_coercion_count` for that retained detail row.
   - Retain one detail row per unique combination of:
     - numeric key
     - coerced `Amount`
     - coerced `Profit`
     - coerced `Quantity`
     - `Category`
     - `Sub-Category`
     - `PaymentMode`
   - Keep the earliest source row for each such combination.

4. Identifier consistency
   - Normalize raw `Order ID` strings by trimming whitespace and uppercasing.
   - `inconsistent_id_flag = 1` if either:
     - the numeric key appears with more than one distinct normalized raw identifier across the two files, or
     - the numeric key appears in only one of the two files
   - otherwise `inconsistent_id_flag = 0`

5. Mixed timestamp flag
   - Parse each retained header `Order Date` both as day-first and month-first.
   - `mixed_timestamp_flag = 1` only when both parses are valid and they disagree.
   - otherwise `mixed_timestamp_flag = 0`

6. Eligibility after linking
   - Keep only linked keys that satisfy all of the following:
     - `normalized_order_id` is non-null
     - the key is present in both tables after numeric-key extraction
     - aggregated `amount_sum > 0`
     - aggregated `quantity_sum > 0`
     - `line_count >= 1`

7. Retained-detail anomaly terms
   - `sign_reversal_count`: retained detail rows where `Amount` and `Profit` have opposite signs
   - `outlier_count`: retained detail rows where either retained-detail `Amount` or retained-detail `Profit` falls outside Tukey fences computed on the retained detail rows using linear-interpolated quartiles
   - `null_coercion_count`: count of retained detail rows where at least one numeric coercion failed

8. Aggregates and rates for each eligible linked key
   - `line_count`: number of retained detail rows
   - `amount_sum`: sum of retained-detail coerced `Amount`
   - `profit_sum`: sum of retained-detail coerced `Profit`
   - `quantity_sum`: sum of retained-detail coerced `Quantity`
   - `margin = profit_sum / amount_sum`
   - `null_coercion_rate = null_coercion_count / line_count`
   - `sign_reversal_rate = sign_reversal_count / line_count`
   - `outlier_rate = outlier_count / line_count`
   - `anomaly_rate = (sign_reversal_count + outlier_count + null_coercion_count + mixed_timestamp_flag + inconsistent_id_flag) / (line_count + 2)`

9. Risk score

```text
data_quality_risk_index =
100 * inconsistent_id_flag
+ 10 * mixed_timestamp_flag
+ 50 * null_coercion_rate
+ 30 * sign_reversal_rate
+ 20 * outlier_rate
+ 10 * abs(margin)
```

10. Ranking
   - Rank eligible linked keys by:
     1. descending `data_quality_risk_index`
     2. descending `anomaly_rate`
     3. ascending `profit_sum`
     4. descending `amount_sum`
     5. ascending `normalized_order_id`

11. Signature
   - For each ranked row, define:

```text
signature = md5(normalized_order_id + '|' + risk_index + '|' + anomaly_rate + '|' + margin)
```

   where `risk_index`, `anomaly_rate`, and `margin` are formatted to exactly 6 decimal places.

Return exactly a Python list with 3 inner lists in this order:

```python
[
  [normalized_order_id, customer_name, state, city, risk_index, anomaly_rate, margin, signature],
  [normalized_order_id, customer_name, state, city, risk_index, anomaly_rate, margin, signature],
  [normalized_order_id, customer_name, state, city, risk_index, anomaly_rate, margin, signature]
]
```

Format `risk_index`, `anomaly_rate`, and `margin` as strings with exactly 6 decimal places using round-half-to-even.

Print only the final Python list.

Grading rubric:
criterion: The final answer is a Python list with exactly 3 inner lists, and each inner list has exactly 8 elements.
weight: 10
criterion: The first inner list is exactly ['B-25688', 'Swetha', 'Madhya Pradesh', 'Indore', '69.801136', '1.000000', '-0.980114', '173a8fc32c139cb26f83e43eb7aebbbc'].
weight: 15
criterion: The second inner list is exactly ['B-25988', 'Nirja', 'Delhi', 'Delhi', '65.696203', '0.666667', '-1.569620', '2e94af5f261ba31d3b0c3d966072f720'].
weight: 15
criterion: The third inner list is exactly ['B-25712', 'Adhvaita', 'Rajasthan', 'Jaipur', '64.248705', '0.666667', '-1.424870', '0c0bfd56181eeb24d8e2e6592f2116ac'].
weight: 15
criterion: The three risk_index values are strictly descending by row position.
weight: 5
criterion: The sum of the three risk_index values is exactly 199.746044 after six-decimal formatting.
weight: 10
criterion: The sum of the three margin values is exactly -3.974604 after six-decimal formatting.
weight: 10
criterion: The md5 of the three signatures joined as `R1[7]|R2[7]|R3[7]` is exactly `25ad11ae13d64b1a7e7c6f36305d7eb2`.
weight: 10

Golden answer:
```python
import csv
import hashlib
import math
from collections import defaultdict
from datetime import datetime
from pathlib import Path


def extract_numeric_key(value):
    digits = "".join(character for character in ("" if value is None else str(value)) if character.isdigit())
    return int(digits) if digits else None


def parse_float(value):
    try:
        return float(str(value).strip())
    except (TypeError, ValueError):
        return None


def parse_dayfirst_date(value):
    try:
        return datetime.strptime(str(value).strip(), "%d-%m-%Y").date()
    except (TypeError, ValueError):
        return None


def parse_monthfirst_date(value):
    try:
        return datetime.strptime(str(value).strip(), "%m-%d-%Y").date()
    except (TypeError, ValueError):
        return None


def percentile_linear(sorted_values, p):
    position = (len(sorted_values) - 1) * p
    lower = int(math.floor(position))
    upper = int(math.ceil(position))
    if lower == upper:
        return sorted_values[lower]
    fraction = position - lower
    return sorted_values[lower] * (1.0 - fraction) + sorted_values[upper] * fraction


def main() -> None:
    base_path = Path(__file__).resolve().parent
    orders = list(csv.DictReader((base_path / "Orders.csv").open(newline="", encoding="utf-8")))
    details = list(csv.DictReader((base_path / "Details.csv").open(newline="", encoding="utf-8")))

    for row_number, row in enumerate(orders):
        row["_row"] = row_number
        row["id_num"] = extract_numeric_key(row["Order ID"])
        row["raw_id"] = str(row["Order ID"]).strip().upper()
        row["dt_dayfirst"] = parse_dayfirst_date(row["Order Date"])
        monthfirst = parse_monthfirst_date(row["Order Date"])
        row["mixed_timestamp_flag"] = int(
            row["dt_dayfirst"] is not None and monthfirst is not None and row["dt_dayfirst"] != monthfirst
        )

    for row_number, row in enumerate(details):
        row["_row"] = row_number
        row["id_num"] = extract_numeric_key(row["Order ID"])
        row["raw_id"] = str(row["Order ID"]).strip().upper()
        for column in ["Amount", "Profit", "Quantity"]:
            row[column + "_num"] = parse_float(row[column])
        row["null_coercion_row"] = int(
            row["Amount_num"] is None or row["Profit_num"] is None or row["Quantity_num"] is None
        )
        for column in ["Amount", "Profit", "Quantity"]:
            if row[column + "_num"] is None:
                row[column + "_num"] = 0.0
        amount_value = row["Amount_num"]
        profit_value = row["Profit_num"]
        row["sign_reversal_row"] = int(
            (amount_value > 0 and profit_value < 0) or (amount_value < 0 and profit_value > 0)
        )

    order_keys = {row["id_num"] for row in orders if row["id_num"] is not None}
    detail_keys = {row["id_num"] for row in details if row["id_num"] is not None}
    one_sided_keys = order_keys.symmetric_difference(detail_keys)

    variants = defaultdict(set)
    for row in orders + details:
        if row["id_num"] is not None:
            variants[row["id_num"]].add(row["raw_id"])
    inconsistent_map = {
        key: int(len(raw_ids) > 1 or key in one_sided_keys) for key, raw_ids in variants.items()
    }

    retained_orders = []
    seen_order_keys = set()
    ordered_headers = sorted(
        [row for row in orders if row["id_num"] is not None],
        key=lambda row: (
            row["id_num"],
            row["dt_dayfirst"] is None,
            row["dt_dayfirst"] or datetime.max.date(),
            row["CustomerName"],
            row["State"],
            row["City"],
            row["_row"],
        ),
    )
    for row in ordered_headers:
        if row["id_num"] not in seen_order_keys:
            seen_order_keys.add(row["id_num"])
            retained_orders.append(row)

    retained_details = []
    seen_detail_keys = set()
    for row in sorted(details, key=lambda item: item["_row"]):
        dedupe_key = (
            row["id_num"],
            row["Amount_num"],
            row["Profit_num"],
            row["Quantity_num"],
            row["Category"],
            row["Sub-Category"],
            row["PaymentMode"],
        )
        if dedupe_key not in seen_detail_keys:
            seen_detail_keys.add(dedupe_key)
            retained_details.append(row)

    retained_amounts = sorted(row["Amount_num"] for row in retained_details)
    retained_profits = sorted(row["Profit_num"] for row in retained_details)
    q1_amount = percentile_linear(retained_amounts, 0.25)
    q3_amount = percentile_linear(retained_amounts, 0.75)
    q1_profit = percentile_linear(retained_profits, 0.25)
    q3_profit = percentile_linear(retained_profits, 0.75)
    iqr_amount = q3_amount - q1_amount
    iqr_profit = q3_profit - q1_profit
    lower_amount = q1_amount - 1.5 * iqr_amount
    upper_amount = q3_amount + 1.5 * iqr_amount
    lower_profit = q1_profit - 1.5 * iqr_profit
    upper_profit = q3_profit + 1.5 * iqr_profit

    for row in retained_details:
        row["outlier_row"] = int(
            row["Amount_num"] < lower_amount
            or row["Amount_num"] > upper_amount
            or row["Profit_num"] < lower_profit
            or row["Profit_num"] > upper_profit
        )

    aggregated_details = defaultdict(
        lambda: {
            "line_count": 0,
            "amount_sum": 0.0,
            "profit_sum": 0.0,
            "quantity_sum": 0.0,
            "null_coercion_count": 0,
            "sign_reversal_count": 0,
            "outlier_count": 0,
        }
    )
    for row in retained_details:
        aggregate = aggregated_details[row["id_num"]]
        aggregate["line_count"] += 1
        aggregate["amount_sum"] += row["Amount_num"]
        aggregate["profit_sum"] += row["Profit_num"]
        aggregate["quantity_sum"] += row["Quantity_num"]
        aggregate["null_coercion_count"] += row["null_coercion_row"]
        aggregate["sign_reversal_count"] += row["sign_reversal_row"]
        aggregate["outlier_count"] += row["outlier_row"]

    linked_rows = []
    for row in retained_orders:
        key = row["id_num"]
        if key is None or key not in aggregated_details:
            continue
        aggregate = aggregated_details[key]
        if aggregate["amount_sum"] <= 0 or aggregate["quantity_sum"] <= 0 or aggregate["line_count"] < 1:
            continue

        null_coercion_rate = aggregate["null_coercion_count"] / aggregate["line_count"]
        sign_reversal_rate = aggregate["sign_reversal_count"] / aggregate["line_count"]
        outlier_rate = aggregate["outlier_count"] / aggregate["line_count"]
        margin = aggregate["profit_sum"] / aggregate["amount_sum"]
        anomaly_rate = (
            aggregate["sign_reversal_count"]
            + aggregate["outlier_count"]
            + aggregate["null_coercion_count"]
            + row["mixed_timestamp_flag"]
            + inconsistent_map.get(key, 0)
        ) / (aggregate["line_count"] + 2)
        risk_index = (
            100 * inconsistent_map.get(key, 0)
            + 10 * row["mixed_timestamp_flag"]
            + 50 * null_coercion_rate
            + 30 * sign_reversal_rate
            + 20 * outlier_rate
            + 10 * abs(margin)
        )

        linked_rows.append(
            {
                "normalized_order_id": f"B-{key:05d}",
                "customer_name": row["CustomerName"],
                "state": row["State"],
                "city": row["City"],
                "risk_index": risk_index,
                "anomaly_rate": anomaly_rate,
                "margin": margin,
                "profit_sum": aggregate["profit_sum"],
                "amount_sum": aggregate["amount_sum"],
            }
        )

    ranked = sorted(
        linked_rows,
        key=lambda row: (
            -row["risk_index"],
            -row["anomaly_rate"],
            row["profit_sum"],
            -row["amount_sum"],
            row["normalized_order_id"],
        ),
    )[:3]

    final_answer = []
    for row in ranked:
        risk_index_text = f"{row['risk_index']:.6f}"
        anomaly_rate_text = f"{row['anomaly_rate']:.6f}"
        margin_text = f"{row['margin']:.6f}"
        signature = hashlib.md5(
            f"{row['normalized_order_id']}|{risk_index_text}|{anomaly_rate_text}|{margin_text}".encode()
        ).hexdigest()
        final_answer.append(
            [
                row["normalized_order_id"],
                row["customer_name"],
                row["state"],
                row["city"],
                risk_index_text,
                anomaly_rate_text,
                margin_text,
                signature,
            ]
        )

    print(final_answer)


if __name__ == "__main__":
    main()
```

This solution reads the two local CSV files, adds stable source-row indexes, extracts numeric linkage keys from `Order ID`, retains one header row per key using the exact day-first and lexicographic precedence stated in the prompt, retains one detail row per key-plus-value combination using earliest source row, computes coercion, sign-reversal, outlier, timestamp, and identifier inconsistency terms, aggregates linked keys, scores them with the stated risk formula, and returns the top three rows in the required order. The formatted `risk_index`, `anomaly_rate`, and `margin` strings all use exactly 6 decimal places with round-half-to-even, and each signature is the md5 of the specified pipe-delimited string.

Verified result:

```python
[['B-25688', 'Swetha', 'Madhya Pradesh', 'Indore', '69.801136', '1.000000', '-0.980114', '173a8fc32c139cb26f83e43eb7aebbbc'], ['B-25988', 'Nirja', 'Delhi', 'Delhi', '65.696203', '0.666667', '-1.569620', '2e94af5f261ba31d3b0c3d966072f720'], ['B-25712', 'Adhvaita', 'Rajasthan', 'Jaipur', '64.248705', '0.666667', '-1.424870', '0c0bfd56181eeb24d8e2e6592f2116ac']]
```