def __init__(self,
                 parent=None,
                 picks=[],
                 editButtons=False,
                 checkCallback=None):
        """
        Parameters
        ----------

        :param parent: the parent window
        :param picks: the list of pairs to show
        :param editButtons: Indicator whether a configuration button should be displayed
        :param checkCallback: Callback for each pair
        """
        Frame.__init__(self, parent)

        self.parent = parent
        self.vars = []
        self.checks = []
        self.buttons = []

        relY = 0
        relX = 0
        enable_functionality = 'active'

        # Iterate over all pairs of check buttons and buttons
        for pick in picks:
            var = IntVar()

            algorithm_show_function = self.get_algorithm_show_function(
                str(pick))

            # Create a check button dynamically
            check_button = Checkbutton(
                self,
                text=pick,
                variable=var,
                state=enable_functionality,
                command=lambda: self.set_button_state(checkCallback))

            check_button.place(relx=relX, rely=relY, height=30, width=150)
            set_widget_to_left(check_button)

            if editButtons:
                # Create a configuration button dynamically
                edit_button = HoverButton(self,
                                          text=pick + " configuration",
                                          state='disabled',
                                          command=algorithm_show_function)

                edit_button.place(relx=relX + 0.35,
                                  rely=relY,
                                  height=30,
                                  width=220)
                edit_button.configure(cursor="hand2")
                self.buttons.append(edit_button)
            self.vars.append(var)
            self.checks.append(check_button)
            relY = relY + 0.1
Beispiel #2
0
class TuningLoadingWindow(tk.Frame):
    """
    A Class used to be presented tuning model process is running in the background of the application

    Methods
    -------
    reset_widgets()
            Description | Reset check bar values

    back_window()
            Description | Handle a click on back button

    stop_model_process()
            Description | Handle a click on stop button

    reinitialize()
            Description | Reinitialize frame values and view

    update_clock()
            Description | Updates the time on the clock

    loading_process()
            Description | Run chosen models and move to results window

    """

    def __init__(self, parent, controller):

        """
        Parameters
        ----------

        :param parent: window
        :param controller: GUI controller
        """

        tk.Frame.__init__(self, parent)

        # Page init
        self.controller = controller
        self.menubar = Menubar(controller)
        # Disables ability to tear menu bar into own window
        self.controller.option_add('*tearOff', 'FALSE')
        system_logo = CROSS_WINDOWS_SETTINGS.get('LOGO')
        photo_location = os.path.join(system_logo)
        global logo_img
        logo_img = tk.PhotoImage(file=photo_location)

        # Page header
        self.logo_png = tk.Button(self)
        self.logo_png.place(relx=0.28, rely=0.029, height=172, width=300)
        set_logo_configuration(self.logo_png, image=logo_img)

        self.instructions = tk.Label(self)
        self.instructions.place(relx=0.015, rely=0.3, height=32, width=635)
        self.instructions.configure(text='''Tuning parameters, please wait...''')
        set_widget_to_left(self.instructions)

        # Page body
        loading_gif = LOADING_WINDOW_SETTINGS.get('LOADING_GIF')
        delay_between_frames = LOADING_WINDOW_SETTINGS.get('DELAY_BETWEEN_FRAMES')

        self.title_font = Font(family='Helvetica', size=12, weight="bold")

        self.loading_gif = AnimatedGif(self, loading_gif, delay_between_frames)
        self.loading_gif.place(relx=0.1, rely=0.35, height=330, width=600)

        self.clock_label = tk.Label(self, text="", font=self.title_font)
        self.clock_label.place(relx=0.38, rely=0.7, height=32, width=150)

        # Page footer
        self.stop_button = HoverButton(self, command=self.stop_model_process)
        self.stop_button.place(relx=0.813, rely=0.839, height=25, width=81)
        set_button_configuration(self.stop_button, text='''Stop''')

        self.back_button = HoverButton(self, command=self.back_window)
        self.back_button.place(relx=0.017, rely=0.839, height=25, width=81)
        set_button_configuration(self.back_button, text='''Back''')
        self.back_button.configure(state='disabled')

        self.copyright = tk.Label(self)
        self.copyright.place(relx=0, rely=0.958, height=25, width=750)
        set_copyright_configuration(self.copyright)

        # Page logic
        self.loading_gif.start()

    def reset_widgets(self):
        """
        Reset check bar values
        :return: empty values in the widgets
        """

        pass

    def back_window(self):
        """
        Handle back button click
        :return: previous window
        """

        self.controller.reinitialize_frame("TuneModel")

    def stop_model_process(self):
        """
        Handle stop button click
        :return: freeze state
        """

        self.back_button.configure(state='active')
        self.stop_button.configure(state='disabled')
        try:
            self.model_process_thread.join()
        except Exception:
            pass

    def reinitialize(self):
        """
        Reinitialize frame values and view
        :return: new frame view
        """

        self.model_process_thread = threading.Thread(name='model_process', target=self.loading_process)
        self.model_process_thread.start()
        self.start_time = timer()
        self.update_clock()

    def update_clock(self):
        """
        Updates the time on the clock
        :return: updated time
        """

        now = timer()
        duration = timedelta(seconds=now - self.start_time)
        self.clock_label.configure(text=strfdelta(duration, '%H:%M:%S'))
        self.controller.after(200, self.update_clock)

    def loading_process(self):
        """
        Run tuning parameters process and move to results window
        :return: results window
        """

        self.controller.run_tuning()
        self.controller.reinitialize_frame("TuneResultsWindow")
