Browse Source

新增进程管理器、新增“CoTan社区”、调整了Log机制

Huan 5 years ago
parent
commit
861801aa78

+ 1 - 0
Database_dir/This_is_cotanDB_dir

@@ -0,0 +1 @@
+这是CoTanDB的文件保存文件夹,该文件夹下会生成*.cotandb文件

+ 278 - 43
Hello.py

@@ -1,10 +1,14 @@
-from multiprocessing import Process
+from multiprocessing import Process, Queue
+import threading
 from _tkinter import TclError
 import tkinter
 from tkinter import ttk
 import tkinter.font as tkfont
 from PIL import ImageTk, Image
 import time
+import os
+import tkinter.messagebox
+import webbrowser
 
 from newtkinter import DragWindow
 
@@ -17,11 +21,109 @@ algebraicfactory_start = None
 machinelearner_start = None
 git_start = None
 crawlef_start = None
+title_color = '#F0FFFF'
+button_color = '#FFFFFF'
+button_cursor = 'tcross'
+
+
+class QueueController:
+    def __init__(self):
+        self.in_dict = {}
+        self.out_dict = {}
+        self.var_dict = {}
+        self.queue_list = []
+        self.var_from = {}
+        self.update_var = lambda x, y: None
+        self.update_queue = lambda x: None
+        self.run = False
+        self.stop_str = "__--$$stop_process$$--__"
+
+    def can_stop(self):
+        return len(self.out_dict) == 0
+
+    def __call__(self, *args, **kwargs):
+        self.run = True
+
+        def done():
+            while self.run:
+                stop_pid = []
+                old_var = list(self.var_dict.keys())
+                for out in self.out_dict:
+                    output: Queue = self.out_dict[out]
+                    if output.empty():
+                        continue
+                    dict_index = f'var_{len(self.var_dict)}'
+                    get_out = output.get()
+                    if get_out == self.stop_str:
+                        stop_pid.append(out)
+                    else:
+                        self.var_dict[dict_index] = get_out
+                        self.var_from[dict_index] = out
+                if old_var != list(self.var_dict.keys()):
+                    self.update_var(self.var_dict, self.var_from)
+                if stop_pid:
+                    for i in stop_pid:
+                        del self.in_dict[i]
+                        del self.out_dict[i]
+                    self.queue_list = list(self.in_dict.keys())
+                    self.update_queue(self.queue_list.copy())
+
+        t = threading.Thread(target=done)
+        t.setDaemon(True)
+        t.start()
+        return self
+
+    def stop(self):
+        self.run = False
+
+    def add_queue(self, inqueue, outqueue, name):
+        self.stop()
+        self.in_dict[name] = inqueue
+        self.out_dict[name] = outqueue
+        self.queue_list = list(self.in_dict.keys())
+        self.update_queue(self.queue_list.copy())
+        self.update_var(self.var_dict, self.var_from)
+
+    def init(self, update_var, update_queue):
+        self.update_var = update_var
+        self.update_queue = update_queue
+        self.update_queue(list(self.in_dict.keys()))
+        self.update_var(self.var_dict, self.var_from)
+
+    def put(self, value: str, index):
+        name_space = self.var_dict.copy()
+        name_space.update(globals())
+        in_queue = self.in_dict[self.queue_list[index]]
+        if value.startswith('put_var '):
+            var_name = value[7:]
+            in_queue.put(self.var_dict.get(var_name))
+        elif value.startswith('put_eval '):
+            in_queue.put(eval(value[8:]), name_space)
+        elif value.startswith('file ') and value.startswith('.py'):
+            try:
+                with open(value[4:], 'r') as f:
+                    code_file = f.read()
+                new_name_space = name_space
+                exec(code_file, new_name_space)
+                in_queue.put(new_name_space.copy())
+            except BaseException as e:
+                in_queue.put(str(e))
+        else:
+            in_queue.put(value)
+
+
+queue_controller = QueueController()
 
 
 def progress_bar(func):
     def make_bar(*agrs, **kwargs):
-        func(*agrs, **kwargs)
+        SCREEN.update()
+        in_queue: Queue
+        out_queue: Queue
+        in_queue, out_queue = func(*agrs, **kwargs)
+        pid = out_queue.get()
+        name = func.__name__
+        queue_controller.add_queue(in_queue, out_queue, f'{name}_{pid}')
         progress_screen = tkinter.Toplevel()
         progress_screen.title('系统持续加载中...')
         progress_screen.geometry("+10+10")  # 设置所在位置
@@ -30,113 +132,246 @@ def progress_bar(func):
         )
         progress.pack()
         progress_screen.resizable(width=False, height=False)
-        progress["maximum"] = 50
+        progress["maximum"] = 10
         progress["value"] = 0
-        for i in range(50):
+        i = 0
+        a = 10
+        while out_queue.empty():
+            i += 1
+            a += 1
             try:
-                progress["value"] = i + 1
+                progress["value"] = i
+                progress["maximum"] = a
                 progress_screen.update()
             except TclError:
                 pass
             SCREEN.update()
             time.sleep(0.015)
