第一章练习答案
任务合同
在正文 classify 中把最后两项检查替换为下面代码,其余输入验证与 JSON 解析保持原样:
python
if value['queue'] not in ('billing', 'technical', 'abstain'):
raise ValueError('invalid queue')
status = 'needs_review' if value['queue'] == 'abstain' else 'classified'
return {'status': status, 'queue': value['queue']}接在函数定义后独立运行以下断言,不依赖前一实验的 calls:
python
assert classify('无法判断', lambda _: '{"queue":"abstain"}')['status'] == 'needs_review'
assert classify('发票', lambda _: '{"queue":"billing"}')['status'] == 'classified'
for raw, reason in [('3', 'invalid shape'), ('{"queue":"other"}', 'invalid queue')]:
try:
classify('问题', lambda _, raw=raw: raw)
except ValueError as error:
assert str(error) == reason
else:
raise AssertionError('invalid output accepted')
print('abstention ok')结果 abstention ok。弃答是被合同认可的状态,不是解析错误;错误时默认账单会把未知错误伪装成成功。
数据隔离
在正文 rows 定义后加入 rows[2]['deleted'] = True,再用下面函数替换原 retrieve:
python
def retrieve(tenant, k):
authorized = [r for r in rows if r['tenant'] == tenant and not r.get('deleted', False)]
return sorted(authorized, key=lambda r: (-r['score'], r['id']))[:k]
assert retrieve('A', 2) == []
assert [r['id'] for r in retrieve('B', 2)] == ['b1', 'b2']
print('tombstone ok')输出 tombstone ok。缺字段的旧记录按未删除处理;已有墓碑立即屏蔽。只有下游物理清理和重建都不会再带回旧版本时才能移除墓碑,否则旧切片重新入索引会复活已删除内容。