C#项目—模拟考试

news/2024/9/19 9:22:00/文章来源:https://www.cnblogs.com/guoenshuo/p/18355969

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();  //读取全部内容到txtPaperstring[] txtQuestions = txtPaper.Trim().Split('&');  //分割内容保存到试题数组;注意去空格string[] txtQuestion = null; //保存一道题到txtQuestionforeach (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();}
}

软件效果


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/783092.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于直流潮流的IEEE30电力系统停电分布及自组织临界性分析matlab仿真

1.课题概述 详细的讲,我们的这个算法的安如下的步骤进行:步骤1:k=k+1,通过慢动态过程中的几个公式,对Pmax,Fmax进行更新;步骤2:考虑随机因素进行线路的断开,以一个随机概率来随机断开一条支路;步骤3:根据慢动态计算得到的参数开始进行慢动态仿真;步骤4:在慢动态仿…

基于多路径路由的全局感知网络流量分配优化算法matlab仿真

1.程序功能描述 2.测试软件版本以及运行结果展示MATLAB2022a版本运行3.核心程序figure; bar(alpha); text(0.5,0.8,用户1,8节点); text(1,0.9,用户2,8节点); text(1.5,0.8,用户1,11节点); text(2,0.9,用户2,11节点); axis([0,3,0,1.2])figure; bar(beta); text(0.6,0.3,用…

概览

https://tech.meituan.com/2018/11/15/java-lock.html

参数化pipeline,凭证管理

参数化pipeline 使用parameters指令pipeline {agent anyparameters {booleanParam(defaultValue: true,description: ,name: userFlag)}stages {stage(foo) {steps {echo "flag: ${params.userFlag}"}}} } 创建代码仓库 添加文件 新建Jenkinsfile文件再次查看,有文…

【第2期】INFINI Easysearch 免费认证培训开放报名啦

探索 Easysearch 的无限可能,与 INFINI Labs 共赴搜索技术前沿! 随着数字化转型的加速,搜索技术已成为企业数据洞察的核心。INFINI Labs 作为搜索创新技术的引领者,诚邀所有对 Easysearch 搜索引擎感兴趣的开发者、技术爱好者及合作伙伴,参加我们即将于 2024 年 8 月 17 日…

2024“钉耙编程”中国大学生算法设计超级联赛(8)

昨天是花冈柚子的生日,把这条信息转发至三个群电脑就会自动下载柚子社全家桶。我试过了是假的,而且我的电脑自动下载了原神,但昨天真的是花冈柚子的生日。目录写在前面10041007101210061005100810031010写在最后 写在前面 补提地址:https://acm.hdu.edu.cn/listproblem.php…

文献阅读——Dynamic Range Compression Preserving Local Image Contrast for Digital Video Camera

Dynamic Range Compression Preserving Local Image Contrast for Digital Video Camera 数字摄像机中保持局部图像对比度的动态范围压缩 摘要 本文提出了一种新的数字摄像机动态范围压缩方法。该算法的目的是在像素和周围注意力区域的亮度比来保持局部对比度。通常,数字视频摄…

Dynamic Range Compression Preserving Local Image Contrast for Digital Video Camera

Dynamic Range Compression Preserving Local Image Contrast for Digital Video Camera 数字摄像机中保持局部图像对比度的动态范围压缩 摘要 本文提出了一种新的数字摄像机动态范围压缩方法。该算法的目的是在像素和周围注意力区域的亮度比来保持局部对比度。通常,数字视频摄…

基于pi控制的数字锁相环simulink建模与仿真

1.算法运行效果图预览 (完整程序运行后无水印)2.算法运行软件版本 matlab2022a3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)01_012m4.算法理论概述数字锁相环(DPLL, Digital Phase Locked Loop)是一种重要的电路系统,广泛应用于通信、信号处理、频率合成等领…

Kubernetes 存储架构及插件使用

目录本文转载本文转载自阿里巴巴云原生微信公众号(ID:Alicloudnative)。一、Kubernetes 存储体系架构1、引例: 在 Kubernetes 中挂载一个 Volume2、Kubernetes 的存储架构3、PV Controller3.1、基本概念3.2、PV 的状态迁移图3.3、PVC 的状态迁移图3.4、PVC 绑定 PV 流程3.5…

BC变换的EWMA控制图对顺丰控股股票的分析研究

全文链接:https://tecdat.cn/?p=37326 原文出处:拓端数据部落公众号 量化投资可以带来不菲的回报,但缺乏丰富的知识却难以实现。统计质量管理的思想通俗易懂,且对于市场相对稳定的股市有监控作用。结合历史股票数据和统计质量管理的思想,对数据作合适的处理并设计合理的控…

微信小程序目录结构

一、小程序框架 微信开放平台——小程序框架介绍 小程序的目录结构很清晰,主要由描述整体内容的app和描述具体页面的page组成。一般来说,习惯对小程序的目录结构进行更加清晰的规划,例如将程序种会用到的图片统一用imgs文件夹进行管理、pages文件夹下面就是不同页面对于的子…