📚 Year 9 AQA Computer Science: Case Study in Action - Voting System Design | 九年级AQA计算机科学:实战案例分析 - 电子投票系统设计
Case studies are a powerful way to connect computing theory with real-world problem solving. In this article, we will step through the design and implementation of a simple electronic voting system. You will see how decomposition, abstraction, algorithmic thinking, programming, testing, security and ethical considerations all come together. This mirrors the kind of practical thinking expected in Year 9 AQA Computer Science and prepares you to tackle similar open-ended challenges.
案例研究是将计算理论与现实问题解决联系起来的有效方法。在本文中,我们将逐步设计并实现一个简单的电子投票系统。你将看到分解、抽象、算法思维、程序设计、测试、安全以及伦理考量如何协同工作。这反映了九年级AQA计算机科学课程所期望的实践思维方式,并帮助你准备好应对类似的开放式挑战。
1. Understanding the Problem | 问题理解
The school council wants a terminal-based voting program for four extracurricular activity options: Sport, Music, Drama and Art. Each student logs in with a unique ID, casts exactly one vote, and the system must prevent the same ID from voting twice. At the end, the program displays the total votes for each activity and announces the winner.
学生会需要一个基于终端界面的投票程序,用于四个课外活动选项:体育、音乐、戏剧和美术。每个学生用一个独特的ID登录,只能投一票,系统必须防止同一ID重复投票。最后,程序显示每个活动的总票数并公布获胜者。
We must also consider what happens when a user enters an invalid choice or tries to vote with an ID that has already been used. Clear feedback should be given in both cases. The system does not need a graphical user interface, and all output can be shown line by line in the console.
我们还需要考虑当用户输入无效选项、或者试图用一个已经投过票的ID再次投票时会发生什么。这两种情况都应该给出清晰的反馈。系统不需要图形用户界面,所有输出都可以逐行显示在控制台中。
2. Decomposition and Abstraction | 问题分解与抽象
Decomposition means breaking the problem into manageable parts. We can identify four main modules:
- User authentication – check if the ID is new or used
- Voting procedure – show the menu and accept a choice
- Counting and storage – keep tallies and record which IDs have voted
- Result display – calculate totals and declare the winner
分解意味着把问题拆解为可管理的部分。我们可以识别出四个主要模块:
- 用户认证 – 检查ID是新的还是已使用过
- 投票流程 – 显示菜单并接受选择
- 计数与存储 – 记录票数以及哪些ID投过票
- 结果显示 – 计算总数并宣布获胜者
Abstraction focuses on the essential details. We do not need to store the student's name, year group or why they chose an activity. We only care about a unique voter ID, the activity choice and the counter for each activity. The activities themselves are represented simply by their names in a list. This abstraction keeps our data model lightweight and efficient.
抽象关注的是本质细节。我们不需要存储学生姓名、年级或选择原因。我们只关心唯一的投票者ID、选择的活动以及每个活动的计数器。活动本身仅通过列表中的名称表示。这种抽象使我们的数据模型保持轻量和高效。
3. Designing the Algorithm: Flowchart | 算法设计:流程图
Before coding, we design the flow of the voting system using a structured sequence of steps. The main process can be visualised as:
Start → Input voter ID → Check if ID already voted? → Yes: Display 'Already voted' → End turn
No: Show activity menu → Input choice (1–4) → Validate choice → Update vote count → Record ID → Another voter? → Yes: Loop back; No: Display totals → End
在编程之前,我们用结构化的步骤序列设计投票系统的流程。主流程可以可视化如下:
开始 → 输入投票者ID → 检查ID是否已投过? → 是:显示“已经投过” → 结束本次
否:显示活动菜单 → 输入选择(1–4) → 验证选择 → 更新票数 → 记录ID → 还有投票者? → 是:循环回去;否:显示总数 → 结束
Notice that the decision diamonds are crucial: they control the flow based on conditions. The loop allows multiple voters to use the system sequentially, while the validation box ensures that only a number between 1 and 4 is accepted. A well-drawn flowchart helps you spot missing steps early.
请注意判断菱形框至关重要:它们根据条件控制流程。循环允许多位投票者依次使用系统,而验证框确保只接受1到4之间的数字。绘制良好的流程图有助于及早发现遗漏的步骤。
4. Pseudocode Representation | 伪代码表示
Writing pseudocode bridges the gap between the flowchart and actual code. Here is a clear, language-neutral description of the algorithm:
编写伪代码弥合了流程图与实际代码之间的差距。下面是对算法的清晰、语言中立的描述:
ACTIVITIES ← ["Sport", "Music", "Drama", "Art"]
votes ← [0, 0, 0, 0]
voted ← empty list
REPEAT
INPUT voter_id
IF voter_id IN voted THEN
OUTPUT "You have already voted."
ELSE
OUTPUT "1 Sport, 2 Music, 3 Drama, 4 Art"
INPUT choice
WHILE choice < 1 OR choice > 4
OUTPUT "Invalid. Choose 1-4."
INPUT choice
ENDWHILE
votes[choice - 1] ← votes[choice - 1] + 1
APPEND voter_id TO voted
ENDIF
INPUT "More voters? (y/n)"
UNTIL answer = "n"
FOR i ← 0 TO 3
OUTPUT ACTIVITIES[i], votes[i]
ENDFOR
可以使用列表存储活动和票数,空列表记录已投票ID。外循环根据用户响应运行,内循环进行输入验证。使用索引 choice - 1 是因为列表索引从0开始。这种伪代码可直接转换为任何高级语言。
5. Data Structures and Variables | 数据结构与变量
Choosing the right data structures simplifies the whole program. We use:
- activities – a list of strings holding the four option names
- votes – a list of integers, each starting at 0, where the index matches an activity
- voted_ids – a list of strings to store the IDs that have already voted; membership is fast to check with the
inoperator
选择正确的数据结构可以简化整个程序。我们使用:
- activities – 包含四个选项名称的字符串列表
- votes – 整数列表,每个初始为0,其索引与活动对应
- voted_ids – 存储已投票ID的字符串列表;使用
in运算符可以快速检查成员
We also need simple variables: voter_id (a string), choice (an integer), and a loop control variable such as more (a string capturing 'y' or 'n'). All these data structures are mutable, which suits the need to update state during the voting session.
我们还需要简单变量:voter_id(字符串)、choice(整数)以及循环控制变量如more(捕获 'y' 或 'n' 的字符串)。所有这些数据结构都是可变的,适合在投票过程中更新状态的需求。
6. Python Implementation | Python 代码实现
Below is a complete Python program that implements the voting system. Notice how it follows the pseudocode closely, using a while loop and suitable built-in functions.
下面是一个完整的Python程序,实现了该投票系统。请注意它是如何紧密遵循伪代码,使用 while 循环和合适的内置函数。
activities = ["Sport", "Music", "Drama", "Art"] votes = [0, 0, 0, 0] voted = [] more = 'y' while more.lower() == 'y': vid = input("Enter your voter ID: ") if vid in voted: print("Sorry, you have already voted.") else: print("1. Sport 2. Music 3. Drama 4. Art") choice = int(input("Enter choice (1-4): ")) while choice < 1 or choice > 4: choice = int(input("Invalid. Enter choice (1-4): ")) votes[choice - 1] += 1 voted.append(vid) print("Vote recorded.") more = input("Any more voters? (y/n): ") print("\nResults:") for i in range(len(activities)): print(f"{activities[i]}: {votes[i]}")
程序首先初始化三个数据结构。外部循环持续询问“还有投票者吗?”,内部验证选项。一旦选择有效,使用索引更新票数列表,并将投票者ID添加到voted列表。最后遍历并输出结果。这展示了输入验证、列表操作和循环控制。
7. Testing and Debugging | 测试与调试
Testing is essential to confirm the program behaves correctly under different scenarios. A thorough test plan should include normal, boundary and erroneous inputs. Below is a test table with expected outcomes.
测试对于确认程序在不同场景下行为正确至关重要。一个全面的测试计划应包括正常、边界和错误输入。下面是一个包含预期结果的测试表。
| Test Case (测试用例) | Input (输入) | Expected Outcome (预期结果) |
|---|---|---|
| Normal vote | ID 'S123', choice 2 | Vote recorded, Music count +1 |
| Duplicate vote | ID 'S123' again | "You have already voted." |
| Out-of-range choice | Choice 5, then 1 | Error message, then accept 1 |
| Non-numeric choice | 'abc' | Program crash (reveals need for further validation) |
| End voting | 'n' when asked for more voters | Display totals and exit |
从测试中我们发现,如果输入非数字选项,程序会因为int()转换而崩溃。这提示我们需要异常处理或使用isdigit()进行预检查。调试时,可以通过在代码中添加print()语句来跟踪变量值,确保逻辑正确。
8. Data Validation and User Input | 数据验证与用户输入
Robust programs anticipate invalid inputs. Our current program fails if the user enters a letter instead of a number for the choice. We can improve the validation by checking that the input is a digit before converting it.
健壮的程序会预料到无效输入。当前程序如果用户为选项输入字母而不是数字,就会失败。我们可以通过先检查输入是否为数字再转换,来改进验证。
One approach is to read everything as a string and use the isdigit() method. For the voter ID, ensuring it is not empty and contains only allowed characters (e.g., alphanumeric) makes the system more reliable. The updated logic could look like:
一种方法是将所有输入作为字符串读取,并使用 isdigit() 方法。对于投票者ID,确保它不为空且只包含允许的字符(例如字母数字),可以使系统更可靠。更新后的逻辑可能如下:
choice_str = input("Enter choice (1-4): ") while not choice_str.isdigit() or int(choice_str) not in range(1,5): choice_str = input("Invalid. Enter choice (1-4): ") choice = int(choice_str)
这样,程序安全地拒绝非数字输入,而不会崩溃。这是一种典型的防御性设计实践,也是AQA考试中常见的要求。
9. Security and Authentication | 安全与身份验证
Even in a simple terminal program, security matters. The voting system uses a voter ID as the sole identifier. While this is basic, we can discuss stronger authentication methods, such as pairing an ID with a secret PIN. For a school setting, an ID might be the student's admission number, which should not be guessable.
即使在简单的终端程序中,安全也很重要。投票系统仅使用投票者ID作为唯一标识。虽然这是基础做法,我们可以讨论更强的身份验证方法,例如将ID与秘密PIN配对。在学校环境中,ID可能是学生入学编号,不应可猜测。
Another security risk is tampering with the vote count after the session. Since the data is stored in memory and lost when the program ends, we could later store it in an encrypted file for an audit trail. For now, ensuring that the voted list cannot be bypassed is the main protection. We could also hash IDs before storing to preserve privacy, but that is an extension for later study.
另一个安全风险是会话结束后篡改票数。由于数据存储在内存中、程序结束即丢失,我们以后可以将其存储到一个加密文件中以留下审计线索。就目前而言,确保voted列表不可被绕过是主要保护措施。我们也可以将ID哈希后再存储以保护隐私,但这属于后续学习的扩展内容。
10. Ethics and Legal Considerations | 伦理与法律考量
Designing any system that handles personal data requires ethical thinking. The voter ID is personal data; in a real deployment, we would need to comply with the UK Data Protection Act and principles such as data minimisation. We should only collect what is absolutely necessary to run the vote – we do not need names or contact details.
设计任何处理个人数据的系统都需要伦理思考。投票者ID属于个人数据;在实际部署中,我们需要遵守英国《数据保护法》以及诸如数据最小化等原则。我们只应收集运行投票所绝对必需的信息——我们不需要姓名或联系方式。
Anonymity in voting is another vital ethical requirement. Our program does not link a specific choice back to an ID in the output, which is good. However, the fact that IDs are stored in plain text means someone with access to the terminal could see who has voted. In a more advanced version, we could use anonymised tokens. Considering the social impact and fairness of algorithmic decisions is a key part of modern computing.
匿名投票是另一个至关重要的伦理要求。我们的程序在输出中不会将特定选项与ID关联,这很好。然而,ID以明文形式存储的事实意味着有权访问终端的人可以看到谁投了票。在更高级的版本中,我们可以使用匿名令牌。考虑社会影响和算法决策的公平性,是现代计算的关键部分。
11. Evaluation and Improvements | 评估与改进
Our voting system meets the basic requirements, but there is always room for improvement. One limitation is that the program cannot handle a large number of voters efficiently, because the voted list grows linearly and the in operator becomes slower. Using a set data type would provide O(1) average lookup time, making duplicate checks instantaneous.
我们的投票系统满足了基本要求,但总有改进空间。一个限制是程序无法高效地处理大量投票者,因为voted列表线性增长,而in运算符的查找会变慢。使用集合数据类型可以提供平均O(1)的查找时间,使重复检查瞬间完成。
Other enhancements could include persistent storage so results survive a power cut, a graphical interface using tkinter, or a web-based front end. From an algorithmic perspective, we could add a tie-breaking rule and display percentages. Each improvement must be weighed against complexity and development time – a perfect demonstration of design trade-offs.
其他增强功能可能包括持久存储以便断电后结果仍能保留、使用tkinter制作图形界面,或基于网页的前端。从算法角度看,我们可以添加平局决胜规则并显示百分比。每次改进都必须权衡复杂性和开发时间——这正是设计权衡的完美展示。
12. Conclusion | 总结
This case study has walked you through the full lifecycle of a computational problem, from initial analysis to implementation and critical evaluation. By applying decomposition, abstraction, algorithm design, programming, testing and ethical reasoning, you have seen how a seemingly simple voting system touches every strand of the AQA Computer Science curriculum.
本案例研究带你走过了一个计算问题从初始分析到实现与批判性评价的完整生命周期。通过应用分解、抽象、算法设计、编程、测试和伦理推理,你看到了一个看似简单的投票系统如何触及AQA计算机科学课程的每一个分支。
Use the same approach when you encounter your own case study tasks. Always start by understanding the problem, break it down, plan before coding, test thoroughly and reflect on the wider implications. These are the habits that turn a good computer scientist into a great one.
当你遇到自己的案例研究任务时,请使用相同的方法。始终从理解问题开始,将其分解,在编码前做好规划,全面测试,并反思更广泛的影响。这些习惯能让一名优秀的计算机科学家变得更卓越。
Published by TutorHao | Computer Science Revision Series | aleveler.com
更多咨询请联系16621398022(同微信)

或截图后用「扫一扫 → 相册」选择本图