1. 程式人生 > >【小專案】簡易計算機等級考試模擬練習

【小專案】簡易計算機等級考試模擬練習

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();
        }
    }
}