作业基本信息

这个作业属于哪个课程 < 2301-计算机学院-软件工程>
这个作业要求在哪里 < 软工实践第二次作业>
这个作业的目标 < 实现一个前后端分离的计算器,用数据库储存相关数据 >
其他参考文献 < python flask > < ajax>

Gitcode项目地址

前端

后端

PSP表格

PSP Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 80
• Estimate • 估计这个任务需要多少时间 20 25
Development 开发 700 1000
• Analysis • 需求分析 (包括学习新技术) 800 1000
• Design Spec • 生成设计文档 60 50
• Design Review • 设计复审 50 60
• Coding Standard • 代码规范 (为目前的开发制定合适的规范) 30 30
• Design • 具体设计 100 150
• Coding • 具体编码 400 450
• Code Review • 代码复审 60 60
• Test • 测试(自我测试,修改代码,提交修改) 120 200
Reporting 报告 120 100
• Test Report • 测试报告 50 60
• Size Measurement • 计算工作量 30 30
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 80 90
合计 2800 3385

设计实现过程

首页:菜单选择计算器
子页:1.基本计算器 2.利率计算器

成品展示

界面展示

菜单:

在这里插入图片描述

基础计算器

功能一:加减乘除、取余、括号运算

完成基础+,-,* ,/,%,()运算,并将输入的字符串和结果存储到后端数据库中
在这里插入图片描述

功能二:清零回退

实现字符串输入的清零和回退功能

在这里插入图片描述

功能三:错误提示

非法输入提示,例如:0不能作为除数,括号不匹配,语法错误等

在这里插入图片描述

功能四:读取历史记录

ans按钮返回上一个计算结果
查看历史记录按钮,输出对应的计算式及结果
数据皆从后端的数据库中读取

在这里插入图片描述

附加功能一:科学计算器

计算三角函数、lg、ln

在这里插入图片描述

附加功能二:页面原型设计

在这里插入图片描述

利率计算器功能

界面展示

在这里插入图片描述

功能一:计算存款、贷款利息

数据库中存储利率表(可随时修改利率),对应利率如下图所示
用两个输入框分别读取前端的输入数据,1.输入存款/贷款金额,2.存/贷时长(单位:年)。
从后端获取利率表,输出计算后对应的存/贷利息。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

功能二:前端修改存贷款利率

在前端页面输入被修改的信息,数据库中表的数值相应修改

在这里插入图片描述

解题思路描述

问题1:实现前端与后端交互

前端使用html、css、JavaScript,vue设计界面及效果展示;使用ajax进行数据传输
后端使用python flask jinja2进行数据传输

问题2:实现后端与数据库连接

后端使用python flask ORM模型的CRUD进行数据库的增删改查
数据库使用mysq进行数据保存

问题3:Python实现基础计算器

创建类Calculate,并定义Add(),Result(),Clear(),back()四个函数进行数据处理
创建类Cal_History,连接数据库

问题4:Python实现利率计算器

创建类deposit和类loan,连接数据库

关键代码展示

html设计界面内容

以基本计算器显示运算式和计算器第一行为例
点击每个按键触发一个函数,执行运算操作

<div class="calculator">
<div class="display" id="display1">0</div>
<div class="display" id="display2"></div>
<p></p>
<table border="0px" align="center">
     <tr >
          <td><button onclick="Add('sin')">sin</button></td>
          <td><button onclick="onehistory()" >ans</button></td>
          <td><button onclick="Add('(')">(</button></td>
          <td><button onclick="Add(')')">)</button></td>
          <td><button onclick="Add('%')">%</button></td>
          <td><button onclick="back()" style="background-color:#ffb735;">AC</button></td>
      </tr>
      .....
</table>

利率计算器设计
采用form结构,提交按钮,绑定函数实现数据传送;重置按钮清空

<form>
      存款利率计算<br><br>
      存款金额:<input  id="deposit"><br><br>
      存款时长:<input  id="deposit_duration"><br><br>
      <input type="button" value="提交" onclick="getInputData1()">
      <input type="reset"><br><br>
</form>

css设计界面图标样式

