24127167-Wu Zhengyang-First Assignment-Front-End and Back-End Separation Calculator

832402223吴正杨 2026-10-02 22:52:44

Assignment 1: Front-End and Back-End Separation Calculator System

Course for This AssignmentSoftware Engineering Practice
Assignment RequirementsFront-end / back-end separated calculator system
ObjectivesMaster front-end/back-end separation, API development, database persistence, system design, and technical blog writing
Name / Student IDWU Zhengyang / 24127167

Repositories

1. PSP Table

PSP2.1StagesEstimated (min)Actual (min)
PlanningPlanning3025
DevelopmentDevelopment320360
· Analysis· Requirements analysis3025
· Design· System/API/DB design4045
· Coding· Backend (RPN + DB)90110
· Coding· Frontend page6070
· Test· Test all features3035
ReportingReporting150160
TotalTotal500545

2. Requirements Analysis

This assignment requires a strictly separated front-end / back-end calculator. All computation must run on the backend; the frontend only collects the expression and sends it via HTTP POST. History must persist in a backend database (no localStorage). Must support operator precedence, parentheses, decimals, unary minus. No eval/exec. Two independent GitHub repos, each with README.md and codestyle.md. Support deleting history by id.

Tech stack: Python + FastAPI, SQLite, plain HTML/CSS/JS, hand-written Reverse Polish Notation.

3. System Design

Browser (index.html)
   │ HTTP/JSON
   ▼
FastAPI (main.py)
   ├── Expression parser (tokenize → infix-to-postfix → evaluate)
   ├── History module (SQLAlchemy ORM)
   ▼
SQLite (calculator.db)
EndpointMethodPurpose
/api/calculatePOSTCalculate expression and save to history
/api/historyGETGet all history (descending)
/api/history/{id}DELETEDelete a record by id

4. Feature Demonstration

Main Interface

Main

Basic Arithmetic (12+8=20)

Basic

Decimal (2.5*4=10)

Decimal

Parentheses ((1+2)*3=9)

Paren

Unary Minus (3*-2=-6)

Unary

Division by Zero

Div0

Invalid Expression

Invalid

History List

History

Refresh Keeps History

Refresh

Delete Record

Delete

5. Key Code

Frontend: submit expression

async function submitCalc(){
    const resp = await fetch(BACKEND_URL + "/api/calculate", {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify({expression: inputDom.value.trim()})
    });
    const data = await resp.json();
    resultDom.innerText = data.success ? "Result = " + data.result : "Error: " + data.message;
    loadHistory();
}

Backend: calculate API

@app.post("/api/calculate")
def calc(req: CalcRequest):
    db = SessionLocal()
    try:
        res = calculate_expression(req.expression)
        record = CalcHistory(expression=req.expression, result=res)
        db.add(record); db.commit()
        return {"success": True, "expression": req.expression, "result": res}
    except ZeroDivisionError:
        return {"success": False, "message": "Division by zero"}
    except Exception as e:
        return {"success": False, "message": "Invalid expression: " + str(e)}
    finally:
        db.close()

Unary minus tokenization

if c == "-":
    if i == 0 or expr[i-1] in "(+-*/":
        tokens.append("u-")   # unary minus
    else:
        tokens.append(c)      # binary subtraction

6. Summary

  1. CORS: opened index.html via file:// blocked fetch; fixed with CORSMiddleware.
  2. Unary minus was the hardest part — 3*-2 and leading -5 needed a separate u- token with highest precedence.
  3. All errors caught at the API layer to avoid 500s.
  4. History verified by refreshing and restarting the backend.
  5. Key takeaway: frontend is dumb (display + request), backend is the brain (compute + store).
...全文
46 回复 打赏 收藏 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

173

社区成员

发帖
与我相关
我的任务
社区描述
梅努斯-软件工程
软件工程 高校 福建省·福州市
社区管理员
  • FZU_SE_LQF
  • zjcTander
  • 木村修
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