CS1602计算导论
Lab 10Part 4 抽象与组织AI Level 1

继承、运算协议与模块 · 素数作业启动

保留图形、账户、Money、Deck和拆模块五项任务,统一接口后验证状态与导入。启动个人作业2素数计数五法,大整数只作后续预告。

下载 PDF截止:小作业 4 · 12 月 8 日 周二 23:59
本页目录

目标与提交

先说明继承状态、支持操作数、失败和副作用,再实现;真实文件工程核对导入与入口,不能把一段孤立代码当完整模块工程。

HW4覆盖10–12周,沿现有校历截止;个人作业2覆盖10/11周,按第11周课后配置计算截止,不另写本周日。两份提交分开。

段代码文字记录原始分
A四道代码题各4自动A设计与验证,8人工24
B模块工程8自动B导入证据,4人工12
C无代码题环境/调试,00

文字分由助教评阅,不因自动测试通过直接给出;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-brutecount_primes_brute(n: int) -> int每候选从2到候选−1试除
w10-primes-sqrtcount_primes_sqrt(n: int) -> int试除界d²≤候选
w10-primes-6kcount_primes_6k(n: int) -> int先2/3,再6k±1候选因子
w10-primes-sievecount_primes_sieve(n: int) -> int埃氏筛,按需数组
w10-primes-mrcount_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区间和小值一致,源码真实采用五法,报告先验证再计时。
  • 使用或未使用声明真实,未做步骤明确说明。保存本机文件不等于在线提交。