基於GUI的四則運算
李志強 201421123028 連永剛 201421123014 林方言 201421123023
coding 地址 https://git.coding.net/lizhiqiang0x01/GUI-sizeyunsuan.git
一、簡述題目要求:
1、除了整數之外,還要支持真分數的四則運算,真分數的運算,例如:1/6 + 1/8 = 7/24
2、運算符為 +, −, ×, ÷
3、並且要求能處理用戶的輸入,並判斷錯誤,打分統計正確率
4、要求能處理用戶輸入的真分數,如 1/2, 5/12 等
5、程序基於GUI 界面
6、記錄用戶的對錯總數,程序退出再啟動的時候,能把以前的對錯數量保存並在此基礎上增量計算
7、有計時功能,能顯示用戶開始答題后的消耗時間
8、界面支持中文簡體/中文繁體/英文,用戶選擇一種
二、實現步驟:
a、需求分析
寫一段程序可以生成GUI界面,在GUI 界面上可以進行中文簡體/中文繁體/英文切換,在做題過程中需要計時並顯示用戶答題時間,在用戶輸入答案時,需要對輸入的參數進行過濾,當用戶輸入非法文字,例如:“#,@,我不知道”等會被檢測到,並給予相應的錯誤提示,在用戶結束答題后,需要顯示用戶答題后的各種參數並實現可以查看錯題庫功能。
b、功能設計
邏輯結構圖
基本功能
計時功能,切換語言功能,兼容獲取分式和整數參數功能,生成真分式題目以及最簡分式功能,運算功能,校驗答案功能。
擴展功能
過濾非法字符功能,題目進度功能,生成用戶錯題庫功能
高級功能
多級運算功能
c、設計實現
為滿足功能需求,下面主要寫了八個函數:
public void add(); //加法運算 public void sub(); //減法運算 public void mul(); //乘法運算 public void div(); //除法運算 public void ran(); //生成題目 public void check(); //校驗答案 public string StringClear(string ai) //過濾非法字符 public void thread() //計時功能
d、代碼說明[source file]
- 生成窗體功能

