结对编程实现(306_418)

222100306洪朗晨 2024-03-26 23:32:57

结对第二次作业——编程实现

这个作业属于哪个课程软件工程实践-2023学年-W班
这个作业要求在哪里结对第二次作业——编程实现
结对学号222100418张星航 && 222100306洪朗晨
这个作业的目标原型设计的编码实现、Gitcode的合作使用、撰写博客
其他参考文献CSDN网站 ;bilibili;

目录:

目录

结对第二次作业——编程实现

目录:

1. Gitcode仓库链接

2. 代码规范链接

3. PSP表格

4. 项目访问链接

5. 项目成品展示

Overview-首页

Athlete Rank-运动员排名

Schedule-日程展示

Detal-详细赛况

Medel-国家奖牌榜

6. 设计实现过程

6.1功能结构图

6.2 爬取数据

6.3 前端实现过程

6.4 后端实现过程

6.5 数据库展示

6.6 代码部署

6.6.3 开放端口

7. 结对讨论过程描述

8. 代码说明

8.1返回数据-Python

8.2 设置端口、监听

8.3 前端抓取数据-js

8.4 容器动态创建布局-js

9. 心路历程和收获

10. 评价结对队友

11. 问题及解决方式

问题:后端收到请求,但前端却没有数据显示

问题:利用内网穿透时,更换url让数据都消失了

问题:cors设置了origin但是显示null

问题:选择代码冗余还是抓取数据冗余


1. Gitcode仓库链接

Gitcode仓库链接

2. 代码规范链接

代码规范

3. PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
• Discuss• 讨论如何实现6060
• Assign tasks• 分配任务1515
• Understanding technology• 了解技术6090
• Front end coding• 前端编码300360
•Backend encoding• 后端编码300320
• Parsing data• 解析数据6040
• Front and rear docking• 前后端对接180200
• Fix bug• 解决bug100150
• Review testing• 复审测试6060
deployment server• 部署服务器6080
• Write a blog• 撰写博客6080
 合计12551455

4. 项目访问链接

项目地址

5. 项目成品展示

根据导航栏,网页有以下页面组成:首页、运动员排名、日程展示、国家奖牌榜、详细赛况。分别用英文表示为Overview、Athlete Rank、Schedule、Medal、Detail.

 

 

 

Overview-首页

首页界面内如下:展示关于世界游泳锦标赛的举办背景,通过丰富的图文使平台更具吸引力,引起人们对世界游泳锦标赛的兴趣。

在这里插入图片描述

 

 

Athlete Rank-运动员排名

选手排名界面 :用下拉框展示了66th International Divers’ Day Rostock的排名,包含Overall Rank,Country,Athlete,Age,Points

img


 

 

Schedule-日程展示

每日赛况和比赛详情:展示比赛日期和比赛项目、类型等 鼠标可以进行日期的选择,放置在某个比赛上显示高亮,点击比赛显示比赛的详情:

 

img

 

Detal-详细赛况

 

img

 

 

Medel-国家奖牌榜

奖牌榜:显示各个国家的获奖情况。

 

img

 

6. 设计实现过程

6.1功能结构图

 

在这里插入图片描述

 

6.2 爬取数据

从官网上找到选手排名、每日赛况、详细赛况、奖牌榜等相应页面,利用浏览器的开发者工具,在network中爬取到了本次作业所需的数据。
说明:本次爬取行为和爬取数据仅用于学习!

6.3 前端实现过程

  • 技术和框架:(本来想用vue来完成本次作业,在经过短暂学习和使用后发现过于复杂,不好上手。最后选择纯前端HTML、CSS、JS)
  • 界面设计:根据原型设计以及作业要求,在原型界面的基础上进行了适当的修改。分为首页、选手排名、每日赛况、详细赛况、奖牌榜五个界面。
  • 数据的获取:通过fetch函数(js),从后端传回的接口抓取数据。

