任務1源碼在Github的倉庫首頁連結位址:https://github.com/zhanghh2018/201571030135-201571030137
賬号 admin 密碼 123456
一、需求分析。
(1)由計算機從題庫檔案中随機選擇20道加減乘除混合算式,使用者輸入算式答案,程式檢查答案是否正确,每道題正确計5分,錯誤不計分,20道題測試結束後給出測試總分;
(2)題庫檔案可采用實驗二的方式自動生成,也可以手工編輯生成。
(3)程式為使用者提供三種進階四則運算練習功能選擇:百以内整數算式(必做)、帶括号算式、真分數算式練習;
(4)程式允許使用者進行多輪測試,提供使用者多輪測試分數柱狀圖,示例如下:
(5)程式記錄使用者答題結果,當程式退出再啟動的時候,可為使用者顯示最後一次測試的結果,并詢問使用者可否進行新一輪的測試;
(6)測試有計時功能,測試時動态顯示使用者開始答題後的消耗時間。
(7)程式人機互動界面是GUI界面(WEB頁面、APP頁面都可),界面支援中文簡體(必做)/中文繁體/英語,使用者可以進行語種選擇
二、軟體設計:
(1)流程圖
(2)類圖(ContentToTxt():将内容寫入檔案 、ContinuTest():詢問是否進行下一輪測試 、DTimeFrame():計時功能 、LoginIn():登入界面、 PrintChart():繪制分數圖、 ReadFile():一行一行讀檔案 、UI():答題界面)三、核心功能代碼展示:展示核心功能代碼。
核心代碼一:自動計時功能
import java.util.Date;
import java.awt.Dimension;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* @author zhanghh
* @time 2018.03.28
*/
public class DTimeFrame extends JFrame implements Runnable{
private JFrame frame;
private JPanel timePanel;
private JLabel timeLabel;
private JLabel displayArea;
private String DEFAULT_TIME_FORMAT = "ss";
private int ONE_SECOND = 1000;
public DTimeFrame(){
timePanel = new JPanel();
timeLabel = new JLabel("您目前用時: ");
displayArea = new JLabel();
timePanel.add(timeLabel);
timePanel.add(displayArea);
this.add(timePanel);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(new Dimension(200,100));
this.setBounds(900, 100, 200, 100);
}
public void run(){
int time=1;
while(true){
SimpleDateFormat dateFormatter = new SimpleDateFormat(DEFAULT_TIME_FORMAT);
displayArea.setText(time+"s");
try{
time++;
Thread.sleep(ONE_SECOND);
}catch(Exception e)
{
displayArea.setText("Error!!!");
}
}
}
}
核心代碼二:柱狀圖顯示
import java.awt.Font;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis3D;
import org.jfree.chart.axis.NumberAxis3D;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.TextAnchor;
/**
*
* @author zhanghh
* @time:2018.03.29
* @function:Display histogram
*
*/
public class PrintChart {
public static void print(int[] Score,int SubmissionsNum){
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
//添加資料
for(int i=1;i<=SubmissionsNum;i++){
dataset.addValue(Score[i],"分數"+i, "第"+i+"輪");
}
JFreeChart chart = ChartFactory.createBarChart3D("分數統計圖", //主标題的名稱
"測試次數", //X軸的标簽
"測試分數(分數)", //Y軸的标簽
dataset, //圖示顯示的資料集合
PlotOrientation.VERTICAL,//圖像的顯示形式(水準或者垂直)
true, //是否顯示子标題
true, //是否生成提示的标簽
true);//是否生成url連結
//處理圖形上的亂碼
//處理主标題的亂碼
chart.getTitle().setFont(new Font("宋體",Font.BOLD,18));
//處理子标題亂碼
chart.getLegend().setItemFont(new Font("宋體",Font.BOLD,15));
//擷取圖表區域對象
CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot();
//擷取X軸的對象
CategoryAxis3D categoryAxis3D = (CategoryAxis3D) categoryPlot.getDomainAxis();
//擷取Y軸的對象
NumberAxis3D numberAxis3D = (NumberAxis3D) categoryPlot.getRangeAxis();
//處理X軸上的亂碼
categoryAxis3D.setTickLabelFont(new Font("宋體",Font.BOLD,15));
//處理X軸外的亂碼
categoryAxis3D.setLabelFont(new Font("宋體",Font.BOLD,15));
//處理Y軸上的亂碼
numberAxis3D.setTickLabelFont(new Font("宋體",Font.BOLD,15));
//處理Y軸外的亂碼
numberAxis3D.setLabelFont(new Font("宋體",Font.BOLD,15));
//處理Y軸上顯示的刻度,以1作為1格
numberAxis3D.setAutoTickUnitSelection(false);
NumberTickUnit unit = new NumberTickUnit(100);
numberAxis3D.setTickUnit(unit);
//擷取繪圖區域對象
BarRenderer3D barRenderer3D = (BarRenderer3D) categoryPlot.getRenderer();
//設定柱形圖的寬度
barRenderer3D.setMaximumBarWidth(0.07);
//在圖形上顯示數字
barRenderer3D.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
barRenderer3D.setBaseItemLabelsVisible(true);
//設定
barRenderer3D.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1,TextAnchor.CENTER));
barRenderer3D.setBaseItemLabelFont(new Font("宋體",Font.BOLD,15));
//使用chartFrame對象顯示圖像
ChartFrame frame = new ChartFrame("測試分數統計", chart);
frame.setVisible(true);
frame.pack();
}
}
核心代碼三:測試成績以及詢問是否進行下一輪測試
import java.awt.event.*;
import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.*;
/*
* @auther:zhangkang
* @time:2018.03.27
* function:Continue to test
*/
public class ContinuTest extends JFrame implements ActionListener{
JFrame jf;
JPanel jp;
JButton jb1,jb2,jb3;
JLabel jlb1=null,jlb2=null,jlb3=null;
JPanel jp1,jp2=null;
DTimeFrame df2=new DTimeFrame();
Thread thread1=new Thread(df2);
public ContinuTest(int sum)
{
String s=sum+"";
jf = new JFrame();
jp = new JPanel();
jlb2=new JLabel("您本次測試成績為:");
if(sum>60&&sum<=100){
jlb3=new JLabel(s+"分 "+"你真的太棒啦!");
}
else{
jlb3=new JLabel(s+"分 "+"還要繼續努力哦!");
}
jlb1 = new JLabel("要不要再測試一次呢?");
jb1 = new JButton("當然要");
jb2 = new JButton("不要啦");
jb3=new JButton("檢視測試結果");
jp1=new JPanel();
jp2=new JPanel();
jp1.add(jlb2);
jp1.add(jlb3);
jp1.add(jlb1);
jp2.add(jb1);
jp2.add(jb2);
jp2.add(jb3);
this.add(jp1);
this.add(jp2);
this.add(jp);
jp1.setBounds(40,20,200,80);
jp2.setBounds(40,100,200,100);
jb1.addActionListener(this);
jb2.addActionListener(this);
jb3.addActionListener(this);
this.setVisible(true);
this.setResizable(false);
this.setTitle("國小生四則運算");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(500, 200, 300, 220);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "當然要") {
new UI();
this.dispose();
df2.setVisible(true);
thread1.start();
} else if (e.getActionCommand() == "不要啦") {
File f = new File("score.txt"); // 輸入要删除的檔案位置
if(f.exists())
f.delete();
df2.setVisible(false);
thread1.stop();
this.dispose();
}else if(e.getActionCommand() == "檢視測試結果"){
PrintChart pc=new PrintChart();
//讀檔案
ReadFile file = new ReadFile("score.txt");
String line = null;
int[] score=new int[500];
int titleNum=0;
while ((line = file.ReadLine()) != null) {
titleNum++;
score[titleNum]=Integer.parseInt(line);
}
pc.print(score,titleNum);
file.close();
}
}
}
四、程式運作:程式運作時每個功能界面截圖。
功能一:登入該系統界面
功能二:實作國小生四則運算(整數以及帶括号題目)随機出題,點選開始答題按鈕顯示題目。
功能三:實作國小生四則運算答案生成以及成績計算與顯示
功能四:實作成績測試柱狀圖
功能五:實作測試自動計時
功能六:實作詢問是否進行下一輪測試
五、描述結對的過程,提供兩人在讨論、細化和程式設計時的結對照片(非擺拍)。
六、結對作業的PSP。
PSP2.1 | 任務内容 | 計劃共完成需要的時間(min) | 實際完成需要的時間(min) |
Planning | 計劃 | 20 | 15 |
Estimate | 估計這個任務需要多少時間,并規劃大緻工作步驟 | ||
Development | 開發 | 470 | 500 |
Analysis | 需求分析 (包括學習新技術) | 10 | |
Design Spec | 生成設計文檔 | ||
Design Review | 設計複審 (和同僚稽核設計文檔) | 5 | |
Coding Standard | 代碼規範 (為目前的開發制定合适的規範) | 30 | |
Design | 具體設計 | 360 | 365 |
Coding | 具體編碼 | ||
Code Review | 代碼複審 | 25 | |
Test | 測試(自我測試,修改代碼,送出修改) | ||
Reporting | 報告 | 180 | 185 |
Test Report | 測試報告 | ||
Size Measurement | 計算工作量 | ||
Postmortem & Process Improvement Plan | 事後總結 ,并提出過程改進計劃 | 150 | 155 |
七、請給你的小夥伴一些點評
在合作的過程中是非常愉快的,她比較細心,學習能力非常強,喜歡追求完美,遇到難題的時候她總是可以想到解決的方法。當然在合作的工程中總會出現交流的問題,她是比較擅長交流的,在交流的工程中無形加強了我們合作解決問題的能力。同時非常感謝她在這個過程中對于我的幫助。
八、結對程式設計真的能夠帶來1+1>2的效果嗎?通過這次結對程式設計,請談談你的感受和體會。
在這次結對程式設計中,使我感到1+1>2的效果,兩個人在同時想解決一個問題方法的時候,就會出現當一個人想到一個方法時,同時也會激發另一個人的想法。這就會讓我們有更多解決這個問題的方法。同時這次實驗使我明白了合作非常的重要,隻有合作才會共赢。