第二次作业--前后端交互计算器
| 这个作业属于哪个课程 | 2301-计算机学院软件工程 |
|---|---|
| 这个作业要求在哪里 | 第二次作业--前后端交互计算器 |
| 这个作业的目标 | 实现前后端分离的计算器 |
| 其他参考文献 | ... |
目录
项目地址
功能展示
前后端分离计算器展示
PSP表格
| PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 45 | 50 |
| • Estimate | • 估计这个任务需要多少时间 | 45 | 50 |
| Development | 开发 | 975 | 1200 |
| • Analysis | • 需求分析 (包括学习新技术) | 300 | 300 |
| • Design Spec | • 生成设计文档 | 60 | 40 |
| • Design Review | • 设计复审 | 30 | 20 |
| • Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 10 |
| • Design | • 具体设计 | 90 | 90 |
| • Coding | • 具体编码 | 300 | 300 |
| • Code Review | • 代码复审 | 45 | 70 |
| • Test | • 测试(自我测试,修改代码,提交修改) | 120 | 370 |
| Reporting | 报告 | 100 | 140 |
| • Test Report | • 测试报告 | 30 | 60 |
| • Size Measurement | • 计算工作量 | 20 | 30 |
| • Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 50 | 50 |
| 合计 | 1120 | 1390 |
解题思路描述
1.理解前后端分离的概念
我对于前后端分离的理解是前端负责用户界面的设计和用户输入的获取,后端负责接收前端发送的计算请求,执行实际的数学运算,并将结果返回给前端,同时建立数据库存储数据。
2.技术选型
这次前端使用了HTML+CSS+JavaScript实现,后端选用Python的flask框架,数据库使用sqlite。
3.逻辑处理
一开始想复用上次写的Calculator类方法,后面发现成员函数跟tkinter库耦合度较高,将前端数据发送给后端的时候会生成一个GUI界面,返回值也经常格式错误。于是选择在JS中实现计算功能,通过fetch向后端数据库发送跨域请求进行数据通信,算是半分离吧。
设计与实现过程
功能结构图
前端
实现科学计算器、利率计算器和历史记录在前端的显示
<body>
<div class="container">
<div class="calculator">
<div class="calculator-title">科学计算器</div>
<div class="display" id="expression">0</div>
<div class="display" id="result">0</div>
<div class="button-grid">
<button class="button darkblue" onclick="onButtonClick('arcsin')">arctan</button>
<button class="button darkgreen" onclick="onButtonClick('sin')">sin</button>
<button class="button darkgreen" onclick="onButtonClick('cos')">cos</button>
<button class="button darkgreen" onclick="onButtonClick('tan')">tan</button>
<button class="button orange" onclick="onButtonClick('x!')">x!</button>
<button class="button orange" onclick="onButtonClick('1/x')">1/x</button>
<button class="button darkblue" onclick="onButtonClick('arcsin')">arcsin</button>
<button class="button lightgreen" onclick="onButtonClick('^')">^</button>
<button class="button lightgreen" onclick="onButtonClick('√')">√</button>
<button class="button lightgreen" onclick="onButtonClick('%')">%</button>
<button class="button grey" onclick="onButtonClick('(')">(</button>
<button class="button grey" onclick="onButtonClick(')')">)</button>
<button class="button darkblue" onclick="onButtonClick('arccos')">arccos</button>
<button class="button yellow" onclick="onButtonClick('7')">7</button>
<button class="button yellow" onclick="onButtonClick('8')">8</button>
<button class="button yellow" onclick="onButtonClick('9')">9</button>
<button class="button lightgreen" onclick="onButtonClick('÷')">÷</button>
<button class="button grey" onclick="onButtonClick('AC')">AC</button>
<button class="button darkblue" onclick="onButtonClick('lg')">lg</button>
<button class="button yellow" onclick="onButtonClick('4')">4</button>
<button class="button yellow" onclick="onButtonClick('5')">5</button>
<button class="button yellow" onclick="onButtonClick('6')">6</button>
<button class="button lightgreen" onclick="onButtonClick('*')">*</button>
<button class="button grey" onclick="gethistory()">ANS</button>
<button class="button darkblue" onclick="onButtonClick('ln')">ln</button>
<button class="button yellow" onclick="onButtonClick('1')">1</button>
<button class="button yellow" onclick="onButtonClick('2')">2</button>
<button class="button yellow" onclick="onButtonClick('3')">3</button>
<button class="button lightgreen" onclick="onButtonClick('-')">-</button>
<button class="button grey" onclick="onButtonClick('←')">←</button>
<button class="button darkblue" onclick="onButtonClick('π')">π</button>
<button class="button darkblue" onclick="onButtonClick('e')">e</button>
<button class="button yellow" onclick="onButtonClick('0')">0</button>
<button class="button yellow" onclick="onButtonClick('.')">.</button>
<button class="button lightgreen" onclick="onButtonClick('+')">+</button>
<button class="button lightblue" onclick="onButtonClick('=')">=</button>
</div>
</div>
<div class="interest-calculator">
<div class="calculator-title">利率计算器</div>
<div class="deposit-section">
<h2>存款</h2>
<label for="deposit-amount">存款金额:</label>
<input type="number" id="deposit-amount" name="deposit-amount" required><br>
<label for="deposit-year">存款时长(年):</label>
<input type="number" id="deposit-year" name="deposit-year" required><br>
<button class="button orange" onclick="calculateDepositInterest()">计算存款利息</button>
<div class="display" id="deposit-result">0</div>
</div>
<div class="loan-section">
<h2>贷款</h2>
<label for="loan-amount">贷款金额:</label>
<input type="number" id="loan-amount" name="loan-amount" required><br>
<label for="loan-year">贷款时长(年):</label>
<input type="number" id="loan-year" name="loan-year" required><br>
<button class="button orange" onclick="calculateLoanInterest()">计算贷款利息</button>
<div class="display" id="loan-result">0</div>
</div>
</div>
</div>
</body>

后端
实现数据库的存取
class historiy(db.Model):
__tablename__='historiy'
id=db.Column(db.Integer,primary_key=True,autoincrement=True)
jisuan=db.Column(db.String(300),nullable=True)
result=db.Column(db.String(300),nullable=True)
with app.app_context():
db.create_all()
@app.route('/',methods=['POST'])
def insert_result():
data=request.get_json()
try:
jisuan=data['jisuan']
result=data['result']
except KeyError:
return jsonify({'msg':'error','code':400},),400
historiy_list=historiy(jisuan=f"{jisuan}",result=result)
db.session.add(historiy_list)
db.session.commit()
return {'code':200}
@app.route('/select_data')
def selete_data():
data=historiy.query.filter_by().all()
result_data=[]
for i in data:
result_data.append({'id':i.id,'jisuan':eval(i.jisuan),'result':i.result})
return jsonify(data=result_data,code=200)
if __name__=='__main__':
app.run(debug=True)

心得体会和经验总结
在本次作业中过程中,我学习了如何使用HTML、CSS和JavaScript。学习了如何使用Flask框架构建后端服务,处理HTTP请求,如何使用Flask配置路由和编写处理请求的视图函数。对后端开发与数据库交互有了初步了解。弯路绕了不少,跨域吃了挺多苦头啊。
2679