Beispiel #3
0
class LoadingWindow(tk.Frame):
    """
    A Class used to be presented while the models are running in the background of the application

    Methods
    -------
    reset_widgets()
            Description | Reset check bar values

    stop_model_process()
            Description | Handle a click on stop button

    reinitialize()
            Description | Reinitialize frame values and view

    update_clock()
            Description | Updates the time on the clock

    loading_process()
            Description | Run chosen models and move to results window

    show_model_process_label(y_coordinate, algorithm):
            Description | Show model process label on the screen
    """
    def __init__(self, parent, controller):
        """
        Parameters
        ----------

        :param parent: window
        :param controller: GUI controller
        """

        tk.Frame.__init__(self, parent)

        # Page init
        self.controller = controller
        self.menubar = Menubar(controller)
        # Disables ability to tear menu bar into own window
        self.controller.option_add('*tearOff', 'FALSE')
        system_logo = CROSS_WINDOWS_SETTINGS.get('LOGO')
        stop_logo = LOADING_WINDOW_SETTINGS.get('STOP')
        photo_location = os.path.join(system_logo)
        stop_photo_location = os.path.join(stop_logo)
        global logo_img, stop_img
        logo_img = tk.PhotoImage(file=photo_location)
        stop_img = tk.PhotoImage(file=stop_photo_location)

        # Page header
        self.logo_png = tk.Button(self)
        self.logo_png.place(relx=0.28, rely=0.029, height=172, width=300)
        set_logo_configuration(self.logo_png, image=logo_img)

        self.instructions = tk.Label(self)
        self.instructions.place(relx=0.015, rely=0.3, height=32, width=635)
        self.instructions.configure(
            text='''Creating models and runs them, please wait...''',
            font=Font(size=9, weight=BOLD))
        set_widget_to_left(self.instructions)

        # Page body
        self.stop_png = tk.Button(self)
        self.loading_gif_animation = LOADING_WINDOW_SETTINGS.get('LOADING_GIF')
        self.delay_between_frames = LOADING_WINDOW_SETTINGS.get(
            'DELAY_BETWEEN_FRAMES')

        self.title_font = Font(family='Helvetica', size=12, weight="bold")

        self.loading_gif = AnimatedGif(self, self.loading_gif_animation,
                                       self.delay_between_frames)
        self.loading_gif.place(relx=0.1, rely=0.38, height=330, width=600)

        self.clock_label = tk.Label(self, text="", font=self.title_font)
        self.clock_label.place(relx=0.38, rely=0.73, height=32, width=150)

        # Page footer
        self.stop_button = HoverButton(self, command=self.stop_model_process)
        self.stop_button.place(relx=0.813, rely=0.839, height=25, width=81)
        set_button_configuration(self.stop_button, text='''Stop''')

        self.copyright = tk.Label(self)
        self.copyright.place(relx=0, rely=0.958, height=25, width=750)
        set_copyright_configuration(self.copyright)

        # Page logic
        self.loading_gif.start()

    def reset_widgets(self):
        """
        Reset check bar values
        :return: empty values in the widgets
        """

        pass

    def stop_model_process(self):
        """
        Handle stop button click
        :return: freeze state
        """

        if self.event.isSet():  # check if the event flag is True or False
            self.event.clear()
            self.stop_button.configure(text='Resume')
            self.loading_gif.place_forget()
            self.stop_png.place(relx=0.385, rely=0.5, height=132, width=132)
            set_logo_configuration(self.stop_png, image=stop_img)
        else:
            self.event.set()
            self.stop_button.configure(text='Stop')
            self.stop_png.place_forget()
            self.loading_gif.place(relx=0.1, rely=0.35, height=330, width=600)

        self.start_time = timer() - self.prev_saved_time
        self.update_clock()

    def reinitialize(self):
        """
        Reinitialize frame values and view
        :return: new frame view
        """

        self.stop_button.configure(text='Stop')
        self.event = threading.Event()
        self.model_process_thread = threading.Thread(
            name='model_process', target=self.loading_process)
        self.model_process_thread.start()
        self.start_time = timer()
        self.event.set()
        self.update_clock()

    def update_clock(self):
        """
        Updates the time on the clock
        :return: updated time
        """

        if not self.event.isSet():
            return
        now = timer()
        duration = timedelta(seconds=now - self.start_time)
        self.prev_saved_time = now - self.start_time
        self.clock_label.configure(text=strfdelta(duration, '%H:%M:%S'))
        self.controller.after(200, self.update_clock)

    def loading_process(self):
        """
        Run chosen models and move to results window
        :return: results window
        """

        similarity_score, test_data_path, results_path, new_model_running = self.controller.init_models(
        )

        if new_model_running:
            chosen_algorithms = self.controller.get_algorithms()
        else:
            chosen_algorithms = set(
                self.controller.get_existing_algorithms().keys())

        y_coordinate = 0.34
        enumerate_details = 0

        for algorithm in chosen_algorithms:
            if new_model_running:
                print_text = '''{0} : Creates a new model and runs the test data on it...'''.format(
                    algorithm)
            else:
                print_text = '''{0} : Runs the test data...'''.format(
                    algorithm)

            if enumerate_details < 4:
                self.algorithm_process_finished = tk.Label(self)
                self.algorithm_process_finished.place(relx=0.015,
                                                      rely=y_coordinate,
                                                      height=22,
                                                      width=400)
                self.algorithm_process_finished.configure(text=print_text)
                set_widget_to_left(self.algorithm_process_finished)

                y_coordinate += 0.04

            self.controller.run_models(algorithm, similarity_score,
                                       test_data_path, results_path,
                                       new_model_running, self.event)

            enumerate_details += 1

        self.controller.reinitialize_frame("ResultsWindow")

    def show_model_process_label(self, y_coordinate, algorithm):
        """
        Show model process label on the screen
        :param y_coordinate: y place coordinate
        :param algorithm: which algorithm to display
        :return: new label
        """

        self.model_process_finished = tk.Label(self)
        self.model_process_finished.place(relx=0.015,
                                          rely=y_coordinate,
                                          height=22,
                                          width=215)
        self.model_process_finished.configure(
            text='''{0} model runs on the test...'''.format(algorithm))
        set_widget_to_left(self.model_process_finished)
