2. 多银行账户余额汇总与币种折算

任务说明

将三家银行、四种币种的账户余额,按给定汇率折算为集团本位币(CNY),并生成按银行、币种、账户类型分组的汇总表。核心逻辑:先折算,再分组聚合。

数据与汇率

账户数据用列表字典表示,汇率用字典表示(1单位外币兑CNY)。折算公式:本位币金额 = 原币金额 × 汇率,CNY汇率固定为1.0。

完整实现

from collections import defaultdict

# 集团本位币
BASE = "CNY"

# 汇率表:1单位外币 = X CNY
FX = {"CNY": 1.0, "USD": 7.15, "EUR": 7.80, "HKD": 0.92}

# 分散的账户余额
accounts = [
    {"bank": "工商银行", "currency": "CNY", "type": "活期", "balance": 1_200_000},
    {"bank": "工商银行", "currency": "USD", "type": "活期", "balance": 85_000},
    {"bank": "中国银行", "currency": "USD", "type": "定期", "balance": 300_000},
    {"bank": "中国银行", "currency": "EUR", "type": "活期", "balance": 42_000},
    {"bank": "汇丰银行", "currency": "HKD", "type": "活期", "balance": 5_600_000},
    {"bank": "汇丰银行", "currency": "USD", "type": "定期", "balance": 120_000},
]

def to_base(amount, currency):
    """将原币金额折算为本位币"""
    if currency not in FX:
        raise KeyError(f"缺少汇率: {currency}")
    return amount * FX[currency]

def summarize(accounts):
    """按 (银行, 币种, 账户类型) 分组汇总本位币余额"""
    groups = defaultdict(lambda: {"原币余额": 0.0, "本位币余额": 0.0})
    for acc in accounts:
        key = (acc["bank"], acc["currency"], acc["type"])
        groups[key]["原币余额"] += acc["balance"]
        groups[key]["本位币余额"] += to_base(acc["balance"], acc["currency"])
    return groups

def print_report(groups):
    header = f"{'银行':<8}{'币种':<6}{'类型':<6}{'原币余额':>14}{'本位币(CNY)':>16}"
    print(header)
    print("-" * len(header))
    total = 0.0
    for (bank, cur, typ), v in sorted(groups.items()):
        print(f"{bank:<8}{cur:<6}{typ:<6}{v['原币余额']:>14,.2f}{v['本位币余额']:>16,.2f}")
        total += v["本位币余额"]
    print("-" * len(header))
    print(f"{'合计':<20}{'':>14}{total:>16,.2f}")

if __name__ == "__main__":
    print_report(summarize(accounts))

运行与验证

直接运行:python summary.py。判定通过的条件:

  • 输出包含6行分组明细,每行本位币金额 = 原币余额 × 对应汇率(如 USD 85,000 → 607,750.00)。
  • 末行合计等于各行本位币金额之和。
  • 若账户币种不在汇率表中,程序抛出 KeyError,提示缺失汇率。

关键点

用 defaultdict 以元组为键做分组,避免手工判断键是否存在;折算与聚合分离,便于后续替换为实时汇率接口或接入数据库。