一、记录开发过程中的时间记录日志。
PSP2.1 | Personal Software Process Stages | Time |
Planning | 计划 | 50小时 |
|
|
|
Development | 开发 |
|
· Analysis | · 需求分析 (包括学习新技术) | 一天+一晚 (32小时) |
· Design Spec | ·生成设计文档 | 2小时 |
·Design Review | ·设计复审(和同事审核设计文档) | 1.5小时 |
·Coding Standard | ·代码规范(为目前的开发制定合适的规范) | 1小时 |
·Design | ·具体设计 | 2小时 |
·Coding | ·具体编码 | 9.5小时 |
·Code Review | ·代码复审 | 1小时 |
·Test | ·测试(自我测试、修改代码、提交修改) | 1小时 |
Reporting | 报告 |
|
·Test Report | ·测试报告 | 1小时 |
·Size Measurement | ·计算工作量 | 1小时 |
·Postmortem & Precess Improvement Plan | ·事后总结,并提出过程改进计划 | 1小时 |
| 合计 | 53小时 |
二、程序设计思想
按Bean+Servlet+jsp模式(即MVC模式),首先数据库要建三个表,一个储存用户信息,一个储存题目,一个储存成绩。其余是Java部分,实现servlet,执行整数运算操作,混合运算操作。最后写jsp文件,实现网页界面显示。
package model;
public class FenShu {
private int denominator,numerator;
private boolean chengLi;
public FenShu(){}
public int getDenominator() {
return denominator;
}
public void setDenominator(int denominator) {
this.denominator = denominator;
}
public int getNumerator() {
return numerator;
}
public void setNumerator(int numerator) {
this.numerator = numerator;
}
public boolean isChengLi() {
return chengLi;
}
public void setChengLi(boolean chengLi) {
this.chengLi = chengLi;
}
//----在构造函数的时候就已经化简了
public FenShu(int numerator,int denominator)
{
this.numerator=numerator;
this.denominator=denominator;
if(denominator==0){
this.chengLi=false;
}
else
{
this.chengLi=true;
huaJian();
}
}
//化简
private void huaJian() {
int y = 1;
for (int i = numerator; i > 1; i--) {
if (numerator % i == 0 && denominator % i == 0) {
y = i;
break;
}
}
numerator /= y;
denominator /= y;
}
//---把字符串分割成分数,每次处理都化简
public FenShu(String str)
{
if(str == null)
{
this.chengLi = false;
}
int index = str.indexOf("/");
if (index == -1) {
this.numerator = Integer.parseInt(str);
this.denominator = 1;
this.chengLi = true;
} else {
this.denominator = Integer.parseInt(str.substring(index + 1));
if (this.denominator == 0) {
chengLi = false;
} else {
chengLi = true;
int zhengShu = str.indexOf("'");
if (zhengShu == -1) {
// 没有整数部分
this.numerator = Integer.parseInt(str.substring(0, index));
} else {
// 有整数部分
this.numerator = Integer.parseInt(str.substring(0, zhengShu)) * this.denominator
+ Integer.parseInt(str.substring(zhengShu + 1, index));
}
huaJian();
}
}
}
// 加
public FenShu add(FenShu b) {
FenShu c = null;
if (this.chengLi && b.isChengLi()) {
int nNumerator = this.numerator * b.getDenominator() + this.denominator * b.getNumerator();
int nDenominator = this.denominator * b.getDenominator();
c = new FenShu(nNumerator, nDenominator);
} else {
c = new FenShu();
c.setChengLi(false);
}
return c;
}
// 减
public FenShu subtract(FenShu b) {
FenShu c = null;
if (this.chengLi && b.isChengLi()) {
int nNumerator = this.numerator * b.getDenominator() - this.denominator * b.getNumerator();
int nDenominator = this.denominator * b.getDenominator();
c = new FenShu(nNumerator, nDenominator);
} else {
c = new FenShu();
c.setChengLi(false);
}
return c;
}
// 乘
public FenShu multiply(FenShu b) {
FenShu c = null;
if (this.chengLi && b.isChengLi()) {
int nNumerator = this.numerator * b.getNumerator();
int nDenominator = this.denominator * b.getDenominator();
c = new FenShu(nNumerator, nDenominator);
} else {
c = new FenShu();
c.setChengLi(false);
}
return c;
}
// 除
public FenShu divide(FenShu b) {
FenShu c = null;
if (this.chengLi && b.isChengLi() && (b.getNumerator() != 0)) {
int nNumerator = this.numerator * b.getDenominator();
int nDenominator = this.denominator * b.getNumerator();
c = new FenShu(nNumerator, nDenominator);
} else {
c = new FenShu();
c.setChengLi(false);
}
return c;
}
// 输出分数形式
public String toString() {
if (this.chengLi) {
if (numerator != 0) {
if (numerator % denominator == 0)
return "" + numerator / denominator;
else if (numerator > denominator) {
return (numerator / denominator) + "'" + (numerator % denominator) + "/" + denominator;
}
return numerator + "/" + denominator;
}
return "0";
}
return "ERROR";
}
}
package model;
import java.util.Stack;
//---存储试题,计算试题答案
public class Question {
private int id,userScore,length,shiJuanID;
private String tiMu,rightAnswer,userAnswer,userName,logicOrder;
public Question(){}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getShiJuanID() {
return shiJuanID;
}
public void setShiJuanID(int shiJuanID) {
this.shiJuanID = shiJuanID;
}
public int getUserScore() {
return userScore;
}
public void setUserScore(int userScore) {
this.userScore = userScore;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public String getTiMu() {
return tiMu;
}
public void setTiMu(String tiMu) {
this.tiMu = tiMu;
try {
expressCalculate();
} catch (MyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}// 计算答案
this.length = (tiMu.split(" ").length + 1) / 2;
}
public String getRightAnswer() {
return rightAnswer;
}
public void setRightAnswer(String rightAnswer) {
this.rightAnswer = rightAnswer;
}
public String getUserAnswer() {
return userAnswer;
}
public void setUserAnswer(String userAnswer) {
this.userAnswer = userAnswer;
}
public String getUsername() {
return userName;
}
public void setUsername(String username) {
this.userName = username;
}
public String getLogicOrder() {
return logicOrder;
}
public void setLogicOrder(String logicOrder) {
this.logicOrder = logicOrder;
}
// 表达式计算,参数为字符串类型的运算式
private void expressCalculate() throws MyException {
if(this.tiMu == null)
{
throw new MyException("试题无效");
}
String express = this.tiMu;
Stack<String> num = new Stack<String>();
Stack<String> symbolS = new Stack<String>();
symbolS.push("#");
express += "#";
String order = "";
char ch;
int i = 0;
ch = express.charAt(i);
while ((!symbolS.peek().equals("#")) || (ch != '#')) {// while循环开始
if (isNumber(ch)) {// 读到的不是空格,说明开始读运算数
String readNumStr = "";
while (true) {
readNumStr += ch;
ch = express.charAt(++i);
if (ch == ' ' || ch == '#' || ch == ')') {// 读到的是空格,或,说明运算数结束
break;
}
}
num.push(readNumStr);
} else if (ch == ' ') {
if ((i + 1) < express.length()) {// 未到字符串末尾
ch = express.charAt(++i);
}
}else {// 读到的是运算符
char compare = priorityCompare(symbolS.peek(), ch + "");
if (compare == '=') {// 若优先级相等,则说明ch是右括号,栈顶为左括号,此时将栈顶弹出,读取下一个字符
symbolS.pop();
ch = express.charAt(++i);
} else if (compare == '>') {// ch的优先级小于栈顶的优先级,要说明栈顶的运算符应该先计算,所以应弹栈运算
// 弹出两个运算数,弹出一个运算符
String bStr = num.pop();
String aStr = num.pop();
String symbolT = symbolS.pop();
// 计算该字表达式
String c = yunSuan(aStr, bStr, symbolT);
if (c.equals("ERROR")) {// 如果计算函数返回error则说明计算过程出现了负数,说明该运算式不符合要求,停止计算,计算结果为error,返回;
this.rightAnswer = "ERROR";
return;
} else {// 计算过程正常,则将计算结果压栈
order += aStr + "," + symbolT + "," + bStr + ",";// 将运算的子表达式加进运算顺序字符串中,操作数和操作符用逗号隔开
num.push(c);
}
} else if(compare == 'E')
{
this.rightAnswer = "ERROR";
return;
} else {// 说明ch优先级大于栈顶元素的优先级,则应将ch压栈,读取下一个运算符
symbolS.push(ch + "");
if ((i + 1) < express.length()) {
ch = express.charAt(++i);
}
}
}
}
this.rightAnswer = num.pop();
this.logicOrder = order;
}
// 判断ch是否为数字
private boolean isNumber(char ch) {
if (ch >= '0' && ch <= '9') {
return true;
}
return false;
}
/*
* 子表达式计算,参数为两个运算数的字符串形式,和一个运算符,也为字符串类型 返回计算结果的字符串形式
* 如果减法运算出现负数,或除数为0,或分数的分母为0则返回ERROR
*
*/
private String yunSuan(String aStr, String bStr, String symbol) throws MyException {
if(aStr == null || bStr == null || symbol == null)
{
throw new MyException("子表达式出现错误!");
}
int adivIndex = aStr.indexOf("/");
int bdivIndex = bStr.indexOf("/");
if ((adivIndex == -1) && (bdivIndex == -1)) {// a.b都是整数
int a = Integer.parseInt(aStr);
int b = Integer.parseInt(bStr);
switch (symbol.charAt(0)) {
case '+':
return a + b + "";
case '-': {
if (a < b) {
return "ERROR";
}
return a - b + "";
}
case '*': {
return a * b + "";
}
case '/': {
if (b == 0) {
return "ERROR";
} else if (a % b == 0) {
return a / b + "";
}
return new FenShu(a, b).toString();
}
default:
return "ERROR";
}
} else {// a,b中存在分数,则将a,b都当做分数进行运算
FenShu a = new FenShu(aStr);
FenShu b = new FenShu(bStr);
switch (symbol.charAt(0)) {
case '+':
return a.add(b).toString();
case '-':
{
FenShu c = a.subtract(b);
if(c.getNumerator() < 0)
{
return "ERROR";
}
return c.toString();
}
case '*':
return a.multiply(b).toString();
case '/':
return a.divide(b).toString();
default:
return "ERROR";
}
}
}
// 判断运算符优先级
private char priorityCompare(String a, String b) {
char[][] priority = { { '>', '>', '<', '<', '<', '>', '>' }, { '>', '>', '<', '<', '<', '>', '>' },
{ '>', '>', '>', '>', '<', '>', '>' }, { '>', '>', '>', '>', '<', '>', '>' },
{ '<', '<', '<', '<', '<', '=', '>' }, { '>', '>', '>', '>', ' ', '>', '>' },
{ '<', '<', '<', '<', '<', ' ', '=' } };
int a_index = index_symbol(a);
int b_index = index_symbol(b);
if(a_index == -1 || b_index == -1)
{
return 'E';
}
return priority[a_index][b_index];
}
// 获取运算符对应的下标
private int index_symbol(String a) {
String p = "+-*/()#";
// System.out.println("判断运算符对应的下标:" + a);
return p.indexOf(a);
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>主页</title>
<embed src="music/网络歌手-哆啦A梦背景音乐08.mp3" hidden=true autostart=true loop=false></embed>
<script src="js/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<style type="text/css">
#logo {
position: absolute;
left: 0px;
top: 17px;
width: 100%;
z-index: 100;
}
img {z-index: -1;}
#logo form h1 {
font-style: 楷体;
font-size: 39px;
color: #C30;
top:90px;}
#user{position:absolute;left:10%;top:20px;z-index:200;}
#login{position:absolute;left:91%;top:10px;z-index:200;}
#logout{position:absolute;left:95%;top:10px;z-index:200;}
#wrap {position:absolute;left:0px;top:0px;width:100%;height:100%}
#menu {text-align: center;}
#userInfo {display: none;text-align: center;}
#zuoTiInput {color: #C30;display: none;}
#selectInput {display: none;text-align: center;}
#show {display: none; height: 350px;overflow: auto;}
#right {position:absolute;left:50%;top:40px;height:80%;width:40%}
#left {
position: absolute;
width: 518px;
top: 116px;
left: 48px;
height: 13px;
}
#zuoTiFuZhu {text-align: center;}
#result {text-align: center;}
#user {
color: #C30;
font-style: 楷体;
}
#user {
font-weight: red;
}
#user {
color: #30;
}
#user {
color: #30;
}
</style>
</head>
<body>
<img src="images/3c15651a653b8fd52a4b313aa119d7a7.gif" width="100%" height="-100%">
<div id="logo">
<form>
<center>
<h1>欢迎来到啦啦啦数学乐园,快跟哆啦A梦一起学习吧</h1>
</center>
</form>
</div>
<!--
<div id="loginBT" align="right">
<a href="Login.html"><button>登录</button></a>
</div>
!-->
<div id="login">
<a href="Login.html"><button>登录</button></a>
</div>
<div id="logout">
<a href="Logoutac"><button>注销</button></a>
</div>
<div id="user">
嗨!${user.username}小朋友
</div>
<div id="wrap">
<div id="left">
<div id="loginMessage"></div>
<!--<div id="userInfo">
用户名:${user.username}
<!-- <div id="loginBT" align="right">
<a href="Logoutac"><button id="logout">注销</button></a>
</div> !-->
<div id="menu">
<button id="zuoTi">做题</button>
<button id="selectLiShiShiTi">查询历史试题</button>
</div>
<div id="zuoTiInput" >
<table align="center">
<tr><td>试题类型:</td><td><label>整数式<input type="radio" name="type" value="0" checked="checked"></label></td><td><label>真分数式<input type="radio" name="type" value="1"></label></td></tr>
<tr><td>有无乘除:</td><td><label>无<input type="radio" name="hasChengChu" value="0" checked="checked"></label></td><td><label>有<input type="radio" name="hasChengChu" value="1"></label></td></tr>
<tr><td>有无括号:</td><td><label>无<input type="radio" name="hasKuoHao" value="0" checked="checked"></label></td><td><label>有<input type="radio" name="hasKuoHao" value="1"></label></td></tr>
<tr><td>最大值:</td><td colspan="2"><input type="text" name="maxNum" value="10"><span id="maxNumInfo"></span></td></tr>
<tr><td>试题个数:</td><td colspan="2"><input type="text" name="num" value="10"><span id="numInfo"></span></td></tr>
<tr><td colspan="10"><input type="button" id="zuoTiInputTiJiao" value="我准备好啦,开始做题"></td></tr>
</table>
</div>
<div id="selectInput">
<select id="shiJuanList">
</select>
<select id="typeSelect">
<option value="all" selected="selected">
全部
</option>
<option value="right">
正确
</option>
<option value="wrong">
错误
</option>
</select>
<button id="selectShiJuan">
查询
</button>
</div>
<div id="show">
<table id="showShiTiTable" align="center" border="1">
</table>
<div id="zuoTiFuZhu"><button id="jiaoJuanBT">我做完了,交卷</button><span id="shengYuTime"></span></div>
<div id="result">
</div>
</div>
</div>
</div>
</body>
</html>