<Project-11 Calculator> 计算器 液体容量转换、温度转换、 美制与公制长度|重量转换,工时计算器、年龄计算器、烹饪容积转换 DOCKER部署 含全部代码 更新在3Apr.2025

updated: on 3Apirl2025

修改/添加 metric_converter , 现为:美制&公制单位转换器 输入数字,点击或回车来获取值,原:长度单位换算 被代换

添加 calculator 计算器

更换了风格,简洁

一、前言

这是一个综合性的单位换算工具,提供了多种常用计量单位之间的转换功能。不断完善 style 各页面风格统一 , 格式一致。

容量单位换算

  • 支持在公制单位(升、毫升、立方厘米)
  • 美制容量单位(加仑、夸脱、品脱、杯、液体盎司)
  • 厨房计量单位(汤匙、茶匙、米杯)之间相互转换

长度单位换算

  • 公制长度单位:毫米、厘米、分米、米
  • 美制长度单位:英寸、英尺、码、英里
  • 中国传统单位:厘、分、寸、尺、丈、里
  • 公制重量单位:克、千克、公吨
  • 美制重量单位:格令、打兰、盎司、磅、短吨、长吨
  • 介绍:蒲式耳、百威特

温度单位换算

  • 支持摄氏度(°C)
  • 华氏度(°F)
  • 开尔文(K)之间的转换

重量单位换算

  • 公制重量:毫克、公克、公斤、公吨
  • 美制重量:格令、打兰、盎司、磅、美吨(短吨)、英吨(长吨)
  • 中国传统重量单位:分、钱、两、斤、担

气压单位换算

  • 支持多种气压单位:巴(bar)、磅力/平方英寸(psi)、千帕(kPa)、标准大气压(atm)、毫米汞柱(mmHg)

特点:

  • 界面简洁,操作简单
  • 一次性显示所有转换结果
  • 分组显示不同计量体系的单位
  • 提供清除功能,方便重新输入
  • 中英文单位名称显示

这个工具特别适合:

  • 烹饪爱好者(在不同食谱单位间转换)
  • 国际单位换算
  • 工程日常计算

公制 - 美制 - 大中华 之间的:容量 长度 温度 重量 气压 之间的转换

公制 - 美制 - 大中华 单位间转换
容量  升 加仑 汤匙 杯 等
长度 厘米 英寸 毫 厘 等
温度  摄氏 华氏 开尔文
重量 克 磅 大小吨 担 钱 两 等
气压  PSI BAR mmHg 等

二、页面展示 Updated on 3Apr.2025

1. 主界面

2. 时间单位转换器

3. 工作时长计算器

4.年龄计算器

5.公制 & 美制单位换算器

6.容量单位换算器

其它部分更改

styles.css

        完全理解这个文件为什么会越来越大

app.py

        加了路由

新建文件

liquid_measures.html 页面
liquid_measures.js   javascript
pressure-diagram.svg 这复制来的 因 AI 图不给力
styles.css

三、完整代码 Updated on 3Apr.2025

1. app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/converters/time')
def time_converter():
    # 渲染位于 templates/converters/time.html 的模板
    return render_template('converters/time.html')

@app.route('/converters/agecal')
def age_calculator():
    # 渲染位于 templates/converters/age calculator 的模板
    return render_template('converters/agecal.html')

@app.route('/converters/workhours')
def work_hours():
    return render_template('converters/workhours.html')

@app.route('/coverters/metric_converter')
def metric_converter():
    return render_template('converters/metric_converter.html')

