| name | Average_Fee_Estimation |
| description | Solve Average_Fee_Estimation questions in the dabstep dataset. Use this skill when asked about the average fee a card scheme charges for a given transaction value, or which card scheme is cheapest/most expensive in an average scenario. Handles filtering by credit type, account type, and merchant category code (MCC). |
Average Fee Estimation Skill
Dataset Files
fees.json — fee rules (1000 rules, card schemes: GlobalCard, NexPay, SwiftCharge, TransactPlus)
merchant_category_codes.csv — MCC code ↔ description lookup
manual.md — domain rules and fee formula
Do not confuse card schemes: payments.csv uses MasterCard/Visa/Amex/Other; fees.json uses GlobalCard/NexPay/SwiftCharge/TransactPlus. All fee questions reference fees.json.
Core Fee Formula
fee = fixed_amount + rate * transaction_value / 10000
fixed_amount is in EUR; rate is in basis points (per 10,000); transaction_value in EUR.
Rule-Matching Logic
Each rule in fees.json may restrict by: card_scheme, account_type, merchant_category_code, is_credit, capture_delay, monthly_fraud_level, monthly_volume, aci, intracountry.
Critical matching semantics (verified from data):
| Field value | Meaning |
|---|
null | applies to all values |
[] (empty list) | applies to all values (same as null) |
| Non-empty list | must contain the target value |
This applies to both account_type and merchant_category_code. An empty list [] is not "no match" — it means the rule imposes no restriction on that field.
Python filter pattern:
def matches(rule, card_scheme=None, account_type=None, mcc=None, is_credit=None):
if card_scheme and rule['card_scheme'] != card_scheme:
return False
if account_type is not None:
acct = rule['account_type']
if acct and account_type not in acct:
return False
if mcc is not None:
mcc_list = rule['merchant_category_code']
if mcc_list and mcc not in mcc_list:
return False
if is_credit is not None:
if rule['is_credit'] is not None and rule['is_credit'] != is_credit:
return False
return True
The key: if acct and target not in acct — Python's truthiness treats [] as falsy, so empty list passes the filter (= applies to all).
Task Types and Solution Patterns
Type 1: Average fee for a card scheme + credit transactions
Example: "For credit transactions, what would be the average fee that GlobalCard would charge for 50 EUR?"
import json
fees = json.load(open('fees.json'))
rules = [r for r in fees
if r['card_scheme'] == 'GlobalCard'
and r['is_credit'] in [True, None]]
avg = sum(r['fixed_amount'] + r['rate'] * 50 / 10000 for r in rules) / len(rules)
print(round(avg, 6))
Type 2: Average fee for card scheme + account type
Example: "For account type R, what would be the average fee that NexPay would charge for 1000 EUR?"
rules = [r for r in fees
if r['card_scheme'] == 'NexPay'
and (not r['account_type'] or 'R' in r['account_type'])]
avg = sum(r['fixed_amount'] + r['rate'] * 1000 / 10000 for r in rules) / len(rules)
print(round(avg, 6))
Type 3: Average fee for card scheme + account type + MCC description
Example: "For account type H and MCC 'Drinking Places...', what is the average fee GlobalCard charges for 50 EUR?"
import pandas as pd
mcc_df = pd.read_csv('merchant_category_codes.csv')
match = mcc_df[mcc_df['description'].str.contains('Drinking Places', case=False)]
mcc_code = int(match.iloc[0]['mcc'])
rules = [r for r in fees
if r['card_scheme'] == 'GlobalCard'
and (not r['account_type'] or 'H' in r['account_type'])
and (not r['merchant_category_code'] or mcc_code in r['merchant_category_code'])]
avg = sum(r['fixed_amount'] + r['rate'] * 50 / 10000 for r in rules) / len(rules)
print(round(avg, 6))
Type 4: Which card scheme is cheapest/most expensive? ("average scenario")
Example: "In the average scenario, which card scheme would provide the cheapest fee for 10 EUR?"
Average ALL rules for each card scheme (no filter), compare averages:
from collections import defaultdict
scheme_fees = defaultdict(list)
for r in fees:
fee = r['fixed_amount'] + r['rate'] * 10 / 10000
scheme_fees[r['card_scheme']].append(fee)
avgs = {s: sum(fs)/len(fs) for s, fs in scheme_fees.items()}
cheapest = min(avgs, key=avgs.get)
most_exp = max(avgs, key=avgs.get)
print(cheapest)
Known results (from fees.json, all transaction values):
- Cheapest average: GlobalCard (consistently lowest average fee at all transaction values)
- Most expensive average: NexPay (consistently highest average fee at all transaction values)
Output Format
- Numeric fee answers: return as a float rounded to 6 decimal places
- Card scheme name answers: return the exact name string (e.g., "GlobalCard", "NexPay")
- If truly not applicable: return
'Not Applicable'
Common Mistakes to Avoid
- Empty list bug: Never use
mcc is None or code in mcc — this misses [] rules. Use Python truthiness: not mcc or code in mcc.
- Wrong card schemes:
fees.json has GlobalCard/NexPay/SwiftCharge/TransactPlus, NOT MasterCard/Visa.
- is_credit None exclusion: When filtering for credit, include rules where
is_credit is None (applies to all).
- MCC from payments.csv: Always look up MCC codes from
merchant_category_codes.csv, not from payments.csv.
- Single rule vs. average: These questions ask for the average across all applicable rules, not a single matching rule.