继承、运算协议与模块 · 素数作业启动
保留图形、账户、Money、Deck和拆模块五项任务,统一接口后验证状态与导入。启动个人作业2素数计数五法,大整数只作后续预告。
本页目录
目标与提交
先说明继承状态、支持操作数、失败和副作用,再实现;真实文件工程核对导入与入口,不能把一段孤立代码当完整模块工程。
HW4覆盖10–12周,沿现有校历截止;个人作业2覆盖10/11周,按第11周课后配置计算截止,不另写本周日。两份提交分开。
| 段 | 代码 | 文字记录 | 原始分 |
|---|---|---|---|
| A | 四道代码题各4自动 | A设计与验证,8人工 | 24 |
| B | 模块工程8自动 | B导入证据,4人工 | 12 |
| C | 无代码题 | 环境/调试,0 | 0 |
文字分由助教评阅,不因自动测试通过直接给出;C完成但不增加分数,原始分不改变学期权重。
每个入口独立,公开方法写类型提示,self不需额外注解。不用input或要求评测先跑课件。参数名和错误规则以下文为准;数值测试用尺度适中的实数,未列出的对象类型不要求自动转换。
A 段 · 类与运算协议
10-1 图形家族
class Shape:
def area(self) -> float: ...
def name(self) -> str: ...
class Circle(Shape):
def __init__(self, r: float) -> None: ...
class Rectangle(Shape):
def __init__(self, w: float, h: float) -> None: ...
class Triangle(Shape):
def __init__(self, a: float, b: float, c: float) -> None: ...
def total_area(shapes: list[Shape]) -> float: ...
Shape可实例化,但area调用抛NotImplementedError;name返回实际类名。三个子类的尺寸须有限正数,Triangle还须严格三角不等式;非法构造统一ValueError。圆用math.pi,三角形用Heron公式。total_area空列表0、逐对象查询面积,不修改列表或对象。
示例:Circle(1)面积π,Rectangle(2,3)面积6,Triangle(3,4,5)面积6。两个实例独立,Triangle(1,1,3)拒绝。解释为什么拒绝退化三角形,不能自行选None等不同错误结果。
入口 w10-shapes,4自动分。
10-2 账户继承
完整提供BankAccount、SavingsAccount、CheckingAccount,不能只提交子类并依赖已运行L09。
class BankAccount:
def __init__(self, owner: str, balance: int = 0) -> None: ...
def deposit(self, amount: int) -> None: ...
def withdraw(self, amount: int) -> bool: ...
def statement(self) -> str: ...
class SavingsAccount(BankAccount):
def __init__(self, owner: str, balance: int = 0,
interest_rate: float = 0.0) -> None: ...
def add_interest(self) -> None: ...
class CheckingAccount(BankAccount):
def __init__(self, owner: str, balance: int = 0,
overdraft_limit: int = 0) -> None: ...
金额为整数分,公开balance/owner/history沿L09。初值非负整数,非法ValueError;存取非正或非整数不接受,deposit返回None且不改状态,withdraw返回False且不改状态。接受时history追加 ("deposit", amount) 或 ("withdraw", amount)。statement第一行 owner: balance cents,之后每条 action: amount cents,以换行连接,无额外末尾换行。
两个子类init均用super。Savings利率有限且0≤rate≤1,非法ValueError;每次利息按Decimal(str(rate))×余额、ROUND_HALF_UP量化为整数分,写入balance。利息正数历史追加 ("interest", cents),零利息不记录;返回None。该规则是教学舍入契约,非真实金融系统。
Checking的限额为非负整数、初值仍非负;重写withdraw,余额允许到−limit,越界拒绝且历史不变。不能把基类的非负余额保证宣称为全家族相同契约。A记录讨论是否直接调用super().withdraw及理由。
入口 w10-accounts,4自动分。
10-3 Money
class Money:
def __init__(self, yuan: float) -> None: ...
def __repr__(self) -> str: ...
def __add__(self, other: "Money") -> "Money": ...
def __sub__(self, other: "Money") -> "Money": ...
def __eq__(self, other: object) -> bool: ...
def __lt__(self, other: "Money") -> bool: ...
元入参为有限int/float且绝对值≤10^9,非法ValueError;内部整数分。约定将传入值的str转换为Decimal,再乘100、以ROUND_HALF_UP量化到整数:1.005→101分,−1.005→−101分。这个规则针对实际传入值的十进制显示,不声称恢复任意原始十进制意图。先阅读decimal接口说明,再使用,不用int(float*100)截断。
repr固定两位,例如Money(12.50)、Money(-1.01)、Money(0.00)。加减新对象,不改操作数;eq/lt按整数分比较。不支持类型的方法返回NotImplemented;表达式Money==无关对象为False,不支持加减/排序通常TypeError。未知类型不能直接误当同值。结果允许超过构造入参上限,不借float来保存大额结果。
Money(0.1)+Money(0.2)==Money(0.3) 为True;排序按金额,负数和相等值要测。入口 w10-money,4自动分。
10-4 Deck
class Deck:
def __init__(self) -> None: ...
def __len__(self) -> int: ...
def __getitem__(self, i: int) -> str: ...
def __contains__(self, card: str) -> bool: ...
def shuffle(self) -> None: ...
def deal(self, n: int) -> list[str]: ...
统一ASCII牌面为“点数+花色”,花色C/D/H/S,点数A/2/…/10/J/Q/K。初始按花色顺序,各花色按上述点数;第0张AC,第12张KC,第13张AD,末张KS。52张唯一,不含大小王,两个Deck独立。
len是剩余张数;getitem支持整数正负下标,越界IndexError;contains返回布尔。可以借从0开始的序列式迭代支持for,不能越界仍不断返回None。
deal(n)从开头取n张并移除,返回新列表;n非负整数且不超余量,否则ValueError、原状态不变。deal(0)空列表且不变。shuffle原地、返回None、牌集合/张数不变;不要求每次都与原序不同或固定随机输出,不在代码内固定种子冒充随机洗牌。
入口 w10-deck,4自动分。
A 设计与验证记录
入口 w10-a-notes,四字段各人工2分:图形拒绝与多态证据;账户基类/透支接口和super理由;Money舍入/哨兵/输入保全;Deck表示、边界和实例隔离。另有0分使用声明,按实际操作填写。
B 段 · 真实模块工程
10-5 拆分与导入
保存五个文件,修正旧题“3个文件”实际列了4行的矛盾:
shapes.py # 图形
accounts.py # 账户
money.py # 金额
cards.py # 牌组
main.py # 演示入口
四个业务模块顶部docstring,各有main guard,直接运行输出可辨认自测消息 SELFTEST shapes/accounts/money/cards(一行)。被import时不输出任何内容。main导入四模块,正常演示至少一个各模块对象,返回0,至少打印一条结果,不打印SELFTEST。main也有docstring与guard,导入main不启动演示。
现有平台单源码入口中,提交文件定义 project_files() -> dict[str, str],返回上述严格五个文件名到完整源码的字典。评测只在自己的临时沙箱目录写这五文件,再执行/导入,不接受任意绝对路径或新增zip上传。project_files 本身不运行工程、不读本机文件、不安装依赖。
这个适配层不替代本机五文件:先独立保存运行,再把源码作为字符串填入字典。模块业务接口至少能正确完成A段正常演示,代码不用input/网络/图形窗口。所有依赖均为标准库及这五文件。
入口 w10-module-project,8自动分。B文字入口 w10-b-notes:模块职责与Money分离2人工分,直接运行/导入预期实际/副作用证据2人工分,另0分声明。不要只贴guard字符串就声称验证导入。
C 段 · 环境与操作记录
入口 w10-c-tools,0分。记录解释器路径、对应pip、实际模块来源、使用环境;在独立临时目录观察一次main guard或同名遮蔽,再清理自己的例子。不要在真实项目里留下random.py,不实际卸载其他人的依赖。
调试时指出self与当前类/MRO,不能把super固定解释为直接父类。不能运行GUI或多文件时,说明限制,不伪造截图或输出。C不增加权重。
四、个人作业2:素数计数五法
solo2按现行日历第10周启动、覆盖10/11周,每份个人作业5%,三份合计15%。具体截止由该题包配置计算;不是旧稿的“大整数7.5%/两周后的周日”。
独立五个入口分别定义:
| 入口 | 函数 | 方法 |
|---|---|---|
w10-primes-brute | count_primes_brute(n: int) -> int | 每候选从2到候选−1试除 |
w10-primes-sqrt | count_primes_sqrt(n: int) -> int | 试除界d²≤候选 |
w10-primes-6k | count_primes_6k(n: int) -> int | 先2/3,再6k±1候选因子 |
w10-primes-sieve | count_primes_sieve(n: int) -> int | 埃氏筛,按需数组 |
w10-primes-mr | count_primes_mr(n: int) -> int | 指定小域的Miller–Rabin |
统计 0≤p<n,0≤n≤100000,n≤2为0,负数ValueError;范围外不是必须完成输入。例子n=0/2→0、n=3→1、n=10→4。返回整数,不打印。
MR先处理小于2、2/3与其他偶数,对剩余奇数按2和3两底数。已知界小于1,373,653,本题候选小于100000,因而此域可用确定性判断;不声称任意大整数确定。算法的分解/模幂、试除和筛法在L11及任务资料继续讲,本周先建立接口与正确性记录,不要求未教先完成全部算法。
五代码题各16自动原始分,方法/计时/验证报告人工20,总原始100归一化为本份5%。自动测试主要看正确结果/边界,助教从源码与记录核对不同方法,不用另一算法包装五个函数蒙混。每个入口完整定义自己的辅助函数,不依赖另一个入口;MR可用pow(a,d,m)。
文字入口 w10-primes-report:五种方法及源码依据6分、边界与交叉验证6分、公平计时和可复现环境6分、结论/限制2分,使用声明0分。计时先验证正确,再选可完成规模;暴力可只测较小n,不替换算法追求同一最大规模。报告包含实际n、轮次、环境、准备与查询是否分离及正确计数,至少三次测量,不把单次倍数当固定结论。
五、后续参考:大整数
第12周正式启动,不在本周提交BigInt或沿旧7.5%规则评分。保留十进制字符串/符号/分组位表示,str/repr/eq/lt/add/sub/mul及不将整体输入转int代替实现的要求。零、前导零、负数、不等长、负差和进位/借位/乘法都要考虑,int可作测试参考。一页报告说明表示、符号和边界/随机对拍。
旧20/20/20/10/15/5/10分项为历史需求,未来正式评分由当前题面另定,不改变现行三份5%的课程权重。完整预告见L10参考,不删知识。
提交自查
- HW4四类题、模块适配和文字卡入口分开,类型提示/异常/返回一致。
- 检查两个实例、拒绝后完整状态、未知类型与舍入、Deck序列停止。
- 模块docstring、真实导入无输出、自测直接运行、main实际演示都有证据。
- solo2区间和小值一致,源码真实采用五法,报告先验证再计时。
- 使用或未使用声明真实,未做步骤明确说明。保存本机文件不等于在线提交。