使用PYQT5和pyechart和FTP实现对服务器用户数据的统计并画图显示

一:工具描述

1:PYQT5

		自己百度,我没找到最新的定义

2:pyechart

		python中一个特别厉害的统计画图模块,和seaborn类似,但是这个模块专门用于统计画图

3:FTP

		见我上一篇博客,记得点赞哟

二:项目描述

	现在在服务器上有一堆用户操作机器产生的json文件,这些json文件里面含有一些关键的信息,我们需要将这些信息提取出来,并用图表的形式,给用户一个直观的感受。数据的形式如下:
	{
			"datatime": "2018-12-12-07:25:34",
			"name": "张三",
			 "No": "001",
			"ID": "222222199808080808",
			"course": "JJ/L6",
			"detail": [
         				 ["操作明细", "得分情况"],
          				["操作明细", "得分情况"],
          				["操作明细", "得分情况"]
       				 ],
			"score": 81,
			"其余必要信息,乙方可以自己考虑": "xxx"
}

我的目的是根据时间的先后顺序,对用户产生的操作得分画折线图,一个用户画一张图,用户有几种练习就画几条折线,废话不多说,直接撸代码

三,代码实现

1:需要导入的包

		from PyQt5 import QtCore
		from PyQt5.QtCore import *
		from PyQt5.QtWidgets import *
		from PyQt5.QtWebEngineWidgets import *
		import sys
		from pyecharts import Line
		import json
		import shutil
		import os
		import re
		from ftplib import FTP

先介绍一些这些包的作用,上面几个关于PYQT的是用来生成浏览器的,浏览器可以显示html文档,下面是系统操作需要的一些包,最后那个FTP是用来下载文件的

2:下载文件并解析信息

class Get_User_Drawing:

#实例化参数并和FTP对象,IP,username和psd属于商业机密,所以用星号代替
def __init__(self,ID,ip="*********", username="********", password="*********"):
    self.ip = ip
    self.username = username
    self.pwd = password
    self.ftp = FTP(self.ip)
    self.ftp.login(self.username,self.pwd)
    self.ID = ID
    
#这个方法是用来下载文件的,通过指定文件名字就可以从服务器下载对应的文件
def down_file_by_name(self,file_name):

    bufsize = 1024  # 设置缓冲器大小
    fp = open(file_name, 'wb')
    self.ftp.retrbinary('RETR %s' % file_name, fp.write, bufsize)
    fp.close()

#这个方法是用来获取需要下载的文件名称,并按照练习的种类和时间的先后顺序归类并排序
def get_file(self):

    pattern = re.compile("[a-z]{6}_" + self.ID + "_JJ_L.+")#正则匹配的模式
    list = self.ftp.nlst()#获取服务器文件列表
    prc_type_list = set()#set()可以对练习种类去重
    file_list = []#获取对应ID所有的文件
    for item in list:
        r = re.findall(pattern, item)
        if r:
            file_list.append(r[0])
            prc_type = r[0][14:16]
            prc_type_list.add(prc_type)  # 找对应ID下所有的练习
    file_download = []#获取需要下载的文件,按照时间先后顺序排序
    for item_prc in prc_type_list:
        pattern = re.compile("[a-z]{6}_"+self.ID+"_JJ_"+str(item_prc)+".+")
        time_list = []
        for file_item in file_list:
            if re.findall(pattern, file_item):
                time_ = re.findall(pattern, file_item)[0][17:-5]
                time_list.append(int(time_))
        time_list = sorted(time_list)
        file_download.append([item_prc, time_list])

    file_download2 = []#拼接下载文件列表并返回
    for item in file_download:
        temp = "record_"+self.ID+"_JJ_"+item[0]+"_"
        temp1 = []
        for time_temp in item[1]:
            file = temp + str(time_temp) + ".json"
            temp1.append(file)
        file_download2.append(temp1)
    return file_download2