6.4 后端实现过程

  • 编程语言:Python
  • Web框架:Flask框架。因为本次内容专注于少量数据的读取和展示,没有过多的复杂功能,因此使用轻量级的Web框架进行开发。
  • 数据来源:首先利用网页抓包爬取(具体参考文件夹中的代码:其他信息\后端处理数据等其他代码\Python_fetch_20240303_task2)网页数据
  • 数据存储:因为将数据库部署到云数据库需要多余的费用,所以弃用了原来的orm映射Mysql(代码在“其他信息\后端处理数据等其他代码“中),改把爬取的数据存在csv文件中,读取文件来实现数据提取。
    • 文件夹swim_cmpt对应原数据库
    • 每一个csv文件对应一个
    • 每个csv文件夹的列名对应原来的字段
  • 数据解析:将需要的EventName, DisciplineName, EventResultDate, HeatName, OverallRank, Country, Athlete, Age, Points, PtsBehind抓取,存在event_result(mysql表/csv)中读取json 解析json 向前端传数据等
  • 数据反馈:使用 JSON 格式返回数据,支持跨域请求。
  • 跨域:调试过程中出现了跨域的Cors问题,根据学习的过程在代码中增加了代理、cors允许等代码,但其实可能失败了,但原代码不敢删除,因为怕引发更大的错误。
  • 主要思路
    • 后端的实现思路很简单:主要就是把数据库中的内容返回就可以。本来只需要一个函数。
    • 但是为了避免重复多次查询,重新设计了表。(具体见[数据库设计](# 6.5 数据库展示))建立了多个表,表之间有多层外键的联系(但在这里没有用外键,为了方便debug,这也是一个缺点)

6.5 数据库展示

表名athlete_info
字段类型
idint(11)
Countryvarchar(255)
Athletevarchar(255)
Gendervarchar(10)
DOBdate
Disciplinevarchar(255)

表名date_list
字段类型
idint(11)
EventResultDatedate

表名event_items
字段类型
idint(11)
DisciplineNamevarchar(255)
EventResultDatedate
HeatNamevarchar(255)

表名event_results2
字段类型
idint(11)
EventNamevarchar(255)
DisciplineNamevarchar(255)
EventResultDatedate
HeatNamevarchar(255)
OverallRankint(11)
Countryvarchar(255)
Athletevarchar(255)
Ageint(11)
Pointsfloat
PtsBehindfloat

表名medals
字段类型
idint(11)
EventNamevarchar(255)
EventTypeNamevarchar(255)
SportCodevarchar(10)
DisciplineCodevarchar(10)
CountryNamevarchar(255)
Rankint(11)
Goldint(11)
Silverint(11)
Bronzeint(11)
Totalint(11)

6.6 代码部署

利用阿里云平台,将平台部署在云服务器上。

6.6.1 环境设置


 
  1. // 更新

  2. apt update

  3. // 安装nginx 80端口,更新,安装

  4. apt install nginx

  5. python3

  6. // 查看python是否正常

  7. pip3 install –upgrade pip

  8. pip list

  9. //更改安装源,可跳过

  10.  
  11. // 配置虚拟环境

  12. // 安装虚拟环境包

  13. pip install virtualenvwrapper

  14. ls -al

  15. vi .bashrc

// .bashrc中插入这段


 
  1. export WORKON_HOME=$HOME/.virtualenvs

  2. VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3

  3. source/usr/local/bin/virtualenvwrapper.sh


 
  1. // 可能是查看一下

  2. source ~/.bashrc


 
  1. // 下面是虚拟环境中运行

  2. cd .virtualenvs

  3. mkdir .....//在这里建了个文件夹

【 .virtualenvs】 如果突然断线……如何快速建立虚拟环境


 
  1. // 虚拟环境创建

  2. mkvirtualenv --python=/usr/bin/python3 test_env

  3.  
  4. cd .virtualenvs

  5. // .virtualenvs文件下是test_dev虚拟环境

  6. workon test_dev

【srv】 找到跑代码的地方


 
  1. // 退出返回到srv

  2. cd /srv

  3.  
  4. cd test

  5. //进入我的文件夹test

然后连接 【git】


 
  1. git init

  2. ......

  3. pull origin dev

6.6.2 云服务器服务中情况

 

img

 

6.6.3 开放端口

购买后,记得开放80端口、服务器运行端口等,才能够正常访问。

 

img

 

7. 结对讨论过程描述

由于洪朗晨同学有接触过后端的相关知识,因此我们经过讨论初步决定她写后端,我写前端(刚开始是学习使用vue框架的,后面感觉出了很多问题转用纯前端了)。

在这里插入图片描述


 

 

创建gitcode的dev分支,但是某条指令有问题,导致一直我无法创建dev分支,最后还是朗晨同学远程控制我的电脑,帮我解决了这个麻烦。

在这里插入图片描述

 


实现过程中的一些讨论

 

在这里插入图片描述

 


后端给我数据的时候我无法接收到数据,不太清楚是什么原因导致的。最后只能辛苦朗晨同学把数据传到我的前端界面,并进行一些代码修改。

 

在这里插入图片描述

 

8. 代码说明

8.1返回数据-Python

此处定义了获取数据路由event_results,前端只要访问 ip/event_results,就可以从这里抓取json数据。


 
  1. @app.route('/event_results', methods=['GET'])

  2. def get_event_results():

  3. auth_header = request.headers.get('Authorization')

  4. date_index = int(request.args.get('date', -1)) # 获取日期索引,默认为-1

  5.  
  6. if auth_header and auth_header.startswith('Basic '):

  7. pass

  8.  
  9. filename = 'event_results2.csv' # 默认使用事件结果文件

  10. event_results = read_csv_file(filename)

  11.  
  12. result = []

  13. # 如果提供了日期索引,则根据日期查询事件结果

  14. ......

  15. # 否则全部返回

  16. for event_result in event_results:

  17. result.append({

  18. 'id': event_result['id'],

  19. 'EventName': event_result['EventName'],

  20. 'DisciplineName': event_result['DisciplineName'],

  21. 'EventResultDate': event_result['EventResultDate'],

  22. 'OverallRank': event_result['OverallRank'],

  23. 'Country': event_result['Country'],

  24. 'Athlete': event_result['Athlete'],

  25. 'Age': event_result['Age'],

  26. 'Points': event_result['Points'],

  27. 'PtsBehind': event_result['PtsBehind'],

  28. 'HeatName': event_result['HeatName']

  29. })

  30.  
  31. return jsonify(result), 200

响应结果如下:

 

img

 

8.2 设置端口、监听


 
  1. if __name__ == '__main__':

  2. app.run(debug=True, host="0.0.0.0", port=8001)

  • 这里对 port=8001 端口进行监听
  • 0.0.0.0的设置是 使得 所有主机都能访问我的服务器。这不太安全,但为了作业能被访问。更安全的做法是设置具体要访问我的电脑的ip,监听多个固定主机。

8.3 前端抓取数据-js

前端除了css外,最关键的是用fetch抓取url的数据,后续进行处理。


 
  1. // 获取后端日期列表

  2. fetch('http://8.138.122.120:8001/date_list')

  3. .then(response => response.json())

  4. .then(data => {

而这里有待优化的地方是 云服务器ip 最好能够输入,或更改,而不要编码进代码。否则更换服务器后必须手动更改此处代码。

8.4 容器动态创建布局-js

这里灵活的地方在于,schedule是根据数据库内容自动创建容器数量的,这很灵活(但也很负杂)。

  • 首先通过date_list:获取到一共表格中有哪些日期dates
  • 再从event_intems中:根据日期date查询相关的记录
  • 再根据event_intems:的个数创建当日的项目个数
  • 遍历所有dates如上。

这里没有页面的跳转,而是容器的变化。


 
  1. function changeDate(index) {

  2. const dateBoxes = document.querySelectorAll('.date-box');

  3.  
  4. if (index >= 0 && index < dateBoxes.length) {

  5. dateBoxes[currentDateIndex].classList.remove('selected');

  6. currentDateIndex = index;

  7. dateBoxes[currentDateIndex].classList.add('selected');

  8.  
  9. // 清空结果容器内容

  10. const resultDiv = document.getElementById('result');

  11. resultDiv.innerHTML = '';

  12.  
  13. // 获取当前选中日期的比赛信息

  14. const selectedDate = dateBoxes[currentDateIndex].textContent;

  15.  
  16. // 请求后端获取比赛信息

  17. fetch('http://8.138.122.120:8001/event_items?date=' + encodeURIComponent(selectedDate))

  18. .then(response => response.json())

  19. .then(data => {

  20. // 遍历比赛信息,创建信息框并填充内容

  21. data.forEach((event, index) => {

  22. resultDiv.innerHTML += `

  23. <div class="info-box" onclick="redirectToDetail('${event.DisciplineName}')">

  24. <div class="title">${event.DisciplineName}</div>

  25. <div class="type">${event.HeatName}</div>

  26. <div class="time">${event.EventResultDate}</div>

  27. </div>`;

  28. });

  29. })

  30. .catch(error => {

  31. console.error('Error fetching event items:', error);

  32. });

  33. }

  34. }

  35.  

9. 心路历程和收获

  • 张星航的心路历程和收获:这次的作业让我感觉有点质壁分离。刚开始本来想用vue来写前端,配置好环境后学习了一下vue的使用手册,但是在实现过程发现用vue有点难,最后放弃了选择去用纯前端技术写前端界面。界面写好后跟队友的数据对接又存在问题(她的后端数据我根本获取不了),俩个人解决了好久。但是回过头想想,这次的作业也让我受益匪浅。对前端技术的认识更进一步,学会了一些环境的配置。个人作业与结对作业完全不一样,与队友的配合至关重要,遇到问题需要俩个人积极配合一起解决才能取得最后的胜利。这次的作业也让我能够在以后的团队作业中更加得心应手。
  • 洪朗晨的心路历程和收获:
    • 【结对编程】:在团队合作中,更能暴露自己的强弱,这种密切的连接让我们更加清楚自己技术上的不足与强项。而更重要的是,我发现在团队开发中,未必两个人技术都强大,就能做好编程,这里软件的“软”实力就体现。
    • 【合作】我和队友优势互补,各司其职,相辅相成。在完成任务的过程中,我们都感受到了对方的不放弃和支持,这是这次作业最激动人心的地方所在。
    • 【差距/分工】我和队友技术水平上有一些差距。总体来说,我们就像老师课上说的“学-带”模式。
      • 【经验只有一点点】因为我了解过前后端交互时后端的工作,一开始分工的时候我做后端,队友做前端。
      • 【不了解对接】很快,我就把需要的数据,用后端返回,并编写好了代码。
      • 【前端对接】后来发现队友对前端的对接难以了解,我变便承担起了对接的工作。
      • 【对接思路】我了解过思路是前端抓取后端返回的数据,并进行显示,项目便解决了。但没有实现过。
      • 【前端编程】因为不了解前端编程,不得不进行一定的学习,并借助AI工具解析代码以便理解。
      • 【对接调试】对接调试的阶段,既改前端,也改后端,有时候出了bug不知道是前端还是后端……但和前后端打架不同,因为自己一个人对接,让我感觉出问题的时候,沟通的压力和负担减少了,提高了效率,让我感受到了全栈工程师的好处和坏处……
    • 【情绪】
      • 我对数据的关注和对数据显示平台的制作充满追求,热情而兴奋。
      • 或许在设计这个数据显示平台的过程中,我遇到了一些挑战,但我和队友的毅力和决心让我克服了这些困难。
      • 在难以坚持下去的时候,我会想到当我最终完成了这个有用的数据显示平台,并且它能够灵活地利用数据,我会感觉一切曾经以为的灾难都是值得的。

10. 评价结对队友

张星航 To 洪朗晨:队友非常优秀,很早就接手过后端的相关项目。在前后端对接遇到问题时,她也能够非常积极帮我去解决。有想法也会跟我及时的沟通交流,询问我的意见。队友的帮助让我感受到团队的温暖。

洪朗晨 To 张星航 :队友是个全力以赴不言弃的人,在合作过程中我感觉到了巨大的鼓励和支持,不论任何问题我们都能共同分担,但希望可以多学习软件工程知识,对于基础工具的使用还不熟练,对于对接的具体实现没有机会了解,这是一个中肯的建议,希望在日后能够渐渐习得这样的知识。

 

11. 问题及解决方式

问题:后端收到请求,但前端却没有数据显示

跨域问题,加上了cors(app)就可以了

问题:利用内网穿透时,更换url让数据都消失了

【原因】后端需要设置代理,因为

在Web开发中,浏览器会限制从一个源加载的资源与来自另一个源的资源进行交互。源是由协议(例如http或https),主机(例如worldaquatics.free.idcfengye.com),和端口号(如果有的话)组成的。如果两个页面的源不同,浏览器就会阻止它们之间的通信。这可能是由于浏览器的安全策略所致,称为"同源策略"。

在这种情况下,前端页面部署在一个源(例如localhost或127.0.0.1)上,而后端数据通过'http://worldaquatics.freeidcfengye.com/event_results' 这个URL提供,这两个源是不同的。因此,浏览器会阻止前端页面尝试从不同源的URL获取数据。

【解决】

使用代理:在你的后端服务器上设置代理,使前端页面可以通过与相同源的URL来获取数据。例如,你可以在后端设置一个路由,该路由将从'http://worldaquatics.free.idcfengye.com/event_results'获取数据并将其转发给前端页面。

问题:cors设置了origin但是显示null

【原因】

如果页面是通过本地文件系统直接打开的(即没有通过 HTTP 或 HTTPS 协议加载页面),浏览器可能会将来源设置为 'null',从而导致 CORS 请求失败。

 

【解决】一种方法是:确保页面是通过 HTTP 或 HTTPS 协议加载的,而不是直接通过文件系统打开的。

问题:选择代码冗余还是抓取数据冗余

因为我其他的y页面需要其他的参数,问题是:这两个页面都调用同一个函数,而可能产生抓取的数据里面参数冗余;编写两个函数,但这样查询数据库就要两编后端冗余。如何取舍?

在设计API时,需要权衡两个方面:端点的简洁性和数据冗余。下面是两种可能的方法:

  1. 共用一个函数:

    • 优点: 代码简洁,维护成本低,不需要重复编写相似的代码。

    • 缺点: 数据可能存在冗余,如果多个页面只需要部分数据,那么获取整个对象可能会浪费资源。

  2. 编写两个函数:

    • 优点: 每个页面只获取所需数据,减少了数据冗余,节省了资源。

    • 缺点: 代码重复,维护成本较高。

如果数据冗余不是太大的问题,而且更看重代码的简洁性和维护成本,那么共用一个函数可能是更好的选择(吧)。

...全文
153 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

310

社区成员

发帖
与我相关
我的任务
社区描述
福州大学的软件工程实践-2023学年-W班
软件工程需求分析结对编程 高校 福建省·福州市
社区管理员
  • FZU_SE_teacherW
  • Pity·Monster
  • 助教张富源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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