First Assignment 832401127 zexin zhang

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

Table of Contents

  1. Course & Assignment Introduction
  2. GitHub Repository Links & Code Style Links
  3. PSP Table
  4. Demonstration of Finished Product
  5. Design & Implementation Process
  6. Core Code Explanation
  7. 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:

  1. Implement basic arithmetic operations: + - * /
  2. 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.
  3. Store calculation history persistently in backend database. The history includes expression, result and timestamp. History will not disappear after page refresh.
  4. Front-end can fetch history and delete single history record via API.
  5. Deploy the project and provide public accessible address.
  6. Upload source code into two independent GitHub repositories: frontend repo and backend repo.
  7. Write PSP table, codestyle.md and README.md for both repositories.
  8. Publish this blog with sufficient screenshots to demonstrate functions.

GitHub Repository Links & Code Style Links

PSP Table

表格

PhaseEstimated Time(min)Actual Time(min)
Requirement Analysis4055
System Design4050
Frontend Development4550
Backend Development7085
Expression Parser Module6075
Database Design3025
History CRUD Module4045
Frontend & Backend Integration5055
Testing & Bug Fix4045
Project Deployment2020
Blog Writing5055
Total485560

Demonstration of Finished Product

  1. Calculator Main UI 【Image 1】 
  2. Basic arithmetic test: 12+8 【Image 2】 
  3. *Compound expression with parentheses: (1+2)3 【Image 3】 
  4. Unary minus at start: -5+8 【Image 4】 
  5. Unary minus after operator: 3*-2【Image 5】 
  6. Division by zero exception:10/0 【Image 6】 
  7. Invalid expression:1++2 【Image 7】 
  8. Decimal calculation 【Image 8】 
  9. Query history and persistence after page refresh 【Image 9】 
  10. 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 /history to 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:

  1. server.js: entry point, listen port 3000, enable CORS and JSON parser.
  2. src/routes/api.js: API router for /calculate, /history, /history/:id.
  3. src/calculator/ExpressionParser.js: hand-written expression parser, infix to postfix, handle priority, parentheses and unary minus.
  4. src/calculator/CalculatorService.js: wrapper for parser, catch exceptions and throw standardized errors.
  5. src/database/model.js: database model, encapsulate insert, query, delete functions.

 

5. API Design

表格

MethodEndpointFunctionRequest BodyResponse Example
POST/calculateCalculate expression and save record{"expression":"(1+2)*3"}{"success":true,"expression":"(1+2)*3","result":9}
GET/historyGet all historynone{"success":true,"data":[{id,expr,result,create_time}]}
DELETE/history/:idDelete one record by idnone{"success":true}

Error response example:

 

6. Database Design

SQLite table history

表格

ColumnTypeDescription
idINTEGER PRIMARY KEY AUTOINCREMENTUnique primary key
exprTEXT NOT NULLOriginal expression string
resultTEXT NOT NULLCalculation result
create_timeDATETIME DEFAULT CURRENT_TIMESTAMPRecord 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:

  1. Lexical analysis (tokenize): split raw string into tokens (number, operator, parenthesis). Reject invalid characters.
  2. Infix to postfix notation: use stack, manage operator priority, identify unary minus.
  3. 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

  1. User clicks buttons on frontend to build expression.
  2. Click =, frontend sends POST request with expression string.
  3. Backend receives expression, parse and compute.
  4. If calculation success: insert record into database and return success JSON. If failed, return error JSON.
  5. Frontend renders result and refresh history list on success; show alert message on error.
  6. Click refresh history: frontend GET /history, render records from database.
  7. 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+8 and 3*-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

  1. Unrecognized unary minus The parser could not tell the difference between subtraction and negative sign, 3*-2 failed. Solution: mark unary minus during infix-to-postfix conversion and assign higher priority.
  2. SQLite file locked When node service is running, better-sqlite3 locks calculator.db and prevents manual deletion. Solution: use CREATE TABLE IF NOT EXISTS, no need manually delete database file.
  3. CORS cross origin error Browser blocks fetch request from static frontend to backend. Solution: add cors middleware on backend.
  4. 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

  1. 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.
  2. Use stack to implement infix expression parsing, learn operator precedence, parentheses and unary minus. Understand security risk of eval() executing raw user input.
  3. RESTful API design, semantic of GET/POST/DELETE, proper HTTP status code usage.
  4. SQLite persistent storage and callback-based database operation.
  5. Git version control, separate frontend and backend repositories, .gitignore to ignore node_modules and database file.
  6. PSP personal software process: estimate working time before development, track defects and quantify development progress.

Future Improvement

  1. Add pagination for history records when there are many entries.
  2. Support keyboard direct input in text box.
  3. Add scientific calculation functions (square root, power) as bonus extension.
  4. 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最新研究)

行业报告QY

政府科技管理者如何提升科技成果转化政策的精准匹配与执行效率?.docx

政府科技管理者如何提升科技成果转化政策的精准匹配与执行效率?

BIZKEEN
评论
收藏 已收藏
分享
返回顶部