Skip to main content

total-fees-calculation

Skill for computing total payment processing fees for a merchant over a specific day, date range, or month in the dabstep dataset. Use this skill whenever the question asks for "total fees", "fees paid", or "fees charged" for a merchant over some time period. The computation requires matching each transaction to a fee rule from fees.json using multiple merchant and transaction properties, then summing fixed_amount + rate * eur_amount / 10000 for each matched transaction.

来源信息

仓库
zjunlp/DataMind
最近来源活动
2026年7月5日 09:13
检测到的 SKILL.md 语言
英语
星标
149
Forks
13

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
Total_Fees_Calculation
description
Skill for computing total payment processing fees for a merchant over a specific day, date range, or month in the dabstep dataset. Use this skill whenever the question asks for "total fees", "fees paid", or "fees charged" for a merchant over some time period. The computation requires matching each transaction to a fee rule from fees.json using multiple merchant and transaction properties, then summing fixed_amount + rate * eur_amount / 10000 for each matched transaction.
# Total Fees Calculation — dabstep Dataset ## Problem Summary Compute total payment processing fees (in euros) for a given merchant over a specified period (a specific day of year, a month, or a full year). Round the final answer to 2 decimal places. ## Data Files Required - `payments.csv` — transactions (filter by `merchant`, `year`, `day_of_year`) - `fees.json` — 1000 fee rules with conditions and fee parameters - `merchant_data.json` — per-merchant properties: `account_type`, `capture_delay`, `merchant_category_code` - `manual.md` — read for domain definitions ## Fee Formula ``` fee = fixed_amount + rate * eur_amount / 10000 ``` Sum fees across all transactions that match a fee rule. Transactions with no matching rule contribute 0. --- ## CRITICAL: Compute Once and Submit Immediately **The #1 failure mode**: computing the correct answer and then entering a debugging loop that exhausts all turns without submitting. Once `round(total_fees, 2)` is printed, that IS the final answer — submit it immediately: ```python print(round(total_fees, 2)) # Then immediately use <answer>VALUE</answer> ``` **Having 30–70% of transactions with no matching fee rule is completely normal and expected.** The fee rule system does NOT provide coverage for every combination of card scheme, ACI, account type, and capture delay. Common legitimate reasons: - ACI='G' (Card Not Present - Non-3-D Secure) is in payments but absent from all fee rule ACI lists — G-transactions only match rules where `aci: []` - Many merchant MCCs (5942, 7372, 7993, 7997, etc.) do NOT appear in any explicit `merchant_category_code` list in fees.json — only rules with `merchant_category_code: []` match these merchants - Specific combinations of card_scheme + capture_delay + account_type have no corresponding rule **Do NOT** spend additional turns investigating why individual transactions have no matching rule. This is by design. --- ## Step-by-Step Algorithm ### Step 1: Load Merchant Properties From `merchant_data.json`, for the target merchant extract: - `account_type`: one of `R`, `D`, `H`, `F`, `S`, `O` - `capture_delay`: raw value (numeric like `"1"` or `"7"`, or categorical like `"immediate"`, `"manual"`) - `merchant_category_code` (MCC): integer **Map numeric `capture_delay` to fee rule category:** ```python def map_capture_delay(cd): try: n = int(cd) return '<3' if n < 3 else ('3-5' if n <= 5 else '>5') except (ValueError, TypeError): return cd # already a string category: 'immediate' or 'manual' ``` ### Step 2: Determine the Query Period and Month Boundaries **2023 is NOT a leap year.** Day-of-year to month mapping: | Month | day_of_year range | |-------|-------------------| | Jan | 1 – 31 | | Feb | 32 – 59 | | Mar | 60 – 90 | | Apr | 91 – 120 | | May | 121 – 151| | Jun | 152 – 181| | Jul | 182 – 212| | Aug | 213 – 243| | Sep | 244 – 273| | Oct | 274 – 304| | Nov | 305 – 334| | Dec | 335 – 365| - "Nth day of the year" → `day_of_year == N`; its month is determined by the table above. - "Month X 2023" → use the full month range for TARGET_DAYS and for monthly stats. - "Full year 2023" → process each month separately (monthly stats differ per month). ### Step 3: Compute Monthly Statistics (Full Natural Month) Monthly stats must be computed from **ALL transactions in the full natural month** (not just the queried day). This is critical for fee rule matching. ```python MONTH_RANGES = { 1:(1,31), 2:(32,59), 3:(60,90), 4:(91,120), 5:(121,151), 6:(152,181), 7:(182,212), 8:(213,243), 9:(244,273), 10:(274,304), 11:(305,334), 12:(335,365) } month_txns = payments[ (payments['merchant'] == MERCHANT) & (payments['year'] == YEAR) & (payments['day_of_year'].between(MONTH_START, MONTH_END)) ] monthly_vol = month_txns['eur_amount'].sum() fraud_vol = month_txns[month_txns['has_fraudulent_dispute'] == True]['eur_amount'].sum() fraud_rate = fraud_vol / monthly_vol if monthly_vol > 0 else 0 ``` **Categorize into fee rule buckets:** ```python def categorize_volume(v): if v < 100_000: return '<100k' elif v < 1_000_000: return '100k-1m' elif v < 5_000_000: return '1m-5m' else: return '>5m' def categorize_fraud(f): # f is a ratio (0-1 scale): 0.072 = 7.2%, 0.077 = 7.7%, 0.083 = 8.3% if f < 0.072: return '<7.2%' elif f < 0.077: return '7.2%-7.7%' elif f < 0.083: return '7.7%-8.3%' else: return '>8.3%' ``` ### Step 4: Match Each Transaction to a Fee Rule **The single most important rule: empty list `[]` in any fee rule field means "applies to all" (same semantics as `null`).** In `fees.json`: `account_type: []`, `merchant_category_code: []`, `aci: []` all mean "no restriction on this field". When multiple rules match: choose the **most specific** (highest number of non-null/non-empty fields), break ties by **lowest ID**. ```python def rule_specificity(rule): return sum([ bool(rule['account_type']), rule['capture_delay'] is not None, rule['monthly_fraud_level'] is not None, rule['monthly_volume'] is not None, bool(rule['merchant_category_code']), rule['is_credit'] is not None, bool(rule['aci']), rule['intracountry'] is not None, ]) def find_best_rule(txn, acct_type, cap_delay, mcc, fraud_level, vol_category): intracountry = (txn['issuing_country'] == txn['acquirer_country']) matches = [] for rule in fees: if rule['card_scheme'] != txn['card_scheme']: continue if rule['account_type'] and acct_type not in rule['account_type']: continue if rule['capture_delay'] is not None and rule['capture_delay'] != cap_delay: continue if rule['monthly_fraud_level'] is not None and rule['monthly_fraud_level'] != fraud_level: continue if rule['monthly_volume'] is not None and rule['monthly_volume'] != vol_category: continue if rule['merchant_category_code'] and mcc not in rule['merchant_category_code']: continue if rule['is_credit'] is not None and rule['is_credit'] != bool(txn['is_credit']): continue if rule['aci'] and txn['aci'] not in rule['aci']: continue if rule['intracountry'] is not None and bool(rule['intracountry']) != intracountry: continue matches.append(rule) if not matches: return None return sorted(matches, key=lambda r: (-rule_specificity(r), r['ID']))[0] ``` ### Step 5: Sum All Transaction Fees and Submit Answer ```python total_fees = 0.0 for _, txn in target_transactions.iterrows(): rule = find_best_rule(txn, acct_type, cap_delay, mcc, fraud_level, vol_category) if rule: total_fees += rule['fixed_amount'] + rule['rate'] * txn['eur_amount'] / 10000 print(round(total_fees, 2)) # Submit this value immediately as <answer>VALUE</answer> ``` --- ## Complete Python Template (Single Day or Month) ```python import json import pandas as pd payments = pd.read_csv('<path>/payments.csv') with open('<path>/fees.json') as f: fees = json.load(f) with open('<path>/merchant_data.json') as f: merchant_data = json.load(f) MERCHANT = '<merchant_name>' YEAR = 2023 # Date range for the QUERY (e.g., single day: [10]; full month: list(range(60, 91)) for March) TARGET_DAYS = [<day_of_year>] # Date range of the full natural MONTH containing the target (for monthly stats): MONTH_START, MONTH_END = <start>, <end> # e.g., 1, 31 for January; 335, 365 for December MONTH_RANGES = { 1:(1,31), 2:(32,59), 3:(60,90), 4:(91,120), 5:(121,151), 6:(152,181), 7:(182,212), 8:(213,243), 9:(244,273), 10:(274,304), 11:(305,334), 12:(335,365) } def map_capture_delay(cd): try: n = int(cd) return '<3' if n < 3 else ('3-5' if n <= 5 else '>5') except (ValueError, TypeError): return cd def categorize_volume(v): if v < 100_000: return '<100k' elif v < 1_000_000: return '100k-1m' elif v < 5_000_000: return '1m-5m' else: return '>5m' def categorize_fraud(f): if f < 0.072: return '<7.2%' elif f < 0.077: return '7.2%-7.7%' elif f < 0.083: return '7.7%-8.3%' else: return '>8.3%' def rule_specificity(rule): return sum([bool(rule['account_type']), rule['capture_delay'] is not None, rule['monthly_fraud_level'] is not None, rule['monthly_volume'] is not None, bool(rule['merchant_category_code']), rule['is_credit'] is not None, bool(rule['aci']), rule['intracountry'] is not None]) def find_best_rule(txn, acct_type, cap_delay, mcc, fraud_level, vol_category): intracountry = (txn['issuing_country'] == txn['acquirer_country']) matches = [] for rule in fees: if rule['card_scheme'] != txn['card_scheme']: continue if rule['account_type'] and acct_type not in rule['account_type']: continue if rule['capture_delay'] is not None and rule['capture_delay'] != cap_delay: continue if rule['monthly_fraud_level'] is not None and rule['monthly_fraud_level'] != fraud_level: continue if rule['monthly_volume'] is not None and rule['monthly_volume'] != vol_category: continue if rule['merchant_category_code'] and mcc not in rule['merchant_category_code']: continue if rule['is_credit'] is not None and rule['is_credit'] != bool(txn['is_credit']): continue if rule['aci'] and txn['aci'] not in rule['aci']: continue if rule['intracountry'] is not None and bool(rule['intracountry']) != intracountry: continue matches.append(rule) if not matches: return None return sorted(matches, key=lambda r: (-rule_specificity(r), r['ID']))[0] # Merchant properties merchant = next(m for m in merchant_data if m['merchant'] == MERCHANT) acct_type = merchant['account_type'] cap_delay = map_capture_delay(merchant['capture_delay']) mcc = merchant['merchant_category_code'] # Monthly stats (full natural month) month_txns = payments[ (payments['merchant'] == MERCHANT) & (payments['year'] == YEAR) & (payments['day_of_year'].between(MONTH_START, MONTH_END)) ] monthly_vol = month_txns['eur_amount'].sum() fraud_vol = month_txns[month_txns['has_fraudulent_dispute'] == True]['eur_amount'].sum() fraud_rate = fraud_vol / monthly_vol if monthly_vol > 0 else 0 fraud_level = categorize_fraud(fraud_rate) vol_category = categorize_volume(monthly_vol) # Target transactions and fee computation target_txns = payments[ (payments['merchant'] == MERCHANT) & (payments['year'] == YEAR) & (payments['day_of_year'].isin(TARGET_DAYS)) ] total_fees = 0.0 for _, txn in target_txns.iterrows(): rule = find_best_rule(txn, acct_type, cap_delay, mcc, fraud_level, vol_category) if rule:
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看