文章目录
Python学习了约一个月的时间,这是一篇综合练习的文章。主要做的内容是通过封装对象、实现抽象方法生成统计图、数据表格的功能。
文件目录如下
articles/
__init__.py
articles.json
articlesData.py
articlesEchartsEntity.py
articlesEntity.py
table_base.html
timeline_bar_with_graphic.html
图标效果
timeline_bar_with_graphic.html
table_base.html
articles.json
是我的csdn文章的标题、得分、阅读量的数据
[
{
"title": "实战之简单OOM",
"url": "https://blog.csdn.net/qq_35716085/article/details/134413400",
"viewCount": 14,
"score": 21
},
{
"title": "使用jenkins持续集成springboot项目(四、nginx域名映射)",
"url": "https://blog.csdn.net/qq_35716085/article/details/132979875",
"viewCount": 47,
"score": 24
},
{
"title": "数据库存储引擎",
"url": "https://blog.csdn.net/qq_35716085/article/details/131707806",
"viewCount": 20,
"score": 24
},
{
"title": "后端开发面试题",
"url": "https://blog.csdn.net/qq_35716085/article/details/131955660",
"viewCount": 318,
"score": 26
},
{
"title": "Mysql锁",
"url": "https://blog.csdn.net/qq_35716085/article/details/131723792",
"viewCount": 25,
"score": 29
},
{
"title": "HashMap详解",
"url": "https://blog.csdn.net/qq_35716085/article/details/131554332",
"viewCount": 34,
"score": 29
},
{
"title": "Java多线程之线程状态",
"url": "https://blog.csdn.net/qq_35716085/article/details/131795708",
"viewCount": 29,
"score": 34
},
{
"title": "Java多线程之interrupt",
"url": "https://blog.csdn.net/qq_35716085/article/details/134310943",
"viewCount": 15,
"score": 39
},
{
"title": "SpringBoot集成ElasticSearch(依赖不同,业务代码与JPA方式也不同)",
"url": "https://blog.csdn.net/qq_35716085/article/details/133940678",
"viewCount": 44,
"score": 41
},
{
"title": "blast安装及简单使用",
"url": "https://blog.csdn.net/qq_35716085/article/details/135109803",
"viewCount": 497,
"score": 44
},
{
"title": "Python基础(三、探索布尔型、if-else语句、while循环和continue语句)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134884680",
"viewCount": 178,
"score": 46
},
{
"title": "Mysql执行计划",
"url": "https://blog.csdn.net/qq_35716085/article/details/131709675",
"viewCount": 22,
"score": 47
},
{
"title": "Mysql隔离级别",
"url": "https://blog.csdn.net/qq_35716085/article/details/131697649",
"viewCount": 34,
"score": 47
},
{
"title": "Python基础(四、探索迷宫游戏)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134906292",
"viewCount": 391,
"score": 51
},
{
"title": "使用jenkins持续集成springboot项目(二、Jenkins任务配置)",
"url": "https://blog.csdn.net/qq_35716085/article/details/132977536",
"viewCount": 50,
"score": 51
},
{
"title": "使用jenkins持续集成springboot项目(三、上服务器)",
"url": "https://blog.csdn.net/qq_35716085/article/details/132978301",
"viewCount": 20,
"score": 52
},
{
"title": "Python基础( 七、休闲大富翁游戏)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135000098",
"viewCount": 589,
"score": 54
},
{
"title": "docker学习(四、修改容器创建新的镜像推送到云上)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134777644",
"viewCount": 109,
"score": 54
},
{
"title": "docker学习(十七、Dockerfile之NodeJs示例)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135151286",
"viewCount": 338,
"score": 56
},
{
"title": "docker学习(八、mysql8.2主从复制遇到的问题)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134871764",
"viewCount": 983,
"score": 56
},
{
"title": "Springboot集成ElasticSearch+JPA",
"url": "https://blog.csdn.net/qq_35716085/article/details/133878232",
"viewCount": 43,
"score": 56
},
{
"title": "Python基础(九、重要的全局变量)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135194814",
"viewCount": 401,
"score": 57
},
{
"title": "logstash同步mysql数据到es(一、es模板问题,请求返回400)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134944124",
"viewCount": 321,
"score": 57
},
{
"title": "Python基础(十三、序列)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135344702",
"viewCount": 249,
"score": 61
},
{
"title": "docker学习(十六、Dockerfile之Java示例)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135151045",
"viewCount": 373,
"score": 61
},
{
"title": "Python基础(缩进:让代码更美观、更清晰)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134993750",
"viewCount": 10,
"score": 62
},
{
"title": "服务启动时报错failed: Connection refused: connect",
"url": "https://blog.csdn.net/qq_35716085/article/details/135057342",
"viewCount": 425,
"score": 64
},
{
"title": "docker学习(十五、Dockerfile之python示例)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135150935",
"viewCount": 537,
"score": 65
},
{
"title": "docker学习(三、常用命令,超实用)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134711071",
"viewCount": 286,
"score": 65
},
{
"title": "使用jenkins持续集成springboot项目(一、项目打包坑集)",
"url": "https://blog.csdn.net/qq_35716085/article/details/132974806",
"viewCount": 58,
"score": 65
},
{
"title": "Java多线程之sleep、yield、join",
"url": "https://blog.csdn.net/qq_35716085/article/details/131787451",
"viewCount": 98,
"score": 65
},
{
"title": "docker重量级容器预警监控系统CIG",
"url": "https://blog.csdn.net/qq_35716085/article/details/135289219",
"viewCount": 405,
"score": 69
},
{
"title": "Python基础(十一、数据容器之元组Tuple)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135222876",
"viewCount": 474,
"score": 71
},
{
"title": "docker学习(十、搭建redis集群,三主三从)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135113131",
"viewCount": 503,
"score": 71
},
{
"title": "docker学习(二十、network使用示例host、none)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135215618",
"viewCount": 658,
"score": 72
},
{
"title": "docker学习(十二、Redis主从容错迁移)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135124607",
"viewCount": 583,
"score": 72
},
{
"title": "docker学习(六、容器卷)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134825570",
"viewCount": 440,
"score": 72
},
{
"title": "springboot跨域问题,解决方法",
"url": "https://blog.csdn.net/qq_35716085/article/details/135108526",
"viewCount": 385,
"score": 75
},
{
"title": "Python基础(八、random模块探秘)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135022724",
"viewCount": 431,
"score": 76
},
{
"title": "Dify.ai 10分钟带你体验Embedding对话应用",
"url": "https://blog.csdn.net/qq_35716085/article/details/134809112",
"viewCount": 919,
"score": 79
},
{
"title": "Mysql优化",
"url": "https://blog.csdn.net/qq_35716085/article/details/131720803",
"viewCount": 22,
"score": 79
},
{
"title": "docker学习(十一、Redis集群存储数据方式)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135114324",
"viewCount": 535,
"score": 80
},
{
"title": "轻松学会Elasticsearch+kibana",
"url": "https://blog.csdn.net/qq_35716085/article/details/134976541",
"viewCount": 175,
"score": 80
},
{
"title": "Java多线程之并发特性",
"url": "https://blog.csdn.net/qq_35716085/article/details/131761923",
"viewCount": 31,
"score": 80
},
{
"title": "Python基础(十五、数据容器之字典Dict)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135275642",
"viewCount": 142,
"score": 81
},
{
"title": "docker-compose启动项目时报错Version in “./docker-compose.yml“ is unsupported.",
"url": "https://blog.csdn.net/qq_35716085/article/details/135065241",
"viewCount": 378,
"score": 81
},
{
"title": "logstash同步mysql数据到es(二、jdbc_driver_library问题)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134944439",
"viewCount": 303,
"score": 81
},
{
"title": "Python基础(一、安装环境及入门)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134877749",
"viewCount": 307,
"score": 82
},
{
"title": "SpringBoot集成Eureka",
"url": "https://blog.csdn.net/qq_35716085/article/details/133941164",
"viewCount": 87,
"score": 82
},
{
"title": "docker学习(一、docker与VM对比)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134732935",
"viewCount": 340,
"score": 83
},
{
"title": "Python基础(十四、数据容器之集合Set)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135222946",
"viewCount": 473,
"score": 84
},
{
"title": "docker学习(二十一、network使用示例container、自定义)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135218009",
"viewCount": 990,
"score": 84
},
{
"title": "docker学习(十九、network使用示例bridge)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135197980",
"viewCount": 718,
"score": 84
},
{
"title": "Mysql事务",
"url": "https://blog.csdn.net/qq_35716085/article/details/131681556",
"viewCount": 54,
"score": 84
},
{
"title": "nginx 一、安装与conf浅析",
"url": "https://blog.csdn.net/qq_35716085/article/details/135337375",
"viewCount": 250,
"score": 85
},
{
"title": "docker学习(五、部署本地私有仓库)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134800765",
"viewCount": 928,
"score": 85
},
{
"title": "服务启动时报错Communications link failure",
"url": "https://blog.csdn.net/qq_35716085/article/details/135057149",
"viewCount": 213,
"score": 86
},
{
"title": "实战之shardingjdbc引入报错Cannot invoke “Object.toString()“ because the return value of “java.util.Map.get(",
"url": "https://blog.csdn.net/qq_35716085/article/details/134790326",
"viewCount": 745,
"score": 88
},
{
"title": "docker学习(二、安装docker)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134733341",
"viewCount": 730,
"score": 88
},
{
"title": "docker学习——汇总版",
"url": "https://blog.csdn.net/qq_35716085/article/details/135293661",
"viewCount": 731,
"score": 89
},
{
"title": "docker学习(十四、Dockerfile基础)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135131649",
"viewCount": 947,
"score": 89
},
{
"title": "docker学习(十三、Redis主从扩容、缩容)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135125327",
"viewCount": 2112,
"score": 89
},
{
"title": "logstash同步mysql数据到es(三、es模板问题)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134945940",
"viewCount": 98,
"score": 89
},
{
"title": "springboot+shardingjdbc(只分表、不分库)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134788951",
"viewCount": 436,
"score": 89
},
{
"title": "Redis设计与实现(阅读笔记、二)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134670760",
"viewCount": 341,
"score": 89
},
{
"title": "Redis设计与实现(阅读笔记、一)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134312572",
"viewCount": 312,
"score": 89
},
{
"title": "docker轻量级可视化工具Portainer",
"url": "https://blog.csdn.net/qq_35716085/article/details/135268224",
"viewCount": 874,
"score": 90
},
{
"title": "Python基础(十、数据容器之列表List)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135220636",
"viewCount": 919,
"score": 90
},
{
"title": "Mysql索引",
"url": "https://blog.csdn.net/qq_35716085/article/details/131657505",
"viewCount": 75,
"score": 90
},
{
"title": "Python基础(十二、数据容器之字符串)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135222922",
"viewCount": 1605,
"score": 91
},
{
"title": "Python基础(五、掌握for循环、range、break和continue用法,猜数游戏)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134993056",
"viewCount": 243,
"score": 91
},
{
"title": "Python基础(八、函数的妙用,猫捉老鼠游戏)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135158407",
"viewCount": 842,
"score": 92
},
{
"title": "使用docker实现logstash同步mysql到es",
"url": "https://blog.csdn.net/qq_35716085/article/details/134946153",
"viewCount": 377,
"score": 92
},
{
"title": "Python基础(二、必备知识,不用背,用用就会了~)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134883841",
"viewCount": 427,
"score": 92
},
{
"title": "docker学习(七、搭建mysql8.2主从)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134854670",
"viewCount": 1093,
"score": 92
},
{
"title": "docker学习(二十二、终篇,docker-compose)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135263672",
"viewCount": 973,
"score": 93
},
{
"title": "docker学习(九、分布式存储亿级数据知识)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135011956",
"viewCount": 974,
"score": 93
},
{
"title": "Java多线程之volatile",
"url": "https://blog.csdn.net/qq_35716085/article/details/131806551",
"viewCount": 91,
"score": 93
},
{
"title": "Python基础(六、掌握if、while用法)",
"url": "https://blog.csdn.net/qq_35716085/article/details/134994680",
"viewCount": 27,
"score": 94
},
{
"title": "Spring IOC 实现原理",
"url": "https://blog.csdn.net/qq_35716085/article/details/132427790",
"viewCount": 45,
"score": 94
},
{
"title": "docker学习(十八、network介绍)",
"url": "https://blog.csdn.net/qq_35716085/article/details/135196020",
"viewCount": 1194,
"score": 95
},
{
"title": "Java多线程之synchronized",
"url": "https://blog.csdn.net/qq_35716085/article/details/131825116",
"viewCount": 456,
"score": 95
}
]
articlesData.py
这个模块相当于我要对外开放的接口汇总,其中包含了:
- init:构造函数
- time_bar:生成统计图的对外接口,最后会给返回统计图的位置,浏览器打开html即可看到统计图
- table_file:生成表格的对外接口,最后会给返回表格的位置,浏览器打开html即可看到表格
- __read_file:读取json文件的私有方法
- __format_file_data:解析json文件数据,提供给表格用
- __format_time_bar_data:解析json文件数据,提供给统计图用
import json
import articlesEntity
from articles import articlesEchartsEntity
class OpenFile:
def __init__(self, path):
self.path = path
# 获取数据中标题、数量、分数
def time_bar(self):
if None == self.path:
return "路径不能为空"
json_data = self.__read_file()
data_list, title_list, count_dict, score_dict = self.__format_time_bar_data(json_data)
path = articlesEchartsEntity.ArticlesEcharts().time_bar(title_list, count_dict, score_dict)
return print(f"已生成<a href='{path}'>超全功能统计图</a>")
# 解析文件,获取数据
def table_file(self):
if None == self.path:
return "路径不能为空"
json_data = self.__read_file()
data_list = self.__format_file_data(json_data)
path = articlesEntity.Articles().articles_table(data_list)
return print(f"已生成<a href='{path}'>表格</a>")
# 读取文件
def __read_file(self):
with open(self.path, "r") as file:
json_data: list = json.loads(file.read())
return json_data
# 解析全部数据
def __format_file_data(self, json_data):
data_list = []
for data in json_data:
articles = articlesEntity.Articles(data["title"], data["url"], data["viewCount"],
data["score"])
data_list.append(articles)
return data_list
# 解析折线图数据
def __format_time_bar_data(self, json_data):
data_list = []
title_list = []
count_dict = {}
score_dict = {}
count_list = []
score_list = []
# 计数器
count = 1
# 月份
month = 0
for data in json_data:
articlesEcharts = articlesEchartsEntity.ArticlesEcharts(data["title"], data["viewCount"],
data["score"])
data_list.append(articlesEcharts)
title_list.append(data["title"])
if count <= 8:
count_list.append(data["viewCount"])
score_list.append(data["score"])
count += 1
else:
month += 1
count_dict[month] = count_list
score_dict[month] = score_list
count_list = []
score_list = []
count = 1
return data_list, title_list[:8], count_dict, score_dict
if __name__ == "__main__":
openFile = OpenFile("D:/test/demo/articles/articles.json")
print(openFile.table_file())
print(openFile.time_bar())
articlesEchartsEntity.py
在这个文件中封装了articlesEchartsEntity对象,包含:
- EchartsData:抽象类,用于写支持的统计图
- time_bar:支持时间柱状图
- ArticlesEcharts:实现抽象类
- init:构造函数
- time_bar:实现抽象方法,生成统计图
from articles.articlesEntity import Articles
from pyecharts import options as opts
from pyecharts.charts import Bar, Timeline
from pyecharts.commons.utils import JsCode
from abc import ABC, abstractmethod
class EchartsData(ABC):
@abstractmethod
def time_bar(self, *args):
pass
class ArticlesEcharts(Articles, EchartsData):
def __init__(self, title=None, viewCount=None, score=None):
super().__init__(title, viewCount, score)
if title is not None:
self.title = title
if viewCount is not None:
self.viewCount = viewCount
if score is not None:
self.score = score
def time_bar(self, x, score_y, count_y):
tl = Timeline()
for i in range(1, 10):
bar = (
Bar()
.add_xaxis(x)
.add_yaxis("阅读量", count_y[i])
.add_yaxis("分数", score_y[i])
.set_global_opts(
title_opts=opts.TitleOpts("文章2023年 - With Graphic 组件"),
graphic_opts=[
opts.GraphicGroup(
graphic_item=opts.GraphicItem(
rotation=JsCode("Math.PI / 4"),
bounding="raw",
right=100,
bottom=110,
z=100,
),
children=[
opts.GraphicRect(
graphic_item=opts.GraphicItem(
left="center", top="center", z=100
),
graphic_shape_opts=opts.GraphicShapeOpts(
width=400, height=50
),
graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
fill="rgba(0,0,0,0.3)"
),
),
opts.GraphicText(
graphic_item=opts.GraphicItem(
left="center", top="center", z=100
),
graphic_textstyle_opts=opts.GraphicTextStyleOpts(
text="文章{}月".format(i),
font="bold 26px Microsoft YaHei",
graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
fill="#fff"
),
),
),
],
)
],
)
)
tl.add(bar, "{}月".format(i))
path = "D:/test/demo/articles/timeline_bar_with_graphic.html"
tl.render(path)
return path
articlesEntity.py
这是文章对象,其中包含的函数:
- init:构造函数
- str:魔法函数,输出字符串
- articles_table:生成表格的方法
- __format_list:格式化数据,提供给表格用,私有方法
from pyecharts.components import Table
from pyecharts.options import ComponentTitleOpts
class Articles:
def __init__(self, title=None, url=None, viewCount=None, score=None):
if title is not None:
self.title = title
if url is not None:
self.url = url
if viewCount is not None:
self.viewCount = viewCount
if score is not None:
self.score = score
def __str__(self):
print(f"<a href='{self.url}'>{self.title}</a>可通过链接查看详细内容~")
def articles_table(self, data_list):
header_list = ["标题", "统计分数", "统计阅读数","地址"]
table = Table()
rows_list_list = self.__format_list(data_list)
table.add(header_list, rows_list_list)
table.set_global_opts(
title_opts=ComponentTitleOpts(title="Table-文章数据统计")
)
path = "D:/test/demo/articles/table_base.html"
table.render("table_base.html")
return path
def __format_list(self, data_list):
rows_list_list = []
for articles in data_list:
rows_list = []
rows_list.append(articles.title)
rows_list.append(articles.score)
rows_list.append(articles.viewCount)
rows_list.append(articles.url)
rows_list_list.append(rows_list)
return rows_list_list