-        progress_screen.destroy()
+        try:
+            progress_screen.title(out_queue.get())
+            progress["value"] = a
+            progress_screen.update()
+            time.sleep(0.5)
+            progress_screen.destroy()
+        except TclError:
+            pass
+        queue_controller()
+
     return make_bar
 
 
-def draftboard_main():
+def draftboard_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from draftboard import draw_main
-    draw_main()
+    out_queue.put('start')
+    time.sleep(0.5)
+    draw_main(in_queue, out_queue)
 
 
 @progress_bar
 def draftboard_run():
-    Process(target=draftboard_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=draftboard_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def datascience_main():
+def datascience_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from datascience import machine_learning
-    machine_learning()
+    out_queue.put('start')
+    time.sleep(0.5)
+    machine_learning(in_queue, out_queue)
 
 
 @progress_bar
 def datascience_run():
-    Process(target=datascience_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=datascience_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def functionmapping_main():
+def functionmapping_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from funcsystem.map import function_mapping
-    print('函数测绘加载完毕...')
-    function_mapping()
+    out_queue.put('start')
+    time.sleep(0.5)
+    function_mapping(in_queue, out_queue)
 
 
 @progress_bar
 def functionmapping_run():
-    Process(target=functionmapping_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=functionmapping_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def functionfactory_main():
+def functionfactory_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from funcsystem.factory import function_factory_main
-    print('函数工厂加载完毕...')
-    function_factory_main()
+    out_queue.put('start')
+    time.sleep(0.5)
+    function_factory_main(in_queue, out_queue)
 
 
 @progress_bar
 def functionfactory_run():
-    Process(target=functionfactory_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=functionfactory_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def algebraicfactory_main():
+def algebraicfactory_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from algebraicfactory import algebraic_factory_main
-    algebraic_factory_main()
+    out_queue.put('start')
+    time.sleep(0.5)
+    algebraic_factory_main(in_queue, out_queue)
 
 
 @progress_bar
 def algebraicfactory_run():
-    Process(target=algebraicfactory_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=algebraicfactory_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def machinelearner_main():
+def machinelearner_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from machinelearning import machine_learning
-    machine_learning()
+    out_queue.put('start')
+    time.sleep(0.5)
+    machine_learning(in_queue, out_queue)
 
 
 @progress_bar
 def machinelearner_run():
-    Process(target=machinelearner_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=machinelearner_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def git_main():
+def git_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from gitrepo import git_main
-    git_main()
+    out_queue.put('start')
+    time.sleep(0.5)
+    git_main(in_queue, out_queue)
 
 
 @progress_bar
 def git_run():
-    Process(target=git_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=git_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def crawler_main():
+def crawler_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from crawler import crawler_main
-    crawler_main()
+    out_queue.put('start')
+    time.sleep(0.5)
+    crawler_main(in_queue, out_queue)
 
 
 @progress_bar
 def crawlef_run():
-    Process(target=crawler_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=crawler_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
 
 
-def system_main():
+def system_main(in_queue, out_queue):
+    out_queue.put(str(os.getpid()))
     from system.gui import system_main
-    system_main()
+    out_queue.put('start')
+    time.sleep(0.5)
+    system_main(in_queue, out_queue)
 
 
+@progress_bar
 def system_run():  # 不需要进度条
-    Process(target=system_main).start()
+    in_queue = Queue(10)
+    out_queue = Queue(10)
+    Process(target=system_main, args=(in_queue, out_queue)).start()
+    return in_queue, out_queue
+
+
+def queuer():
+    global title_color, button_color, button_cursor
+    queue_screen = tkinter.Toplevel()
+    queue_screen.title('通信管理器')
+    queue_screen.resizable(width=False, height=False)
+    queue_screen.geometry(f'+30+30')
+    font = ("黑体", 11)  # 设置字体
+
+    def sent():
+        nonlocal sent_text, queue_box
+        value = sent_text.get()
+        try:
+            index = queue_box.curselection()[0]
+        except IndexError:
+            return
+        queue_controller.put(value, index)
+
+    width_b = 20
+    height_b = 2
+    a_x = 0
+    a_y = 0
+    sent_text = tkinter.Entry(queue_screen, width=width_b * 2)
+    sent_text.grid(column=a_x, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N)
+    tkinter.Button(queue_screen, bg=button_color, text='发送', command=sent, font=font, width=10, height=height_b)\
+        .grid(column=a_x+2, row=a_y, sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N)
+    a_y += 1
+    queue_box = tkinter.Listbox(queue_screen, height=height_b * 8)
+    queue_box.grid(column=a_x, row=a_y, columnspan=3, rowspan=8, sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N)
+    a_x += 3
+    a_y = 0
+    var_box = tkinter.Listbox(queue_screen, width=width_b * 3, height=height_b * 9)
+    var_box.grid(column=a_x, row=a_y, columnspan=3, rowspan=9, sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N)
+
+    def update_queue_box(queue_list):
+        try:
+            queue_box.delete(0, tkinter.END)
+            queue_box.insert(0, *queue_list)
+        except TclError:
+            pass
+
+    def update_var_box(var_dict, var_from):
+        var = []
+        for name in var_dict:
+            var.append(f'{name}[{var_from[name]}] : {var_dict[name]}')
+        try:
+            var_box.delete(0, tkinter.END)
+            var_box.insert(0, *var)
+        except TclError:
+            pass
+
+    queue_controller.init(update_var_box, update_queue_box)
+
+
+def to_website():
+    SCREEN.update()
+    webbrowser.open('https://cotan.songzh.website/')
+
+
+def close():
+    global SCREEN
+    if not queue_controller.can_stop():
+        tkinter.messagebox.showinfo('操作不被允许', '请先关闭其他模块。')
+    else:
+        SCREEN.destroy()
 
 
 def cotan_main():
-    global SCREEN
+    global SCREEN, title_color, button_color, button_cursor
     SCREEN = DragWindow(alpha=0.97, width=1200, height=800)
     font1 = tkfont.Font(family='Comic Sans MS', size=20, weight=tkfont.BOLD)
     font2 = tkfont.Font(family='Comic Sans MS', size=16, weight=tkfont.BOLD)
@@ -159,9 +394,6 @@ def cotan_main():
     bg_image = ImageTk.PhotoImage(Image.open('Pic/Night2.jpg'))
     canvas.create_image(500, 400, image=bg_image)
     canvas.grid(column=1, row=0, sticky=tkinter.S + tkinter.N, rowspan=20)
-    title_color = '#F0FFFF'
-    button_color = '#FFFFFF'
-    button_cursor = 'tcross'
     # 标题
     tkinter.Label(
         frame,
@@ -174,7 +406,7 @@ def cotan_main():
         sticky=tkinter.N)  # 设置说明
     tkinter.Label(
         frame,
-        text='寄忆学术',
+        text='CoTan学术',
         bg=title_color,
         font=font2).grid(
         column=0,
@@ -183,11 +415,12 @@ def cotan_main():
         tkinter.E)
     tkinter.Button(
         frame,
-        text='我的寄忆',
+        text='CoTan社区',
         cursor=button_cursor,
         height=2,
         font=font3,
         bg=button_color,
+        command=to_website,
         activebackground=title_color,
         bd=0,
         justify=tkinter.LEFT).grid(
@@ -418,7 +651,7 @@ def cotan_main():
         tkinter.E)
     tkinter.Button(
         frame,
-        text='系统扩展',
+        text='系统管理',
         cursor=button_cursor,
         command=system_run,
         height=1,
@@ -434,11 +667,12 @@ def cotan_main():
         tkinter.W)
     tkinter.Button(
         frame,
-        text='Tensorflew深度学习',
+        text='通信管理器',
         cursor=button_cursor,
         height=1,
         font=font3,
         bg=button_color,
+        command=queuer,
         activebackground=title_color,
         bd=0,
         justify=tkinter.LEFT).grid(
@@ -458,6 +692,7 @@ def cotan_main():
         sticky=tkinter.W +
         tkinter.E)
     canvas.create_text(500, 750, text='CoTan~别来无恙', font=font4, fill='#FFFFE0')
+    SCREEN.protocol("WM_DELETE_WINDOW", close)
     SCREEN.mainloop()
 
 

+ 1 - 0
Log/This_is_log_dir

@@ -0,0 +1 @@
+这是Log文件夹,该文件夹下会生成log_system.log文件

+ 6 - 2
algebraicfactory/gui.py

@@ -3,9 +3,10 @@ import tkinter.messagebox
 import tkinter.font as tkfont
 
 from algebraicfactory.controller import AlgebraPolynomial
-from system import exception_catch
+from system import exception_catch, QueueController
 
 
+queue_controller = QueueController()
 algebra_list = []
 variable_list = []
 SCREEN = tkinter.Tk()
@@ -1758,9 +1759,12 @@ class API(UIAPI):
         API.update_symbol_algebraic_box_gui()
 
 
-def algebraic_factory_main():
+def algebraic_factory_main(in_queue, out_queue):
     global SCREEN
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
     SCREEN.mainloop()
+    queue_controller.stop_process()
 
 
 algebra_controller = AlgebraPolynomial(API.output_prompt_gui)

+ 15 - 6
crawler/gui.py

@@ -7,8 +7,10 @@ import logging
 import crawler.controller
 import crawler.template
 from newtkinter import askdirectory
-from system import exception_catch, basicConfig
+from system import exception_catch, basicConfig, QueueController
 
+
+queue_controller = QueueController()
 logging.basicConfig(**basicConfig)
 SCREEN = tkinter.Tk()
 database_list = []
@@ -674,13 +676,20 @@ class API(UIAPI):
         API.update_parser_func_box_gui()
 
 
-def crawler_main():
+def crawler_main(in_queue, out_queue):
     global SCREEN
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
+
+    def before_stop():
+        loader.stop()
+        database.close_all()
+        url.close()
+        loader.close()
+
+    queue_controller.set_before_stop(before_stop)
     SCREEN.mainloop()
-    loader.stop()
-    database.close_all()
-    url.close()
-    loader.close()
+    queue_controller.stop_process()
 
 
 SCREEN.title("CoTan自动化网页")

+ 1 - 2
crawler/template.py

@@ -1413,8 +1413,7 @@ class PageParserTool(PageParserFunc):
         self.add_func(f"Webpage_snapshot", action)  # 添加func
 
 
-class PageParserData(PageParserDatabase, PageParserDatabase, PageParserDataSource, PageParserDataFindall,
-                     PageParserTool):
+class PageParserData(PageParserDatabase, PageParserDataSource, PageParserDataFindall,PageParserTool):
     pass
 
 

+ 15 - 10
datascience/gui.py

@@ -8,8 +8,10 @@ from tkinter.scrolledtext import ScrolledText
 import chardet
 
 import datascience.controller
-from system import exception_catch
+from system import exception_catch, QueueController
 
+
+queue_controller = QueueController()
 render_dict = {}  # 保存了画图的List
 learn_dict = {}  # 保存数据处理
 PATH = os.getcwd()
@@ -339,7 +341,7 @@ class UIAPI:
     def rendering_one_gui():
         render_dir = asksaveasfilename(title="选择渲染保存地址", filetypes=[("HTML", ".html")])
         try:
-            assert not render_dir.startswith(".html")
+            assert render_dir.startswith(".html")
         except AssertionError:
             render_dir += ".html"
         return render_dir
@@ -349,7 +351,7 @@ class UIAPI:
     def rendering_gui():
         render_dir = asksaveasfilename(title="选择渲染保存地址", filetypes=[("HTML", ".html")])
         try:
-            assert not render_dir.startswith(".html")
+            assert render_dir.startswith(".html")
         except AssertionError:
             render_dir += ".html"
         return render_dir
@@ -429,7 +431,7 @@ class UIAPI:
     def get_data_split_gui():
         try:
             split = float(data_split.get())
-            assert split < 0 or 1 < split
+            assert not split < 0 or 1 < split
         except (AssertionError, ValueError):
             split = 0.3
         return split
@@ -518,7 +520,7 @@ class API(UIAPI):
         learner = API.get_learner_name_gui()
         try:
             split = float(data_split.get())
-            assert split < 0 or 1 < split
+            assert not split < 0 or 1 < split
         except (AssertionError, ValueError):
             split = 0.3
         socore = machine_controller.training_machine(
@@ -1082,10 +1084,10 @@ class API(UIAPI):
     @staticmethod
     @exception_catch()
     def show_report():
-        assert API.askokcancel_gui(f"是否统计数据,大量的数据需要耗费一定的时间(确定后,系统会在后台统计)")
+        assert not API.askokcancel_gui(f"是否统计数据,大量的数据需要耗费一定的时间(确定后,系统会在后台统计)")
         report_dir = f"{PATH}{os.sep}$Show_Des_Sheet.html"
         name = API.get_sheet_name_gui()
-        assert name is None
+        assert not name is None
         machine_controller.to_report(name, report_dir)
         webbrowser.open(report_dir)
 
@@ -1125,7 +1127,7 @@ class API(UIAPI):
         global PATH, to_html_type
         html_dir = f"{PATH}{os.sep}$Show_Sheet.html"
         name = API.get_sheet_name_gui()
-        assert name is None
+        assert not name is None
         machine_controller.render_html_one(name, html_dir)
         webbrowser.open(html_dir)
 
@@ -1135,7 +1137,7 @@ class API(UIAPI):
         global PATH, to_html_type
         html_dir = f"{PATH}{os.sep}$Show_Sheet.html"
         name = API.get_sheet_name_gui()
-        assert name is None
+        assert not name is None
         machine_controller.render_html_all(name, html_dir, to_html_type.get())
         webbrowser.open(html_dir)
 
@@ -1165,9 +1167,12 @@ class API(UIAPI):
         API.update_sheet_box_gui()
 
 
-def machine_learning():
+def machine_learning(in_queue, out_queue):
     global SCREEN
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
     SCREEN.mainloop()
+    queue_controller.stop_process()
 
 
 tkinter.Button(

+ 2 - 2
datascience/template.py

@@ -1656,7 +1656,7 @@ class RelationshipPlot(Render):
                             data.append([])
                             a = -1
                         else:
-                            assert True
+                            assert False
                     except (AssertionError, ValueError):
                         data_type[a] = GeoType.LINES  # 当前变为Line
                 data[a].append((map_, v))
@@ -1806,7 +1806,7 @@ class GeographyPlot(Render):
                                 type_=GeoType.EFFECT_SCATTER,
                                 color="#1E90FF" if args["is_Dark"] else "#0000FF",
                             )
-                            assert True  # continue
+                            assert False  # continue
                     except (ValueError, TypeError, AssertionError):
                         continue
                 try:

+ 6 - 3
draftboard/board.py

@@ -6,8 +6,9 @@ import pygame
 from pygame.locals import *
 
 from draftboard.toolbox import tool_box
-from system import basicConfig
+from system import basicConfig, QueueController
 
+queue_controller = QueueController()
 logging.basicConfig(**basicConfig)
 
 # 定义一些变量
@@ -244,13 +245,14 @@ def top_draw():
     SCREEN.blit(model_tip, (0, SCREEN_Y - 16))
 
 
-def draw_main():
+def draw_main(in_queue, out_queue):
     global previous_x, previous_y, pen_color, pen_weight, coordinate_system_drawing_method
     global coordinate_click_point, record_origin_x
     global record_origin_y, span, line
     global continuous_draw, middle_key, rect, poly, SCREEN, SCREEN_CAPTION, init_done, previous_x, previous_y, save_dir
     global increasing_color, subtraction_color, bottom_tip, FONT, SCREEN_X, SCREEN_Y, tips
-
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
     flat = True  # 循环条件(不是全局)
     while flat:
         top_draw()
@@ -726,6 +728,7 @@ def draw_main():
                     line = []
                     rect = []
                     poly = []
+    queue_controller.stop_process()
 
 # 快捷键操作指南
 # d-不用点击左键画线(再次点击关闭)

+ 6 - 2
funcsystem/factory.py

@@ -12,8 +12,9 @@ from matplotlib.animation import FuncAnimation
 
 from funcsystem.controller import ExpFunc as ExpFunc
 from newtkinter import asksaveasfilename
-from system import exception_catch, basicConfig
+from system import exception_catch, basicConfig, QueueController
 
+queue_controller = QueueController()
 logging.basicConfig(**basicConfig)
 func = None
 fig = None
@@ -831,9 +832,12 @@ class API(UIAPI):
             raise
 
 
-def function_factory_main():  # H_S-默认函数GF-关闭时询问返回函数
+def function_factory_main(in_queue, out_queue):  # H_S-默认函数GF-关闭时询问返回函数
     global SCREEN
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
     SCREEN.mainloop()
+    queue_controller.stop_process()
 
 
 SCREEN["bg"] = bg_color

+ 6 - 2
funcsystem/map.py

@@ -12,8 +12,9 @@ from matplotlib import rcParams
 
 from funcsystem.controller import SheetFunc, ExpFunc
 from newtkinter import askopenfilename, asksaveasfilename
-from system import exception_catch, basicConfig
+from system import exception_catch, basicConfig, QueueController
 
+queue_controller = QueueController()
 logging.basicConfig(**basicConfig)
 func_logger = []
 fig = None
@@ -588,9 +589,12 @@ class API(UIAPI):
             raise
 
 
-def function_mapping():
+def function_mapping(in_queue, out_queue):
     global SCREEN
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
     SCREEN.mainloop()
+    queue_controller.stop_process()
 
 
 SCREEN.title("CoTan函数测绘")

+ 12 - 12
funcsystem/template.py

@@ -433,14 +433,14 @@ class SheetProperty(SheetFuncInit, metaclass=ABCMeta):
                     if flat is None:
                         flat = 0
                     elif flat == 1:
-                        assert True
+                        assert False
                 elif symmetry_y == -now_y:
                     if flat is None:
                         flat = 1
                     elif flat == 0:
-                        assert True
+                        assert False
                 else:
-                    assert True
+                    assert False
             except AssertionError:
                 flat = None
                 break
@@ -568,7 +568,7 @@ class SheetProperty(SheetFuncInit, metaclass=ABCMeta):
             elif count == max_count:
                 possible_cycle.append(i)
         try:
-            assert not possible_cycle
+            assert possible_cycle
             possible_cycle.sort()
             output_prompt("计算完毕")
             return possible_cycle[0], possible_cycle
@@ -610,7 +610,7 @@ class SheetProperty(SheetFuncInit, metaclass=ABCMeta):
             elif count == max_count:
                 possible_symmetry_axis.append(i)
         try:
-            assert possible_symmetry_axis
+            assert not possible_symmetry_axis
             possible_symmetry_axis.sort()  #
             output_prompt("计算完毕")
             return possible_symmetry_axis[0], possible_symmetry_axis
@@ -657,7 +657,7 @@ class SheetProperty(SheetFuncInit, metaclass=ABCMeta):
             elif count == max_count:
                 possible_center.append(i)
         try:
-            assert max_count < 5 or not possible_center
+            assert not max_count < 5 or not possible_center
             output_prompt("计算完毕")
             possible_center.sort()
             return possible_center[int(len(possible_center) / 2)], possible_center
@@ -1370,14 +1370,14 @@ class ExpProperty(ExpFuncInit, metaclass=ABCMeta):
                     if flat is None:
                         flat = 0
                     elif flat == 1:
-                        assert True
+                        assert False
                 elif symmetry_y == -now_y:
                     if flat is None:
                         flat = 1
                     elif flat == 0:
-                        assert True
+                        assert False
                 else:
-                    assert True
+                    assert False
             except (AssertionError, ValueError, TypeError):
                 flat = None
                 break
@@ -1536,7 +1536,7 @@ class ExpProperty(ExpFuncInit, metaclass=ABCMeta):
             elif count == max_count:
                 possible_cycle.append(i)
         try:
-            assert not possible_cycle
+            assert possible_cycle
             possible_cycle.sort()
             output_prompt("计算完毕")
             return possible_cycle[0], possible_cycle
@@ -1584,7 +1584,7 @@ class ExpProperty(ExpFuncInit, metaclass=ABCMeta):
             elif n_c == c:
                 possible_symmetry_axis.append(i)
         try:
-            assert not possible_symmetry_axis
+            assert possible_symmetry_axis
             possible_symmetry_axis.sort()  #
             output_prompt("计算完毕")
             return possible_symmetry_axis[0], possible_symmetry_axis
@@ -1634,7 +1634,7 @@ class ExpProperty(ExpFuncInit, metaclass=ABCMeta):
             elif count == max_count:
                 possible_center.append(i)
         try:
-            assert max_count < 5 or not possible_center
+            assert not max_count < 5 or not possible_center
             output_prompt("计算完毕")
             possible_center.sort()  #
             return possible_center[int(len(possible_center) / 2)], possible_center

+ 19 - 7
gitrepo/gui.py

@@ -1,8 +1,9 @@
 import time
-import threading
 import tkinter
 import os
 import logging
+from sys import exit
+import threading
 
 import tkinter.messagebox
 from tkinter import ttk
@@ -11,8 +12,9 @@ from tkinter.scrolledtext import ScrolledText
 
 import gitrepo.template
 from gitrepo import controller
-from system import exception_catch, basicConfig
+from system import exception_catch, basicConfig, QueueController
 
+queue_controller = QueueController()
 logging.basicConfig(**basicConfig)
 
 
@@ -120,8 +122,8 @@ class UIAPI:
                             cli_screen.update()
                         except BaseException as e:
                             logging.warning(str(e))
-                    assert time.time() - start >= break_time != 0
-                    assert break_time == 0 and start == 0
+                    assert not time.time() - start >= break_time != 0
+                    assert not break_time == 0 and start == 0
                 except AssertionError:
                     start = 0
                     break
@@ -208,7 +210,7 @@ class UIAPI:
                         data += f"[END]"
                         break
                     elif command_thread.returncode is not None:
-                        assert True
+                        assert False
                 except (tkinter.TclError, AssertionError):
                     if show_screen:
                         text.insert(tkinter.END, "[ERROR]")
@@ -950,9 +952,19 @@ class API(UIAPI):
         API.update_repo_box_gui()
 
 
-def git_main():
-    global SCREEN, git, PATH, bg_color, buttom_color, word_color, repo_list, last_name, file_list, FONT
+def git_main(in_queue, out_queue):
+    global SCREEN, queue_controller
+    queue_controller.set_queue(in_queue, out_queue)
+
+    class Stop:
+        def __call__(self, *args, **kwargs):
+            exit(0)
+
+    stop = Stop()
+    queue_controller.set_before_stop(stop)
+    queue_controller()
     SCREEN.mainloop()
+    queue_controller.stop_process()
 
 
 file_list = []

+ 1 - 1
gitrepo/template.py

@@ -468,7 +468,7 @@ class GitRepo(ViewClasses, NewClasses, RemoveClass, BackClasses, ParallelClasses
             elif repo_dir.endswith(".git"):
                 repo_dir = repo_dir[:-5]  # -5,得把/去掉
             else:
-                assert True
+                assert False
         except (AssertionError, IndexError):
             subprocess.Popen(
                 f"{git_path} init", cwd=self.repo_dir, **sys_seeting

+ 13 - 5
machinelearning/gui.py

@@ -5,11 +5,16 @@ import tkinter.messagebox
 from newtkinter import askopenfilename, asksaveasfilename, askdirectory
 import chardet
 import webbrowser
+from multiprocessing import Queue
+import threading
 
 import machinelearning.controller
 import machinelearning.template
-from system import exception_catch
+from system import exception_catch, QueueController
 
+queue_controller = QueueController()
+input_queue: Queue
+output_queue: Queue
 calculation_list = []
 calculation_method = []
 PATH = os.getcwd()
@@ -431,7 +436,7 @@ class API(UIAPI):
         learner = API.get_learner_gui()
         try:
             split = float(data_split.get())
-            assert split < 0 or 1 < split
+            assert not split < 0 or 1 < split
         except (AssertionError, ValueError):
             split = 0.3
         socore = learner_controller.fit_model(
@@ -751,7 +756,7 @@ class API(UIAPI):
     def to_html_one():
         html_dir = f"{PATH}{os.sep}$Show_Sheet.html"
         name = API.get_data_name_gui()
-        assert name is None
+        assert not name is None
         learner_controller.to_html_one(name, html_dir)
         webbrowser.open(html_dir)
 
@@ -760,7 +765,7 @@ class API(UIAPI):
     def to_html():
         html_dir = f"{PATH}{os.sep}$Show_Sheet.html"
         name = API.get_data_name_gui()
-        assert name is None
+        assert not name is None
         learner_controller.to_html(name, html_dir, to_html_type.get())
         webbrowser.open(html_dir)
 
@@ -784,9 +789,12 @@ class API(UIAPI):
         API.update_sheet_box_gui()
 
 
-def machine_learning():
+def machine_learning(in_queue, out_queue):
     global SCREEN
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
     SCREEN.mainloop()
+    queue_controller.stop_process()
 
 
 SCREEN.title("CoTan机器学习")

+ 13 - 13
machinelearning/template.py

@@ -268,7 +268,7 @@ class LearnerSplit(LearnBase, metaclass=ABCMeta):
             if split < 1:
                 split = int(split * len(sheet) if axis == 1 else len(sheet[0]))
             else:
-                assert True
+                assert False
         except (ValueError, AssertionError):
             split = int(split)
         if axis == 0:
@@ -428,7 +428,7 @@ class StudyMachinebase(Machinebase):
     def fit_model(self, x_data, y_data, split=0.3, increment=True, **kwargs):
         y_data = y_data.ravel()
         try:
-            assert self.x_traindata is None or not increment
+            assert not self.x_traindata is None or not increment
             self.x_traindata = np.vstack((x_data, self.x_traindata))
             self.y_traindata = np.vstack((y_data, self.y_traindata))
         except (AssertionError, ValueError):
@@ -438,7 +438,7 @@ class StudyMachinebase(Machinebase):
             x_data, y_data, test_size=split
         )
         try:  # 增量式训练
-            assert not increment
+            assert increment
             self.model.partial_fit(x_data, y_data)
         except (AssertionError, AttributeError):
             self.model.fit(self.x_traindata, self.y_traindata)
@@ -639,14 +639,14 @@ class PrepBase(StudyMachinebase):  # 不允许第二次训练
         if not self.have_predict:  # 不允许第二次训练
             y_data = y_data.ravel()
             try:
-                assert self.x_traindata is None or not increment
+                assert not self.x_traindata is None or not increment
                 self.x_traindata = np.vstack((x_data, self.x_traindata))
                 self.y_traindata = np.vstack((y_data, self.y_traindata))
             except (AssertionError, ValueError):
                 self.x_traindata = x_data.copy()
                 self.y_traindata = y_data.copy()
             try:  # 增量式训练
-                assert not increment
+                assert increment
                 self.model.partial_fit(x_data, y_data)
             except (AssertionError, AttributeError):
                 self.model.fit(self.x_traindata, self.y_traindata)
@@ -669,12 +669,12 @@ class Unsupervised(PrepBase):  # 无监督,不允许第二次训练
         if not self.have_predict:  # 不允许第二次训练
             self.y_traindata = None
             try:
-                assert self.x_traindata is None or not increment
+                assert not self.x_traindata is None or not increment
                 self.x_traindata = np.vstack((x_data, self.x_traindata))
             except (AssertionError, ValueError):
                 self.x_traindata = x_data.copy()
             try:  # 增量式训练
-                assert not increment
+                assert increment
                 self.model.partial_fit(x_data)
             except (AssertionError, AttributeError):
                 self.model.fit(self.x_traindata, self.y_traindata)
@@ -686,7 +686,7 @@ class UnsupervisedModel(PrepBase):  # 无监督
     def fit_model(self, x_data, increment=True, *args, **kwargs):
         self.y_traindata = None
         try:
-            assert self.x_traindata is None or not increment
+            assert not self.x_traindata is None or not increment
             self.x_traindata = np.vstack((x_data, self.x_traindata))
         except (AssertionError, ValueError):
             self.x_traindata = x_data.copy()
@@ -970,7 +970,7 @@ class ClassBar(ToPyebase):  # 类型柱状图
                         f"({iter_num})[{round(start, 2)}-"
                         f"{round((start + n) if (start + n) <= end or not iter_num == 9 else end, 2)}]")
                     try:
-                        assert iter_num == 9  # 执行到第10次时,直接获取剩下的所有
+                        assert not iter_num == 9  # 执行到第10次时,直接获取剩下的所有
                         s = (start <= i) == (i < end)  # 布尔索引
                     except AssertionError:  # 因为start + n有超出end的风险
                         s = (start <= i) == (i <= end)  # 布尔索引
@@ -1431,7 +1431,7 @@ class CategoricalData:  # 数据统计助手
                 self.x_means.append(np.mean(x1))
                 self.add_range(x1)
             else:
-                assert True
+                assert False
             return x1_con
         except TypeError:  # 找出出现次数最多的元素
             new = np.unique(x1)  # 去除相同的元素
@@ -1445,7 +1445,7 @@ class CategoricalData:  # 数据统计助手
 
     def add_range(self, x1: np.array, range_=True):
         try:
-            assert not range_
+            assert range_
             min_ = int(x1.min()) - 1
             max_ = int(x1.max()) + 1
             # 不需要复制列表
@@ -3388,7 +3388,7 @@ class FastFourier(StudyMachinebase):  # 快速傅里叶变换
     def fit_model(self, y_data, *args, **kwargs):
         y_data = y_data.ravel()  # 扯平为一维数组
         try:
-            assert self.y_traindata is None
+            assert not self.y_traindata is None
             self.y_traindata = np.hstack((y_data, self.x_traindata))
         except (AssertionError, ValueError):
             self.y_traindata = y_data.copy()
@@ -3587,7 +3587,7 @@ def FUNC({",".join(model.__code__.co_varnames)}):
         y_data = y_data.ravel()
         x_data = x_data.astype(np.float64)
         try:
-            assert self.x_traindata is None
+            assert not self.x_traindata is None
             self.x_traindata = np.vstack((x_data, self.x_traindata))
             self.y_traindata = np.vstack((y_data, self.y_traindata))
         except (AssertionError, ValueError):

+ 77 - 3
system/__init__.py

@@ -1,5 +1,10 @@
 import os
 import logging
+from multiprocessing import Queue
+import time
+import threading
+from sys import exit
+
 
 PATH = os.getcwd()
 LOG_DIR = rf'{PATH}{os.sep}Log{os.sep}log_system.log'
@@ -31,10 +36,10 @@ def plugin_class_loading(template_path):
             else:
                 raise NoPluginError
         except NoPluginError as e:
-            logging.info(str(e) + 'no plugin')
+            # logging.info(str(e) + 'no plugin')
             return base
         except BaseException as e:
-            logging.warning(str(e))
+            logging.info(f'{base.__name__} plugin wrong {e}')
             return base
     return plugin_read
 
@@ -51,6 +56,75 @@ def exception_catch(*args_catch, **kwargs_catch):
                 return return_
             except BaseException as e:
                 logging.error(f'{e}  {func.__name__} args:{args}  kwargs:{kwargs}')
-                assert func.__name__.endswith('_gui'), str(e)
+                assert not func.__name__.endswith('_gui'), str(e)
         return adorner
     return catch
+
+
+class QueueController:
+    def __init__(self):
+        self.in_queue: Queue
+        self.out_queue: Queue
+        self.run = True
+        self.var_dict = {}
+        self.stop = None
+        self.before_stop = lambda: None
+
+    def set_queue(self, in_queue: Queue, out_queue: Queue):
+        self.in_queue = in_queue
+        self.out_queue = out_queue
+        return self
+
+    def set_before_stop(self, func):
+        self.before_stop = func
+
+    def stop_process(self):
+        self.run = False
+        self.out_queue.put("__--$$stop_process$$--__")
+        self.before_stop()
+        time.sleep(0.5)
+
+    def __call__(self, *args, **kwargs):
+        self.run = True
+
+        def done():
+            while self.run:
+                if self.in_queue.empty():
+                    continue
+                get = self.in_queue.get()
+                try:
+                    assert isinstance(get, str)
+                    name_space = self.var_dict.copy()
+                    name_space.update(globals())
+                    if get.startswith('done '):
+                        exec(get[5:], name_space)
+                    elif get == 'get var_*':
+                        self.out_queue.put(list(name_space.keys()))
+                    elif get == 'get *':
+                        self.out_queue.put(list(self.var_dict.keys()))
+                    elif get.startswith('get_var '):
+                        result = name_space.get(get[8:])
+                        if result == '__--$$stop_process$$--__':
+                            result += '_'
+                        self.out_queue.put(result)
+                        self.var_dict[f'var_{len(self.var_dict)}'] = result
+                    elif get.startswith('get_eval '):
+                        result = eval(get[9:], name_space)
+                        if result == '__--$$stop_process$$--__':
+                            result += '_'
+                        self.out_queue.put(result)
+                        self.var_dict[f'var_{len(self.var_dict)}'] = result
+                    elif get.startswith('file ') and get.startswith('.py'):
+                        with open(get[4:], 'r') as f:
+                            code_file = f.read()
+                        new_name_space = name_space
+                        exec(code_file, new_name_space)
+                        self.var_dict[f'var_{len(self.var_dict)}'] = new_name_space.copy()
+                except AssertionError:
+                    self.var_dict[f'var_{len(self.var_dict)}'] = get
+                except BaseException as e:
+                    self.out_queue.put(str(e))
+
+        t = threading.Thread(target=done)
+        t.setDaemon(True)
+        t.start()

+ 8 - 2
system/gui.py

@@ -2,9 +2,12 @@ import tkinter
 from newtkinter import askopenfilename
 from tkinter.messagebox import showwarning, askokcancel
 from tkinter.scrolledtext import ScrolledText
+import webbrowser
 
 from system.controller import Systemctl, NamingError, ConflictError
+from system import QueueController
 
+queue_controller = QueueController()
 SCREEN = tkinter.Tk()
 systemctl = Systemctl()
 SCREEN.title("插件管理")
@@ -112,9 +115,12 @@ def show_log():
         pass
 
 
-def system_main():
+def system_main(in_queue, out_queue):
     global SCREEN
+    queue_controller.set_queue(in_queue, out_queue)
+    queue_controller()
     SCREEN.mainloop()
+    queue_controller.stop_process()
 
 
 (
@@ -249,7 +255,7 @@ row += 1
         SCREEN,
         bg=botton_color,
         fg=word_color,
-        command=show_log,
+        command=lambda: webbrowser.open(r'E:\SongZihuan\PyProject\CoTan\Log\log_system.log'),
         text="查看日记",
         font=FONT,
         width=gui_width,