@app.route('/coverters/liquid_measures')
def liquid_measures():
    return render_template('converters/liquid_measures.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9007, debug=True)

2. index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="单位换算工具和科学计算器">
    <title>主页 - 单位换算工具</title>
    
    <!-- Tailwind CDN for calculator styling -->
    <script src="https://cdn.tailwindcss.com"></script>
    
    <!-- React and ReactDOM -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
    
    <!-- Calculator Styles -->
    <style>
        /* Root CSS variables for theme management */
        :root {
            --primary-color: #007BFF;
            --background-color: #f4f4f4;
            --text-color: #333;
            --border-color: #ddd;
        }

        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: var(--background-color);
        }

        .container {
            display: flex;
            justify-content: space-around;
            align-items: flex-start;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        .tools-list {
            list-style: none;
            padding: 0;
            margin: 0;
            display: block;
            width: 100%;
        }

        .tools-list a {
            display: inline-block;
            width: 100%;
            max-width: 180px;
            padding: 10px 15px;
            font-size: 1.2em;
            color: var(--primary-color);
            border: 1px solid var(--primary-color);
            border-radius: 5px;
            text-align: center;
            text-decoration: none;
            transition: background-color 0.3s, color 0.3s;
            background-color: white;
            margin: 0 auto 20px;
        }

        .tools-list a:hover {
            background-color: var(--primary-color);
            color: white;
        }

        .centered {
            text-align: center;
            width: 100%;
            margin: 0 auto;
        }

        h1 {
            color: var(--text-color);
            font-size: 2em;
            margin: 20px 0;
        }

        .calculator-container {
            margin-left: 100px;
            flex: 0 0 auto;
        }

        /* Calculator specific styles */
        .calculator {
            background-color: #4a4a4a;
            padding: 15px;
            border-radius: 10px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
            width: 300px;
        }

        .model-name {
            color: white;
            font-size: 14px;
            margin-bottom: 10px;
        }

        .display {
            background-color: #c8c8c8;
            border: 1px solid #999;
            margin-bottom: 15px;
            padding: 10px;
            text-align: right;
            font-family: "Courier New", monospace;
            font-size: 24px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: flex-end;
        }

        .buttons {
            display: grid;
            grid-template-columns: repeat(5, 1fr);
            gap: 8px;
        }

        button {
            border: none;
            border-radius: 5px;
            padding: 12px 0;
            font-size: 18px;
            cursor: pointer;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
            transition: background-color 0.1s;
        }

        button:hover {
            filter: brightness(90%);
        }

        button:active {
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
            transform: translateY(1px);
        }

        @media (max-width: 768px) {
            .container {
                flex-direction: column;
                align-items: center;
            }

            .calculator-container {
                margin-left: 0;
                margin-top: 30px;
            }
        }
    </style>
</head>
<body>
    <div class="body">
        <div class="centered">
            <h1>单位换算工具</h1>
            <p>请选择一个单位换算工具:</p>
        </div>
        
        <div class="container">
            <!-- 左侧工具列表 -->
            <div style="flex: 0 1 auto; min-width: 200px;">
                <div class="content centered">
                    <ul class="tools-list">
                        <li><a href="/converters/time">时间换算器</a></li>
                        <li><a href="/converters/workhours">工作小时计算器</a></li>
                        <li><a href="/converters/agecal">年龄计算器</a></li>
                    </ul>
                </div>
                <div class="content centered">
                    <ul class="tools-list">
                        <li><a href="/coverters/metric_converter">美制&公制单位转换器</a></li>
                        <li><a href="/coverters/liquid_measures">容量单位换算器</a></li>
                    </ul>
                </div>
            </div>

            <!-- 右侧计算器 -->
            <div id="calculator-root" class="calculator-container"></div>
        </div>
    </div>

    <!-- Calculator Component Script -->
    <script type="text/babel">
        const Calculator = () => {
            const [display, setDisplay] = React.useState('0');
            const [memory, setMemory] = React.useState(0);
            const [firstOperand, setFirstOperand] = React.useState(null);
            const [operator, setOperator] = React.useState(null);
            const [waitingForSecondOperand, setWaitingForSecondOperand] = React.useState(false);

            // 处理数字输入
            const inputDigit = digit => {
                if (waitingForSecondOperand) {
                    setDisplay(String(digit));
                    setWaitingForSecondOperand(false);
                } else {
                    setDisplay(display === '0' ? String(digit) : display + digit);
                }
            };

            // 处理小数点
            const inputDecimal = () => {
                if (!display.includes('.')) {
                    setDisplay(display + '.');
                }
            };

            // 处理基本运算
            const handleOperator = nextOperator => {
                const inputValue = parseFloat(display);
                
                if (firstOperand === null) {
                    setFirstOperand(inputValue);
                } else if (operator) {
                    const result = calculate(firstOperand, inputValue, operator);
                    setDisplay(String(result));
                    setFirstOperand(result);
                }
                
                setWaitingForSecondOperand(true);
                setOperator(nextOperator);
            };

            // 计算结果
            const calculate = (first, second, op) => {
                switch(op) {
                    case '+': return first + second;
                    case '-': return first - second;
                    case '×': return first * second;
                    case '÷': return first / second;
                    default: return second;
                }
            };

            // 科学函数
            const handleScientific = func => {
                const num = parseFloat(display);
                let result;
                
                switch(func) {
                    case 'sin':
                        result = Math.sin(num * Math.PI / 180);
                        break;
                    case 'cos':
                        result = Math.cos(num * Math.PI / 180);
                        break;
                    case 'tan':
                        result = Math.tan(num * Math.PI / 180);
                        break;
                    case 'x²':
                        result = Math.pow(num, 2);
                        break;
                    case '√':
                        result = Math.sqrt(num);
                        break;
                    case 'π':
                        result = Math.PI;
                        break;
                    default:
                        result = num;
                }
                setDisplay(String(result));
            };

            // 处理内存操作
            const handleMemory = operation => {
                const currentValue = parseFloat(display);
                
                switch(operation) {
                    case 'STO':
                        setMemory(currentValue);
                        break;
                    case 'RCL':
                        setDisplay(String(memory));
                        break;
                    default:
                        break;
                }
            };

            // 清除操作
            const clear = () => {
                setDisplay('0');
                setFirstOperand(null);
                setOperator(null);
                setWaitingForSecondOperand(false);
            };

            // 删除最后一位
            const handleDelete = () => {
                if (display.length > 1) {
                    setDisplay(display.slice(0, -1));
                } else {
                    setDisplay('0');
                }
            };

            // 正负号转换
            const toggleSign = () => {
                setDisplay(String(-parseFloat(display)));
            };

            return (
                <div className="calculator">
                    <div className="model-name">Dave Model-1</div>
                    <div className="display">{display}</div>
                    <div className="buttons">
                        <button className="bg-green-500 text-white" onClick={() => handleScientific('HYP')}>HYP</button>
                        <button className="bg-green-500 text-white" onClick={() => handleScientific('sin')}>SIN</button>
                        <button className="bg-green-500 text-white" onClick={() => handleScientific('cos')}>COS</button>
                        <button className="bg-green-500 text-white" onClick={() => handleScientific('tan')}>TAN</button>
                        <button className="bg-gray-200" onClick={() => handleOperator('÷')}>÷</button>
                        
                        <button className="bg-green-500 text-white" onClick={() => handleScientific('π')}>π</button>
                        <button className="bg-green-500 text-white" onClick={() => handleScientific('x²')}>x²</button>
                        <button className="bg-green-500 text-white" onClick={() => handleScientific('√')}>√</button>
                        <button className="bg-green-500 text-white" onClick={() => handleOperator('y^x')}>y^x</button>
                        <button className="bg-gray-200" onClick={() => handleOperator('×')}>×</button>
                        
                        <button className="bg-gray-100" onClick={() => inputDigit(7)}>7</button>
                        <button className="bg-gray-100" onClick={() => inputDigit(8)}>8</button>
                        <button className="bg-gray-100" onClick={() => inputDigit(9)}>9</button>
                        <button className="bg-green-500 text-white" onClick={handleDelete}>DEL</button>
                        <button className="bg-gray-200" onClick={() => handleOperator('-')}>-</button>
                        
                        <button className="bg-gray-100" onClick={() => inputDigit(4)}>4</button>
                        <button className="bg-gray-100" onClick={() => inputDigit(5)}>5</button>
                        <button className="bg-gray-100" onClick={() => inputDigit(6)}>6</button>
                        <button className="bg-green-500 text-white" onClick={() => handleMemory('RCL')}>RCL</button>
                        <button className="bg-gray-200" onClick={() => handleOperator('+')}>+</button>
                        
                        <button className="bg-gray-100" onClick={() => inputDigit(1)}>1</button>
                        <button className="bg-gray-100" onClick={() => inputDigit(2)}>2</button>
                        <button className="bg-gray-100" onClick={() => inputDigit(3)}>3</button>
                        <button className="bg-green-500 text-white" onClick={() => handleMemory('STO')}>STO</button>
                        <button className="bg-blue-500 text-white" onClick={() => handleOperator('=')}>=</button>
                        
                        <button className="bg-gray-100" onClick={() => inputDigit(0)}>0</button>
                        <button className="bg-gray-100" onClick={inputDecimal}>.</button>
                        <button className="bg-green-500 text-white" onClick={toggleSign}>±</button>
                        <button className="bg-green-500 text-white" onClick={clear}>CLR</button>
                        <button className="bg-green-500 text-white">ON</button>
                    </div>
                </div>
            );
        };

        // Mount the Calculator component
        const container = document.getElementById('calculator-root');
        const root = ReactDOM.createRoot(container);
        root.render(React.createElement(Calculator));
    </script>

    <!-- Babel for JSX transpilation -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.20/babel.min.js"></script>
</body>
</html>

2.1 style.css

/* Calculator Component Styles */
:root {
    --calc-bg: #4a4a4a;
    --display-bg: #c8c8c8;
    --btn-function: #3CB043;
    --btn-number: #f8f8f8;
    --btn-operation: #f0f0f0;
    --btn-equals: #4a90e2;
    --text-light: #ffffff;
    --text-dark: #000000;
    --border-color: #999;
    --shadow-color: rgba(0, 0, 0, 0.3);
}

/* Calculator Container */
.calculator {
    background-color: var(--calc-bg);
    padding: 15px;
    border-radius: 10px;
    box-shadow: 0 4px 8px var(--shadow-color);
    width: 300px;
}

/* Model Name */
.model-name {
    color: var(--text-light);
    font-size: 14px;
    margin-bottom: 10px;
    font-family: Arial, sans-serif;
}

/* Calculator Display */
.display {
    background-color: var(--display-bg);
    border: 1px solid var(--border-color);
    margin-bottom: 15px;
    padding: 10px;
    text-align: right;
    font-family: "Courier New", monospace;
    font-size: 24px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    border-radius: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Button Grid Layout */
.buttons {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 8px;
}

/* Base Button Styles */
button {
    background-color: var(--btn-number);
    border: none;
    border-radius: 5px;
    padding: 12px 0;
    font-size: 18px;
    cursor: pointer;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    transition: all 0.1s ease;
    user-select: none;
}

button:hover {
    filter: brightness(90%);
}

button:active {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    transform: translateY(1px);
}

/* Function Buttons */
.function-btn {
    background-color: var(--btn-function);
    color: var(--text-light);
}

/* Operation Buttons */
.operation-btn {
    background-color: var(--btn-operation);
}

/* Number Buttons */
.number-btn {
    background-color: var(--btn-number);
}

/* Equals Button */
.equals-btn {
    background-color: var(--btn-equals);
    color: var(--text-light);
}

/* Responsive Design */
@media screen and (max-width: 320px) {
    .calculator {
        width: 100%;
        padding: 10px;
    }

    .buttons {
        gap: 6px;
    }

    button {
        font-size: 16px;
        padding: 10px 0;
    }

    .display {
        font-size: 20px;
        height: 35px;
    }
}

/* Button States for Touch Devices */
@media (hover: none) {
    button:hover {
        filter: none;
    }
}

/* High Contrast Mode */
@media (prefers-contrast: high) {
    :root {
        --calc-bg: #000000;
        --display-bg: #ffffff;
        --btn-function: #006400;
        --btn-equals: #00008b;
    }
}

/* Reduced Motion */
@media (prefers-reduced-motion: reduce) {
    button {
        transition: none;
    }
}

/* Print Styles */
@media print {
    .calculator {
        box-shadow: none;
        border: 1px solid #000;
    }

    .display {
        border: 1px solid #000;
        background-color: #fff;
    }
}

2.2 styles.css

/* Root CSS variables for easy theme management */
:root {
    --primary-color: #007BFF;
    --primary-hover: #0056b3;
    --background-color: #f4f4f4;
    --text-color: #333;
    --border-color: #ddd;
    --shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Base styles */
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: var(--background-color);
}

/* Core layout */
.body {
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
}

.container {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    gap: 20px;
    margin: 0 auto;
    padding: 20px;
}

/* Headings and text */
h1, h2 {
    color: var(--text-color);
    margin: 10px 0;
    text-align: center;
}

.centered {
    text-align: center;
    width: 100%;
    margin: 0 auto;
}

/* Tools list styling */
.tools-list {
    list-style: none;
    padding: 0;
    margin: 0;
    width: 180px;
}

.tools-list li {
    margin-bottom: 20px;
}

.tools-list a {
    display: block;
    width: 100%;
    padding: 10px 15px;
    font-size: 1.2em;
    color: var(--primary-color);
    border: 1px solid var(--primary-color);
    border-radius: 5px;
    text-align: center;
    text-decoration: none;
    transition: background-color 0.3s, color 0.3s;
    background-color: white;
    box-sizing: border-box;
}

.tools-list a:hover {
    background-color: var(--primary-color);
    color: white;
}

/* Content sections */
.content {
    display: flex;
    width: 100%;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    text-align: center;
}

.calculator-container {
    flex: 0 0 auto;
}

/* Form elements */
input[type="text"],
input[type="number"] {
    width: 120px;
    padding: 8px;
    font-size: 1em;
    border: 1px solid var(--border-color);
    border-radius: 4px;
}

select {
    width: 120px;
    padding: 8px;
    font-size: 0.9em;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background-colo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值