软件工程实践结对作业二
| 这个作业属于哪个课程 | 2022年福大-软件工程;软件工程实践-W班 |
|---|---|
| 这个作业要求在哪里 | 软件工程实践结对作业一 |
| 结对学号 | 221900135;221900234 |
| 这个作业的目标 | 1.实现三个基础功能板块(奖牌总榜、每日赛程、奖牌地图) 2.酌情完成附加功能 3.将项目部署到云服务器 |
| 其他参考文献 | CSDN、博客园、简书、B站、部分参考资料 |
目录
- 一、项目成果
- 1.1 Gitcode仓库网址
- 1.2 云服务器项目网址
- 1.3 代码规范来源
- 二、PSP表格和效能分析
- 2.1 PSP表格
- 2.2 效能分析
- 三、设计思路和成品展示
- 3.1 设计思路
- (1)技术和框架选择
- (2)数据来源
- (3)功能结构图
- 3.2 成品展示
- 四、结对讨论过程
- 4.1 结对过程群聊展示
- 4.2 结对过程照片展示
- 五、设计实现过程
- 5.1 页面实现过程
- 5.2 实现过程中的难点
- 六、代码说明
- newnav导航栏
- firstpage首页
- medals奖牌总榜
- medalMap奖牌地图
- matches查询赛程
- 七、心路历程和收获
- 7.1 心路历程
- 7.2 收获
- 八、评价结对队友
- 九、参考资料
一、项目成果
1.1 Gitcode仓库网址
1.2 云服务器项目网址
1.3 代码规范来源
二、PSP表格和效能分析
2.1 PSP表格
| Personal Software ProcessStages | 预估耗时(分钟) | 实际耗时(分钟) | |
|---|---|---|---|
| Planning | 计划 | 30 | 40 |
| - Estimate | - 估计这个任务需要多少时间 | 15 | 20 |
| Development | 开发 | 400 | 520 |
| - Analysis | - 需求分析(包括学习新技术) | 200 | 260 |
| - Coding Stardard | - 代码规范 | 15 | 15 |
| - Discuss | - 结对讨论 | 40 | 50 |
| - Coding | - 编码 | 450 | 520 |
| - Code Review | - 代码复审 | 30 | 30 |
| - Test | - 测试(自我测试、修改代码) | 55 | 60 |
| Reporting | 报告 | 60 | 60 |
| - Test Report | - 测试报告 | 30 | 40 |
| - Size Measurement | - 计算工作量 | 10 | 20 |
| - Postmortem & Process Improvement Plan | - 事后总结, 并提出过程改进计划 | 120 | 120 |
| 合计 | 1455 | 1755 |
2.2 效能分析
对比PSP表格中实际用时和预估用时,发现主要是编码过程和需求分析(学习新技术)差距较大。
- 需求分析(学习新技术)(Learning)
主要是学习新技术效率较低,拖慢了该项进程,最开始预估已经预留出了一定的额外时间,但实际上还是超出预计了。下次可以在
过程中先定好基础编程框架和(细一点的)功能的实现方向,然后再去找相关资料学习,避免大量无意义学习。
(eg.之前去B站搜到的Vue语言学习标题是《一周学会Vue》,看到这个已经有点恐慌了,评论区还火上浇油“不愧是大佬只要一周”,实际上本次开发不需要全面掌握,只要了解涉及到的部分技巧就可以顺利完成编写啦~ 引以为戒引以为戒 ) - 编码(Coding)
使用不熟悉的编程语言也很大程度上拖慢了编程效率(
整个过程非常艰难简直是面向百度编程)。下次使用新技术之前可以先多查阅相关的资料视频,定好基础框架之后也不会脑子浆糊一样一团糟了。编程过程要尽量目标明确,功能模块封装实现会让代码的阅读性更好,也能帮助梳理思路,让编码过程更加顺畅。
三、设计思路和成品展示
3.1 设计思路
(1)技术和框架选择
我们原本打算做前后端分离的网站,前端用vue-cli的脚手架,后端用Node.js。但是因为我们不熟悉基于 Node.js 的构建工具。于是选择使用前后端不分离的形式来进行开发。具体情况如下:
相关技术:CSS、HTML、Vue、ElementUI、Echarts
相关工具:VSCode IDEA
数据库:SQlite
代码托管平台:Gitcode
(2)数据来源
【该爬取行为仅用于课程教学】
数据来源主要是直接对某CCTV冬奥栏目的数据获取然后保存于json格式文件
(3)功能结构图

3.2 成品展示
首页
可以点击导航栏进行页面跳转,首页轮播图展示2022冬奥精彩时刻。

