First Assignment 832401127 zexin zhang
Table of Contents
- Course & Assignment Introduction
- GitHub Repository Links & Code Style Links
- PSP Table
- Demonstration of Finished Product
- Design & Implementation Process
- Core Code Explanation
- Development Experience & Learnings
Course & Assignment Introduction
Course: Software Engineering
Assignment: Develop a calculator system based on front-end and back-end separation architecture
Assignment Objectives: Master the separated front-end and back-end architecture. The front-end handles UI interaction only. The back-end independently completes expression parsing, mathematical calculation, exception handling and persistent storage of calculation history in database. The front-end sends raw expression string to backend.
The front-end cannot compute the result directly. All core calculation logic runs on the backend.
Main Requirements:
- Implement basic arithmetic operations:
+ - * / - Support compound expressions, including operator precedence, parentheses, unary minus, decimal numbers. Catch division-by-zero and invalid expression errors. Expression parsing is implemented manually,
eval()is forbidden. - Store calculation history persistently in backend database. The history includes expression, result and timestamp. History will not disappear after page refresh.
- Front-end can fetch history and delete single history record via API.
- Deploy the project and provide public accessible address.
- Upload source code into two independent GitHub repositories: frontend repo and backend repo.
- Write PSP table,
codestyle.mdandREADME.mdfor both repositories. - Publish this blog with sufficient screenshots to demonstrate functions.
GitHub Repository Links & Code Style Links
- Frontend Repository: https://github.com/zzx66689/832401127_calculator-frontend
- Backend Repository: https://github.com/zzx66689/832401127_calculator_backend
- Frontend Code Standard: https://github.com/zzx66689/832401127_calculator-frontend/blob/main/832401127_calculator-frontend/codestyle.md
- Backend Code Standard: https://github.com/zzx66689/832401127_calculator_backend/blob/main/832401127_calculator_backend/codestyle.md
PSP Table
表格
| Phase | Estimated Time(min) | Actual Time(min) |
|---|---|---|
| Requirement Analysis | 40 | 55 |
| System Design | 40 | 50 |
| Frontend Development | 45 | 50 |
| Backend Development | 70 | 85 |
| Expression Parser Module | 60 | 75 |
| Database Design | 30 | 25 |
| History CRUD Module | 40 | 45 |
| Frontend & Backend Integration | 50 | 55 |
| Testing & Bug Fix | 40 | 45 |
| Project Deployment | 20 | 20 |
| Blog Writing | 50 | 55 |
| Total | 485 | 560 |
Demonstration of Finished Product
- Calculator Main UI 【Image 1】

- Basic arithmetic test: 12+8 【Image 2】

- *Compound expression with parentheses: (1+2)3 【Image 3】

- Unary minus at start: -5+8 【Image 4】

- Unary minus after operator: 3*-2【Image 5】

- Division by zero exception:10/0 【Image 6】

- Invalid expression:1++2 【Image 7】

- Decimal calculation 【Image 8】

- Query history and persistence after page refresh 【Image 9】

- Delete single history record 【Image 10】