以按钮为例
button {…}设计初始样式;button:hover {…}设计鼠标触碰样式

<style type="text/css">
        button {
            height: 60px;
            width: 90px;
            font-size: 18px;
            background-color: #eaecf3;
            border-radius: 5px;
        }
        button:hover {
            background-color: #ccc;
            cursor: pointer;
        }
        ...
</style>

JavaScript设计图标功能

在script中调用函数

 <script>
        let display1 = document.getElementById("display1");
        let display2 = document.getElementById("display2");
        let expression1 = "";
        let expression2 = "";
        function getInputData1() {}
        ...
 </script>

前端向后端发送请求并接收数据

利用ajax框架,定义ajax内部属性
type(请求方式):“POST”;
url(请求地址):“http://127.0.0.1:5000/base_cal”
datatype(返回数据类型):json——json有两种形式,类似与python的字典和列表
success: function()(请求成功并接收数据执行函数操作)
error: function()(请求失败并在控制台显示错误信息)
以Add()函数为例

 function Add(number){
            $.ajax({
                type: "POST",
                url: "http://127.0.0.1:5000/base_cal",
                dataType: "json", 
                data:JSON.stringify({
                    "type":1,
                    "data":number
                }),
                success: function(msg){
                    console.log(msg['result']);
                    expression = msg['result'];
                    display1.innerHTML = expression;
                },// 请求成功时执行的回调函数,msg是服务器返回的数据
                error: function(xhr, textStatus, errorThrown) {
                // 请求失败时执行的回调函数,xhr 是 XMLHttpRequest 对象,                        textStatus 是错误状态文本,errorThrown 是抛出的错误信息
                   console.log("请求失败,错误信息:", textStatus, errorThrown);}
           });
        }

数据库创建

这个计算器共有三个库:Cal_History库 、Deposit库、 loan库
以db.Model为父类,创建类
__tablename__设计数据库名称
利用db.Column()创建数据库每列的数据要求

class Cal_History(db.Model):
    __tablename__="Cal_History"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    result = db.Column(db.String(100),nullable=False)
    
class Deposit(db.Model):
    __tablename__="Deposit"
    deposit = db.Column(db.String(100), primary_key=True,nullable=False)
    deposit_duration= db.Column(db.Float,nullable=False)

class loan(db.Model):
    __tablename__="Loan"
    loan = db.Column(db.String(100), primary_key=True,nullable=False)
    loan_duration= db.Column(db.Float,nullable=False)

python后端连接数据库

数据库采用mysql类型
app.config(数据库地址)
HOSTNAME(mysql所在主机名)
PORT(mysql监听的端口号,默认3306)
USERNAME(连接mysql的用户名)
PASSWORD(连接mysql的密码)
DATABASE(数据库名称)

HOSTNAME="127.0.0.1"
PORT=3306
USERNAME="root"
PASSWORD="123456"
DATABASE="cal_history"
app.config["SQLALCHEMY_DATABASE_URI"]=f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8"

测试是否连接成功——成功返回1

db=SQLAlchemy(app)
with app.app_context():
    with db.engine.connect() as conn:
        rs = conn.execute(text("select 1"))
        print(rs.fetchone())

python后端接收请求并向前端返回数据

app = Flask(name):使用flask类创建一个app对象;name:代表当前app.py模板
@app.route()创建一个路由和视图函数的映射
def base_cal()函数接收前端json数据,并根据前端数据,分析所需功能,返回json数据

app = Flask(__name__)
cal = Calculator()
@app.route('/base_cal',methods=["GET", "POST"])
def base_cal():  # put application's code here
    print(request.method)
    val = request.get_data()
    val = json.loads(val)
    res=''
    history=[]
    if val['type']==1:
        res=cal.Add(val['data'])
        data={
        'result':res
    }
    ....
    return data

解决跨域问题

from flask_cors import CORS
CORS(app, resources=r'/*')

后端增删改查数据库数据

