Front-End and Back-End Separated Calculator System

黄和Hh 黄和Hh 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

Software Engineering Practice Assignment 1 - Front-End and Back-End Separated Calculator System

 

## 课程信息

 

| 项目 | 内容 |

| 计算器 | --- |

| 这个作业属于哪个课程 | 软件工程实践 |

| 作业要求 | 前后端分离计算器系统 |

| 这个作业的目标 | 理解前后端分离、HTTP API、表达式解析、数据库持久化和软件工程基本流程 |

| 学号 | 832401308 |

| 姓名 | 黄和 |

| 其他参考文献 | PEP 8、Google JavaScript Style Guide、FastAPI 文档 |

 

## 目录

 

1. [Git 仓库和代码规范链接]

2. [PSP 表格]

3. [成品展示]

4. [设计与实现过程]

5. [代码说明]

6. [部署与测试]

7. [心路历程与收获]

 

## 一、Git 仓库和代码规范链接

 

- 前端 GitHub 仓库:https://github.com/Huang269999/832401308_calculator_frontend

- 后端 GitHub 仓库:https://github.com/Huang269999/832401308_calculator_backend 

 

- 前端代码规范:https://github.com/Huang269999/832401308_calculator_frontend/blob/main/codestyle.md

- 后端代码规范:https://github.com/Huang269999/832401308_calculator_backend/blob/main/codestyle.md

- 公网访问地址:https://huang269999.github.io/832401308_calculator_frontend/

 

## 二、PSP 表格

 

> 下表中的“预计时间”可以作为开发前记录的参考;“实际时间”必须按你自己的真实开发过程填写。

 

| PSP 阶段 | 预计时间(分钟) | 实际时间(分钟) |

| 需求分析 | 20 | 60 |

| 系统设计 | 25 | 90 |

| 前端开发 | 90 | 180 |

| 后端开发 | 90 | 180 |

| 表达式计算模块 | 45 | 60 |

| 数据库设计 | 30 | 30 |

| 历史记录模块 | 35 | 30 |

| 前后端联调 | 45 | 45 |

| 测试与修复 | 50 | 15 |

| 部署 | 40 | 120 |

| 博客整理 | 60 | 60 |

| **合计** | **530** | **870** |

 

## 三、成品展示

 

本项目实现了一个前后端分离的 Web 计算器。前端负责用户交互与结果展示,后端负责表达式解析、计算、异常处理以及 SQLite 数据持久化。

 

 ###3.1 主界面

 

### 3.2 加法

 

输入 `12+8`,后端返回结果 `20`。

 

### 3.3 减法

 

输入 `5-8`,结果为 `-3`。

 

 

### 3.4 乘法和除法

 

分别测试 `3*7` 和 `10/2`。

 

 

 

 

### 3.5 小数与复合表达式

 

测试 `1.5+2.8`、`1+2*3`,验证小数和运算符优先级。

 

 

### 3.6 括号与一元负号

 

测试 `(1+2)*3`、`-5+8`。

 

 

 

 

### 3.7 异常处理

 

测试 `1/0` 与非法表达式 `1+++`,后端返回错误信息,前端进行展示。

 

 

 

 

### 3.8 历史记录与删除

 

成功计算会写入 SQLite。刷新前端页面后记录仍然存在;点击某一条记录的“删除”按钮后,前端调用后端删除接口并重新拉取数据库数据。

 

 

 

### 3.9 扩展功能

 

项目额外实现:

 

- 清空全部历史记录;

- 键盘 Enter 计算、Esc 清空;

- 明暗主题切换。

 

- 后端在线状态显示。

 

## 四、设计与实现过程

 

### 4.1 需求分析

 

核心需求包括四则运算、复合表达式、括号、小数、一元正负号、非法表达式和除零处理;每次成功计算必须保存到后端数据库;前端必须能够读取历史并删除指定记录。

 

本次作业的关键不是单纯实现一个计算器,而是保证“最终计算结果由后端生成”。因此前端只发送表达式,不负责表达式求值。

 

### 4.2 总体架构

 

```text

浏览器前端

HTML + CSS + JavaScript

        |

        | HTTP / JSON

        v

FastAPI 后端

        |

        |-- 表达式校验

        |-- AST 安全解析

        |-- 数学计算

        |-- 异常处理

        v

SQLite 数据库

calculation_history

```

 

### 4.3 功能结构图

 

```text

Calculator System

|

|-- Calculator

|   |-- Basic Calculation

|   |-- Compound Expression

|   |-- Error Handling

|

|-- Calculation History

|   |-- Save History

|   |-- Query History

|   |-- Delete History

|   |-- Clear History (扩展)

|

|-- Front End

|   |-- User Input

|   |-- Result Display

|   |-- History Display

|   |-- Theme Switch (扩展)

|

|-- Back End

    |-- API

    |-- Safe Expression Parser

    |-- Calculation Service

    |-- SQLite Database

```

 