private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.button1 = new System.Windows.Forms.Button(); this.textBox2 = new System.Windows.Forms.TextBox(); this.radioButton1 = new System.Windows.Forms.RadioButton(); this.radioButton2 = new System.Windows.Forms.RadioButton(); this.radioButton3 = new System.Windows.Forms.RadioButton(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(154, 81); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(143, 12); this.label1.TabIndex = 0; this.label1.Text = "請輸入題目數(滿分100)"; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(25, 201); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(35, 12); this.label3.TabIndex = 2; this.label3.Text = "v1.00"; // // button1 // this.button1.Location = new System.Drawing.Point(178, 166); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 3; this.button1.Text = "開始做題"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // textBox2 // this.textBox2.Location = new System.Drawing.Point(165, 118); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(100, 21); this.textBox2.TabIndex = 5; // // radioButton1 // this.radioButton1.AutoSize = true; this.radioButton1.CheckAlign = System.Drawing.ContentAlignment.TopLeft; this.radioButton1.Checked = true; this.radioButton1.Location = new System.Drawing.Point(13, 13); this.radioButton1.Name = "radioButton1"; this.radioButton1.Size = new System.Drawing.Size(47, 16); this.radioButton1.TabIndex = 6; this.radioButton1.TabStop = true; this.radioButton1.Text = "中文"; this.radioButton1.UseVisualStyleBackColor = true; this.radioButton1.CheckedChanged += new System.EventHandler(this.radioButton1_CheckedChanged); // // radioButton2 // this.radioButton2.AutoSize = true; this.radioButton2.Location = new System.Drawing.Point(13, 36); this.radioButton2.Name = "radioButton2"; this.radioButton2.Size = new System.Drawing.Size(65, 16); this.radioButton2.TabIndex = 7; this.radioButton2.TabStop = true; this.radioButton2.Text = "English"; this.radioButton2.UseVisualStyleBackColor = true; this.radioButton2.CheckedChanged += new System.EventHandler(this.radioButton2_CheckedChanged); // // radioButton3 // this.radioButton3.AutoSize = true; this.radioButton3.Location = new System.Drawing.Point(13, 59); this.radioButton3.Name = "radioButton3"; this.radioButton3.Size = new System.Drawing.Size(71, 16); this.radioButton3.TabIndex = 8; this.radioButton3.Text = "中文繁體"; this.radioButton3.UseVisualStyleBackColor = true; this.radioButton3.CheckedChanged += new System.EventHandler(this.radioButton3_CheckedChanged); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(443, 255); this.Controls.Add(this.radioButton3); this.Controls.Add(this.radioButton2); this.Controls.Add(this.radioButton1); this.Controls.Add(this.textBox2); this.Controls.Add(this.button1); this.Controls.Add(this.label3); this.Controls.Add(this.label1); this.Name = "Form1"; this.Text = "中文"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); this.PerformLayout(); }
- 計時功能
public void thread() //創建線程實現計時功能 { int sec = 0; int min = 0; int hour = 0; while (true) { sec++; if (sec >=60) { min++; sec =0; if (min >=60) { hour++; min =0; } } s.label10.Text = hour + ":" + min + ":" + sec; Thread.Sleep(1000); if (s.next == 1) { break; } } } ThreadStart th = new ThreadStart(thread); Console.WriteLine("In Main: Creating the Child thread"); Thread the = new Thread(th); the.Start();
- 切換語言功能
private void radioButton2_CheckedChanged(object sender, EventArgs e) //切換成英文 { this.label1.Text = "Please enter the subject number"; this.button1.Text = "start"; s.label8.Text = "Time"; s.label1.Text = "Schedule"; s.button1.Text = "NEXT"; this.Text = "English"; s.Text = "English"; } private void radioButton1_CheckedChanged(object sender, EventArgs e) //切換成中文簡體 { this.label1.Text = "請輸入題目數(滿分100)"; this.button1.Text = "開始做題"; s.label8.Text = "時間"; s.label1.Text = "題目進度"; s.button1.Text = "下一題"; this.Text = "中文"; s.Text = "中文"; } private void radioButton3_CheckedChanged(object sender, EventArgs e) //切換成中文繁體 { this.label1.Text = "請輸入題目數(滿分100)"; this.button1.Text = "開始做題"; s.label8.Text = "時間"; s.label1.Text = "題目進度"; s.button1.Text = "下壹題"; this.Text = "中文繁體"; s.Text = "中文繁體"; }
- 過濾非法字符功能
public string StringClear(string ai) { bool temp = bolnum(ai); if (temp == true) { return ai; } else { cro = 1; if (this.Text == "中文") { MessageBox.Show("輸入錯誤,請正確輸入字符!例如:12,1/2"); } else if (this.Text == "English") { MessageBox.Show("Input error, please correct input character! For example:12,1/2"); } else { MessageBox.Show("輸入錯誤,請正確輸入字符!例如:12,1/2"); } this.textBox1.Text = ""; return ""; } } public bool bolnum(string temp) //若為非法字符,返回false { for (int i = 0; i < temp.Length; i++) { byte tempByte = Convert.ToByte(temp[i]); if ((tempByte > 46) && (tempByte < 58)) return true; } return false; }
- 生成用戶錯題庫功能
FileStream f = new FileStream("cuoti.txt", FileMode.Append, FileAccess.Write); StreamWriter fi = new StreamWriter(f); fs = "你的答案:" + this.label2.Text + this.label4.Text + this.label5.Text + this.label9.Text + ai + " 正確答案:" + au + " " + "\r\n"; fi.Write(fs); fi.Flush(); fi.Close(); f.Close();
- 多級運算功能
public void select() { int l1, l2; Random ra = new Random(); int x = ra.Next(0, 4); switch (x) //產生一級運算 { case 0: add(); break; case 1: sub(); break; case 2: mul(); break; case 3: div(); break; } int y = ra.Next(0, 5); switch (y) //產生二級運算 { case 0: if (q6 == 1) this.label12.Text = q5.ToString(); else this.label12.Text = q5 + "/" + q6; this.label13.Text = "+"; this.label14.Text = ""; this.label15.Text = ""; l1 = r1;l2=r2; r1 = l1 * q6 + l2 * q5; r2 = l2 * q6; break; case 1: if (q6 == 1) this.label12.Text = q5.ToString(); else this.label12.Text = q5 + "/" + q6; this.label13.Text = "-"; this.label14.Text = "("; this.label15.Text = ")"; l1 = r1;l2=r2; r1 = l1 * q5 - l2 * q6; r2 = l2 * q6; break; case 2: if (q6 == 1) this.label12.Text = q5.ToString(); else this.label12.Text = q5 + "/" + q6; this.label13.Text = "×"; this.label14.Text = "("; this.label15.Text = ")"; l1 = r1;l2=r2; r1 = l1 * q5; r2 = l2 * q6; break; case 3: if (q6 == 1) this.label12.Text = q5.ToString(); else this.label12.Text = q5 + "/" + q6; this.label13.Text = "÷"; this.label14.Text = "("; this.label15.Text = ")"; l1 = r1;l2=r2; this.r1 = this.q5 * l2; this.r2 = this.q6 * l1; break; case 4: this.label12.Text = ""; this.label13.Text = ""; this.label14.Text = ""; this.label15.Text = ""; break; } }
- 校驗答案功能
public void check() { int w = 1; for (int i = 2; i < 100; i++) { if (r1 % i == 0 && r2 % i == 0) { w = i; } } r1 = r1 / w; r2 = r2 / w; ai = StringClear(this.textBox1.Text); if (cro != 1) { if (r2 == 1) au = this.r1.ToString(); if (r2 != 1) au = r1 + "/" + r2; if (ai == au) { n1++; } if (ai != au) { FileStream f = new FileStream("cuoti.txt", FileMode.Append, FileAccess.Write); StreamWriter fi = new StreamWriter(f); fs = "你的答案:" + this.label2.Text + this.label4.Text + this.label5.Text + this.label9.Text + ai + " 正確答案:" + au + " " + "\r\n"; fi.Write(fs); fi.Flush(); fi.Close(); f.Close(); if (this.Text == "中文") { MessageBox.Show("回答錯誤!正確答案:" + au); } else if (this.Text == "English") { MessageBox.Show("Wrong answer!The correct answer:" + au); } else { MessageBox.Show("回答錯誤!正確答案:" + au); } } } }
e、測試運行
1.首頁(中文)及過濾錯誤字符:
2.檢查答案,得出成績報告單:
3.查看錯題及其他語言的部分截圖:
4、多級運算高級功能
GIF過程瀏覽
三、PSP
PSP2.1 | Personal Software Process Stages | Estimated time(h) | actual time(h) |
Planning | 計划 | 1 | 1.5 |
· Estimate | 估計這個任務需要多少時間 | 24 | 40 |
Development | 開發 | 24 | 34 |
· Analysis | 需求分析 (包括學習新技術) | 1 | 1.2 |
· Design Spec | 生成設計文檔 | 7 | 10 |
· Design Review | 設計復審 | 0.5 | 0.5 |
· Coding Standard | 代碼規范 | 0.5 | 0.8 |
· Design | 具體設計 | 1.5 | 1.5 |
· Coding | 具體編碼 | 20 | 30 |
· Code Review | 代碼復審 | 10 | 15 |
· Test | 測試(自我測試,修改代碼,提交修改) | 1 | 3 |
Reporting | 報告 | 20 | 25 |
· | 測試報告 | 1 | 1.5 |
· | 計算工作量 | 0.5 | 1 |
· | 並提出過程改進計划 | 2 | 4 |
四、總結
先來一片面包:隊友之前作業都是用c++寫的,都對c#比較熟悉,代碼以我的為基礎進行GUI轉換。
再把肉放上:首先我們設計了一套流程圖,根據流程圖具體分析問題,發現問題,解決問題,問題的解決方法都在博客上做了總結,我們共同編寫生成題目功能,實現動態計時功能,錯題庫功能,語言切換功能,字符過濾功能,對話框的彈出功能,在代碼復審期間我們做了加減乘除運算優化升級和代碼的重構,代碼格式的規范,碰到難點,便和隊友lianyg(連永剛)、Dialect(林方言)探討,共同解決,連永剛同學缺點是做事慢了一點,優點持之以恆,最終找到解決方法,林方言同學缺點是對代碼語法不是太熟悉,不過他確實挺好問,理解能力好。
然后再來一片面包:經過了兩天的共同奮斗,從剛開始對GUI的一無所知,到將四個GUI窗體靈活調用,最終能實現所有功能,並讓界面最大程度簡潔化,提高界面整潔度。
由於要用C#做成GUI界面,並且內容新加了其他功能,下面總結一下這次我們所遇到難點
問題一:如何產生GUI界面
解決該問提主要是借助於VS2013平台可自動生成窗體控件,然后閱讀自動生成的源碼,從中學習並加以利用。
問題二:計時功能
由於要計時功能,使時間在窗體上動態變化,這就意味這要使用線程,從而可以保證主線程可以繼續監聽消息。
問題三:過濾功能
在用戶輸入答案,如果輸入非法字符就會被過濾並得到提示,在這里主要是將用戶輸入的值轉化成 char ,然后將其與 ASCII 值進行對比,從而實現此功能。
We are a team and we work as a team!