目录
1.从后端数据库中读取历史记录,按下ans键之后会将历史记录显示在前端的计算器中
6.建立一个XMLHttpRequest来进行后端数据库的连接
3.读取后端的数据库,并且使用select语句来选出按照时间排序前10条记录来返回到前端的界面来,使得按下ans之后能够返回记录
1.代码地址
前端:https://gitcode.net/W5217543/102101534
后端:https://gitcode.net/W5217543/mytest1
2.作业基本信息
这个作业属于哪个课程 | https://bbs.csdn.net/forums/ssynkqtd-05 |
---|---|
这个作业要求在哪里 | https://bbs.csdn.net/topics/617377308 |
这个作业的目标 | 开发一个前后端分离的计算器 |
其他参考文献 | 网上的各种资源 |
3.PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 15 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 15 |
Development | 开发 | 600 | 800 |
• Analysis | • 需求分析 (包括学习新技术) | 40 | 60 |
• Design Spec | • 生成设计文档 | 60 | 70 |
• Design Review | • 设计复审 | 5 | 15 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 15 |
• Design | • 具体设计 | 30 | 60 |
• Coding | • 具体编码 | 240 | 200 |
• Code Review | • 代码复审 | 60 | 30 |
• Test | • 测试(自我测试,修改代码,提交修改) | 20 | 20 |
Reporting | 报告 | 120 | 120 |
• Test Repor | • 测试报告 | 20 | 20 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 90 | 70 |
合计 | 1345 | 1520 |
4.界面展示
1.从后端数据库中读取历史记录,按下ans键之后会将历史记录显示在前端的计算器中
2.基础运算
运算
3.清零回退
回退清零
4.错误提示
error
5.解题思路分析
因为我上次使用的是visual studio2022自带的窗体应用设计来设计一个计算器,但是这次要制作一个前后端交互的计算器,所以我只能先自己写一个html+css+js的网页版计算器,然后我构建完前端的计算器之后,建立了一个XMLHttpRequest来进行前后端的连接,然后后端用pymysql+flask来进行远程连接数据库,整体实现前后端的交互
6.重要代码的展示
前端:
html的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计算器</title>
<link rel="stylesheet" href="./caculator.css">
</head>
<body>
<div class="calculator">
<div id="dots">
<div id="red-dot" class=dot></div>
<div id="yellow-dot" class="dot"></div>
<div id="green-dot" class="dot"></div>
</div>
<form name="form">
<input class="show" id="show" placeholder="0">
</form>
</div>
<main class="flex">
<aside-left class="flex">
<div id="top" class="flex">
<input class="button" type="button" value="CE" onclick="clean()">
<input class="button" type="button" value="C" onclick="back()">
<button class="button"onclick="display('(')">(</button>
<button class="button"onclick="display(')')">)</button>
<input class="button" type="button" value="sqrt" onclick="calculate('sqrt')">
<input class="button" type="button" value="ln" onclick="calculate('ln')">
<button class="button" onclick="switchToDeg()">deg</button>
<input class="button" type="button" value="x!" onclick="calculate('x!')">
</div>
<div id="num" class="flex" >
<input class="button" type="button" value="sin"onclick="calculate('sin')">
<input class="button" type="button" value="7" onclick="calculate(7)">
<input class="button" type="button" value="8" onclick="calculate(8)">
<input class="button" type="button" value="9" onclick="calculate(9)">
<input class="button" type="button" value="cos"onclick="calculate('cos')">
<input class="button" type="button" value="4" onclick="calculate(4)">
<input class="button" type="button" value="5" onclick="calculate(5)">
<input class="button" type="button" value="6" onclick="calculate(6)">
<input class="button" type="button" value="tan"onclick="calculate('tan')">
<input class="button" type="button" value="1" onclick="calculate(1)">
<input class="button" type="button" value="2" onclick="calculate(2)">
<input class="button" type="button" value="3" onclick="calculate(3)">
<button class="button" onclick="switchToRad()">rad</button>
<input class="button" type="button" value="0" onclick="calculate(0)">
<input class="button" type="button" value="." onclick="calculate('.')">
<input class="button" type="button" value="ans"onclick="gethistory()">
</div>
</aside-left>
<aside-right class="flex">
<input class="button" type="button" value="%"onclick="calculate('%')">
<input class="button" type="button" value="/"onclick="calculate('/')">
<input class="button" type="button" value="*"onclick="calculate('*')">
<input class="button" type="button" value="-"onclick="calculate('-')">
<input class="button" type="button" value="+"onclick="calculate('+')">
<input class="button" type="button" value="="onclick="calculate('=')">
</aside-right>
</main>
<script src="./caculator.js"></script>
</body>
</html>
css的代码:
.calculator{
height:80px;
width:250px;
background-color:#554f57;
}
#dots{
display:flex;
}
.button{
height:50px;
width:50px;
color:aliceblue;
font-size: large;
}
.show{
display: flex;
flex-direction: row-reverse;
height:50px;
width:244px;
font-size: 2em;
color:rgb(62, 114, 160);
margin-top: 7px;
margin-right: 2px;
}
.form{
color: rgb(200, 200, 34);
}
.flex{
display: flex;
}
.dot{
height:13px;
width:13px;
border-radius: 50%;
margin-left: 5px;
margin-top:5px;
}
#red-dot{
background-color: red;
}
#yellow-dot{
background-color: yellow;
}
#green-dot{
background-color:green;
}
/*#show{
}*/
#top .button{
background-color: #666067;
}
#num .button{
background-color: #7f7a80;
}
aside-right .button{
background-color: #f2a23c;
}
main{
width:250px;
height:300px;
flex-wrap:wrap
}
#num{
flex-wrap: wrap;
}
#top{
flex-wrap: wrap;
}
aside-right{
flex-direction: column;
}
aside-left{
width:200px;
flex-direction: row;
flex-wrap:wrap;
}
js代码的实现
1.实现清零和回退
function clean(){
document.form.show.value = ""
}
function back(){
var text = document.form.show.value
len = text.length
document.form.show.value = text.substring(0,text.length-1)
}
2.进行加减乘除,以及括号的实现
var arr=[]//存放历史记录
var jieguo=[]//用于存放结果与arr拼接的记录
function insert_num(num){
document.form.show.value += num
return document.form.show.value
}
function insert_op(op){
var text = document.form.show.value
var len = text.length
if(text[len-1]<'0'||text[len]>'9'){
document.form.show.value = text.substring(0,text.length-1)
}
document.form.show.value += op
}
function display(op){
var text = document.form.show.value
text+=op
document.form.show.value=text
}
3.实现运算以及运算时捕获异常
function equal(){
try{
var exp = document.form.show.value
if(exp){
document.form.show.value = eval(exp)
if(eval(exp)=="Infinity")
{
document.form.show.value="error";
}
var result=eval(exp)
var xhr= new XMLHttpRequest
xhr.open('POST','http://127.0.0.1:5000/get_history',true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
const data = {
calculation: exp,
result: result
};
xhr.send(JSON.stringify(data));
}
}
catch{
document.form.show.value = "error"
}
}
4.运算拓展功能:三角函数,ln,阶乘,开方等
function sin(){
equal()
var angle = document.form.show.value
var view = Math.sin(angle/180*Math.PI)
view =view.toFixed(2)
clean()
document.form.show.value += view
}
function cos(){
equal()
var angle = document.form.show.value
var view = Math.cos(angle/180*Math.PI)
view =view.toFixed(2)
clean()
document.form.show.value += view
}
function tan(){
equal()
var angle = document.form.show.value
var view = Math.tan(angle/180*Math.PI)
view =view.toFixed(2)
clean()
document.form.show.value += view
}
function ln(){
equal()
document.form.show.value = Math.log10(document.form.show.value)
}
function sqrt(){
equal()
document.form.show.value = Math.sqrt(document.form.show.value)
}
function factorial(n) {
let result = 1
for(let i = 1; i <= n; i++) {
result *= i
}
return result
}
function jiecheng(){
equal()
document.form.show.value = factorial(document.form.show.value)
}
5.在显示框上面显示出运算式的值
function calculate(str){
if(str>='0'&&str<='9') insert_num(str)
if(str=='+'||str=='*'||str=='/'||str=='-'||str=='.'||str=='%') insert_op(str)
if(str=='sin') sin()
if(str=='cos') cos()
if(str=='tan') tan()
if(str=='ln') ln()
if(str=='x!') jiecheng()
if(str=='=') equal()
if(str=='AC') clean()
if(str=='sqrt') sqrt()
if(str=='BACK') back()
return document.form.show.value
}
6.建立一个XMLHttpRequest来进行后端数据库的连接
function gethistory(){
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:5000/get_calculation', true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
Data = JSON.parse(xhr.responseText);
array = Data['data'];
let str="";
for(let i=0;i<array.length;i++){
str +=array[i][0]+" = "+array[i][1]+"\n";
}
document.form.show.value=str
}
}
};
xhr.send();
}
后端:
1.采用pymysql和flask插件进行对前端的连接
from flask import Flask, request, jsonify
import pymysql
from flask_cors import CORS
import datetime
con = pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123456',
database='calculate'
)
app = Flask(__name__)
CORS(app)
cursor = con.cursor()
2.读取前端的记录,并且把他们存放在数据库里面
@app.route('/get_history', methods=['POST'])
def get_history():
data = request.get_json()
calculation = data.get('calculation')
result = data.get('result')
time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
data = (time, calculation, result)
insert = "INSERT INTO app1_calculation VALUES (%s, %s, %s)"
cursor.execute(insert, data)
con.commit()
response_message = "ok"
return jsonify({"message": response_message})
3.读取后端的数据库,并且使用select语句来选出按照时间排序前10条记录来返回到前端的界面来,使得按下ans之后能够返回记录
@app.route('/get_calculation', methods=['GET'])
def get_calculation():
cursor.execute("SELECT calculation, result FROM app1_calculation ORDER BY time DESC LIMIT 10")
data = cursor.fetchall()
return jsonify({"data": data})
7.心得体会
本次我完成了一个前后端交互的计算器,相比第一次作业来说难度感觉提升了很大,因为我要从头开始用html+css+js来写一个前端的计算器,时间会花的比别人更多,而且一开始的时候没有方向,不知道该用什么框架来实现前后端数据库的连接,后面还是看到了多位大佬的博客才有了用pymysql+flask实现的方向。这次项目也花了我很长的时间,大部分的时间都用来学习和开发当中,对我来说收获挺大的,也算是学习了前后端的开发,同时也知道自己的不足,知道要学的东西还有很多,以后也会更加努力学习软件开发的相关知识