Design & Implementation Process
1. Requirement Analysis
This project adopts front-end and back-end separation architecture.
- Frontend responsibility: Render UI, listen button click, concatenate expression string; send HTTP POST request with expression; receive and display result; fetch history list; send delete request; display error messages from backend.
- Backend responsibility: Receive expression string from frontend; lexical and syntax analysis; calculate following math rules; catch exceptions; save successful calculation records into SQLite database; provide REST API for history query and deletion; return standardized JSON response.
Hard constraint: All calculations are done on backend. Frontend cannot compute anything. eval() is forbidden.
2. System Architecture
Frontend HTML Page
↓ HTTP JSON API
Backend Express Server
↓
SQLite Database
Function Structure Diagram
Calculator System
├── Calculator Core Module
│ ├── Basic Arithmetic
│ ├── Compound Expression Parser
│ └── Exception Handler (Division by zero, invalid syntax)
├── Calculation History Module
│ ├── Save History
│ ├── Query History
│ └── Delete Single Record
├── Frontend
│ ├── User Button Input
│ ├── Result Display
│ └── History Display & Delete Operation
└── Backend
├── API Layer
├── Expression Parser Service
├── Calculation Service
└── Database Persistence
3. Frontend Design
Frontend uses native HTML+CSS+JavaScript, no framework.
- Button click handler: append characters to expression input box.
- Equal button triggers fetch POST request, send expression to
/calculate. - Refresh history button: GET
/historyto get record array and render page. - Delete button: send DELETE request to
/history/:id. After deletion, reload history. - Parse JSON response: if success, show result; if failed, show error message from backend.
4. Backend Design
Backend based on Node.js Express, better-sqlite3 for SQLite database. Modules:
server.js: entry point, listen port 3000, enable CORS and JSON parser.src/routes/api.js: API router for/calculate,/history,/history/:id.src/calculator/ExpressionParser.js: hand-written expression parser, infix to postfix, handle priority, parentheses and unary minus.src/calculator/CalculatorService.js: wrapper for parser, catch exceptions and throw standardized errors.src/database/model.js: database model, encapsulate insert, query, delete functions.
5. API Design
表格
| Method | Endpoint | Function | Request Body | Response Example |
|---|---|---|---|---|
| POST | /calculate | Calculate expression and save record | {"expression":"(1+2)*3"} | {"success":true,"expression":"(1+2)*3","result":9} |
| GET | /history | Get all history | none | {"success":true,"data":[{id,expr,result,create_time}]} |
| DELETE | /history/:id | Delete one record by id | none | {"success":true} |
Error response example:

6. Database Design
SQLite table history
表格
| Column | Type | Description |
|---|---|---|
| id | INTEGER PRIMARY KEY AUTOINCREMENT | Unique primary key |
| expr | TEXT NOT NULL | Original expression string |
| result | TEXT NOT NULL | Calculation result |
| create_time | DATETIME DEFAULT CURRENT_TIMESTAMP | Record timestamp |
After successful calculation, backend inserts a new row. Query records ordered by id DESC so newest records appear first. Delete operation uses id to locate target row.
7. Calculation Module & Exception Handling
Hand-written expression parser in three steps:
- Lexical analysis (tokenize): split raw string into tokens (number, operator, parenthesis). Reject invalid characters.

- Infix to postfix notation: use stack, manage operator priority, identify unary minus.
- Evaluate postfix expression: stack-based calculation. Check divisor=0 and throw division-by-zero error.

Exception capture:
- Division by zero → return
Division by zero - Syntax error, mismatched parentheses, consecutive operators → return
Invalid expression
8. Frontend Backend Interaction Workflow
- User clicks buttons on frontend to build expression.
- Click
=, frontend sends POST request with expression string. - Backend receives expression, parse and compute.
- If calculation success: insert record into database and return success JSON. If failed, return error JSON.
- Frontend renders result and refresh history list on success; show alert message on error.
- Click refresh history: frontend GET
/history, render records from database. - Click delete button: frontend send DELETE request. Backend deletes row in database, frontend reload history.
9. Deployment
Node.js backend deployed on cloud server with port 3000 open. Static frontend HTML deployed on Github Pages, public accessible.
Core Code Explanation
1. Frontend: Request calculation API

Explanation: Frontend only sends raw expression string without any calculation. Show result returned by backend and refresh history after success.
2. Backend: Calculate API router

Explanation: Receive expression, invoke calculation service. Save record to database after success. Catch exceptions and return standardized error response with HTTP 400 for client input error.
3. Expression parser: judge unary minus

Explanation: Distinguish subtraction operator and unary minus. Mark
-as unary minus in cases like-5+8and3*-2, assign higher priority in postfix conversion.
4. Database model: query history