### 4.4 前端设计

 

前端使用原生 HTML、CSS 和 JavaScript。这样可以减少框架依赖,并把重点放在前后端交互上。

 

前端职责:

 

1. 收集用户表达式;

2. 调用 `POST /api/calculate`;

3. 显示后端返回的结果或错误;

4. 调用 `GET /api/history` 显示数据库历史;

5. 调用 `DELETE /api/history/{id}` 删除指定记录。

 

前端没有表达式计算逻辑。如果停止后端,用户仍可输入和点击按键,但无法得到新的有效结果。

 

### 4.5 后端设计

 

后端采用 FastAPI,将计算逻辑、数据访问和 API 分开:

 

- `calculator_service.py`:安全解析和计算;

- `database.py`:SQLite CRUD;

- `schemas.py`:请求数据校验;

- `main.py`:HTTP API。

 

### 4.6 API 设计

 

| 方法 | 地址 | 说明 |

| --- | --- | --- |

| POST | `/api/calculate` | 计算表达式并保存历史 |

| GET | `/api/history` | 查询历史记录 |

| DELETE | `/api/history/{id}` | 删除指定历史 |

| DELETE | `/api/history` | 清空全部历史(扩展) |

| GET | `/api/health` | 后端健康检查(扩展) |

 

计算请求:

 

```json

{

  "expression": "(1+2)*3"

}

```

 

计算成功:

 

```json

{

  "success": true,

  "id": 1,

  "expression": "(1+2)*3",

  "result": 9

}

```

 

### 4.7 数据库设计

 

```text

calculation_history

-------------------

id          INTEGER PRIMARY KEY AUTOINCREMENT

expression  TEXT NOT NULL

result      TEXT NOT NULL

created_at  TEXT NOT NULL

```

 

SQLite 文件由后端首次启动时自动创建。前端刷新或重新打开不会清除数据库数据。

 

### 4.8 计算模块设计

 

为了避免直接执行用户输入,本项目没有使用 `eval()` 或 `exec()`。

 

实现步骤:

 

1. 将界面中的 `×`、`÷` 标准化为 `*`、`/`;

2. 使用 Python `ast.parse(..., mode="eval")` 将表达式解析为语法树;

3. 只允许数字常量、`+ - * /`、括号形成的语法结构、一元 `+ -`;

4. 遇到函数调用、变量、列表、幂运算等其他节点立即拒绝;

5. 递归计算允许的 AST 节点;

6. 对除数为 0、表达式过长和结果过大等情况进行异常处理。

 

这种方式利用 AST 完成“解析”,但没有把表达式作为普通 Python 程序直接执行。

 

### 4.9 前后端交互流程

 

```text

用户输入表达式

      ↓

前端 POST /api/calculate

      ↓

后端校验并解析表达式

      ↓

后端完成数学计算

      ↓

成功结果写入 SQLite

      ↓

后端返回 JSON

      ↓

前端显示结果

      ↓

重新查询并显示历史记录

```

 

## 五、代码说明

 

### 5.1 前端 API 请求

 

前端使用 `fetch()` 把表达式作为 JSON 发送给后端。收到响应后直接显示 `data.result`,前端自身不计算表达式。

 

### 5.2 安全表达式解析

 

后端通过 AST 对允许的节点做白名单判断,只接受四则运算和一元正负号。任何函数调用、属性访问或其他 Python 语法都会被拒绝。

 

### 5.3 数据库插入

 

只有成功计算后才调用 `save_history()`,因此非法表达式与除零错误不会产生历史记录。

 

### 5.4 历史查询与删除

 

前端通过 `GET /api/history` 读取数据库记录;删除时将记录 ID 发给后端,后端执行 SQL `DELETE`,随后前端重新读取历史列表。

 

## 六、部署与测试

 

### 6.1 本地后端

 

```bash

pip install -r requirements.txt

uvicorn app.main:app --reload

```

 

### 6.2 本地前端

 

```bash

python -m http.server 5500 -d src

```

 

### 6.3 公网部署

 

- 前端地址:https://huang269999.github.io/832401308_calculator_frontend/

- 后端地址:https://832401308calculatorbackend-production.up.railway.app/docs

 

部署后应将前端 `src/config.js` 的 `API_BASE_URL` 改为公网后端 HTTPS 地址,并在后端设置 `CORS_ORIGINS` 为公网前端域名。

 

### 6.4 测试用例

 

| 输入 | 预期结果 |

| --- | --- |

| `1+2` | `3` |

| `5-8` | `-3` |

| `3*7` | `21` |

| `10/2` | `5` |

| `1.5+2.8` | `4.3` |

| `1+2*3` | `7` |

| `(1+2)*3` | `9` |

| `-5+8` | `3` |

| `3*-2` | `-6` |

| `1/0` | 返回除零错误 |

| `1+++` | 返回表达式格式错误 |

 

## 七、心路历程与收获

 

本次作业让我第一次比较完整地理解了前后端分离项目的基本流程。最开始容易把“网页计算器”理解成在 JavaScript 中直接计算,但作业要求强调最终结果必须由后端生成,因此我重新梳理了前后端职责:前端负责交互,后端才是业务逻辑和数据的真实来源。

 

实现过程中比较关键的问题是表达式解析。如果直接使用 `eval()` 虽然代码很短,但存在任意代码执行风险,也不符合题目要求。因此最终使用 AST 解析表达式,并只允许指定的数学节点。这样既保留了运算符优先级和括号等语法能力,也能够拒绝函数调用等危险输入。

 

第二个明显收获是数据库持久化。只有把历史记录真正写入 SQLite,前端刷新以后数据才不会消失,这让我更直观地区分了浏览器临时状态和后端持久数据。

 

通过本次实践,我进一步熟悉了 HTTP API、JSON、CORS、SQLite、异常处理、Git 仓库拆分以及前后端联调的完整流程。后续还可以继续增加科学计算、搜索分页、用户登录等功能。

 

...全文

相关推荐

嵌入式Linux驱动开发实战(四):温湿度IMU传感器驱动+应用层采集完整工程-从内核到用户空间的全链路实战

本文以温湿度传感器(HTU21D/SHT30)和IMU传感器(MPU9250/ICM20948)为例,完整呈现从设备树配置、I2C/SPI驱动编写、hwmon/IIO子系统集成,到用户空间采集应用开发的全链路工程实践。

佛渡红尘

【二维快速傅里叶变换的调频连续波雷达目标参数估计】基于FMCW雷达体制的距离多普勒联合估计与恒虚警检测方法研究(Matlab代码实现)

内容概要:本文系统解读了一套完整的多机器人路径规划(MAPF)MATLAB代码库,聚焦于优先级规划算法的工程实现。该框架采用“几何—拓扑—调度—呈现”四层解耦架构,涵盖地图解析、四邻域拓扑与Petri网建模、基于优先级启发式的路径规划、时间同步与冲突消解等核心模块,并提供动画与视频可视化支持。其核心设计思想为“空间规划与时间消解分离”,通过动态边权膨胀引导避让、节点预留历史优化冲突查询、几何惩罚驱动的局部同步等机制显著提升算法效率与可扩展性。文章还对比分析了三种同步策略的适用场景,探讨了Petri网双阶段优化路径,并对框架的完备性、复杂度及工程可维护性进行了系统评价,旨在为MAPF的研究与教学提供一份可复现、可批判的参考范本。; 适合人群:具备一定算法基础和MATLAB编程经验,从事路径规划、机器人调度、智能交通等相关领域研究的科研人员及研究生。; 使用场景及目标:① 学习多机器人路径规划的基本流程与关键技术实现;② 掌握优先级规划、冲突消解、Petri网建模等核心算法的设计与优化方法;③ 借鉴模块化、分层解耦的工程框架设计思路,用于仓储物流、无人机编队等实际场景的算法开发与仿真验证。; 阅读建议:建议结合文中提到的MovingAI地图数据与MATLAB环境运行代码,逐步调试各模块以深入理解算法细节,并重点关注动态边权膨胀与局部同步策略的实现逻辑,以便在实际应用中进行参数调优与功能扩展。

程序猿鑫

YOLO算法隧道内车辆目标检测数据集-52张-包含 VOC 和 Yolo 格式标签-支持多种算法训练模型.zip

页面底部附数据集可视化效果预览,可直接参考。 YOLO隧道内车辆目标检测数据集 目标类别:['bus', 'car', 'motocycle', 'truck'] 中文类别:['公交车', '轿车', '摩托车', '卡车'] 训练集:41 张 验证集:11 张 测试集:0 张 总计:52 张 该数据集提供了data.yaml文件,内容如下: train: ../train/images val: ../valid/images test: ../test/images nc: 4 names: ['bus', 'car', 'motocycle', 'truck'] 使用场景:毕业设计、课程设计、深度学习入门、工业场景落地验证。

guo_xiao_xiao_

loras.7z.007

loras.7z.007

WSH_SRE

(共159页PPT)麦肯锡图表汇总.ppt

(共159页PPT)麦肯锡图表汇总.ppt

数智顾问
评论 1
收藏 已收藏
分享
返回顶部
黄和Hh
2601_FZU-MU_SE 173 成员 138 内容