软件工程现场编程

作业所属课程 班级的链接
作业要求 2024秋软件工程现场编程作业 - 作业 - 软件工程2024 - 班级博客 - 博客园
作业的目标 开发一个个人记账本
团队名称 银河战舰
团队成员名字-学号 102202129-林伟宏 102202131-林鑫 102202109-木合塔拉提 102202143-梁锦盛 102202126-陈家凯 102202148-路治 102202116-李迦勒 102202103-王文豪 102202113-许煊宇 102202155-王贺雯
  1. 组员职责分工:
姓名 角色 具体分工
林宏伟 组长 负责项目的整体规划、执行和控制,确保项目按时、按质完成
林鑫 后端负责人 副组长 负责后端任务协调 代码编写
木合塔拉提 后端 负责后端代码编写
梁锦盛 后端 负责后端代码编写
陈家凯 前后端 负责协调前后端工作 ai接口
路治 前端 前端代码编写
李迦勒 前端 前端代码编写
王文豪 前端 前端代码编写
许煊宇 前后端 负责协调前后端工作 ai接口
王贺雯 美工和文档扁编写 美工展示和博客编写
  1. 程序运行环境:

    • 操作系统:任何支持Python的操作系统,如Windows、macOS或Linux。

    • Python版本:Python 3.x(具体版本取决于Flask和其他依赖库的兼容性)。

    • 依赖库:Flask(用于Web应用框架),axios(用于浏览器端发起HTTP请求)。

    • 数据存储:本地JSON文件(billing.json)用于存储交易记录。

    • 运行环境:可以在本地开发环境中运行,如PyCharm、VSCode等IDE,或者直接在命令行中运行。

  2. 软件运行截图和视频:

  3. 软件实现的关键代码:

    后端 Flask 应用的关键代码:
    
    数据文件初始化
    # 确保数据文件存在,如果不存在则创建一个空的JSON数组文件
    DATA_FILE = 'billing.json'
    if not os.path.exists(DATA_FILE):
        with open(DATA_FILE, 'w', encoding='utf-8') as f:
            json.dump([], f, ensure_ascii=False)  # 确保非ASCII字符被正确处理
    
    
    当然,以下是一些关键代码段及其注释说明:
    后端 Flask 应用的关键代码:
    数据文件初始化
    python
    # 确保数据文件存在,如果不存在则创建一个空的JSON数组文件
    DATA_FILE = 'billing.json'
    if not os.path.exists(DATA_FILE):
        with open(DATA_FILE, 'w', encoding='utf-8') as f:
            json.dump([], f, ensure_ascii=False)  # 确保非ASCII字符被正确处理
    这段代码确保了应用的数据文件billing.json存在,如果不存在则创建一个空的JSON数组。
    添加交易记录的API
    @app.route('/billing/loadData', methods=['POST'])
    def add_Data():
        data = request.json  # 获取JSON请求体中的数据
        # 确保所有必要的字段都存在
        if not all(key in data for key in ['date', 'price', 'category']):
            return jsonify({'error': 'Missing required fields'}), 400
        # 读取和更新数据文件
        with open(DATA_FILE, 'r+', encoding='utf-8') as f:
            transactions = json.load(f)
            new_transaction = {
                'date': data['date'],
                'price': data['price'],
                'category': data['category'],
                'note': data.get('note', '')  # 备注是可选的
            }
            transactions.append(new_transaction)
            f.seek(0)
            json.dump(transactions, f, ensure_ascii=False)
            f.truncate()
        return jsonify({'redirect': url_for('index', _external=True)}), 201
    
    读取最新记录的API
    @app.route('/read')
    def read():
        try:
            # 读取 JSON 文件
            with open("billing.json", 'r', encoding='utf-8') as f:
                data = json.load(f)
            # 获取最新的十条数据
            latest_records = data[-10:]  # 如果数据不足十条,将返回所有数据
            # 渲染网页并传递数据
            return render_template('index_read.html', records=latest_records)
        except FileNotFoundError:
            return "JSON 文件未找到。"
    
    收支统计API
    @app.route('/billing/statistics', methods=['GET'])
    def get_statistics():
        # 从请求参数获取日期范围和类别过滤条件
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        category = request.args.get('category')
        # 设置过滤条件
        date_filter = (start_date, end_date) if start_date and end_date else None
        category_filter = category if category else None
        # 读取数据
        records = read_records_from_json()
        # 计算统计结果
        result = calculate_totals(records, date_filter=date_filter, category_filter=category_filter)
        # 返回 JSON 格式的统计结果
        return jsonify(result)
    
    
    前端 HTML/JavaScript 应用的关键代码:
    
    提交表单并调用后端API
    <script>
        function submitForm(event) {
            event.preventDefault();
    
            const data = {
                date: document.getElementById('date').value,
                price: parseFloat(document.getElementById('price').value),
                category: document.getElementById('category').value,
                note: document.getElementById('note').value
            };
    
            axios.post('/billing/loadData', data)
               .then(function (response) {
                    alert('数据添加成功!');
                    console.log(response.data);
                })
               .catch(function (error) {
                    alert('添加数据失败:' + error.response.data.error);
                    console.error(error);
                });
        }
    </script>
    
    加载最近记录并显示
    <script>
        document.getElementById('loadRecentRecords').onclick = function() {
            axios.get('/billing/recentRecords') // 确保这个URL与后端设置的路由相匹配
                .then(function (response) {
                    const records = response.data; // 假设后端返回的数据是一个数组
                    const recentRecordsList = document.getElementById('recentRecords');
                    recentRecordsList.innerHTML = '';
                    records.forEach(record => {
                        const item = document.createElement('li');
                        item.textContent = `日期:${record.date}, 金额:${record.price}, 类别:${record.category}, 备注:${record.note}`; // 确保属性名与后端返回的数据结构相匹配
                        recentRecordsList.appendChild(item);
                    });
                })
                .catch(function (error) {
                    alert('加载最近记录失败');
                });
        };
    </script>
    
  4. 软件的亮点:

    o 前后端分离:前端使用HTML/CSS/JavaScript构建用户界面,后端使用Flask提供API服务,实现了前后端分离,有利于项目的模块化开发和维护。

    o 实时数据交互:使用axios库在前端实现与后端的实时数据交互,用户可以即时看到自己的操作结果,提升了用户体验。

    o 简洁的数据存储:使用本地JSON文件作为数据存储,简化了部署和配置,同时易于数据的迁移和备份。

  5. 编码、争论、复审等活动中花费时间较长,收获较大的事件:

    · 数据一致性处理:在处理并发请求时,如何保证数据的一致性是一个挑战。我们讨论并实现了文件锁定机制,确保在写入数据时不会有多个请求同时操作文件,这提升了系统的稳定性。

    · 前端用户体验优化:在前端实现时,我们花费了较多时间讨论如何优化用户界面和用户体验,包括按钮的动画效果、输入字段的验证提示等,这些细节的提升显著增强了用户满意度。

    · 安全性考虑:在开发过程中,我们意识到需要对输入数据进行验证以防止注入攻击。我们引入了对输入数据的校验逻辑,并讨论了如何更全面地保护API免受恶意攻击,这个过程中我们对Web安全有了更深入的理解。

  6. 每个组员的团队编程体验

    林宏伟:

    在这次现场编程中,我像是置身于战场的战士,代码就是我的武器。每一次敲击键盘,都伴随着紧张与兴奋。
    现场编程的紧迫感是最大挑战,时间像紧箍咒,促使我快速思考。但这也激发了潜能,思路在压力下更加清晰有条理。看到代码一行行实现功能,那种成就感无法言喻。同时,我深知准备工作的重要性,扎实的基础知识和事先练习的算法是成功的基石。这次经历让我明白,编程不仅是技术,更是在有限条件下的突破与创新。
    

    林鑫:

      通过本次项目的实践,我不仅学会了如何使用 Flask 构建后端服务,还加深了对数据处理、用户友好性设计以及系统安全性的理解。这些经验对我的未来学习和工作都有极大的帮助。此外,团队协作让我学会了如何与团队成员沟通和协作,共同推动项目向前发展。
    

    木合塔拉提:

    在本次项目的实践中,我深入了解了如何在后端实现个人记账系统的统计功能,不仅巩固了对数据处理和分类统计的掌握,还逐步培养了分析和优化代码的能力。通过这个项目,我对数据实时性和用户界面友好性有了更深刻的认识,同时也学习了如何将系统设计与用户需求相结合。此次经验让我更清晰地意识到结构化开发和功能模块设计在项目中的重要性,这些积累将为我未来的开发工作提供宝贵的帮助。此外,独立开发的过程中,我也感受到不断完善和调试代码的重要性,未来会更主动地去改进和提升我的编程能力,以适应更多复杂的开发任务。
    

    李迦勒:

    从功能设计角度来看,基础记账功能是整个记账本的核心。允许用户记录日期、金额、类别和备注等详细信息,能够让用户全面地了解每一笔收支的具体情况。选择使用本地文件保存数据,如 JSON 或者 CSV 格式,既保证了数据的持久性,又相对容易实现。在实际开发中,需要考虑数据的格式规范和读写操作的效率,确保数据的准确存储和快速读取。
    
    查看数据功能为用户提供了便捷性,让他们可以随时回顾最近的几笔记录。这对于用户快速了解自己的近期收支情况非常有帮助,同时也有助于他们及时发现可能的错误记录。
    

    梁锦盛 :

      这是我们团队第一次现场合作编写代码,我之前对于如何与其它队员合作编写代码尚不熟悉,通过本次项目与队员的充分沟通与协作,我对如何实现前后端分离编写项目代码有了初步的经验,我也对利用Flask完成中小型web项目有了一定理解,对根据用户需求进行项目设计有了认识。这些东西都将在未来进行团队开发时起到重要作用,帮助我更好地理解并满足用户和团队的需求。我将积极汲取本次现场编码的经验并将其运用到未来的团队项目开发中。
    

    陈家凯:

      第一次小组现场编程的过程中,我认感受到沟通真的是特别重要,每个成员都要明确自己的任务,而且大家要积极交流,分享进度和遇到的问题。这样不仅能避免重复劳动,还能及时发现问题并一起解决。在合作过程中,还要学会尊重每个人的想法和贡献。每个人的视角和经验都不同,这些差异往往是解决问题的关键。在这次项目中,我作为前端的编写人员,更要特别注意前后端的分离和交互。要确保前端页面能够正确地请求后端接口,并且能优雅地处理后端返回的数据。
    

    路治:

      从项目一开始,我就深知用户界面对于整个记账本软件的重要性。它是用户与软件交互的窗口,直接影响用户体验。在设计记账界面时,我精心规划每个输入框的位置和大小,比如,对于日期输入框,既要保证它有足够的空间清晰显示,又不能让整个界面显得拥挤。在选择颜色搭配时,我避免过于刺眼或暗淡的色彩组合,选择了简洁明了的色调,以确保用户在长时间使用时眼睛不会感到疲劳。对于每个按钮的设计,从形状到颜色变化的交互效果,都经过了反复斟酌,让用户能够直观地知道如何操作。                        
      这次现场编程经历让我在前端和 UI 设计领域有了新的认识和提升。我更加明白了用户体验的核心地位,以及如何在技术和设计之间找到平衡。同时,与团队成员共同克服困难的过程也让我收获了宝贵的团队协作经验。在未来的项目中,我将带着这些经验,继续探索更优秀的前端和 UI 设计,为用户创造更加美观、便捷的软件界面。
    

    王文豪:

     通过本次的团队实验(第一次现场合作),我学习了如何引入 Bootstrap, 通过添加Bootstrap 的CDN链接,使页面可以利用Bootstrap 的样式和组件,从而优化界面,使其有更好的视觉效果。同时培养了与团队成员之间的默契,通过对问题的探讨,交流沟通与合作,我进一步提升了自身适应性,为下一次的团队合作奠定了基础
    

    许煊宇 :

      通过本次项目的实践,我熟悉了 Flask 框架在前端呈现方面的特点和规则。同时,在设计用户界面时,考虑要让操作简单直观,方便大家记录收支情况。经过反复调整布局和样式,期望能给用户较好的体验。和后端的同学对接也不轻松,要弄清楚数据如何传递、格式如何统一。好在通过不断沟通和协作,对接逐渐变得顺畅起来。限时完成任务有一定压力,但在这个过程中,我不仅学到了 Flask 前端开发的一些技巧,还明白了团队协作的重要性。这次作业让我收获颇丰。
    

    王贺雯:

      万万没想到还有现场编程,知道这个消息的时候天都塌了,疑是十一月的第一枪。要在短短几个小时内完成编程任务和答辩展示,我真的不敢现象。一开始自己尝试做一个模块,但做出来的不尽人意,所以最后采用了其他组员的代码,看着队员们为实现功能绞尽脑汁头脑风暴感觉他们真不容易,我自己十分感到抱歉,对团队的贡献并没有多少,再次给分担了大部分工作的队友们和队长致歉。我来了这边访学,真的感觉与同学们差距很大,但我会去具体学一下,争取以后不拖后腿。
    
  7. PSP:

    PSP2.1 Personal Software Process Stages 预估耗时(min) 实际耗时(min)
    Planning 计划 20 30
    · Estimate · 估计这个任务需要多少时间 10 15
    Development 开发 200 180
    · Analysis · 需求分析 (包括学习新技术) 40 30
    · Design Spec · 生成设计文档 30 30
    · Design Review · 设计复审 (和同事审核设计文档) 20 15
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20 15
    · Design · 具体设计 20 15
    · Coding · 具体编码 50 45
    · Code Review · 代码复审 20 15
    · Test · 测试(自我测试,修改代码,提交修改) 40 30
    Reporting 报告 70 60
    · Test Report · 测试报告 20 15
    · Size Measurement · 计算工作量 20 15
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 30
    合计 360 360
  8. GitHub 仓库地址:Branches · lin10-coding/yinghe

  9. 提交记录:


11.评分

组员 分工(满分100)
林伟宏 98
林鑫 99
木合塔拉提 98
梁锦盛 97
陈家凯 94
路治 95
李迦勒 96
王文豪 96
许煊宇 95
王贺雯 96