功能:增加——为cal_history数据库中增添数据
通过db.session.add()函数为数据库添加数据
db.session.commit()提交添加结果,真正完成添加

       res=cal.Result()
       cal_history = Cal_History(result=res)
       db.session.add(cal_history)
       db.session.commit()
       cal.result='=' + cal.result
        data={
            'equ':cal.screen_equ,
            'result': cal.result
        }
        return data

功能:查找——获取cal_history数据库中的全部数据并返回前端
通过query.all()函数获取全部数据

        results = Cal_History.query.all()
        for result in results:
            history.append((result.result))
        data = {
            'result': history
        }
        print(data)
        return data

查找存款三个月的存款利率

    d=Deposit.query.filter_by(deposit="三个月").first()
    rate=d.deposit_duration

功能:修改——为deposit数据库数据
修改功能基于查找功能,对查找到的数据进行修改

      d=Deposit.query.filter_by(deposit="三个月").first()
      d.loan_duration = lrate/100
      db.session.commit()

基础计算器功能实现

创建Calculate类,包含Add()添加字符,Result()运算结果,Clear()清空屏幕,back()返回一个字符四个函数

Add()

equ变量为python中的运算式,screen_equ变量为屏幕显示的运算式
例如:2的3次方 ——equ:2**3=8 ;screen_equ:2^3=8

 def Add(self, num):
        temp_equ = self.equ
        temp_screen_equ = self.screen_equ
        temp_screen_equ = temp_screen_equ + num
        if num == '×':
            temp_equ = temp_equ + '*'
        elif num == '÷':
            temp_equ = temp_equ + '/'
        elif num == '^':
            temp_equ = temp_equ + '**'
        elif num == 'lg':
            temp_equ = temp_equ + 'log10'
        elif num == 'ln':
            temp_equ = temp_equ + 'log'
        elif num == 'π':
            temp_equ = temp_equ + 'pi'
        else:
            temp_equ = temp_equ + num

        self.equ = temp_equ
        self.screen_equ = temp_screen_equ
        print(self.equ)
        return self.screen_equ

Result() 利用python自带的eval计算字符串

通过try…except…,进行错误判断
运行try,表示运算式正确,返回运算值
except (ZeroDivisionError): 提示:‘Error: 除零错误’
except NameError:提示’Error: 请加上括号’
except SyntaxError:s提示:‘Error: 语法错误,请正确输入’

  def Result(self):
        temp_equ = self.equ
        print(self.equ )
        try:
            result = round(float(eval(temp_equ)), 2)
            self.result = str(result)
            self.screen_history.append(self.screen_equ + '=' + self.result)
            return self.screen_equ + '=' + self.result
        except ZeroDivisionError:  # 其他除0错误,或语法错误返回Error
            self.result = str('Error: 除零错误')
        except NameError:
            self.result = str('Error: 请加上括号')
        except SyntaxError:
            self.result = str('Error: 语法错误,请正确输入')
        return self.result

back()

back()函数与Add()函数相对应

      def back(self):
        temp_equ = self.equ
        temp_screen_equ = self.screen_equ
        if temp_equ[-2:] in ['**', 'pi']:  # ^  π
            self.equ = temp_equ[:-2]
            self.screen_equ = temp_screen_equ[:-1]
        elif temp_equ[-3:] in ['sin', 'cos', 'tan']:  # sin cos tan
            self.equ = temp_equ[:-3]
            self.screen_equ = temp_screen_equ[:-3]
        elif temp_equ[-3:] == 'log':  # ln
            self.equ = temp_equ[:-3]
            self.screen_equ = temp_screen_equ[:-2]
        elif temp_equ[-5:] == 'log10':  # lg
            self.equ = temp_equ[:-5]
            self.screen_equ = temp_screen_equ[:-2]
        else:
            self.equ = temp_equ[:-1]
            self.screen_equ = temp_screen_equ[:-1]

        return self.screen_equ

心得体会

本次作业学习了解了python-flask框架、ajax框架等,明白了基础的前后端数据传递的方式,能简单实现前后端分离;同时对前端页面设计html、css、javaScript中的各类标签语法等有了更深的理解,能够更好的结合使用。
同时,我也学习了python中一些基本数据类型如字典、列表的操作方法,学会了python类的写法;对json类型有了初步了解。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