The Link Your Class | 2301-MUSE社区-CSDN社区云 |
The Link of Requirement of This Assignment | https://bbs.csdn.net/topics/617378696 |
The Aim of This Assignment | Back-end separation calculator programming |
MU STU ID and FZU STU ID | 21125911_832102103 |
Github project address | https://github.com/8233244/calculator.git |
1. Introduction
This assignment requires us to make a calculator with a separate front end and back end. On the basis of the original front-end code of job 1, I added functions such as trigonometric function and decimal operation. In addition, in order to read the historical calculation results from the back-end database, I consider using the SQLite database under the flask framework for data storage and reading.
2. PSP
Personal Software Process Stages | Estimated Time(minutes) | Actual Time(minutes) |
Planning | ||
• Estimate | 30 | 50 |
Development | ||
• Analysis | 20 | 30 |
• Design Spec | 30 | 60 |
• Design Review | 40 | 60 |
• Coding Standard | 60 | 90 |
• Design | 60 | 90 |
• Coding | 120 | 150 |
• Code Review | 30 | 50 |
• Test | 20 | 30 |
Reporting | ||
• Test Report | 30 | 35 |
• Size Measurement | 20 | 20 |
• Postmortem & Process Improvement Plan | 30 | 40 |
Sum | 490 | 705 |
3. Design and Implementation Process
(1) Front end
The front-end part adopts the original html, css, JavaScript design structure, and adds several new buttons for calculating trigonometric functions and decimals. JavaScript code has been added to read data from input in the database.
(2) Back end
SQLite database is used to store the calculation history, providing the function of saving, obtaining, and clearing the history, and a simple Web interface is created through Flask to allow users to interact with the calculator.
(3) Database
Use SQLite database and connect to SQLite database using Navicat for data monitoring.
4. Code Explanation
(1) /static/calculator.js (front end)
'appendToDisplay(value)': appends the value passed in to the display:
function appendToDisplay(value) {
document.getElementById('display').value += value;
}
'clearDisplay()': clears the contents of the display:
function clearDisplay() {
document.getElementById('display').value = '';
}
'calculateResult()': computes the expression on the display and saves the result to the database. This function does the following:
• Gets the expression on the display.
• Evaluate the result of an expression using the eval() function.
• Use fetch() to send a POST request to the /save_result route, sending the expression and result to the back end as JSON data.
• If the save succeeds, clear the display, display the result on the display, and refresh the history record.
• If saving fails, record an error message.
function calculateResult() {
const expression = document.getElementById('display').value;
const result = eval(expression);
fetch('/save_result', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ expression, result }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
clearDisplay();
document.getElementById('display').value=result;
refreshHistory(); // 刷新历史记录
} else {
console.error('保存结果失败');
}
})
.catch(error => {
console.error('保存结果失败:', error);
});
}
'refreshHistory()': Get the history and display it on the page. This function does the following:
• Use fetch() to send a GET request to the /get_history route to get the history.
• If successful, clear the history list, then create a li element for each history item and add it to the history list.
• If the retrieval fails, log an error message.
function refreshHistory() {
fetch('/get_history')
.then(response => response.json())
.then(data => {
if (data.success) {
const historyList = document.getElementById('history-list');
historyList.innerHTML = '';
data.history.forEach(item => {
const historyItem = document.createElement('li');
historyItem.textContent = item;
historyList.appendChild(historyItem);
});
} else {
console.error('获取历史记录失败');
}
})
.catch(error => {
console.error('获取历史记录失败:', error);
});
}
'clearHistory()': Clears the history. This function does the following:
• Use fetch() to send a POST request to the /clear_history route to request that the history be cleared.
• If the command is successfully cleared, the historical record is refreshed.
• If the cleanup fails, record an error message.
function clearHistory() {
fetch('/clear_history', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(data => {
if (data.success) {
refreshHistory(); // 刷新历史记录
} else {
console.error('清除历史记录失败');
}
})
.catch(error => {
console.error('清除历史记录失败:', error);
});
}
And the calculation of trigonometric functions:
function calculateSin() {
const value = parseFloat(document.getElementById('display').value);
const result = Math.sin(value);
appendToDisplay(result);
//document.getElementById('display').value = result;
}
function calculateCos() {
const value = parseFloat(document.getElementById('display').value);
const result = Math.cos(value);
document.getElementById('display').value = result;
}
function calculateTan() {
const value = parseFloat(document.getElementById('display').value);
const result = Math.tan(value);
document.getElementById('display').value = result;
}
(2) app.py (back end)
Import the required libraries:
'Flask': Used to create Web applications.
'render_template': Used to render HTML templates.
'request': Used to process HTTP requests.
'jsonify': Used to convert data to JSON format.
'SQLAlchemy': Used to process database operations.
'Migrate': Used for database migration.
'CORS': used to process cross-domain resource sharing.
from flask import Flask, render_template, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_cors import CORS
Create Flask application instances and configure the application, including using SQLite database, automatically reloading templates, and initializing database objects:
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///calculator.db' # 使用SQLite数据库
app.config['TEMPLATES_AUTO_RELOAD'] = True # 自动重新加载模板
db = SQLAlchemy(app)
migrate = Migrate(app, db)
CORS(app)
Define a database model 'Calculation' to represent a table of calculation histories:
class Calculation(db.Model):
__tablename__ = 'calculator'
id = db.Column(db.Integer, primary_key=True)
expression = db.Column(db.String(100))
result = db.Column(db.Float)
Create database tables, create routes and view functions:
with app.app_context():
db.create_all()
@app.route('/')
def index():
return render_template('history.html')
@app.route('/save_result', methods=['POST'])
def save_result():
data = request.get_json()
expression = data.get('expression')
result = data.get('result')
calculation = Calculation(expression=expression, result=result)
db.session.add(calculation)
db.session.commit()
return jsonify({'success': True})
@app.route('/get_history')
def get_history():
calculations = Calculation.query.all()
history = [f'{calculation.expression} = {calculation.result}' for calculation in calculations]
return jsonify({'success': True, 'history': history})
@app.route('/history')
def history():
calculations = Calculation.query.all()
return render_template('history.html', calculations=calculations)
@app.route('/clear_history', methods=['GET', 'POST'])
def clear_history():
Calculation.query.delete()
db.session.commit()
return jsonify({'success': True})
The application runs on port 4000 on host 0.0.0.0 with debug mode enabled:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=4000, debug=True)
5. Presentation of the Finished Product
6. Personal Journey and Learnings
This assignment is very difficult for me as a person with insufficient knowledge of front end and back end. However, I learned to use Python's Flask framework to build the database, which strengthened the development of the front-end interface. I benefited a lot from this experience.