作业基本信息…
这个作业属于哪个课程 | https://bbs.csdn.net/forums/ssynkqtd-05 |
---|---|
这个作业要求在哪里 | https://bbs.csdn.net/topics/617377308 |
这个作业的目标 | 实现一个前后端交互计算器 |
其他参考文献 | … |
git仓库链接
PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 1460 | 1805 |
• Analysis | • 需求分析 (包括学习新技术) | 450 | 600 |
• Design Spec | • 生成设计文档 | 30 | 45 |
• Design Review | • 设计复审 | 30 | 30 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
• Design | • 具体设计 | 60 | 90 |
• Coding | • 具体编码 | 750 | 800 |
• Code Review | • 代码复审 | 60 | 100 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 120 |
Reporting | 报告 | 55 | 65 |
• Test Repor | • 测试报告 | 30 | 30 |
• Size Measurement | • 计算工作量 | 10 | 15 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 15 | 20 |
合计 | 1545 | 1900 |
成品展示
-
加减乘除、取余、括号运算
-
清零回退
- 错误提示
- 科学计算器(计算根号、三角函数、log)
- 读取历史记录(能用ans按钮返回上一个计算结果,并且查看历史记录读取最后十个字符串式子和对应的计算结果)
- 一开始以为能完成利率计算器就先写了个页面出来,然后发现实在来不及,后面再慢慢完善吧。。
设计实现过程
-
前端使用html+javascript+css设计计算器,用XMLHttpRequest发送请求,实现数据交换。
-
后端使用Python的Flask框架,以及使用Python的pymysql连接数据库。
代码说明
- 前端我写了一个函数test()来获取button按钮对象
function test(btn){
//获取button按钮对象
var num = btn.value;
if(num>='0'&&num<='9'){
document.getElementById("input").value+=num;
return document.getElementById("input").value;
}
if(num=='ans') get();
if(num=='tax'){
document.querySelector(".base-calculator").style.display = "none";
document.querySelector(".tax-calculator").style.display = "block";
}
if(num=='base'){
document.querySelector(".tax-calculator").style.display = "none";
document.querySelector(".base-calculator").style.display = "block";
}
if(num=='π'){
document.getElementById("input").value+=Math.PI;
return document.getElementById("input").value;
}
if(num=='e'){
document.getElementById("input").value+=Math.E;
return document.getElementById("input").value;
}
if(num=='C') document.getElementById("input").value="";
if(num=='+'||num=='-'||num=='*'||num=='/'||num=='.'||num=='%') op(num);
if(num=='('||num==')') kuohao(num);
if(num=='del') del();
if(num=='sin') sin();
if(num=='cos') cos();
if(num=='tan') tan();
if(num=='√') sqrt();
if(num=='ln') ln();
if(num=='=') res();
return document.getElementById("input").value;
}
- 下面是一些计算功能实现的函数
//括号
function kuohao(num){
document.getElementById("input").value+=num;
return document.getElementById("input").value;
}
//删除一位
function del(){
var text = document.getElementById("input").value;
len = text.length
document.getElementById("input").value = text.substring(0,text.length-1)
}
function ln(){
var exp='sin';
exp+=document.getElementById("input").value;
res=Math.log(document.getElementById("input").value);
document.getElementById("input").value="";
document.getElementById("input").value += res;
post(exp,res);
}
//加减乘除
function op(num){
var text = document.getElementById("input").value;
var len = text.length;
if(text[len-1]=='+'||text[len-1]=='-'||text[len-1]=='*'||text[len-1]=='/'||text[len-1]=='.'||text[len-1]=='%'){
document.getElementById("input").value = text.substring(0,text.length-1);
}
document.getElementById("input").value += num;
}
//三角函数
function sin()
{
var exp='sin';
exp+=document.getElementById("input").value;
var res = Math.sin(document.getElementById("input").value/180*Math.PI);
res =res.toFixed(5);
document.getElementById("input").value="";
document.getElementById("input").value += res;
post(exp,res);
}
function cos()
{
var exp='cos';
exp+=document.getElementById("input").value;
var res = Math.cos(document.getElementById("input").value/180*Math.PI);
res =res.toFixed(5);
document.getElementById("input").value="";
document.getElementById("input").value += res;
post(exp,res);
}
function tan()
{
var exp='tan';
exp+=document.getElementById("input").value;
var res = Math.tan(document.getElementById("input").value/180*Math.PI);
res =res.toFixed(5);
document.getElementById("input").value="";
document.getElementById("input").value += res;
post(exp,res);
}
//开方
function sqrt()
{
var exp='√';
exp+=document.getElementById("input").value;
res=Math.sqrt(document.getElementById("input").value);
document.getElementById("input").value="";
document.getElementById("input").value += res;
post(exp,res);
}
- 获取结果的函数
function res(){
try{
var exp = document.getElementById("input").value;
if(exp){
if(exp=='Infinity'||exp=='-Infinity') document.getElementById("input").value='error';
else document.getElementById("input").value = eval(exp);
}
}
catch{
document.getElementById("input").value = "error"
}
result=document.getElementById("input").value;
post(exp,result);
}
- 前端发出请求进行连接的代码
function post(calculation,result){
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:5000/post_history', true);
xhr.setRequestHeader('Content-type', 'application/json');
const data = {
calculation: calculation,
result: result
};
xhr.send(JSON.stringify(data));
}
function get(){
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:5000/history', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
Data = JSON.parse(xhr.responseText);
array = Data['data'];
let string="";
for(let i=0;i<array.length;i++){
string +=array[i][0]+" = "+array[i][1]+"\n";
}
document.getElementById("input").value = string;
}
};
xhr.send();
}
- 前端css部分
body {
align-items: center;
background-image: linear-gradient(236deg, #74ebd5, #acb6e5);
display: flex;
height: 100vh;
justify-content: center;
}
.base-calculator{
border: solid 1px;
border-radius: 20px;
width: 350px;
height: 470px;
text-align: center;
margin: auto;/*设置居中*/
margin-top: 50x;
background-color:white
}
.tax-calculator{
border: solid 1px;
border-radius: 20px;
width: 350px;
height: 470px;
text-align: center;
margin: auto;/*设置居中*/
margin-top: 50x;
background-color:white
}
.btn {
outline: none;
cursor: pointer;
font-size: 18px;
font-weight: 600;
height: 50px;
margin: 5px 0px 5px 10px;
width: 50px;
border-radius: 15px;
color:#e667af;
}
.btn:hover {
background-color:rgb(238, 212, 229);
}
#input {
background-color:rgb(238, 212, 229);
font-size: 20px;
height: 46px;
text-align: right;
width: 290px;
border-radius: 10px;
padding-right: 10px;
margin: 22px 5px;
overflow:auto;
}
.choicebtn{
outline: none;
cursor: pointer;
font-size: 18px;
font-weight: 600;
height: 40px;
margin: 10px 0px 5px 10px;
width: 200px;
border-radius: 15px;
color:#e667af;
}
.inputtxt{
background-color:rgb(238, 212, 229);
font-size: 20px;
height: 23px;
text-align: left;
width: 200px;
border-radius: 5px;
padding-right: 10px;
margin: 10px 5px;
}
.change{
outline: none;
cursor: pointer;
font-size: 18px;
font-weight: 600;
height: 50px;
margin: 10px 0px 5px 10px;
width: 80px;
border-radius: 15px;
color:#e667af;
}
.title{
font-size:30px;
color:#690866;
margin:20px;
}
- 后端代码(因为没有实现利率计算器所以很短)
from flask import Flask, jsonify, request
import pymysql
from datetime import datetime
from flask_cors import CORS
#连接mysql
con = pymysql.connect(
host='localhost',
port=3306,
user='root',
password='20030914',
database='history'
)
app = Flask(__name__)
CORS(app)
cursor = con.cursor()
@app.route("/post_history",methods=['POST'])
def post_history():
data = request.get_json()
calculation = data.get('calculation')
result = data.get('result')
time = datetime.now()
data = (time, calculation, result)
sql = "INSERT INTO basehistory VALUES (%s, %s, %s)"
cursor.execute(sql, data)
con.commit()
@app.route('/history', methods=['GET'])
def history():
sql="SELECT calculation, result FROM basehistory ORDER BY time DESC LIMIT 10"
cursor.execute(sql)
data = cursor.fetchall()
return jsonify({"data": data})
if __name__ == '__main__':
app.run()
心路历程和收获
在此之前完全没有相关的知识储备,甚至由于上次作业是用windows窗体应用写的,无奈之下从头学习了html+javascript+css后重新写了一个计算器。关于后端的学习网上也是推荐了各式各样的框架,最后想着Python可能比较简单就选择了Python的Flask框架,然后还学习了MySQL的使用方法,花了大量的时间。在具体编码之前的各种环境配置也是十分繁琐,总之是非常痛苦的一次体验。最终的效果也差了一点,没能实现利率计算器,代码可能也不是很规范,后面也会找时间再继续完善。
同时这也是一次十分宝贵的经历,通过不断的学习和探索,我对前后端的知识都有了更深的了解,对后面的团队作业以及今后的学习工作应该都会有一定的帮助,希望以后也能时刻保持这种学习新知识的干劲。