diff --git a/README.md b/README.md index 8fc3e0747c8f0b9cd16f10cdb088bf778e1370f9..d63b7f445ba11bb4ea45ccba40b6e5bdb015440c 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,14 @@ PyMiner一款数据分析工具,目的是使pandas\sklearn的操作进行可视 1. 下载项目源码 2. 安装python并打开命令行工具,使用 pip install -r requirements.txt 导入python包,如果你的python依赖包下载太慢,建议使用:pip install -i https://mirrors.cloud.tencent.com/pypi/simple -r requirements.txt -3. 调用python 执行目录下pyminer.py,例如python安装在C盘根目录下,可以在cmd命令行中执行:C:\python\python.exe C:\PyMiner\pyminer.py -4. 此外,你也可以使用pyinstaller进行编译后使用,编译语句:pyinstaller -i logo.ico -w pyminer.py +3. 调用python 执行目录下app.py,例如python安装在C盘根目录下,可以在cmd命令行中执行:C:\python\python.exe C:\PyMiner\pyminer.py #### 联系我 1. 作者:PyMiner Development Team 2. 邮箱:aboutlong@qq.com -3. Q Q:454017698 +3. QQ:454017698 4. QQ群:945391275 #### 预览 diff --git a/pyminer/features/preprocess/PMDataInfoForm.py b/pyminer/features/preprocess/PMDataInfoForm.py index 8800afdd41ee870c5921609dfabe1da858f8e5c5..6bbf9ad9dbf2f31f7da9f45a1e4b083a1f5d721f 100644 --- a/pyminer/features/preprocess/PMDataInfoForm.py +++ b/pyminer/features/preprocess/PMDataInfoForm.py @@ -8,10 +8,10 @@ import pandas as pd from PyQt5.QtWidgets import QTableWidgetItem, QInputDialog from PyQt5.QtCore import Qt - from pyminer.ui.data.data_info import Ui_Form as DataInfo_Ui_Form # 数据信息 from .PMDialog import PMDialog + class DataInfoForm(PMDialog, DataInfo_Ui_Form): """ 打开"数据-数据信息" @@ -20,7 +20,7 @@ class DataInfoForm(PMDialog, DataInfo_Ui_Form): def __init__(self): super().__init__() self.setupUi(self) - self.all_dataset = dict() + self.data_manager = dict() self.all_dataset_name = list() self.current_dataset_name = '' # 当前数据集名称 @@ -36,13 +36,11 @@ class DataInfoForm(PMDialog, DataInfo_Ui_Form): # 更新当前数据信息 self.lineEdit_dataset_name.textChanged.connect(self.change_dataset_info) - - def info_init(self): # print(self.info) #None # print(type(self.info)) # # print(isinstance(self.info,pd.DataFrame)) # py3.7 :False ?? - if self.info: + if self.info is not None: input_table_rows = self.info.head(100).shape[0] input_table_colunms = self.info.shape[1] input_table_header = self.info.columns.values.tolist() @@ -73,15 +71,13 @@ class DataInfoForm(PMDialog, DataInfo_Ui_Form): def change_dataset_info(self): # 修改当前数据集的数据信息 - self.lineEdit_path.setText(self.all_dataset.get(self.current_dataset_name + ".path")) - self.lineEdit_row.setText(self.all_dataset.get(self.current_dataset_name + ".row")) - self.lineEdit_col.setText(self.all_dataset.get(self.current_dataset_name + ".col")) - self.lineEdit_file_size.setText(self.all_dataset.get(self.current_dataset_name + ".file_size")) - self.lineEdit_memory_usage.setText( - self.all_dataset.get(self.current_dataset_name + ".memory_usage")) - self.lineEdit_create_time.setText( - self.all_dataset.get(self.current_dataset_name + ".create_time")) - self.lineEdit_update_time.setText( - self.all_dataset.get(self.current_dataset_name + ".update_time")) - self.info = self.all_dataset.get(self.current_dataset_name + ".info") + property_dic = self.data_manager.get_info(self.current_dataset_name) + self.lineEdit_path.setText(property_dic.get("path")) + self.lineEdit_row.setText(property_dic.get("row")) + self.lineEdit_col.setText(property_dic.get('col')) + self.lineEdit_file_size.setText(property_dic.get("file_size")) + self.lineEdit_memory_usage.setText(property_dic.get("memory_usage")) + self.lineEdit_create_time.setText(property_dic.get("create_time")) + self.lineEdit_update_time.setText(property_dic.get("update_time")) + self.info = property_dic.get("info") self.info_init() diff --git a/pyminer/features/preprocess/PMDataReplaceForm.py b/pyminer/features/preprocess/PMDataReplaceForm.py index 04962fa8cbd4decc9f27db446ac8d7d36d25a0a8..528afcaa0233042b949a6efcce8ff8b1c8fe2cd2 100644 --- a/pyminer/features/preprocess/PMDataReplaceForm.py +++ b/pyminer/features/preprocess/PMDataReplaceForm.py @@ -12,6 +12,7 @@ from pandas.core.dtypes.common import is_string_dtype, is_numeric_dtype from .PMDialog import PMDialog from pyminer.ui.data.data_repace import Ui_Form as DataReplace_Ui_Form + class DataReplaceForm(PMDialog, DataReplace_Ui_Form): """ 打开"数据-内容替换"窗口 @@ -28,7 +29,7 @@ class DataReplaceForm(PMDialog, DataReplace_Ui_Form): self.result_col = [] self.result_value = [] self.current_dataset_name = "" - self.all_dataset = dict() + self.data_manager = dict() self.result_dataset = pd.DataFrame() self.dataset_alter = pd.DataFrame() # 修改后的数据集 self.tableWidget_dataset.setVisible(False) @@ -208,10 +209,11 @@ class DataReplaceForm(PMDialog, DataReplace_Ui_Form): if reply == QMessageBox.Yes: logging.info("发射导入数据信号") if len(self.dataset_alter) > 0: - create_time = self.all_dataset.get(self.current_dataset_name + '.create_time') + property_dic = self.data_manager.get_info(self.current_dataset_name) + create_time = property_dic.get('create_time') update_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 数据更新时间 - path = self.all_dataset.get(self.current_dataset_name + '.path') - file_size = self.all_dataset.get(self.current_dataset_name + '.file_size') + path = property_dic.get('path') + file_size = property_dic.get('file_size') remarks = '' self.signal_data_change.emit(self.current_dataset_name, self.dataset_alter.to_dict(), @@ -233,10 +235,11 @@ class DataReplaceForm(PMDialog, DataReplace_Ui_Form): if ok and (len(dataset_name) != 0): logging.info("发射导入数据信号") if len(self.dataset_alter) > 0: - create_time = self.all_dataset.get(self.current_dataset_name + '.create_time') + property_dic = self.data_manager.get_info(self.current_dataset_name) + create_time = property_dic.get('create_time') update_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 数据更新时间 - path = self.all_dataset.get(self.current_dataset_name + '.path') - file_size = self.all_dataset.get(self.current_dataset_name + '.file_size') + path = property_dic.get('path') + file_size = property_dic.get('file_size') remarks = '' self.signal_data_change.emit(dataset_name, self.dataset_alter.to_dict(), @@ -271,4 +274,3 @@ class DataReplaceForm(PMDialog, DataReplace_Ui_Form): newItem = QTableWidgetItem(input_table_items) newItem.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.tableWidget_dataset.setItem(i, j, newItem) - diff --git a/pyminer/features/preprocess/PMDataRowFilterForm.py b/pyminer/features/preprocess/PMDataRowFilterForm.py index 0873159ada7bff804326b89587597c6343fb0ea7..323a042bd1ee20350251142e6bfcba56dc7c3c4e 100644 --- a/pyminer/features/preprocess/PMDataRowFilterForm.py +++ b/pyminer/features/preprocess/PMDataRowFilterForm.py @@ -25,7 +25,7 @@ class DataRowFilterForm(PMDialog, DataRowFilter_Ui_Form): self.current_dataset = pd.DataFrame() self.current_dataset_name = '' - self.all_dataset = {} + self.data_manager = {} self.current_dataset_columns = [] self.data_type = [] self.filter_dataset = pd.DataFrame() @@ -202,10 +202,10 @@ class DataRowFilterForm(PMDialog, DataRowFilter_Ui_Form): if ok and (len(dataset_name) != 0): logging.info("发射导入数据信号") if len(self.filter_dataset) > 0: - create_time = self.all_dataset.get(self.current_dataset_name + '.create_time') + create_time = self.data_manager.get(self.current_dataset_name + '.create_time') update_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 数据更新时间 - path = self.all_dataset.get(self.current_dataset_name + '.path') - file_size = self.all_dataset.get(self.current_dataset_name + '.file_size') + path = self.data_manager.get(self.current_dataset_name + '.path') + file_size = self.data_manager.get(self.current_dataset_name + '.file_size') remarks = '' self.signal_data_change.emit(dataset_name, self.filter_dataset.to_dict(), @@ -225,10 +225,10 @@ class DataRowFilterForm(PMDialog, DataRowFilter_Ui_Form): if reply == QMessageBox.Yes: logging.info("发射导入数据信号") if len(self.filter_dataset) > 0: - create_time = self.all_dataset.get(self.current_dataset_name + '.create_time') + create_time = self.data_manager.get(self.current_dataset_name + '.create_time') update_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 数据更新时间 - path = self.all_dataset.get(self.current_dataset_name + '.path') - file_size = self.all_dataset.get(self.current_dataset_name + '.file_size') + path = self.data_manager.get(self.current_dataset_name + '.path') + file_size = self.data_manager.get(self.current_dataset_name + '.file_size') remarks = '' self.signal_data_change.emit(self.current_dataset_name, self.filter_dataset.to_dict(), diff --git a/pyminer/features/sample/io.py b/pyminer/features/sample/io.py index 85f587d9924efaabd9303cbd902c4faed51ec165..886a6d810dd8b24b41c3c33f341f9eeb8a3cba19 100644 --- a/pyminer/features/sample/io.py +++ b/pyminer/features/sample/io.py @@ -256,7 +256,7 @@ class ImportDatabase(QDialog,ImportDatabase_Ui_Form): self.current_dataset_name = '' # 当前数据集名称 self.current_dataset = pd.DataFrame() # 修改后的数据集 - self.all_dataset='' #当前已导入的全部数据 + self.data_manager= '' #当前已导入的全部数据 self.file_path='' #当前数据路径 #QssTools.set_qss_to_obj(ui_dir + "/source/qss/patata.qss", self) diff --git a/pyminer/pmapp.py b/pyminer/pmapp.py index 5e0826db448ec9fc63403677f46b10ad537275f3..46342e931efeea72a4b4a98d758ee562127e8806 100644 --- a/pyminer/pmapp.py +++ b/pyminer/pmapp.py @@ -37,9 +37,9 @@ from pyminer.ui.source.qss.qss_tools import QssTools from pyminer.pmutil import get_root_dir, get_application from pyminer.ui.base.widgets.notificationwidget import NotificationWindow +from pyminer.share.datamanager import DataManager from pyminer.features.statistics.test_basic_stats import StatsBaseForm - from pyminer.features.preprocess.PMDataInfoForm import DataInfoForm from pyminer.features.preprocess.PMDataFilterForm import DataFilterForm from pyminer.features.preprocess.PMDataRoleForm import DataRoleForm @@ -60,8 +60,6 @@ from pyminer.features.preprocess.PMDataSortForm import DataSortForm from pyminer.features.preprocess.PMDataStandardForm import DataStandardForm from pyminer.features.preprocess.PMDataTransposeForm import DataTransposeForm - - TextStyle = """ QMessageBox QPushButton[text="OK"] { qproperty-text: "确认"; @@ -128,7 +126,6 @@ class Application(QApplication): QApplication.__init__(self, argv) QApplication.setStyle('Fusion') - def _slot_setStyle(self): """ 设置app样式 @@ -142,7 +139,6 @@ class Application(QApplication): self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) - class CustomRect(QGraphicsObject): def __init__(self): super(CustomRect, self).__init__() @@ -182,9 +178,6 @@ class CustomRect(QGraphicsObject): painter.end() - - - class MyMainForm(QMainWindow, Ui_MainWindow): """ 主窗体 @@ -196,8 +189,13 @@ class MyMainForm(QMainWindow, Ui_MainWindow): self.center() self.__file_path_choose = "" - self.__all_dataset = dict() # 定义字典,保存全部数据集的基本信息 - self.__all_dataset_name = set() # 定义集合,保存全部数据集名称,确保不会重复 + + # 将原有的数据存储工具注释掉。方便之后查阅。 + # self.__all_dataset = dict() # 定义字典,保存全部数据集的基本信息 + # self.__all_dataset_name = set() # 定义集合,保存全部数据集名称,确保不会重复 + # 新的工具存储类。 + self.data_manager = DataManager() + self.__current_dataset_name = "" self.__current_dataset = pd.DataFrame() self.__current_dataset_dtype = set() # 定义集合,保存当前数据集中存在的数据类型,确保不会重复 @@ -238,9 +236,6 @@ class MyMainForm(QMainWindow, Ui_MainWindow): self.action_menu_data_merge_h.triggered.connect(self.data_merge_horizontal_display) self.action_menu_data_merge_v.triggered.connect(self.data_merge_vertical_display) - - - self.treeView_files.bind_events(self) # 流程图 @@ -412,7 +407,6 @@ class MyMainForm(QMainWindow, Ui_MainWindow): # ================================自定义功能函数========================= - def openActionHandler(self): print("打开功能的函数是openActionHandler") @@ -845,7 +839,7 @@ class MyMainForm(QMainWindow, Ui_MainWindow): # 修改当前正在使用的数据集 self.__current_dataset = dataset self.__current_dataset_name = dataset_name - self.__all_dataset_name.add(dataset_name) # 保存数据集名称 + self.data_manager.set_data(self.__current_dataset_name,dataset) row = str(dataset.shape[0]) # 行数 col = str(dataset.shape[1]) # 列数 memory_size = self.__current_dataset.memory_usage().sum() @@ -880,33 +874,23 @@ class MyMainForm(QMainWindow, Ui_MainWindow): data_notna_cnt.append(dataset.loc[:, i].notna().sum()) info = pd.DataFrame({"变量名称": list(dataset.columns), "数据类型": data_type, "非空值数量": data_notna_cnt}) - dataset_new = {dataset_name: dataset, - dataset_name + ".path": path, - dataset_name + ".create_time": create_time, - dataset_name + ".update_time": update_time, - dataset_name + ".row": row, - dataset_name + ".col": col, - dataset_name + ".remarks": remarks, - dataset_name + ".file_size": file_usage, - dataset_name + ".memory_usage": memory_usage, - dataset_name + ".info": info, } + # dataset_new = {dataset_name: dataset, + # dataset_name + ".path": path, + # dataset_name + ".create_time": create_time, + # dataset_name + ".update_time": update_time, + # dataset_name + ".row": row, + # dataset_name + ".col": col, + # dataset_name + ".remarks": remarks, + # dataset_name + ".file_size": file_usage, + # dataset_name + ".memory_usage": memory_usage, + # dataset_name + ".info": info, } # 添加当前数据集到数据集列表中 print("添加当前数据集到数据集列表中") # 检查数据集名称是否已存在,如果存在则修改相关信息,否则进行新增 - if self.__current_dataset_name in list(self.__all_dataset.keys()): - self.__all_dataset[dataset_name] = dataset - self.__all_dataset[dataset_name + ".path"] = path - self.__all_dataset[dataset_name + ".create_time"] = create_time - self.__all_dataset[dataset_name + ".update_time"] = update_time - self.__all_dataset[dataset_name + ".row"] = row - self.__all_dataset[dataset_name + ".col"] = col - self.__all_dataset[dataset_name + ".remarks"] = remarks - self.__all_dataset[dataset_name + ".file_size"] = file_size - self.__all_dataset[dataset_name + ".memory_usage"] = memory_usage - self.__all_dataset[dataset_name + ".info"] = info - else: - self.__all_dataset.update(dataset_new) + self.data_manager.set_info(dataset_name, path, create_time=create_time, update_time=update_time, row=row, + col=col, remarks=remarks, file_size=file_usage, memory_usage=memory_usage, info=info) + self.tabWidget.setCurrentIndex(0) def add_dataset_to_workdir(self, dataset_name): @@ -947,7 +931,7 @@ class MyMainForm(QMainWindow, Ui_MainWindow): 显示"从数据库导入"窗口 """ self.import_database = io.ImportDatabase() - self.import_database.all_dataset = self.__all_dataset + self.import_database.data_manager = self.data_manager self.import_database.signal_data_change.connect(self.slot_dataset_reload) self.import_database.show() @@ -960,7 +944,7 @@ class MyMainForm(QMainWindow, Ui_MainWindow): self.data_row_filter_form.current_dataset = self.__current_dataset self.data_row_filter_form.current_dataset_name = self.__current_dataset_name - self.data_row_filter_form.all_dataset = self.__all_dataset + self.data_row_filter_form.data_manager = self.data_manager self.data_row_filter_form.current_dataset_columns = self.__current_dataset.columns self.data_row_filter_form.comboBox_columns.addItems(list(self.__current_dataset.columns)) for col in self.__current_dataset.columns: @@ -977,21 +961,19 @@ class MyMainForm(QMainWindow, Ui_MainWindow): self.data_info = DataInfoForm() self.data_info.unset_effect_signal.connect(self.page_data.btn_data_info.unset_btn_clicked_effect) - self.data_info.all_dataset = self.__all_dataset - self.data_info.all_dataset_name = list(self.__all_dataset_name) + self.data_info.data_manager = self.data_manager + self.data_info.all_dataset_name = list(self.data_manager.all_data_names) self.data_info.current_dataset_name = self.__current_dataset_name self.data_info.lineEdit_dataset_name.setText(self.__current_dataset_name) - self.data_info.lineEdit_path.setText(self.__all_dataset.get(self.__current_dataset_name + ".path")) - self.data_info.lineEdit_row.setText(self.__all_dataset.get(self.__current_dataset_name + ".row")) - self.data_info.lineEdit_col.setText(self.__all_dataset.get(self.__current_dataset_name + ".col")) - self.data_info.lineEdit_file_size.setText(self.__all_dataset.get(self.__current_dataset_name + ".file_size")) - self.data_info.lineEdit_memory_usage.setText( - self.__all_dataset.get(self.__current_dataset_name + ".memory_usage")) - self.data_info.lineEdit_create_time.setText( - self.__all_dataset.get(self.__current_dataset_name + ".create_time")) - self.data_info.lineEdit_update_time.setText( - self.__all_dataset.get(self.__current_dataset_name + ".update_time")) - self.data_info.info = self.__all_dataset.get(self.__current_dataset_name + ".info") + property_dic = self.data_manager.get_info(self.__current_dataset_name) + self.data_info.lineEdit_path.setText(property_dic.get("path")) + self.data_info.lineEdit_row.setText(property_dic.get("row")) + self.data_info.lineEdit_col.setText(property_dic.get("col")) + self.data_info.lineEdit_file_size.setText(property_dic.get("file_size")) + self.data_info.lineEdit_memory_usage.setText(property_dic.get("memory_usage")) + self.data_info.lineEdit_create_time.setText(property_dic.get("create_time")) + self.data_info.lineEdit_update_time.setText(property_dic.get("update_time")) + self.data_info.info = property_dic.get('info') self.data_info.info_init() self.data_info.exec_() @@ -1160,7 +1142,7 @@ class MyMainForm(QMainWindow, Ui_MainWindow): self.data_replace.unset_effect_signal.connect(self.page_data.btn_data_info.unset_btn_clicked_effect) self.data_replace.current_dataset = self.__current_dataset - self.data_replace.all_dataset = self.__all_dataset + self.data_replace.data_manager = self.data_manager self.data_replace.current_dataset_name = self.__current_dataset_name self.data_replace.current_dataset_columns = self.__current_dataset.columns self.data_replace.comboBox_find_columns.addItems(list(self.__current_dataset.columns)) @@ -1302,7 +1284,7 @@ class MyMainForm(QMainWindow, Ui_MainWindow): self.th.finishSignal.connect(self.jupyter_log) self.th.start() except Exception as e: - print('jupyter_notebook_display:',e) + print('jupyter_notebook_display:', e) def jupyter_log(self, msg): self.slot_flush_console("info", "jupyter", msg) diff --git a/pyminer/pmstart.py b/pyminer/pmstart.py index b2fc416237490862556a7dc942e7243ad81480d4..c89ad6d59ae579e4ab446cb1069da6a4b8b24c70 100644 --- a/pyminer/pmstart.py +++ b/pyminer/pmstart.py @@ -30,7 +30,7 @@ def boot(): myWin.load_data(splash) pmutil._main_window = myWin - #myWin.data_import_file_test('class.csv') + myWin.data_import_file_test('class.csv') # 窗口美化设置 # QssTools.set_qss_to_obj(root_dir + "/ui/source/qss/pyminer.qss", app) diff --git a/pyminer/share/datamanager/__init__.py b/pyminer/share/datamanager/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c4e52bdb5801f1d8a784797a203a004edc2b7967 --- /dev/null +++ b/pyminer/share/datamanager/__init__.py @@ -0,0 +1 @@ +from .datamanager import DataManager \ No newline at end of file diff --git a/pyminer/share/datamanager/datamanager.py b/pyminer/share/datamanager/datamanager.py new file mode 100644 index 0000000000000000000000000000000000000000..f78acb5474ada498c503e54af850c06d70908fb3 --- /dev/null +++ b/pyminer/share/datamanager/datamanager.py @@ -0,0 +1,325 @@ +import time +import warnings + +MAX_STEPS = 15 +import copy +from typing import Dict + + +class Data(): + ''' + 这是一个数据对象,可以管理数据的历史。 + 支持的对象类型应当是有限的,比如dataframe,ndarray等。 + 目前使用的就是这个类。 + ''' + value = None + info = {} + + def __init__(self, ini_value: object): + self.info = {} + self.set_data(ini_value) + + def set_data(self, value: object): + ''' + 添加数据。 + :param value: + :return: + ''' + self.value = value + # self.update_info() + + def get_data(self, copy_val=True) -> object: + ''' + 获取数据的值,采用当前的指针。 + :param copy_val: + 如果为True(默认),就返回复制后的对象。反之返回引用。当需要修改对象的时候,请保持True。 + 特别的,不要使用类似如下的方式。这样会多次复制对象,从而导致不必要的开销: + for i in range(10): + Data.get('a')[i] + 可以使用如下方案: + for i in range(10): + Data.get('a',copy=False)[i] + 但还是推荐使用: + a = Data.get('a') + for i in range(10): + a[i] + :return:object + ''' + return self.value + + def update_info(self): # 目前逻辑是写死了的。 + name = 'test_file' + path = '../class.csv' + create_time = '2017.9.1' # self.info['create_time'] + update_time = '时间戳:' + str(time.time()) + row = '10' + col = '10' + remarks = '' + file_size = '123' + memory_usage = '123kb' + info = '' + self.set_info(name, path, create_time, update_time, row, col, remarks, file_size, memory_usage, info) + + def set_info(self, dataset_name: str, path: str, create_time: str, + update_time: str, row: str, col: str, remarks: str, file_size: str, + memory_usage: str, info=''): + dataset_info = {"name": dataset_name, + "path": path, + "create_time": create_time, + "update_time": update_time, + "row": row, + "col": col, + "remarks": remarks, + "file_size": file_size, + "memory_usage": memory_usage, + "info": info} + self.info = dataset_info + + +class Data_With_Undo_Func(): + ''' + 这是一个数据对象,可以管理数据的历史。 + 支持的对象类型应当是有限的,比如dataframe,ndarray等。 + 目前用不上这个类,因为这个比较复杂。 + ''' + + def __init__(self, ini_value: object): + self.value_stack = [] + self.stack_pointer = 0 # 指向起始位置的指针。以下代码注释中简称‘指针’ + self.info = {} + self.set_data(ini_value) + + def __len__(self): + return len(self.value_stack) + + def get_latest(self, copy_val=True) -> object: + if copy_val: + return copy.copy(self.value_stack[-1]) + return self.value_stack[-1] + + def set_data(self, value: object): + ''' + 添加数据。 + :param value: + :return: + ''' + self.value_stack.append(value) + while len(self.value_stack) > MAX_STEPS: + self.value_stack.pop(0) + self.stack_pointer = len(self) - 1 + # self.update_info() + + def get_data(self, copy_val=True) -> object: + ''' + 获取数据的值,采用当前的指针。 + :param copy_val: + 如果为True(默认),就返回复制后的对象。反之返回引用。当需要修改对象的时候,请保持True。 + 特别的,不要使用类似如下的方式。这样会多次复制对象,从而导致不必要的开销: + for i in range(10): + Data.get('a')[i] + 可以使用如下方案: + for i in range(10): + Data.get('a',copy=False)[i] + 但还是推荐使用: + a = Data.get('a') + for i in range(10): + a[i] + :return:object + ''' + index = self.stack_pointer + if copy_val: + return copy.copy(self.value_stack[index]) + return self.value_stack[index] + + def get_index(self) -> int: + return self.stack_pointer + + def set_index(self, index: int): + if 0 <= index < len(self.value_stack): + self.stack_pointer = index + + def update_info(self): # 目前逻辑是写死了的。 + name = 'test_file' + path = '../class.csv' + create_time = '2017.9.1' # self.info['create_time'] + update_time = '时间戳:' + str(time.time()) + row = '10' + col = '10' + remarks = '' + file_size = '123' + memory_usage = '123kb' + info = '' + self.set_info(name, path, create_time, update_time, row, col, remarks, file_size, memory_usage, info) + + def set_info(self, dataset_name: str, path: str, create_time: str, + update_time: str, row: str, col: str, remarks: str, file_size: str, + memory_usage: str, info=''): + + dataset_info = {"name": dataset_name, + "path": path, + "create_time": create_time, + "update_time": update_time, + "row": row, + "col": col, + "remarks": remarks, + "file_size": file_size, + "memory_usage": memory_usage, + "info": info} + self.info = dataset_info + + +class DataManager(): + ''' + 以下举例均默认data_manager = DataManager() + ''' + + def __init__(self): + self.vars: Dict[str, Data] = {} + self.recycle_bin: Dict[str, Data] = {} + self.current_data = None + # self.all_data_sets_info: Dict[str, dict] = {} # 管理数据集的信息 + + @property + def all_data_names(self) -> set: + ''' + 调用方式:data_manager.all_data_names + 可以代替__all_data_names + Returns: + + ''' + return {k for k in self.vars.keys()} + + def get_info(self, name: str): + ''' + + Args: + name: 变量的名称 + + Returns:字典。返回变量的全部属性字典。比如get_info('class')['path'],就是返回名为‘class’的数据集中的‘path’属性。 + + ''' + return self.vars[name].info + + def set_data(self, name: str, value: object) -> None: + ''' + 设置信息。 + 比如说,set_data('a'),就是设置数据集a的值。 + Args: + name: + value: + + Returns: + + ''' + if name in self.vars.keys(): + self.vars[name].set_data(value) + else: + self.vars[name] = Data(value) + + def get_all_data_dic(self): + ''' + 获取所有数据,是一个名称对元素的字典。但是要注意,返回的值是一个Data对象,而不是变量的字典。 + Returns: + + ''' + return self.vars + + def get_data(self, name: str, copy_val: bool = False) -> object: + ''' + 获取名为name的data。如果copy_val是True,那么就将其设置为True之后再 + Args: + name: + copy_val: + + Returns: + + ''' + if name in self.vars.keys(): + return self.vars[name].get_data(copy_val=copy_val) + else: + warnings.warn("Variable \'%s\' isn\'t exist." % name) + + def get(self, name: str) -> object: + ''' + 等于get_data。 + Args: + name: + + Returns: + + ''' + return self.get_data(name) + + def move_data_stack_pointer(self, name: str, step: int = 1): + ''' + 无效方法,暂时无用。等到引入撤销功能之后就用上了。 + Args: + name: + step: + + Returns: + + ''' + if name not in self.vars.keys(): + return + var = self.vars[name] + pos = var.stack_pointer + step + if 0 <= pos < len(var): + var.stack_pointer = pos + elif pos < 0: + var.stack_pointer = 0 + print('到达最初数据,不可再撤销!') + elif pos >= len(var): + var.stack_pointer = len(var) - 1 + print('到达最新数据,不可再重做!') + + def move_data_stack_pointer_to(self, name: str, pos: int = -1): + ''' + 暂时用不上的方法。 + Args: + name: + pos: + + Returns: + + ''' + if name not in self.vars.keys(): + return + var = self.vars[name] + if pos < 0: + pos = len(var.value_stack) - pos + + if 0 <= pos < len(var): + var.stack_pointer = pos + elif pos < 0: + var.stack_pointer = 0 + print('到达最初数据,不可再撤销!') + elif pos >= len(var): + var.stack_pointer = len(var) - 1 + print('到达最新数据,不可再重做!') + + def delete_data(self, name: str) -> None: + '''删除数据,也就是移动到回收站。''' + if name in self.vars.keys(): + self.recycle_bin[name] = self.vars[name] + self.vars.pop(name) + else: + warnings.warn("Variable \'%s\' isn\'t exist." % name) + + def recover_data(self, name: str) -> None: + '''从回收站中恢复数据''' + if name in self.recycle_bin.keys(): + self.vars[name] = self.recycle_bin[name] + self.recycle_bin.pop(name) + else: + warnings.warn("Variable \'%s\' isn\'t exist." % name) + + def set_info(self, dataset_name: str, path: str, create_time: str, + update_time: str, row: str, col: str, remarks: str, file_size: str, + memory_usage: str, info=''): + '''设置信息''' + + self.vars[dataset_name].set_info(dataset_name, path=path, create_time=create_time, update_time=update_time, + row=row, col=col, remarks=remarks, file_size=file_size, + memory_usage=memory_usage, + info=info)