结对作业二
🎵提示:点击页面左下角播放背景音乐配合阅读更佳🎵
0. 作业基本信息
这个作业属于哪个课程 | 2021春软件工程实践|W班 (福州大学) |
---|---|
这个作业要求在哪里 | 结对第二次作业——顶会热词统计的实现 |
结对学号 | 221801412 & 221801405 |
这个作业的目标 | 编程实现顶会热词统计+撰写博客+github协作 |
其他参考文献 | CSDN GitHub |
目录:
0. 作业基本信息
1. PSP表格
2. 相关链接
3. 成品展示
3.1 主页
3.2 论文列表
3.3 收藏列表
3.4 热门领域
3.5 注册/登录
3.6 关于我们
4. 结对讨论过程描述
5. 设计实践过程
6. 代码说明
7 心路历程和收获
8 评价结对队友
1. PSP表格
PSP2.1 | Personal Software Process stages | 预估耗时(min) | 实际耗时(min) |
---|---|---|---|
Planning | 计划 | 60 | 180 |
·Estimate | ·估计这个任务需要多少时间 | 60 | 180 |
Development | 开发 | 1950 | 2455 |
· Analysis | · 需求分析 (包括学习新技术) | 2160 | 2880 |
· Design Spec | · 生成设计文档 | 60 | 75 |
· Design Review | · 设计复审 | 60 | 60 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 40 |
· Design | · 具体设计 | 120 | 120 |
· Coding | · 具体编码 | 1200 | 1440 |
· Code Review | · 代码复审 | 120 | 180 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 55 | 60 |
· Test Repor | · 测试报告 | 15 | 30 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 20 |
合计 | 3925 | 5095 |
2. 相关链接
3. 成品展示
3.1 主页
- 主页有我们的网站的logo和搜索框,简约大气。可以在文本框内输入您想要搜寻的论文,点击“爬一下”即可查阅。
3.2 论文列表
-
在主页搜索之后跳转到此页面,默认为标题搜索。同时该页面也支持关键词搜索和摘要搜索。
-
搜索后提示搜索的记录数量,自动分页,每页六个论文。在论文下方有一个收藏按钮,点击之后可以把你想要的论文收藏,并提示信息。右侧浮动栏有三峰会链接和今年以来热词的推荐。
3.3 收藏列表
-
在论文列表页面所收藏的论文会在这里显示,与搜索界面布局大同小异。同样有分页和侧边栏。侧边栏为三峰会链接和最近收藏的论文链接。同时有删除按钮,可以删除收藏的论文。
-
点击收藏或者删除之后,会在网页形成一个提示信息。
3.4 热门领域
- 热门领域模块包括论文数目年度走势图,关键词top10榜,以及关键词一览。采用了折线图,柱状图和饼状图,用户可以点击图表进行交互。其中以饼状图中的旭日图为最,其中分析了大量数据,让用户清楚的明白各年间的热词如何。
3.6 注册/登录
- 在这个页面,为登录点击之后进入登录界面,其中可以跳转到注册页面。该页面的输入框中带有输入验证。在用户已经登录之后该页面会转变为用户界面,较为简单的显示用户的一些信息。其中也可以退出登录。
3.7 关于我们
- 这是我们结对的人员介绍
4. 结对讨论过程描述
-
刚拿到题目后,对如何实现这次作业我俩进行了一些讨论,原本打算采用bootstrap框架进行前端部分的开发,但由于时间不足,改成使用html原生框架进行开发;后端综合考虑了实现难度和学习时间成本的问题,则采用了python+flask进行编写。在结对过程中我们主要线上交流为主,同时也进行了不少线下交流。例如,关于设计论文列表部分页面的交流。
-
以221801405同学为主,221801412同学为辅,由于这次时间不足,因此我们剑走偏锋采用了前后端不分离的做法。221801405同学主要进行后端语句的编写,而221801412同学则进行前方html的设计,同时也有json数据的提取,以及三个图表的数据提取。以工作量来衡量,几乎不比主要编写逻辑的221801405少。
-
在开发的过程中,我们互相交流,边写代码边学习新的知识,最终撰写文档部分我们也做了简单的分工,提高了效率。
5. 设计实现过程
-
功能结构图:
-
前端:采用HTML、CSS、JS的形式来编写代码
-
后端:采用Flask框架,通过python语言来进行数据库操作。
-
目录结构:
经典的flask布局,templates放html页面,static放静态数据,包括css和js和图片
py文件:init为配置文件,models为数据库类表,forms为后台生成的表单,main类主要处理页面之间的路由,为视图函数。
值得一提的是,为了解决每次用户打开都要加载图表数据,导致打开时间过长,后台编写了三个图表数据生成的类,用于生成图表数据。用户打开时读取生成的数据chart.txt速度快一大截。几秒钟加载完毕,而如果不这么做的话,光是分析旭日图的数据就要花费将近十分钟的时间。
6. 代码说明
- 首页搜索栏部分
<div class="informs" style="border:0px;width:800px;margin:200px auto 0px auto;">
<div class="margin:10px auto;width:auto;" align="center">
<img src="{{url_for('static', filename='快爬.png') }}" alt="爬" />
<span class="big">快爬! </span>
</div>
<form method="POST" >
<input type="text" value="" name="text" style="margin:0px 0px 0px 82px;border:3px solid #c0c0c0;width:500px; height:40px;border-radius: 5px;font-size:20px;">
<input type="submit" name="search" style="border:3px solid #c0c0c0;width:120px; height:50px;border-radius: 5px;font-size:25px;" value="爬一下!">
</form>
</div>
- 论文列表中单篇文章搜索结果的实现,利用div将搜索结果的各个部分进行分割,使得页面更加简洁大方美观。
<div class="item">
<div class="main">
<div class="fengmian">
<img src="{{url_for('static',filename='fengmian.jpg')}}" alt="fengmian" width="200px"/>
</div>
<h3>{{u[0].title}}</h3>
<p>{{u[0].meeting}} {{u[0].date}}</p>
<p>关键词:
<b>
{%for k in u[1]%}
<span id="keyword">{{k.keyword}}</span>
<span> </span>
{%endfor%}
</b>
</p>
<p class="css-border" style="border-left:6px solid #2196F3;
background-color:#ddffff;">
{{u[0].paper_abstract}}</p>
<p>原文链接:<a href={{u[0].url}}>{{u[0].url}}</a></p>
</div>
<form method="post">
<input type="text"
style="visibility: hidden;"
name="collect"
value={{u[0].id}}
/>
<input type="submit" name="submit" value="收藏" class="form_float"
onmouseover="this.style.backgroundPosition='left -36px'"
onmouseout="this.style.backgroundPosition='left top'"
onclick="display_alert()"/>
</form>
</div>
-
通过图片展示三大顶会,点即可进入相关网页
<div class="right1"> <a href="http://iccv2021.thecvf.com/"> ICCV: <img src={{url_for('static',filename='ICCV.png')}} alt="ICCV"> </a> <a href="http://cvpr2020.thecvf.com/"> CVPR: <img src={{url_for('static',filename='CVPR.png')}} alt="CVPR"> </a> <a href="https://eccv2020.eu/"> ECCV: <img src={{url_for('static',filename='ECCV.png')}} alt="ECCV"> </a> </div>
-
以2013-2020各峰会论文走势图为例,通过Highchart工具进行有关图表的展示
var chart = Highcharts.chart('container', {
title: {
text: '2013 ~ 2020 各峰会论文发布走势图'
},
subtitle: {
text: '数据来源:三峰会:ICCV,ECCV,CVPR'
},
yAxis: {
title: {
text: '论文数量'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
pointStart: 2013
}
},
series: [{{data|safe}}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
-
Flask配置部分
class Config(object): SQLALCHEMY_DATABASE_URI = SQLALCHEMY_TRACK_MODIFICATIONS = False app = Flask(__name__) app.config.from_object(Config) app.secret_key = '我是密码' db = SQLAlchemy(app)
-
有关图标数据的获取,以热词top10为例(先前通过json进行数据库内容的转换)
key_list=PaperToKeyword.query.all()
dit=dict()
for k in key_list:
dit[k.keyword] = dit.get(k.keyword,1)+1
if __name__ == '__main__':
key_name = list(dit.keys())
key_value = list(dit.values())
for i in range(0,10):
index = i
max = key_value[i]
for j in range(i+1,len(key_value)):
if max<key_value[j]:
max=key_value[j]
index=j
temp=key_value[i]
key_value[i]=key_value[index]
key_value[index]=temp
temp2 = key_name[i]
key_name[i] = key_name[index]
key_name[index] = temp2
f=open('chart2.txt','w')
f.truncate()
f.write(str(key_name[0:10])+'\n')
f.write(str(key_value[0:10]))
f.close()
f1 = open('chart2.txt')
data = f1.readline()
data2 =f1.readline()
print(data)
print(data2)
- 注册/登录的flask实现
class Login(FlaskForm):
username = StringField('用户名')
password = PasswordField('密码')
submit = SubmitField('登录')
class Signup(FlaskForm):
username = StringField('用户名')
password = PasswordField('密码')
password2 = PasswordField('确认密码')
submit = SubmitField('注册')
-
数据库类表设计
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(50)) password = db.Column(db.String(50)) class UserCollection(db.Model): __tablename__ = "usercolletion" id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer) paper_id = db.Column(db.Integer) class Paper(db.Model): __tablename__ = "paper" id = db.Column(db.Integer, primary_key=True) title = db.Column(db.Text) meeting = db.Column(db.String(10)) url = db.Column(db.String(50)) paper_abstract = db.Column(db.Text) date = db.Column(db.Date) class PaperToKeyword(db.Model): __tablename__ = "papertokeyword" id = db.Column(db.Integer, primary_key=True) paper_id = db.Column(db.Integer, db.ForeignKey('User.id')) keyword = db.Column(db.Text)
7. 心路历程和收获
PZY:
怎么说,这次作业让我十分惊讶,觉得这次作业十分的不合理,但是也让我体验到了996的生活(实际上是7.5 2 7)全天几乎不眠不休的工作,这让我收获的很多,不仅对html css js等基础web知识有了巨大的深入了解,同时学习了python语言,flask框架,一堆数据处理所需要的步骤以及心得。对代码规范更加严格。代价就是几个晚上近乎晕厥。
LXJ:一开始看到这个作业的时候十分的害怕,虽然已经完成了原型的设计,但一开始对编码实现中一些功能的实现理解的不是很到位。尽管我的Web基础不是特别的扎实,并因此遇到不少困难,但是有了队友的帮助,我们的大部分问题都迎刃而解。整个结对过程让我受益颇多。
8. 评价结对队友
PZY->LXJ
很庆幸能有这样晓君这样优秀的队友。他不仅对任务态度认真,同时也十分的靠谱。当我在编码过程中遇到难题,几近崩溃的时候,他都会主动出来帮助我承担任务。尽管都是从0开始,但我们在相互交流相互督促的过程中能力得到了迅速提升,和他结对可以说是一段非常难忘的经历。
LXJ->PZY
在上次结对作业一原型设计的过程中,增滢同学那渴望求知、坚持不懈的态度就给我带来了深深的感动。他不仅能够主动学习,也很认真靠谱。尽管我的技术不够熟练,但他都一直给予我最无私的帮助,在做作业做到快自闭的时候,我们也相互助力打气,整个结对过程的气氛可以说是十分的融洽,能找到这样子的队友可以说实在是十分十分的荣幸,在他身上我学到了很多。