Explanation: Read all history records from SQLite, sorted by id descending. Pass data to API router via callback.
5. Delete history API

Explanation: Receive id from url parameter, call database delete function. Return 404 if target record not found.
Development Experience & Learnings
Problems & Solutions
- Unrecognized unary minus The parser could not tell the difference between subtraction and negative sign,
3*-2failed. Solution: mark unary minus during infix-to-postfix conversion and assign higher priority. - SQLite file locked When node service is running, better-sqlite3 locks
calculator.dband prevents manual deletion. Solution: useCREATE TABLE IF NOT EXISTS, no need manually delete database file. - CORS cross origin error Browser blocks fetch request from static frontend to backend. Solution: add
corsmiddleware on backend. - History list not refresh after deletion After delete API call, page content stayed unchanged. Solution: call
loadHistory()again to fetch latest data from backend after deletion.
Knowledge Gained
- Deep understanding of front-end/back-end separation: frontend only handles view and interaction. Core calculation and data persistence must be on backend. If backend stops, frontend cannot compute new expressions.
- Use stack to implement infix expression parsing, learn operator precedence, parentheses and unary minus. Understand security risk of
eval()executing raw user input. - RESTful API design, semantic of GET/POST/DELETE, proper HTTP status code usage.
- SQLite persistent storage and callback-based database operation.
- Git version control, separate frontend and backend repositories,
.gitignoreto ignorenode_modulesand database file. - PSP personal software process: estimate working time before development, track defects and quantify development progress.
Future Improvement
- Add pagination for history records when there are many entries.
- Support keyboard direct input in text box.
- Add scientific calculation functions (square root, power) as bonus extension.
- Write unit tests for expression parser module
相关推荐
基于MATLAB的复合弹性模量分析,采用混合法则,结合纤维体积分数变化和图形结果。.zip
1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
基于MATLAB的自适应纯追踪曲线跟踪机器人仿真,采用多路径、自适应速度控制和图形界面可视化。.zip
1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
【数据库优化】通信行业B/O域查询性能提升:基于分区裁剪与覆盖索引的秒级溯源系统实现
内容概要:本文围绕通信行业中海量话单与信令数据的查询性能问题,系统阐述了从全表扫描到秒级响应的数据库优化路径。文章以运营商 cdr_detail 表为案例,揭示了因使用函数操作索引列(如DATE(call_start_time))和深分页(LIMIT offset, size)导致的全表扫描问题,并提出完整的优化方案:通过时间范围RANGE分区实现分区裁剪、构建msisdn与时间的联合覆盖索引、消除索引列函数运算、采用游标分页替代OFFSET等方式,使查询性能从P95 8.3秒降至290毫秒。同时介绍了执行计划分析(EXPLAIN)在调优中的关键作用,并展望了HTAP架构、向量化执行与AI自治优化器等未来方向。; 适合人群:具备一定数据库基础知识,从事通信行业数据开发、DBA或后端研发的技术人员,尤其是面对大规模时序数据查询性能瓶颈的工程师;; 使用场景及目标:①解决营业厅用户详单查询、网间结算对账、VoNR信令分析等高并发、低延迟查询场景下的性能问题;②掌握如何通过分区策略、索引设计和SQL改写实现从全表扫描到精准索引访问的优化落地; 阅读建议:建议结合实际生产环境中的大表查询案例,对照本文的反例与正例进行执行计划对比分析,并在测试环境中实践分区表创建、覆盖索引构建及游标分页改写,深入理解每项优化技巧的实际效果。
石墨提纯全球市场结构与产业发展趋势分析报告(QYResearch最新研究).docx
石墨提纯全球市场结构与产业发展趋势分析报告(QYResearch最新研究)
政府科技管理者如何提升科技成果转化政策的精准匹配与执行效率?.docx
政府科技管理者如何提升科技成果转化政策的精准匹配与执行效率?