#下载对应的文件,在本地创建对应的目录,将下载的文件全部移进这个目录中
def down_practice_file_by_ID(self):

    path = os.path.abspath(os.curdir)+"\\"+str(self.ID)
    if os.path.isdir(path):
        pass
    else:
        os.mkdir(path)
    file_list = self.get_file()
    for item in file_list:
        for file_name in item:
            self.down_file_by_name(file_name)
            try:
                shutil.move(file_name,path)#尝试将文件移动到对应的目录中
            except BaseException:
                os.remove(path+"\\"+file_name)#如果对应目录下有文件,将原文件删除并将下载的文件移入,保证文件是最新的
                shutil.move(file_name,path)
                
#解析下载好的文件,获取数据并返回一个字典
def get_practice_file_info(self):
    self.down_practice_file_by_ID()
    path = str(os.path.abspath(os.curdir)) + "\\" + str(self.ID) + "\\"
    if os.path.isdir(path):
        pass
    else:
        print("文件未下载!")
    list = self.get_file()
    info = {}#信息的字典,练习种类作为键,值是一个列表,包含用户所有的信息
    for item in list:
        prc = item[0][14:16]
        info1 = []
        for file_name in item:
            info2 = []
            json_file = path+file_name
            with open(json_file, 'r', encoding='utf8') as f:
                data = json.load(f)
            info2.append(data["name"])
            info2.append(data["No"])
            info2.append(data["course"][0:2])
            info2.append(data["score"])
            info1.append(info2)
        info[prc] = info1
    return info

#对info中的信息绘图
def draw(self):
    info = self.get_practice_file_info()
    path = str(os.path.abspath(os.curdir)) + "\\" + str(self.ID)
    file_name = str(self.ID)+".html"#绘图需要的html文件
    if info:#如果info不为空则绘图
        title = info[list(info.keys())[0]][0][0] + "_" + info[list(info.keys())[0]][0][1]#图的标题
        subtitle = info[list(info.keys())[0]][0][2]#图的子标题
        line = Line(title, subtitle, subtitle_color="green", background_color='#f8f8ff',width=830,height=470)#创建折线对象,对应参数指定
        for key in info.keys():#获取信息
            value = []
            for val in info[key]:
                value.append(val[3])
            line.add(key, [i for i in range(len(value))], value, mark_point=["max", "min"], mark_line=["average"], )#添加折线
        line.render(file_name)#生成html文件
        #将生成的文件移入用户文件夹,如果有则删除并移入,保证文件是最新的
        try:
            shutil.move(file_name, path)
        except BaseException:
            os.remove(path+"\\"+file_name)
            shutil.move(file_name, path)
    else:
        print("用户未练习!")
        
        #这个类是用来创建浏览器并显示html文件            

class MainWindow(QMainWindow):

def __init__(self,id):
    super(QMainWindow,self).__init__()
    self.get_user_draw = Get_User_Drawing(id)
    self.draw = self.get_user_draw.draw()#生成html文件
    self.setGeometry(400,300,851,501)#前两个参数是到左上角的距离,后两个参数是浏览器的大小
    self.browser = QWebEngineView()
    file_str = os.path.abspath(os.curdir)+"\\"+str(id)+"\\"+str(id) + ".html"
    file_name = ""
    for item in file_str.split("\\"):
        file_name+=item+"/"
    file_name = file_name[:-1]#将\换成/,不然文件找不到
    self.browser.load(QUrl(file_name))
    self.setCentralWidget(self.browser)
    self.setWindowFlags(QtCore.Qt.FramelessWindowHint)#生成无边框的浏览器,伪造图片的效果

if name==“main”:
app = QApplication(sys.argv)
win = MainWindow(“001”)
win.show()
sys.exit(app.exec_())

四,结果展示

![在这里插入图片描述](https://img-blog.csdnimg.cn/2018122910473875.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTM4OTM4,size_16,color_FFFFFF,t_70)

你可能感兴趣的:(技术)