class ExistingAlgorithmsWindow(tk.Frame):
    """
    A Class used to enable the user load existing machine learning model

    Methods
    -------
    reset_widgets()
            Description | Reset check bar values

    back_window()
            Description | Handle back button click

    set_input_entry()
            Description | Set input entry and update the state

    set_algorithm_path()
            Description | Set the algorithm path in the UI

    next_window()
            Description |  Handle next button click

    validate_next_step()
            Description | Validation before approving the move to the next window

    update_selected_algorithms()
            Description | Updates local variables which algorithms were selected by the user

    set_load_model_parameters()
            Description | Updates input settings and move to next window

    """

    def __init__(self, parent, controller):

        """
        Parameters
        ----------

        :param parent: window
        :param controller: GUI controller
        """

        tk.Frame.__init__(self, parent)

        # Page init
        self.controller = controller
        self.menubar = Menubar(controller)
        # Disables ability to tear menu bar into own window
        self.controller.option_add('*tearOff', 'FALSE')
        system_logo = CROSS_WINDOWS_SETTINGS.get('LOGO')
        photo_location = os.path.join(system_logo)
        global logo_img
        logo_img = tk.PhotoImage(file=photo_location)

        # Page header
        self.logo_png = tk.Button(self)
        self.logo_png.place(relx=0.28, rely=0.029, height=172, width=300)
        set_logo_configuration(self.logo_png, image=logo_img)

        self.instructions = tk.Label(self)
        self.instructions.place(relx=0.015, rely=0.3, height=32, width=635)
        self.instructions.configure(
            text='''Please insert paths for existing models.''')
        set_widget_to_left(self.instructions)

        # Page body
        self.algorithms = dict()
        self.browse_buttons = dict()
        self.input_entries = dict()

        # LSTM existing algorithm
        self.lstm_var = tk.IntVar()
        self.lstm_check_button = tk.Checkbutton(self)
        self.lstm_check_button.place(relx=0.015, rely=0.38, height=32, width=146)
        self.lstm_check_button.configure(text="LSTM",
                                         variable=self.lstm_var,
                                         command=lambda: self.set_input_entry("LSTM", self.lstm_var.get()))
        set_widget_to_left(self.lstm_check_button)

        self.lstm_input = tk.Entry(self)
        self.lstm_input.place(relx=0.195, rely=0.38, height=25, relwidth=0.624)
        self.lstm_input.configure(state='disabled')

        self.lstm_btn = HoverButton(self, command=lambda: self.set_algorithm_path("LSTM"))
        self.lstm_btn.place(relx=0.833, rely=0.38, height=25, width=60)
        self.lstm_btn.configure(state='disabled')
        set_button_configuration(self.lstm_btn, text='''Browse''')

        self.browse_buttons["LSTM"] = self.lstm_btn
        self.input_entries["LSTM"] = self.lstm_input

        # SVR existing algorithm
        self.svr_var = tk.IntVar()
        self.svr_check_button = tk.Checkbutton(self)
        self.svr_check_button.place(relx=0.015, rely=0.47, height=32, width=146)
        self.svr_check_button.configure(text="SVR",
                                        variable=self.svr_var,
                                        command=lambda: self.set_input_entry("SVR", self.svr_var.get()))
        set_widget_to_left(self.svr_check_button)

        self.svr_input = tk.Entry(self)
        self.svr_input.place(relx=0.195, rely=0.47, height=25, relwidth=0.624)
        self.svr_input.configure(state='disabled')

        self.svr_btn = HoverButton(self, command=lambda: self.set_algorithm_path("SVR"))
        self.svr_btn.place(relx=0.833, rely=0.47, height=25, width=60)
        self.svr_btn.configure(state='disabled')
        set_button_configuration(self.svr_btn, text='''Browse''')

        self.browse_buttons["SVR"] = self.svr_btn
        self.input_entries["SVR"] = self.svr_input

        # MLP existing algorithm
        self.mlp_var = tk.IntVar()
        self.mlp_check_button = tk.Checkbutton(self)
        self.mlp_check_button.place(relx=0.015, rely=0.56, height=32, width=146)
        self.mlp_check_button.configure(text="MLP",
                                        variable=self.mlp_var,
                                        command=lambda: self.set_input_entry("MLP",
                                                                             self.mlp_var.get()))
        set_widget_to_left(self.mlp_check_button)

        self.mlp_input = tk.Entry(self)
        self.mlp_input.place(relx=0.195, rely=0.56, height=25, relwidth=0.624)
        self.mlp_input.configure(state='disabled')

        self.mlp_btn = HoverButton(self, command=lambda: self.set_algorithm_path("MLP"))
        self.mlp_btn.place(relx=0.833, rely=0.56, height=25, width=60)
        self.mlp_btn.configure(state='disabled')
        set_button_configuration(self.mlp_btn, text='''Browse''')

        self.browse_buttons["MLP"] = self.mlp_btn
        self.input_entries["MLP"] = self.mlp_input

        # Random Forest existing algorithm
        self.random_forest_var = tk.IntVar()
        self.random_forest_check_button = tk.Checkbutton(self)
        self.random_forest_check_button.place(relx=0.015, rely=0.65, height=32, width=146)
        self.random_forest_check_button.configure(text="Random Forest",
                                                  variable=self.random_forest_var,
                                                  command=lambda: self.set_input_entry("Random Forest",
                                                                                       self.random_forest_var.get()))
        set_widget_to_left(self.random_forest_check_button)

        self.random_forest_input = tk.Entry(self)
        self.random_forest_input.place(relx=0.195, rely=0.65, height=25, relwidth=0.624)
        self.random_forest_input.configure(state='disabled')

        self.random_forest_btn = HoverButton(self, command=lambda: self.set_algorithm_path("Random Forest"))
        self.random_forest_btn.place(relx=0.833, rely=0.65, height=25, width=60)
        self.random_forest_btn.configure(state='disabled')
        set_button_configuration(self.random_forest_btn, text='''Browse''')

        self.browse_buttons["Random Forest"] = self.random_forest_btn
        self.input_entries["Random Forest"] = self.random_forest_input

        # Page footer
        self.next_button = HoverButton(self, command=self.next_window)
        self.next_button.place(relx=0.813, rely=0.839, height=25, width=81)
        set_button_configuration(self.next_button, text='''Next''')

        self.back_button = HoverButton(self, command=self.back_window)
        self.back_button.place(relx=0.017, rely=0.839, height=25, width=81)
        set_button_configuration(self.back_button, text='''Back''')

        self.copyright = tk.Label(self)
        self.copyright.place(relx=0, rely=0.958, height=25, width=750)
        set_copyright_configuration(self.copyright)

    def reset_widgets(self):
        """
        Reset check bar values
        :return: empty values in the widgets
        """

        widgets = [
            self.lstm_input,
            self.svr_input,
            self.mlp_input,
            self.random_forest_input
        ]

        variables = [
            self.lstm_var,
            self.svr_var,
            self.mlp_var,
            self.random_forest_var
        ]

        check_buttons = [
            self.lstm_check_button,
            self.svr_check_button,
            self.mlp_check_button,
            self.random_forest_check_button
        ]

        for widget in widgets:
            clear_text(widget)
            widget['state'] = 'disabled'

        for var, check_button in zip(variables, check_buttons):
            var.set(0)
            check_button['variable'] = var

    def back_window(self):
        """
        Handle back button click
        :return: previous window
        """

        self.controller.set_new_model_running(False)
        self.controller.show_frame("MainWindow")

    def set_input_entry(self, entry_name, state):
        """
        Set input entry and update the state
        :param entry_name: input's algorithm name
        :param state: input's state
        :return: updated input
        """

        if state:
            self.browse_buttons[entry_name]['state'] = 'active'
            self.input_entries[entry_name]['state'] = 'normal'
            self.algorithms[entry_name] = ""
        else:
            self.input_entries[entry_name].delete(0, END)
            self.browse_buttons[entry_name]['state'] = 'disabled'
            self.input_entries[entry_name]['state'] = 'disabled'
            self.algorithms.pop(entry_name, None)

    def set_algorithm_path(self, algorithm):
        """
        Set the algorithm path in the UI
        :param algorithm: input algorithm
        :return: updated state
        """

        self.input_entries[algorithm].delete(0, END)
        path = set_path()
        self.input_entries[algorithm].insert(0, path)

    def next_window(self):
        """
        Handle next button click
        :return: if validations pass move to next window
        """

        self.update_selected_algorithms()
        if self.validate_next_step():
            self.set_load_model_parameters()

    def validate_next_step(self):
        """
        Validation before approving the move to the next window
        :return:
        """

        if not self.algorithms:
            win32api.MessageBox(0, 'Please select algorithm & path for the model before the next step.',
                                'Invalid algorithm', 0x00001000)
            return False

        if not is_valid_model_paths(self.algorithms.values()):
            win32api.MessageBox(0,
                                'At least one of your algorithms paths invalid or not include the required files! '
                                'Please check that there are no duplicate files in the same directory.',
                                'Invalid inputs', 0x00001000)
            return False

        if not is_valid_model_data_file(self.algorithms.values()):
            win32api.MessageBox(0,
                                'At least one of the required data is missing in model_data json file!',
                                'Missing data', 0x00001000)
            return False

        return True

    def update_selected_algorithms(self):
        """
        Updates local variables which algorithms were selected by the user
        :return: updated selection
        """

        tmp_algorithms = dict()

        for algorithm in self.algorithms:
            tmp_algorithms[algorithm] = self.input_entries[algorithm].get()

        self.algorithms = tmp_algorithms

    def set_load_model_parameters(self):
        """
        Updates input settings and move to next window
        :return: next window
        """

        self.controller.set_existing_algorithms(self.algorithms)
        self.controller.reinitialize_frame("SimilarityFunctionsWindow")