在前面的章节中,您通过直接查看代码并尝试尽快理解它来“深入探讨”。现在您已经掌握了一些 Python 知识,您将退后一步,看看在编写代码之前需要执行哪些步骤。
在接下来的几章中,您将编写、调试和优化一组实用函数,以在罗马数字之间进行转换。您在第 7.3 节“案例研究:罗马数字”中看到了构建和验证罗马数字的机制,但现在让我们退后一步,考虑将其扩展为双向实用程序需要什么。
罗马数字的规则引出了一些有趣的观察结果
- 只有一种正确的方法可以将特定数字表示为罗马数字。
- 反之亦然:如果一串字符是有效的罗马数字,则它只代表一个数字(即 它只能以一种方式读取)。
- 可以用罗马数字表示的数字范围有限,特别是 1 到 3999。(罗马人确实有几种表示更大数字的方法,例如,在数字上加一条横线表示其正常值应乘以 1000,但您不必处理这个问题。就本章而言,让我们规定罗马数字的范围是从 1 到 3999。)
- 没有办法用罗马数字表示 0。(令人惊讶的是,古罗马人没有将 0 视为数字的概念。数字是用来计算你拥有的东西的;你怎么能计算你没有的东西呢?)
- 没有办法用罗马数字表示负数。
- 没有办法用罗马数字表示分数或非整数。
考虑到所有这些,您希望从一组用于在罗马数字之间进行转换的函数中得到什么?
roman.py 要求
- toRoman 应该返回所有整数 1 到 3999 的罗马数字表示形式。
- 当给定 1 到 3999 范围之外的整数时,toRoman 应该失败。
- 当给定非整数时,toRoman 应该失败。
- fromRoman 应该接受一个有效的罗马数字并返回它所代表的数字。
- 当给定无效的罗马数字时,fromRoman 应该失败。
- 如果您取一个数字,将其转换为罗马数字,然后再将其转换回数字,则您应该得到与开始时相同的数字。所以对于 1..3999 中的所有 n,fromRoman(toRoman(n)) == n。
- toRoman 应该始终返回使用大写字母的罗马数字。
- fromRoman 应该只接受大写罗马数字(即 当给定小写输入时,它应该失败)。
延伸阅读
- 本网站 提供了更多关于罗马数字的信息,包括关于罗马人和其他文明如何真正使用罗马数字的迷人历史(简而言之:随意且不一致)。