【小專案】簡易計算機等級考試模擬練習
阿新 • • 發佈:2018-12-19
1 執行效果
登陸介面:
答題介面:
提交試卷介面:
2 專案分析
2.1 資料
資料以固定的格式存放在文字檔案中。
2.2 面向物件程式設計的分析基本步驟
(1)分析專案中有哪些類(或物件)參與程式。
物件選擇的標準:
- 第一,這個物件的確能夠參與程式的執行。
- 第二,這個物件有物件的基本特徵。
- 第三,物件必須與專案是強相關的物件。
初步找到的:試卷、試題、計算機、考生、答案、題幹、選項…
篩選後:
- 試卷類:本專案中只有一張試卷(後續擴充套件可以做成多套試卷)
- 試題類:包括題幹、選項、答案。(經過分析答案還應該有一個獨立的物件)
- 答案類:包括正確答案、答案分析、所選答案。(答案和試題是關聯的)
- 邊界類:專案主介面(負責和使用者互動,完成物件關聯)
(2)分析專案中類或物件之間的關係。 分析結果:
- 試卷->試題:一張試卷包含若干試題。一對多。試題在試卷中應該以集合物件形式存在。
- 試題->答案:一道試題有一個答案,一對一。答案物件應該在試題中以物件屬性形式存在。
- 邊界類->試卷:一個窗體中有一個試卷物件。
2.3 設計類
設計答案類
- 屬性:正確答案、所選答案、答案分析。
設計試題類
- 屬性:試題編號、題幹、選擇A、B、C、D、答案物件(類似資料庫外來鍵)
設計試卷類
- 屬性:試題集合List
- 方法:(1)抽取試題(2)提交試卷。
設計邊界類
- 屬性:試卷物件,試題序號。
- 事件:(1)抽取試題(2)題目選擇(3)提交試卷
3 程式碼實現
專案結構:
Answer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TeachDemo
{
/// <summary>
/// 答案類
/// </summary>
[Serializable]
public class Answer
{
//因為後面我們要直接使用這些屬性值,所以必須有初始值,因為預設值是null
public string RightAnaswer { get; set; } = string.Empty;
public string SeletedAnswer { get; set; } = string.Empty;
public string AnaswerAnalysis { get; set; } = string.Empty;
}
}
Questions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TeachDemo
{
/// <summary>
/// 試題類
/// </summary>
[Serializable ]
public class Question
{
public Question()
{
QAnswer = new Answer();//因為外面是直接使用這個物件,不需要建立,所以我們在這個地方必須直接例項化
}
public int QuestionId { get; set; }
public string Title { get; set; }
public string OptionA { get; set; }
public string OptionB { get; set; }
public string OptionC { get; set; }
public string OptionD { get; set; }
public Answer QAnswer { get; set; }//答案(物件屬性)
}
}
Paper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace TeachDemo
{
/// <summary>
/// 試卷類
/// </summary>
public class Paper
{
public Paper()
{
this.questions = new List<Question>();
}
/// <summary>
/// 試題集合物件(因為一張試卷包括若干試題)
/// </summary>
private List<Question> questions;
public List<Question> Questions
{
get { return this.questions; }
}
///// <summary>
///// 抽取全部試題
///// </summary>
//public void ExtractQuestions()
//{
// FileStream fs = new FileStream("questions.txt", FileMode.Open);
// StreamReader sr = new StreamReader(fs, Encoding.Default);
// string content = sr.ReadToEnd();//一次性讀取全部內容
// string[] questionArray = content.Split(Convert.ToChar("&"));//將字串分隔為試題物件陣列
// string[] question = null;//用來儲存一道試題
// foreach (string item in questionArray)
// {
// //將一道試題字串分隔後變成陣列資訊
// question = item.Trim().Split(Convert.ToChar("\r"));
// this.questions.Add(new Question
// {
// Title = question[0].Trim(),
// OptionA = question[1].Trim(),
// OptionB = question[2].Trim(),
// OptionC = question[3].Trim(),
// OptionD = question[4].Trim(),
// QAnswer = new Answer { RightAnaswer = question[5].Trim() }
// });
// }
// sr.Close();
// fs.Close();
// SavePaper();
//}
//private void SavePaper()
//{
// FileStream fs = new FileStream("questions.obj", FileMode.Create);
// BinaryFormatter bf = new BinaryFormatter();
// bf.Serialize(fs, this.questions);//將當前文字檔案中讀取的資料物件,儲存為集合物件,並以序列化方式存在
// fs.Close();
//}
/// <summary>
/// 通過反序列化的方式讀取試題
/// </summary>
public void ExtractQuestions()
{
FileStream fs = new FileStream("questions.obj", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
this.questions = (List<Question>)bf.Deserialize(fs);
fs.Close();
}
/// <summary>
/// 提交試卷
/// </summary>
/// <returns></returns>
public int SubmitPaper()
{
int score = 0;
foreach (Question item in this.questions)
{
if (item.QAnswer.SeletedAnswer == string.Empty) continue;
if (item.QAnswer.RightAnaswer.Equals(item.QAnswer.SeletedAnswer))
score += 5;
}
return score;
}
}
}
FrmMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TeachDemo
{
public partial class FrmMain : Form
{
//試卷物件(如果我們後續擴充套件,可以包含若干試卷,這個地方應該設計成集合)
private Paper paper = new Paper();
//。。。。。。
private int questionIndex = 0;//當前試題的序號
public FrmMain()
{
InitializeComponent();
}
//抽取試題
private void btnStart_Click(object sender, EventArgs e)
{
paper.ExtractQuestions();
//隱藏抽取試題面板和按鈕
this.panelPaper.Visible = false;
this.btnStart.Visible = false;
//顯示第一題
ShowQuestion();
}
private void ShowQuestion()
{
this.lblTitle.Text = paper.Questions[this.questionIndex].Title;
this.lblA.Text = paper.Questions[this.questionIndex].OptionA;
this.lblB.Text = paper.Questions[this.questionIndex].OptionB;
this.lblC.Text = paper.Questions[this.questionIndex].OptionC;
this.lblD.Text = paper.Questions[this.questionIndex].OptionD;
}
//上一題
private void btnPre_Click(object sender, EventArgs e)
{
if (questionIndex == 0) return;
else
{
SaveAnswer();
this.questionIndex--;
ShowQuestion();
ResetAnswer();
}
}
//下一題
private void btnNext_Click(object sender, EventArgs e)
{
if (questionIndex == paper.Questions .Count -1) return;
else
{
SaveAnswer();
this.questionIndex++;
ShowQuestion();
ResetAnswer();
}
}
private void SaveAnswer()
{
string answer = string.Empty;
if (this.ckbA.Checked)
answer += "A";
if (this.ckbB.Checked)
answer += "B";
if (this.ckbC.Checked)
answer += "C";
if (this.ckbD.Checked)
answer += "D";
//找到當前試題物件,儲存當前使用者所選答案
paper.Questions[questionIndex].QAnswer.SeletedAnswer = answer;
}
//重置答案(在上一題、下一題選擇中,如果試題已經選過答案,則顯示以前選擇的答案)
private void ResetAnswer()
{
this.ckbA.Checked = paper.Questions[this.questionIndex].QAnswer.SeletedAnswer.Contains("A");
this.ckbB.Checked = paper.Questions[this.questionIndex].QAnswer.SeletedAnswer.Contains("B");
this.ckbC.Checked = paper.Questions[this.questionIndex].QAnswer.SeletedAnswer.Contains("C");
this.ckbD.Checked = paper.Questions[this.questionIndex].QAnswer.SeletedAnswer.Contains("D");
}
//提交試卷
private void btnSubmit_Click(object sender, EventArgs e)
{
SaveAnswer();//儲存最後一次使用者所選答案
//計算分數
int score = this.paper.SubmitPaper();
//顯示面板和當前成績
this.panelPaper.Visible = true;
this.lblInfo.Text = $"您當前成績為:{score}分!";
}
//關閉窗體
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}
}