奖牌总榜
- 跳转页面

- 金牌、银牌、铜牌、总数升降序展示

- 改变每页展示行数

- 跳转页面
奖牌地图
- 跳转页面

- 图例对应奖牌总数范围的国家进行高亮

- 点击国家进行高亮,点击图例对应范围国家褪色

- 跳转页面
查询赛程
- 单个查询

- 组合查询


- 单个查询
了解更多

四、结对讨论过程
4.1 结对过程群聊展示
- 团队分工和初期计划

- 进度mark

- 分工进度交流

- 云服务器部署

4.2 结对过程照片展示
P.S.因为没有抓到人拍一起打代码的照片,所以就放一张两个人的电脑合照代替啦>_>
五、设计实现过程
5.1 页面实现过程
我们根据我们上次结对作业的原型,把这次作业分成了六个界面,分别是首页、奖牌总榜、奖牌地图、查询赛程、了解更多和导航栏。
首页
我们通过
CDN引入VUETIFY,实现可选择调节的轮播图来进行冬奥会的精彩展示。奖牌总榜
我们通过
CDN引入VUETIFY引入基于VUE.js的UI-element,实现可点击表格头部对奖牌进行升序和降序,同时在奖牌榜的右下角实现可选展示行数和分页。奖牌地图
首先,我们在网上找到了世界热力图ECHARTS组件,然后通过css调整地图的样式,在JavaScript中存入国家的奖牌数据,最后通过
tooltips这个属性实现了鼠标移动到对应国家显示对应国家的奖牌数据。查询赛程
最开始是想使用
JDBC进行数据库连接和数据查询,但是由于数据库服务器部署到云服务器上较为困难,所以改为使用SQLite嵌入式数据库。数据库返回查询结果之后使用JSTL的<c:for>标签循环输出展示,实现赛程查询功能。
我们创建了rank_table标存放查询赛程所需数据。表中设有九个字段,(ID、itemcodename……)数据库结构如下。
了解更多
在了解更多的这个界面,我们选择了科普与冬奥吉祥物有关的知识。我们选取了近几届的冬奥吉祥物,通过图文并茂的方式展示了吉祥物的外观名字以及由来。
导航栏
为了提高代码的复用率,我们将导航栏写了一个单独的页面,并用css进行美化,用JavaScript进行导航栏的交互颜色变化,最后我们将导航栏这个界面用
iframe这个组件引入到每一个界面中。
5.2 实现过程中的难点
- 难点1: 奖牌地图——实现及数据载入
之前原型的时候就有点难搞,世界地图的贴图数据有点难处理,自己写的话工作量和难度都有点大。不过好在这次找到了相应的echarts组件——world.js,导入之后对照echarts手册,查找部件对应属性进行修改添加,修改图例
format、增加光标提示信息tooltips,以及细节方面的处理,让它更加契合我们的整体风格。 - 难点2:查询赛程——数据库连接和表单提交
因为很久没有用html写页面了(忏悔)所以对整体语法架构都生疏了很多。也是查了各种资料试了很多方法,先是用的Mysql进行的数据库连接,因为IDEA有相关组件
SSMS用起来会比较方便,但是部署到云服务器上就麻烦很多,因为远程服务器上软件残缺不全都要重新下载安装配置环境。
所以转换方向使用SQLite进行嵌入式数据库编写,这样可以直接将数据库db文件带过去在云服务器上进行部署,节约时间成本。
表单提交最开始是用jsp实现,因为想要实现“点击查询之后刷新页面数据,不进行页面跳转”(动态查询),所以也查了一点资料,像是ajax(异步请求),但是有和我们的项目框架不合所以放弃了,转而将表单提交到自身,然后对请求request进行parameter参数校验,刷新整个页面,达到数据刷新的目的。
- 难点3:对引入的vue.js组件的样式调整
因为之前web的知识不扎实,对css语法格式比较生疏。引入组件后一直不知道怎么对组件的内部样式进行更改。我们有两个组件都会出现莫名的空白,查了许多资料都没有解决。最后通过
F12开发者选项一步步的调试,最终才确定了是哪个div,才通过CSS取消了空白。这让我意识到F12开发者选项是web程序编写过程中是很有帮助的一个武器,可以很好地帮助我们对网页进行排版。 - 难点4:部署到云服务器遇到的问题
我们的导航栏部署到云服务器上有些页面出现了乱码,有些页面却是正常的。我通过查询一系列阿里云的资料和各种配置都没有解决这个问题。我们甚至挂了阿里云的公件,咨询了阿里云的工程师也没有解决。最后我发现是因为我一开始偷懒直接将导航栏的html文件在网上的网站进行在线转换成JSP文件直接引入。最后我们通过在head部分强调
utf-8,并且用iframe引入导航栏,才解决了文字乱码问题。
我们一开始项目的搭建是通过IDEA的webapp的形式,我们很自然地用了IDEA自带的数据库。可是我们部署云服务器的时候发现我们的jsp文件老是因为连接不到数据库而打不开。最后通过查资料和询问同学们,我们改用了嵌入式数据库SQLite,最后才成功地将文件部署到云服务器上。
六、代码说明
newnav导航栏
我们将导航栏打包成组件形式,然后在每个界面使用iframe引入,减少代码冗余。
//css样式
<style>
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: rgba(255,255,255,0.5);
}
li {
float: left;
}
li a {
display: block;
color: rgb(10, 0, 0);
text-align: center;
padding: 20px 22px;
text-decoration: none;
}
li a:hover {
background-color: rgb(158, 217, 245);
}
</style>
</head>
//导航栏主体
<body>
<ul>
<li><a class="active" href="firstpage.html">首页</a></li>
<li><a href="medals.html">奖牌总榜</a></li>
<li><a href="medalmap.html">奖牌地图</a></li>
<li><a href="matches.jsp">查询赛程</a></li>
<li><a href="konwmore.html">了解更多</a></li>
</ul>
//点击事件
<script>
let navButtons = document.getElementsByTagName('a');
for (let i = 0; i < navButtons.length; ++i) {
navButtons[i].onclick = function () {
window.parent.location.href = navButtons[i].href;
}
}
</script>
firstpage首页
我们通过
CDN引入VUETIFY实现轮播图
- 组件导入
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" /> <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, height=device-width,user-scalable=no, minimal-ui"> <link href="style.css" rel="stylesheet" type="text/css" /> </head> - 首页风采展示主体代码
```html
//轮播图组件下有空白,通过下面这个css取消空白
//引入轮播组件
<div class="showpicture" id="app">
<v-app>
<template>
<v-carousel>
<v-carousel-item
v-for="(item,i) in items"
:key="i"
:src="item.src"
reverse-transition="fade-transition"
transition="fade-transition"
></v-carousel-item>
</v-carousel>
</template>
</v-app>
</div>
```
medals奖牌总榜
我们通过CDN引入VUETIFY引入基于VUE.js的
UI-element,实现可点击表格头部对奖牌进行升序和降序,同时在奖牌榜的右下角实现可选展示行数和分页。因为奖牌榜的数据是静态的且数据量很小,于是我们选择直接存在JavaScript中。
- 组件导入
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8" />
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
//奖牌榜组件下有空白,通过下面这个css取消空白
<style>
.v-application--wrap {
min-height: 0ch;
}
</style>
- 奖牌榜主体代码
<body>
//引入导航栏
<div class="medalnav">
<iframe MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0
SCROLLING=no src="newnav.html" height=“auto” width="100%">
</iframe>
</div>
//引入奖牌榜组件
<div class="medalchart" id="app">
<v-app>
<template>
<v-data-table
:headers="headers"
:items="medalsList"
:items-per-page="15"
class="elevation-1"
></v-data-table>
</template>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{
text: '排名',
align: 'start',
// sortable: false,
value: 'rank',
},
{
text: '国家',
sortable: false,
value: 'countryname'
},
{ text: '金牌', value: 'gold' },
{ text: '银牌', value: 'silver' },
{ text: '铜牌', value: 'bronze' },
{ text: '总数', value: 'count' },
],
medalsList: [
{
rank: "1",
countryname: "挪威",
gold: "16",
silver: "8",
bronze: "13",
count: "37",
}</script>
</body>
</html>
medalMap奖牌地图
奖牌地图部分我们使用了
echart组件进行代码实现,使界面简洁美观。
- 组件导入
```javascript奖牌地图 //导入echart组件 //导入世界地图world.js文件
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
option = {
backgroundColor: '#ffffff',
title: {
subtext: '冬奥奖牌地图',
left: 'center',
top: 'top'
},
//设置光标悬停时的提示框
tooltip: {
trigger: 'item',
formatter: function (params) {
return '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">'
+ params.data.cname
+ '</div>'
+ '总数:' + params.value
+ "<div></div>"
+ '金牌:' + params.data.gold
+ "<div></div>"
+ '银牌:' + params.data.silver
+ "<div></div>"
+ '铜牌:' + params.data.bronze;
}
},
//设置图例样式
visualMap: {
pieces: [
{min:21},
{min:16,max:20},
{min:11,max:15},
{min:6,max:10},
{min:0,max:5}
],
text:['>20','0'],
splitNumber: 5,
realtime: false,
calculable: false,
color: ['#02a7f0', '#4ec2f5', '#b3e0fb', '#a7e0fa', '#ccedfc']
},
……
}
</script>
……
```
matches查询赛程
- 查询栏下拉菜单
<div class="scheduleSearchCard">
<form id="w0" action="matches.jsp" method="get">
<div class="itemcodenameSearch" display="inline">
<label class="control-label" for="schedulesearch-itemcodename">项目名称</label>
<select id="schedulesearch-itemcodename" class="form-control" name="itemcodename">
<option value="">全部项目赛程</option>
<option value="高山滑雪">高山滑雪</option>
<option value="雪车">雪车</option>
<option value="冬季两项">冬季两项</option>
<option value="越野滑雪">越野滑雪</option>
<option value="冰壶">冰壶</option>
<option value="自由式滑雪">自由式滑雪</option>
<option value="花样滑冰">花样滑冰</option>
<option value="冰球">冰球</option>
<option value="雪橇">雪橇</option>
<option value="北欧两项">北欧两项</option>
<option value="单板滑雪">单板滑雪</option>
<option value="跳台滑雪">跳台滑雪</option>
<option value="钢架雪车">钢架雪车</option>
<option value="速度滑冰">速度滑冰</option>
<option value="短道速滑">短道速滑</option>
<option value="开幕式">开幕式</option>
<option value="闭幕式">闭幕式</option>
</select>
</div>
<div class="startdatecnSearch" display="inline">
<label class="control-label" for="schedulesearch-startdatecn">比赛日期</label>
<select id="schedulesearch-startdatecn" class="form-control" name="startdatecn">
<option value="">全部日期赛程</option>
<option value="02">02-02</option>
<option value="03">02-03</option>
<option value="04">02-04</option>
<option value="05">02-05</option>
<option value="06">02-06</option>
<option value="07">02-07</option>
<option value="08">02-08</option>
<option value="09">02-09</option>
<option value="10">02-10</option>
<option value="11">02-11</option>
<option value="12">02-12</option>
<option value="13">02-13</option>
<option value="14">02-14</option>
<option value="15">02-15</option>
<option value="16">02-16</option>
<option value="17">02-17</option>
<option value="18">02-18</option>
<option value="19">02-19</option>
<option value="20">02-20</option>
</select>
</div>
<div class="venueSearch" display="inline">
<label class="control-label" for="schedulesearch-venuename">场馆</label>
<select id="schedulesearch-venuename" class="form-control" name="venuename">
<option value="">全部场馆赛程</option>
<option value="国家高山滑雪中心">国家高山滑雪中心</option>
<option value="国家雪车雪橇中心">国家雪车雪橇中心</option>
<option value="国家冬季两项中心">国家冬季两项中心</option>
<option value="国家越野滑雪中心">国家越野滑雪中心</option>
<option value="国家游泳中心">国家游泳中心</option>
<option value="云顶滑雪公园">云顶滑雪公园</option>
<option value="首钢滑雪大跳台">首钢滑雪大跳台</option>
<option value="首都体育馆">首都体育馆</option>
<option value="国家体育馆">国家体育馆</option>
<option value="五棵松体育中心">五棵松体育中心</option>
<option value="国家跳台滑雪中心">国家跳台滑雪中心</option>
<option value="国家速滑馆">国家速滑馆</option>
<option value="国家体育场">国家体育场</option>
</select>
</div>
<div class="subbuttun">
<button type="submit" name="Submit" class="scheduleSearch" >查询</button>
</div>
</form>
</div>
- 数据库查询输入
<table border="1" width="100%"> <tr> <th>项目类型</th> <th>比赛名称</th> <th>比赛队伍</th> <th>赛后比分</th> <th>比赛时间</th> <th>场馆名字</th> </tr> <tbody> <c:forEach var="row" items="${result.rows}"> <tr> <td><c:out value="${row.itemcodename}"/></td> <td><c:out value="${row.title} "/></td> <td> <c:if test="${row.homename != \"\"}"> <c:out value="${row.homename}VS${row.awayname}"/> </c:if> <c:if test="${row.homename == \"\"}"> <c:out value="非对抗赛"/> </c:if> </td> <td> <c:if test="${row.homescore != \"\"}"> <c:out value="${row.homescore}:${row.awayscore}"/> </c:if> <c:if test="${row.homescore == \"\"}"> <c:out value="无比分信息"/> </c:if> </td> <td><c:out value="${row.startdatecn}"/> </td> <td><c:out value="${row.venuename}"/> </td> </tr> </c:forEach> </tbody> </table>
七、心路历程和收获
7.1 心路历程
最开始的设想是使用Vue框架,摸索了一段,包括配置node.js环境 和npm,搭建Vue框架,查阅相关资料试着写代码之后,终于!完全被打败了。Vue框架对于纯新手来说有点难懂,框架里的代码编写和实现逻辑实在难懂。
所以我们决定不用框架啦!直接了当就是干(ノ=Д=)ノ┻━┻!干脆放弃沉没成本重新开始之后顺利很多,按照之前讨论的分工重新自己细化、完善、提交、测试,互相看过进度之后又自己修改,提交代码到Gitcode上,最后将整个项目部署到云服务器上(又是一场艰难战争T_T)。
过程中还是有很多困难的,但是一个成熟的软工人是不会被轻易打倒的。不断查找资料修改代码,一次次尝试功能实现,踏着前人的脚印往前走,最终呈现出满意的成果啦~
7.2 收获
收获还是很多的,浅显的像是jsp和vue的语法组件学习,以及html、css相关语句的复习;更深层的当然是新的项目经验和团队合作磨合的处理啦~一起讨论一起努力一起熬夜
掉头发的经历是真的很珍贵,就算很久以后想起来这样的时光也会觉得珍惜吧。
八、评价结对队友
- 221900135_黄林馨对221900234_柯婉婷:
超级棒的队友呀!本来平时就在一块玩,步调习惯比较吻合,编程和环境配置的时候遇到问题都一块顺利解决了,讨论过程也是小case啦。虽然写
bug代码的过程很痛苦,但是友好的结对伙伴真是大大减轻了这个过程中的折磨啦~~
- 221900234_柯婉婷对221900135_黄林馨:
超级nice!!对界面设计的嗅觉真的棒,基本上不用操心css样式的事情(滑水脸),工作效率也真的高,一直在鞭策督促我赶工OTZ。合作起来非常省心。

九、参考资料
1、Gitcode项目多人合作
2、用echartsjs 实现散点图与table表格双向交互
3、Tomcat的下载与安装
4、Tomcat配置到IDEA
5、IntelliJ IDEA 2020.2 破解版(附永久破解激活方法)
6、VUE中CDN引入VUETIFY,实现轮播图
相关推荐
软件工程实践结对作业二.md
软件工程实践结对作业二.md
软件工程实践——结对作业一
这个作业属于哪个课程 软件工程实践2022年春-F班 这个作业要求在哪里 软件工程实践——结对作业一 结对学号 221900418 221900403 这个作业的目标 完成一个平台网页的原型设计 其他参考文献 CSDN 、BiliBili 、博客园 文章目录一、博客链接二、原型链接三、原型设计1、NABCD模型分析Ⅰ、N(Need,需求)Ⅱ、A(Approach,做法)Ⅲ、B(Benefit,好处)Ⅳ、C(Competitors,竞争)Ⅴ、D(Delivery,推广;Data...
软件工程实践结对作业一
这个作业属于哪个课程 <2022年福大-软件工程、实践-W班> 这个作业要求在哪里 <软件工程实践结对作业一> 这个作业的目标 <结对合作,NABCD模型,需求分析,原型设计> 结对学号 <221900112、221900104> 其他参考文献 见文章末尾 文章目录1、原型设计地址2、NABCD模型分析2.1 N(Need,需求)2.2 A(Approach,做法)2.3 B(Benefit,好处)2.4 C(Competit...
PairProject:W班软件工程实践结对第二次作业仓库
结对第二次作业-顶会热词统计的实现 为了不遗漏作业内容,这里有一个清单检查表方便同学们快速检阅。 fork仓库,和伙伴商讨如何通过github协作/代码规范等 编程实现 功能一,操作爬取的论文列表 功能二,爬取结果分析展示 功能三,爬取论文信息(附加功能,实现有附加分) 其他附加功能 部署 发布发布版本,发起拉取请求 撰写博客,在预先之前提交一份博客 包含作业描述和目录 核对评分标准 上一次结对作业中,大家都和小伙伴完成了原型的设计,那么现在再联合小伙伴动手实现原型中的部分功能吧。采用网络技术来实现原型中的功能。 一,作业内容 1.基础功能 功能1:对已爬取的论文列表进行操作 可对论文列表进行删除; 可对论文列表进行查询详细信息(支持模糊查询,查询结果的展示,排序等功能可自行设计); 功能2:分析已爬取到的论文信息,提取top10个热门领域或热门研究方向 形成如关键字图谱之类直观的查看方式
2020级计算机系软件工程第二次结对编程作业.zip
2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip




