C#项目—模拟考试
C#模拟考试软件
开发了一个《模拟考试》的小软件,此小软件练习的目的主要是为了体会编程思想,深度理解高内聚、低耦合,掌握编程思维逻辑的大招,告别垃圾代码,重点体会编程之美,练习时长30分钟;
开发一个项目之前,切记不要打开程序就写代码,首先要做的就是分析项目,从项目的架构开始思考,软件要实现什么功能(思考UI界面布局);数据从哪里获取?(数据库、文本文件、通讯接口...);重点思考项目对象、功能有哪些?(对象的属性<成员>、方法<功能>,之间的关系...),以此项目为例,思维导图如下:
No1. 软件实现的功能有哪些?(UI如何设计)
答: 用一个主界面实现,有标题栏(项目名称及关闭按钮)、菜单栏(上一题、下一题、提交按钮)、内容显示题目,选项以勾选的方式答题,最后提交得出总分;
No2.数据在哪里获取?
答: 文本文件(是否可靠,避免用户更改源文件,进一步优化<序列化保存文件后反序列化读取>—用到的技能:文本文件操作<后续总结概括>)
No3.对象有哪些,它们之间的关系是什么?
答: 软件运行强相关的对象有试卷、试题、答案(正确答案、错误答案);一张试卷中若干试题(一对多),试题在试卷中以集合的方式存在;试题的答案唯一(一对一),答案在试题中以对象属性的形式存在;
No4.如何设计类(列出属性<成员>、方法<功能>)?
答: 窗体加载试卷对象(试题加载(答案));从最底层答案类开始设计:
【答案类】
属性:所选答案、正确答案;
/// <summary>
/// 答案类(属性<成员变量>:所选答案、正确答案)
/// </summary>
[Serializable] //实体类需序列化保存
public class Answer
{
public string SelectAnswer { get; set; } = string.Empty;
public string RightAnswer { get; set; } = string.Empty;
}
【试题类】
属性:题干、选项、答案(对象属性<需在类的构造方法初始化>);
/// <summary>
/// 试题类(属性:题干、答案<对象属性-构造函数初始化>)
/// </summary>
[Serializable]
public class Question
{
public Question() //构造函数初始化
{
QueAnswer = new Answer();
}
public string Title { get; set; } = string.Empty;
public string DescriptionA { get; set; } = string.Empty;
public string DescriptionB { get; set; } = string.Empty;
public string DescriptionC { get; set; } = string.Empty;
public string DescriptionD { get; set; } = string.Empty;
public Answer QueAnswer { get; set; } //答案为对象属性
}
【试卷类】
属性:试题集合List;
方法:计算总分、读取文本(抽取试题);
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace WindowsFormsApp_试卷抽题.Models
{
/// <summary>
/// 试卷类(属性:试题集合、 方法:抽题、分数)
/// </summary>
public class Paper
{
//构造函数初始化(对象属性)
public Paper()
{
questions = new List<Question>();
}
//字段:试题对象集合
private List<Question> questions;
//属性:只读
public List<Question> Questions { get { return this.questions; } }
//方法:分数【遍历试题选择的答案与正确答案相等即可得分】
public int Grade()
{
int score = 0;
foreach (Question item in questions)
{
if (item.QueAnswer.SelectAnswer == string.Empty) continue;
if (item.QueAnswer.SelectAnswer.Equals(item.QueAnswer.RightAnswer)) score += 5;
}
return score;
}
//方法:抽题:【初始化(1.读文件 2.保存为序列化文件 3.打开序列化文件)】
//读文本文件
public void OpenPaper1()
{
FileStream fs = new FileStream("questions.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.Default); //注意默认编码方法
string txtPaper = sr.ReadToEnd(); //读取全部内容到txtPaper
string[] txtQuestions = txtPaper.Trim().Split('&'); //分割内容保存到试题数组;注意去空格
string[] txtQuestion = null; //保存一道题到txtQuestion
foreach (string item in txtQuestions)
{
txtQuestion = item.Trim().Split('\r');
this.questions.Add(new Question
{
Title = txtQuestion[0].Trim(),
DescriptionA = txtQuestion[1].Trim(),
DescriptionB = txtQuestion[2].Trim(),
DescriptionC = txtQuestion[3].Trim(),
DescriptionD = txtQuestion[4].Trim(),
QueAnswer = new Answer { RightAnswer = txtQuestion[5].Trim() }
});
}
sr.Close();
fs.Close();
}
//保存为序列化文件
public void SavePaper()
{
FileStream fs = new FileStream("Paper.obj", FileMode.Create); //创建文件
BinaryFormatter bf = new BinaryFormatter(); //序列化器
bf.Serialize(fs, this.questions); //序列化对象
fs.Close();
}
//打开序列化文件【保存文件后用此方法将独到的数据传递到试题集合中即可】
public void OpenPaper2()
{
FileStream fs = new FileStream("Paper.obj", FileMode.Open); //打开文件
BinaryFormatter bf = new BinaryFormatter(); //序列化器
this.questions = (List<Question>)bf.Deserialize(fs); //反序列化到对象
fs.Close();
}
}
}
【边界类】
属性:试卷对象;
方法:显示题目、保存答案、重置答案;
/// <summary>
/// 边界类:试卷对象、题序 方法:显示题目、保存答案、重置答案
/// </summary>
public partial class FrmMain : Form
{
//窗口初始化
public FrmMain()
{
InitializeComponent();
this.palCover.Visible = true;
this.lblView.Text = "试卷密封中,等待抽题......";
}
//试卷对象、题序号
private Paper Paper = new Paper();
private int QuestionIndex = 0;
//开始抽题
private void btnStart_Click(object sender, EventArgs e)
{
this.palCover.Visible = false;
//显示第一题
this.Paper.OpenPaper1(); //打开txt文件
//this.Paper.SavePaper(); //保存文序列化文件
//this.Paper.OpenPaper2(); //反序列化打开试卷
ShowPaper();
}
//提交试卷
private void btnSubmit_Click(object sender, EventArgs e)
{
this.palCover.Visible = true;
//保存答案并判断
SaveAnswer();
int score = this.Paper.Grade();
//显示成绩
this.lblView.Text = $"您的得分是: {score} 分";
}
//上一题
private void btnUp_Click(object sender, EventArgs e)
{
if (QuestionIndex == 0) return;
else
{
SaveAnswer();
QuestionIndex--;
ResetAnswer();
ShowPaper();
}
}
//下一题
private void btnDown_Click(object sender, EventArgs e)
{
if (QuestionIndex == Paper.Questions.Count - 1) return;
else
{
SaveAnswer();
QuestionIndex++;
ResetAnswer();
ShowPaper();
}
}
//显示试题
public void ShowPaper()
{
this.lblTiltle.Text = this.Paper.Questions[this.QuestionIndex].Title;
this.lblA.Text = this.Paper.Questions[this.QuestionIndex].DescriptionA;
this.lblB.Text = this.Paper.Questions[this.QuestionIndex].DescriptionB;
this.lblC.Text = this.Paper.Questions[this.QuestionIndex].DescriptionC;
this.lblD.Text = this.Paper.Questions[this.QuestionIndex].DescriptionD;
}
//保存答案
public void SaveAnswer()
{
string selecetAnswer = string.Empty;
if (this.ckbA.Checked) selecetAnswer += "A";
if (this.ckbB.Checked) selecetAnswer += "B";
if (this.ckbC.Checked) selecetAnswer += "C";
if (this.ckbD.Checked) selecetAnswer += "D";
this.Paper.Questions[QuestionIndex].QueAnswer.SelectAnswer = selecetAnswer;
}
//重置答案
public void ResetAnswer()
{
this.ckbA.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("A");
this.ckbB.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("B");
this.ckbC.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("C");
this.ckbD.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("D");
}
//退出
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}
软件效果

思维导图如下所示(重点体会思路,思路清晰代码就成了):

C#项目—模拟考试的更多相关文章
- 驾照理论模拟考试系统Android源码下载
驾照理论模拟考试系统Android源码下载 <ignore_js_op> 9.png (55.77 KB, 下载次数: 0) <ignore_js_op> 10.png ...
- RHCE模拟考试
真实考试环境说明: 你考试所用的真实物理机器会使用普通账号自动登陆,登陆后,桌面会有两个虚拟主机图标,分别是system1和system2.所有的考试操作都是在system1和system2上完成.S ...
- PHPEMS在线模拟考试系统 v4.2
官网地址 :http://www.phpems.net/ 下载地址 : http://www.phpems.net/index.php?content-app-content&contenti ...
- 试题管理/在线课程/模拟考试/能力评估报告/艾思在线考试系统www.aisisoft.cn
艾思软件发布在线考试系统, 可独立部署, 欢迎咨询索要测试账号 一. 主要特点: ThinkPHP前后端分离框式开发 主要功能有: 在线视频课程, 模拟考试, 在线考试, 能力评估报告, 考试历史错题 ...
- PMP模拟考试-2
1. Increasing resources on the critical path activities may not always shorten the length of the pro ...
- PMP模拟考试-1
1. A manufacturing project has a schedule performance index (SPI) of 0.89 and a cost performance ind ...
- vue项目模拟后台数据
这次我们来模拟一些后台数据,然后去请求它并且将其渲染到界面上.关于项目的搭建鄙人斗胆向大家推荐我的一篇随笔<Vue开发环境搭建及热更新> 一.数据建立 我这里为了演示这个过程所以自己编写了 ...
- 2017 五一 清北学堂 Day1模拟考试结题报告
预计分数:100+50+50 实际分数:5+50+100 =.= 多重背包 (backpack.cpp/c/pas) (1s/256M) 题目描述 提供一个背包,它最多能负载重量为W的物品. 现在给出 ...
- Python做的第一个小项目-模拟登陆
1. 用户输入帐号密码进行登陆 2. 用户信息保存在文件内 3. 用户密码输入错误三次后锁定用户 主要采用循环语句和条件语句进行程序流程的控制,加入文件的读写操作 while True: choice ...
- Dubbo开发,利用项目模拟提供者和消费者之间的调用--初学
开发工具:IDEA,虚拟机 VMware Workstation 预备工作:安装好zookeeper的虚拟机,电脑jdk更换为1.7,本地tomcat启动,能够访问以下页面即可进行开发 2.建立以下s ...
随机推荐
- 嵌入式工程师进阶,基于AM64x开发板的IPC多核开发案例分享
前 言 本文档主要说明AM64x基于IPC的多核开发方法.默认使用AM6442进行测试演示,AM6412测试步骤与之类似. 适用开发环境如下: Windows开发环境:Windows 7 64bit. ...
- debian11安装备忘
1. 网卡驱动 参考网址:如何安装Debian RTL8821CE驱动? 2. 分辨率 貌似还是有点问题,还要进一步研究一下 参考网址:虚拟机中debian11修改控制台(console)分辨率|li ...
- 深度学习pytorch常用操作以及流程
在微信公众号上看到这篇文章,担心以后想找的时候迷路,所以记录到了自己的博客上,侵扰致歉,随时联系可删除. 1.基本张量操作 1. 1 创建张量 介绍: torch.tensor() 是 PyTorch ...
- 2024-07-13:用go语言,给定一个从0开始的长度为n的整数数组nums和一个从0开始的长度为m的整数数组pattern,其中pattern数组仅包含整数-1、0和1。 一个子数组nums[i.
2024-07-13:用go语言,给定一个从0开始的长度为n的整数数组nums和一个从0开始的长度为m的整数数组pattern,其中pattern数组仅包含整数-1.0和1. 一个子数组nums[i. ...
- 解决方案 | 预装win11如何退回win10?
0.定义 本文所说的[退回]并不指的是win10升级后的变成win11再变为win10的退回.退回应该理解为[降级],或者叫作返回上一个版本.本文的适用范围局限于,预装系统是win11,想要不通过u盘 ...
- 数据仓库建模工具之一——Hive学习第一天
hive分布式搭建文档 谷歌浏览器下载网址:Google Chrome – Download the fast, secure browser from Google 华为云镜像站:https://m ...
- 关键点检测(1)——标注关键点检测数据(labelme和CVAT)
关键点检测,作为计算机视觉领域的重要分支,广泛应用于人体姿态估计.面部表情识别.手部动作分析等多个场景.其核心在于从图像中准确检测并定位特定的关键点位置.然而,高效的模型训练离不开大量高质量的标注数据 ...
- UE5 打不开
在游戏开发中,出现了UE打不开的情况 初步推测,新增了接口Attacker, 而我们的DefaultPawn可能一下子实现了两个接口造成的 而这两个接口都在一个插件里,一个是c++实现的,一个是蓝图实 ...
- redis如何实现主从同步
redis实现主从同步分为两种:全量同步和增量同步:第一次连入集群的slave需要进行全量同步,那些断开后重连的slave需要进行增量同步 每个redis都有自己的replid,他们是master的标 ...
- 【Binary】XShell6 无法使用的解决办法
感谢博主的解决方案: https://www.cnblogs.com/pinkpolk/articles/13554445.html 首先需要安装VsCode,并且安装一个[Hex Editor]的插 ...