173
社区成员
发帖
与我相关
我的任务
分享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:
+ - * /eval() is forbidden.codestyle.md and README.md for both repositories.表格
| 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 |










This project adopts front-end and back-end separation architecture.
Hard constraint: All calculations are done on backend. Frontend cannot compute anything. eval() is forbidden.
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
Frontend uses native HTML+CSS+JavaScript, no framework.
/calculate./history to get record array and render page./history/:id. After deletion, reload history.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.
表格
| 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:

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.
Hand-written expression parser in three steps:


Exception capture:
Division by zeroInvalid expression=, frontend sends POST request with expression string./history, render records from database.Node.js backend deployed on cloud server with port 3000 open. Static frontend HTML deployed on Github Pages, public accessible.

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

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.

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

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

Explanation: Receive id from url parameter, call database delete function. Return 404 if target record not found.
3*-2 failed. Solution: mark unary minus during infix-to-postfix conversion and assign higher priority.calculator.db and prevents manual deletion. Solution: use CREATE TABLE IF NOT EXISTS, no need manually delete database file.cors middleware on backend.loadHistory() again to fetch latest data from backend after deletion.eval() executing raw user input..gitignore to ignore node_modules and database file.