def __init__(self, parent):
        """Initializes the `ttk.Notebook` widget in the given window.

        The `ttk.Notebook` widget is populated with tabs defined by the classes
        :class:`pyplt.gui.experiment.dataset.loading.DataLoadingTab`,
        :class:`pyplt.gui.experiment.preprocessing.preproctab.PreProcessingTab`,
        :class:`pyplt.gui.experiment.featureselection.featselectiontab.FeatureSelectionTab`, and
        :class:`pyplt.gui.experiment.preflearning.pltab.PLTab`.

        :param parent: the parent window on which this experiment setup window will be stacked.
        :type parent: `tkinter.Toplevel`
        """
        self._parent = parent

        tk.Toplevel.__init__(self, parent, height=250)
        img = tk.PhotoImage(file=os.path.join(ROOT_PATH, 'assets/plt_logo.png'))
        self.tk.call('wm', 'iconphoto', self._w, img)
        ws.disable_parent(self, parent, ws.Mode.WITH_CLOSE)
        ws.stack_window(self, parent)

        self.title("Experiment Setup (Advanced)")

        self._tabs_bar = ttk.Notebook(self)

        self._files_tab = DataLoadingTab(self._tabs_bar, self)

        self._preproc_tab = PreProcessingTab(self._tabs_bar, self, self._files_tab)
        self._fs_tab = FeatureSelectionTab(self._tabs_bar, self, self._files_tab)
        self._pl_tab = PLTab(self._tabs_bar, self, self._files_tab, self._preproc_tab, self._fs_tab)

        self._pic = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/icons/load_icon_18_light_blue.png"))
        self._pp_pic = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/icons/preprocessing_icon_18_blue.png"))
        self._fs_pic = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/icons/fs_icon_18.png"))
        self._pl_pic = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/icons/pl_icon_18.png"))

        self._tabs_bar.add(self._files_tab, image=self._pic, text="Load Data", compound=tk.LEFT, sticky='nsew')
        self._tabs_bar.add(self._preproc_tab, text="Preprocessing", image=self._pp_pic, compound=tk.LEFT,
                           sticky='nsew')
        self._tabs_bar.add(self._fs_tab, text="Feature Selection", image=self._fs_pic, compound=tk.LEFT, sticky='nsew')
        self._tabs_bar.add(self._pl_tab, text="Preference Learning", image=self._pl_pic, compound=tk.LEFT,
                           sticky='nsew')
        self._tabs_bar.pack(fill=tk.BOTH, expand=True)

        self._nav_frame = tk.Frame(self, bg=colours.NAV_BAR)
        self._nav_frame.pack(side=tk.BOTTOM, fill=tk.X)

        self._next_img = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/buttons/next_76_30_01.png"))
        self._back_img = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/buttons/back_76_30_01.png"))
        self._run_img = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/buttons/run_128_30_01_white.png"))
        self._help_img = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/buttons/help.png"))

        self._back_btn = tk.Button(self._nav_frame, command=self._select_prev_tab, image=self._back_img, relief='flat',
                                   bd=0, highlightbackground=colours.NAV_BAR, highlightcolor=colours.NAV_BAR,
                                   highlightthickness=0, background=colours.NAV_BAR, activebackground=colours.NAV_BAR)
        self._next_btn = tk.Button(self._nav_frame, command=self._select_next_tab, image=self._next_img, relief='flat',
                                   bd=0, highlightbackground=colours.NAV_BAR, highlightcolor=colours.NAV_BAR,
                                   highlightthickness=0, background=colours.NAV_BAR, activebackground=colours.NAV_BAR)
        self._run_btn = tk.Button(self._nav_frame, command=self._pl_tab.run_experiment, image=self._run_img,
                                  relief='flat', bd=0, highlightbackground=colours.NAV_BAR,
                                  highlightcolor=colours.NAV_BAR, highlightthickness=0, background=colours.NAV_BAR,
                                  activebackground=colours.NAV_BAR)

        help_btn = tk.Button(self._nav_frame, command=self._help_dialog, image=self._help_img, relief='flat', bd=0,
                             highlightbackground=colours.NAV_BAR, highlightcolor=colours.NAV_BAR, highlightthickness=0,
                             background=colours.NAV_BAR, activebackground=colours.NAV_BAR)
        help_btn.pack(side=tk.LEFT, padx=10, pady=10)

        # Lock tabs for the first time
        self._data_loaded = False
        self._preproc_tab.lock()
        self._fs_tab.lock()
        self._pl_tab.lock()

        self._tabs_bar.bind('<<NotebookTabChanged>>', self._check_data)

        ws.place_window(self, parent, position=ws.SIDE)
    def __init__(self, parent):
        """Initializes the `BeginnerMenu` object.

        :param parent: the parent window on top of which this `tkinter.Toplevel` window will be stacked.
        :type parent: `tkinter.Toplevel`
        """
        self._apply_fs = tk.BooleanVar(value=False)
        self._apply_ae = tk.BooleanVar(value=False)
        self._autoencoder_menu = None
        self._algorithm = tk.StringVar(value=PLAlgo.RANKSVM.name)
        self._include_settings = {}
        self._norm_settings = {}

        self._parent = parent

        tk.Toplevel.__init__(self, parent, height=250)
        img = tk.PhotoImage(file=os.path.join(ROOT_PATH, 'assets/plt_logo.png'))
        self.tk.call('wm', 'iconphoto', self._w, img)
        ws.disable_parent(self, parent, ws.Mode.WITH_CLOSE)
        ws.stack_window(self, parent)

        self.title("Experiment Setup (Beginner)")

        # self._main_frame = tk.Frame(self)
        # self._main_frame.pack()

        self._OS = platform.system()

        self._main_canvas = tk.Canvas(self, width=500, height=500)  # , background='yellow'
        self._main_canvas.bind("<Configure>", self._on_resize)
        self._main_canvas.bind('<Enter>', self._bind_mousewheel)
        self._main_canvas.bind('<Leave>', self._unbind_mousewheel)
        self._canvas_width = self._main_canvas.winfo_reqwidth()
        self._canvas_height = self._main_canvas.winfo_reqheight()
        self._main_sub_frame = tk.Frame(self._main_canvas)  # , background='green'
        self._main_sub_sub_frame = tk.Frame(self._main_sub_frame)

        ebrima_big = font.Font(family='Ebrima', size=12, weight=font.BOLD)
        # ebrima_small = font.Font(family='Ebrima', size=10, weight=font.NORMAL)

        self._run_img = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/buttons/run_128_30_02.png"))
        self._help_img = tk.PhotoImage(file=os.path.join(ROOT_PATH, "assets/buttons/help.png"))

        # 1. LOAD DATA

        self._data_frame = tk.Frame(self._main_sub_sub_frame, bd=2, relief='groove')
        self._data_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        title_frame = tk.Frame(self._data_frame, bg=colours.NAV_BAR)
        title_frame.pack(side=tk.TOP, fill=tk.X)
        tk.Label(title_frame, text="Step 1: Load Data", font=ebrima_big, fg='white',
                 bg=colours.NAV_BAR).pack(padx=10, pady=5, side=tk.LEFT)
        help_btn = tk.Button(title_frame, command=lambda s=1: self._help_dialog(s), image=self._help_img,
                             relief='flat', bd=0, highlightbackground=colours.NAV_BAR,
                             highlightcolor=colours.NAV_BAR, highlightthickness=0, background=colours.NAV_BAR,
                             activebackground=colours.NAV_BAR)
        help_btn.pack(padx=10, pady=5, side=tk.RIGHT)
        self._load_frame = DataLoadingTab(self._data_frame, self)
        self._load_frame.pack(side=tk.BOTTOM)

        # 2. PREPROCESSING -- FEATURE EXTRACTION

        self._others_frame = tk.Frame(self._main_sub_sub_frame)
        self._others_frame.pack(fill=tk.BOTH, expand=True)

        self._ae_frame = tk.Frame(self._others_frame, bd=2, relief='groove')
        self._ae_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

        title_frame = tk.Frame(self._ae_frame, bg=colours.NAV_BAR)
        title_frame.pack(side=tk.TOP, fill=tk.X)
        tk.Label(title_frame, text="Step 2: Preprocessing", font=ebrima_big, fg='white',
                 bg=colours.NAV_BAR).pack(padx=10, pady=5, side=tk.LEFT)
        help_btn = tk.Button(title_frame, command=lambda s=2: self._help_dialog(s), image=self._help_img,
                             relief='flat', bd=0, highlightbackground=colours.NAV_BAR,
                             highlightcolor=colours.NAV_BAR, highlightthickness=0, background=colours.NAV_BAR,
                             activebackground=colours.NAV_BAR)
        help_btn.pack(padx=10, pady=5, side=tk.RIGHT)

        self._sub_ae_frame = tk.Frame(self._ae_frame)
        self._sub_ae_frame.pack(pady=10, side=tk.BOTTOM)

        self._sub_sub_ae_frame = tk.Frame(self._sub_ae_frame)
        self._sub_sub_ae_frame.pack()

        tk.Label(self._sub_sub_ae_frame, text="Enable Automatic Feature Extraction?").grid(row=0, column=0)
        ttk.Checkbutton(self._sub_sub_ae_frame, variable=self._apply_ae, onvalue=True, offvalue=False,
                        style="PLT.TCheckbutton").grid(row=0, column=1, padx=(10, 0))
        self._apply_ae.trace('w', self._toggle_autoencoder_menu)

        # 3. FEATURE SELECTION

        self._fs_frame = tk.Frame(self._others_frame, bd=2, relief='groove')
        self._fs_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

        title_frame = tk.Frame(self._fs_frame, bg=colours.NAV_BAR)
        title_frame.pack(side=tk.TOP, fill=tk.X)
        tk.Label(title_frame, text="Step 3: Feature Selection", font=ebrima_big, fg='white',
                 bg=colours.NAV_BAR).pack(padx=10, pady=5, side=tk.LEFT)
        help_btn = tk.Button(title_frame, command=lambda s=3: self._help_dialog(s), image=self._help_img,
                             relief='flat', bd=0, highlightbackground=colours.NAV_BAR,
                             highlightcolor=colours.NAV_BAR, highlightthickness=0, background=colours.NAV_BAR,
                             activebackground=colours.NAV_BAR)
        help_btn.pack(padx=10, pady=5, side=tk.RIGHT)

        sub_fs_frame = tk.Frame(self._fs_frame)
        sub_fs_frame.pack(pady=10, side=tk.BOTTOM)

        tk.Label(sub_fs_frame, text="Enable Feature Selection?").grid(row=0, column=0)
        ttk.Checkbutton(sub_fs_frame, variable=self._apply_fs, onvalue=True, offvalue=False,
                        style="PLT.TCheckbutton").grid(row=0, column=1, padx=(10, 0))

        # 4. PREFERENCE LEARNING

        self._pl_frame = tk.Frame(self._others_frame, bd=2, relief='groove')
        self._pl_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

        title_frame = tk.Frame(self._pl_frame, bg=colours.NAV_BAR)
        title_frame.pack(side=tk.TOP, fill=tk.X)
        tk.Label(title_frame, text="Step 4: Preference Learning", font=ebrima_big, fg='white',
                 bg=colours.NAV_BAR).pack(padx=10, pady=5, side=tk.LEFT)
        help_btn = tk.Button(title_frame, command=lambda s=4: self._help_dialog(s), image=self._help_img,
                             relief='flat', bd=0, highlightbackground=colours.NAV_BAR,
                             highlightcolor=colours.NAV_BAR, highlightthickness=0, background=colours.NAV_BAR,
                             activebackground=colours.NAV_BAR)
        help_btn.pack(padx=10, pady=5, side=tk.RIGHT)

        sub_pl_frame = tk.Frame(self._pl_frame)
        sub_pl_frame.pack(pady=10, side=tk.BOTTOM)

        tk.Label(sub_pl_frame, text="Choose Preference Learning Algorithm: ").grid(row=0, column=0, padx=(10, 0))
        options = [key.name for key in supported_methods.supported_algorithms_beginner.keys()]
        algo_menu = ttk.OptionMenu(sub_pl_frame, self._algorithm, options[0], *options, style='PLT.TMenubutton')
        algo_menu.grid(row=0, column=1, padx=(10, 10))
        algo_menu["menu"].config(bg="#e6e6e6")

        # 5. RUN EXPERIMENT

        self._run_frame = tk.Frame(self._others_frame, bd=2, relief='groove')
        self._run_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

        title_frame = tk.Frame(self._run_frame, bg=colours.NAV_BAR)
        title_frame.pack(side=tk.TOP, fill=tk.X)
        tk.Label(title_frame, text="Step 5: Run Experiment", font=ebrima_big, fg='white',
                 bg=colours.NAV_BAR).pack(padx=10, pady=5, side=tk.LEFT)
        help_btn = tk.Button(title_frame, command=lambda s=5: self._help_dialog(s), image=self._help_img,
                             relief='flat', bd=0, highlightbackground=colours.NAV_BAR,
                             highlightcolor=colours.NAV_BAR, highlightthickness=0, background=colours.NAV_BAR,
                             activebackground=colours.NAV_BAR)
        help_btn.pack(padx=10, pady=5, side=tk.RIGHT)

        sub_run_frame = tk.Frame(self._run_frame)
        sub_run_frame.pack(pady=10, side=tk.BOTTOM)

        self._run_btn = tk.Button(sub_run_frame, command=self._run_exp, image=self._run_img, relief='flat', bd=0)
        self._run_btn.pack()

        self._others_locked = False
        self._load_frame.bind('<<FileChange>>', self._toggle_lock)
        self._toggle_lock(None)  # force call self._toggle_lock() once to disable steps 2-4 the first time.
        self._run_btn.bind("<<PLTStateToggle>>", self._check_lock)  # bind

        # ^ n.b. ensured that 'Run Experiment' button, OutputLayer#nuerons checkbox and Steps 2-4 of BeginnerMenu
        # are re-disabled or re-enabled accordingly on close of stacked windows (help dialog or load params).
        # solution via binding state changes to method which ensures re-disable (or re-enable if appropriate time/case).

        ws.place_window(self, parent, position=ws.SIDE)

        # add scrollbars
        v_scroll = ttk.Scrollbar(self, orient="vertical", command=self._main_canvas.yview,
                                 style="PLT.Vertical.TScrollbar")  # self._results_frame
        v_scroll.pack(side='right', fill='y')
        self._main_canvas.configure(yscrollcommand=v_scroll.set)
        h_scroll = ttk.Scrollbar(self, orient="horizontal", command=self._main_canvas.xview,
                                 style="PLT.Horizontal.TScrollbar")  # self._results_frame
        h_scroll.pack(side='bottom', fill='x')
        self._main_canvas.configure(xscrollcommand=h_scroll.set)

        # pack everything
        self._main_sub_sub_frame.pack()
        self._main_sub_frame.pack(fill=tk.BOTH, expand=True)  # useless line... doesn't work here it seems
        self._main_canvas.pack(side='left', expand=True, fill=tk.BOTH)

        self.c_win = self._main_canvas.create_window((0, 0), window=self._main_sub_frame, anchor='nw')
        self._main_canvas.config(scrollregion=self._main_canvas.bbox("all"))

        self._main_sub_frame.bind('<Configure>', self._on_canvas_config)
    def __init__(
            self,
            parent,
            parent_window,
            experiment,
            time_info,
            data_info,
            preproc_info,
            pl_algo_info,
            eval_metrics,
            shuffle_info,  # mandatory
            fs_info=None,
            fs_algo_info=None,
            fs_eval_info=None,
            pl_eval_info=None,
            fold_metrics=None):  # optional
        """Initializes the window widget with all of the information about and results obtained from the given experiment.

        :param parent: the parent widget of this window widget.
        :type parent: `tkinter widget`
        :param parent_window: the window which this window widget will be stacked on top of.
        :type parent_window: `tkinter.Toplevel`
        :param experiment: the given experiment.
        :type experiment: :class:`pyplt.experiment.Experiment`
        :param time_info: a list containing meta-data about the experiment related to time (the start timestamp (UTC),
            the end timestamp (UTC), and the duration).
        :type time_info: list of float (size 3)
        :param data_info: a list containing the number of objects, the number of ranks, and the list of data file paths.
        :type data_info: list (size 3)
        :param preproc_info: a list containing the include settings dict and the normalization settings dict.
        :type preproc_info: list of dict (size 2)
        :param pl_algo_info: a list containing the algorithm type (:class:`pyplt.util.enums.PLAlgo`)
            and the string representation of its parameters.
        :type pl_algo_info: list (size 2)
        :param eval_metrics: the evaluation/training results in the form of a dict with keys:

            * '`Training Accuracy`'
            * '`Test Accuracy`' (if applicable)
        :type eval_metrics: dict
        :param shuffle_info: list containing the chosen settings related to shuffling the dataset:

            * shuffle -- bool specifying whether or not the dataset was shuffled at the start of the experiment
              execution.
            * random_seed -- optional seed (int or None) used to shuffle the dataset.
        :type shuffle_info: list (size 2)
        :param fs_info: a list containing the chosen feature selection method type
            (:class:`pyplt.util.enums.FSMethod`), the string representation of its parameters, and the list of
            features selected by the feature selection method.
        :type fs_info: list (size 3) or None, optional
        :param fs_algo_info: a list containing the chosen algorithm type
            (:class:`pyplt.util.enums.PLAlgo`) for the feature selection stage and the string
            representation of its parameters.
        :type fs_algo_info: list (size 2) or None, optional
        :param fs_eval_info: a list containing the evaluation method type
            (:class:`pyplt.util.enums.EvaluatorType`) for the feature selection stage and the
            string representation of its parameters.
        :type fs_eval_info: list (size 2) or None, optional
        :param pl_eval_info: a list containing the evaluation method type
            (:class:`pyplt.util.enums.EvaluatorType`) and the string representation of its parameters.
        :type pl_eval_info: list (size 2) or None, optional
        :param fold_metrics: optional fold-specific information (default None) in the form of list of tuples, each
            containing the start timestamp, end timestamp, evaluation metrics, and a `pandas.DataFrame`
            representation of the trained model as follows:

                * start_time -- `datetime` timestamp (UTC timezone)
                * end_time -- `datetime` timestamp (UTC timezone)
                * eval_metrics -- dict with keys:

                  * '`Training Accuracy`'
                  * '`Test Accuracy`' (if applicable)
                * model -- `pandas.DataFrame`
        :type fold_metrics: list of tuple, optional
        """
        self._parent = parent
        self._parent_window = parent_window
        self._exp = experiment
        tk.Toplevel.__init__(self, self._parent)
        img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, 'assets/plt_logo.png'))
        self.tk.call('wm', 'iconphoto', self._w, img)
        ws.disable_parent(self, self._parent_window, ws.Mode.OPEN_ONLY)
        ws.stack_window(self, self._parent_window)
        self.protocol("WM_DELETE_WINDOW", self._on_close_safe)

        self.title("Experiment Report")  # Results

        self._OS = platform.system()

        # (for scrollbars/)
        self._results_canvas = tk.Canvas(self)
        self._results_canvas.bind("<Configure>", self._on_resize)
        self._results_canvas.bind('<Enter>', self._bind_mousewheel)
        self._results_canvas.bind('<Leave>', self._unbind_mousewheel)
        self._canvas_height = self._results_canvas.winfo_reqheight()
        self._canvas_width = self._results_canvas.winfo_reqwidth()
        self._results_sub_frame = tk.Frame(self._results_canvas,
                                           padx=10,
                                           pady=10)
        # (/for scrollbars)

        n_obj = data_info[0]
        n_ranks = data_info[1]
        obj_path, ranks_path, single_path = data_info[2]
        f_include = preproc_info[0]  # dict
        f_norm = preproc_info[1]  # dict
        n_feats = len([f for f in f_include if f_include[f].get()
                       ])  # no need for -1 as ID column not included
        # ^ only if True i.e. ignore excluded features!!!
        fs_method = fs_info[0]
        fs_method_params = fs_info[1]
        sel_feats = fs_info[2]
        fs_algo = fs_algo_info[0]
        fs_algo_params = fs_algo_info[1]
        fs_eval = fs_eval_info[0]
        fs_eval_params = fs_eval_info[1]
        pl_algo = pl_algo_info[0]
        pl_algo_params = pl_algo_info[1]
        pl_eval = pl_eval_info[0]
        pl_eval_params = pl_eval_info[1]
        s_time, e_time, duration = time_info
        shuffle, random_seed = shuffle_info

        orig_feats = experiment.get_orig_features()
        autoencoder_loss = experiment.get_autoencoder_loss()
        autoencoder_details = experiment.get_autoencoder_details()

        self._pl_algo = self._exp.get_pl_algorithm(
        )  # get the actual algorithm PLAlgo object

        #############
        # META DATA
        #############

        exp_frame = tk.Frame(self._results_sub_frame,
                             bd=2,
                             relief='groove',
                             padx=50,
                             pady=5)
        exp_frame.grid(row=0, column=0, pady=5, sticky='ew')
        exp_title_frame = tk.Frame(exp_frame)
        exp_title_frame.pack(fill=tk.BOTH, expand=True)
        tk.Label(exp_title_frame,
                 text="Experiment Times",
                 justify='center',
                 font='Ebrima 14 bold').pack()
        exp_sub_frame = tk.Frame(exp_frame)
        exp_sub_frame.pack()
        tk.Label(exp_sub_frame, text="Start timestamp (UTC):").grid(row=0,
                                                                    column=0,
                                                                    sticky='w')
        tk.Label(exp_sub_frame, text=str(s_time)).grid(row=0,
                                                       column=1,
                                                       sticky='w')
        tk.Label(exp_sub_frame, text="End timestamp (UTC):").grid(row=1,
                                                                  column=0,
                                                                  sticky='w')
        tk.Label(exp_sub_frame, text=str(e_time)).grid(row=1,
                                                       column=1,
                                                       sticky='w')
        tk.Label(exp_sub_frame, text="Duration:").grid(row=2,
                                                       column=0,
                                                       sticky='w')
        tk.Label(exp_sub_frame, text=str(duration)).grid(row=2,
                                                         column=1,
                                                         sticky='w')

        #############
        # DATA
        #############

        data_frame = tk.Frame(self._results_sub_frame,
                              bd=2,
                              relief='groove',
                              padx=50,
                              pady=5)
        data_frame.grid(row=1, column=0, pady=5, sticky='ew')
        data_title_frame = tk.Frame(data_frame)
        data_title_frame.pack(fill=tk.BOTH, expand=True)
        tk.Label(data_title_frame,
                 text="Data",
                 justify='center',
                 font='Ebrima 14 bold').pack()
        data_sub_frame = tk.Frame(data_frame)
        data_sub_frame.pack()
        data_paths_frame = tk.Frame(data_sub_frame)
        data_paths_frame.grid(row=0, column=0, sticky='w')
        if not (single_path == ""):
            tk.Label(data_paths_frame,
                     text="Single file path:").grid(row=0,
                                                    column=0,
                                                    sticky='w')
            tk.Label(data_paths_frame, text=str(single_path)).grid(row=0,
                                                                   column=1,
                                                                   sticky='w')
        else:
            tk.Label(data_paths_frame,
                     text="Objects file path:").grid(row=0,
                                                     column=0,
                                                     sticky='w')
            tk.Label(data_paths_frame, text=str(obj_path)).grid(row=0,
                                                                column=1,
                                                                sticky='w')
            tk.Label(data_paths_frame,
                     text="Ranks file path:").grid(row=1, column=0, sticky='w')
            tk.Label(data_paths_frame, text=str(ranks_path)).grid(row=1,
                                                                  column=1,
                                                                  sticky='w')
        data_other_frame = tk.Frame(data_sub_frame)
        data_other_frame.grid(row=1, column=0, sticky='ew')
        data_other_sub_frame = tk.Frame(data_other_frame)
        data_other_sub_frame.pack()
        tk.Label(data_other_sub_frame,
                 text="Number of objects/samples:").grid(row=0,
                                                         column=0,
                                                         sticky='w')
        tk.Label(data_other_sub_frame, text=str(n_obj)).grid(row=0,
                                                             column=1,
                                                             sticky='e')
        tk.Label(data_other_sub_frame,
                 text="Number of included/extracted features:").grid(
                     row=1, column=0, sticky='w')
        tk.Label(data_other_sub_frame, text=str(n_feats)).grid(row=1,
                                                               column=1,
                                                               sticky='e')
        tk.Label(data_other_sub_frame,
                 text="Number of ranks/preferences:").grid(row=2,
                                                           column=0,
                                                           sticky='w')
        tk.Label(data_other_sub_frame, text=str(n_ranks)).grid(row=2,
                                                               column=1,
                                                               sticky='e')

        ####################################
        # FEATURES INCLUDED & PRE-PROCESSING
        ####################################
        preproc_frame = tk.Frame(self._results_sub_frame,
                                 bd=2,
                                 relief='groove',
                                 padx=50,
                                 pady=5)
        preproc_frame.grid(row=2, column=0, pady=5, sticky='ew')
        tk.Label(preproc_frame,
                 text="Features Included & Pre-processing",
                 justify='center',
                 font='Ebrima 14 bold').pack()

        # autoencoder
        ae_frame = tk.Frame(preproc_frame)
        ae_frame.pack(pady=(5, 0))

        ae_applied = "No"
        if autoencoder_details is not None:
            ae_applied = "Yes"
        tk.Label(ae_frame,
                 text="Automatic feature extraction enabled?").grid(row=0,
                                                                    column=0,
                                                                    sticky='e',
                                                                    padx=(0,
                                                                          5))
        tk.Label(ae_frame, text=str(ae_applied)).grid(row=0,
                                                      column=1,
                                                      sticky='w',
                                                      padx=(5, 0))
        if autoencoder_details is not None:
            # loss
            tk.Label(ae_frame,
                     text="Autoencoder Mean Squared Error loss:").grid(
                         row=1, column=0, sticky='e', padx=(0, 5))
            tk.Label(ae_frame, text=str(autoencoder_loss)).grid(row=1,
                                                                column=1,
                                                                sticky='w',
                                                                padx=(5, 0))
            ae_frame.grid_columnconfigure(0, weight=1)
            ae_frame.grid_columnconfigure(1, weight=1)
            # details
            tk.Label(preproc_frame,
                     text="Autoencoder Parameters:",
                     font='Ebrima 10 italic').pack()
            ae_params_frame = tk.Frame(preproc_frame)
            ae_params_frame.pack()
            col = 0
            for key, value in autoencoder_details.items():
                key = str(key).replace("Autoencoder-", "")  # remove prefix
                tk.Label(ae_params_frame, text=key).grid(row=col,
                                                         column=0,
                                                         sticky='e',
                                                         padx=(0, 5))
                tk.Label(ae_params_frame, text=str(value)).grid(row=col,
                                                                column=1,
                                                                sticky='w',
                                                                padx=(5, 0))
                ae_params_frame.grid_columnconfigure(col, weight=1)
                col += 1

        ttk.Separator(preproc_frame, orient=tk.HORIZONTAL).pack(fill=tk.BOTH,
                                                                expand=True,
                                                                pady=5)

        # included features & normalization
        pf = tk.Frame(preproc_frame)
        pf.pack()
        r = 0
        tk.Label(pf, text="Feature", font='Ebrima 11 normal').grid(row=r,
                                                                   column=0,
                                                                   sticky='w',
                                                                   padx=(0, 5))
        tk.Label(pf, text="Normalization",
                 font='Ebrima 11 normal').grid(row=r, column=1, padx=(5, 0))
        for f in range(len(orig_feats)):
            r += 1
            # no need to skip first row as ID is excluded in f_include and f_norm
            # no need to check if feature included (==True) as orig_feats and f_norm only contain included features!
            tk.Label(pf, text=str(orig_feats[f])).grid(row=r,
                                                       column=0,
                                                       sticky='w')
            tk.Label(pf, text=text.real_type_name(str(f_norm[f].get()))).grid(
                row=r, column=1)

        ttk.Separator(preproc_frame, orient=tk.HORIZONTAL).pack(fill=tk.BOTH,
                                                                expand=True,
                                                                pady=5)

        # shuffle & random seed
        shuffle_frame = tk.Frame(preproc_frame)
        shuffle_frame.pack()
        shuffle_applied = "No"
        seed = "N/A"
        if shuffle:
            shuffle_applied = "Yes"
            seed = random_seed
        tk.Label(shuffle_frame,
                 text="Dataset shuffle enabled?").grid(row=0,
                                                       column=0,
                                                       sticky='e',
                                                       padx=(0, 5))
        tk.Label(shuffle_frame, text=str(shuffle_applied)).grid(row=0,
                                                                column=1,
                                                                sticky='w',
                                                                padx=(5, 0))
        tk.Label(shuffle_frame, text="Random seed:").grid(row=1,
                                                          column=0,
                                                          sticky='e',
                                                          padx=(0, 5))
        tk.Label(shuffle_frame, text=str(seed)).grid(row=1,
                                                     column=1,
                                                     sticky='w',
                                                     padx=(5, 0))
        shuffle_frame.grid_columnconfigure(0, weight=1)
        shuffle_frame.grid_columnconfigure(1, weight=1)

        ###################
        # FEATURE SELECTION
        ###################

        fs_frame = tk.Frame(self._results_sub_frame,
                            bd=2,
                            relief='groove',
                            padx=50,
                            pady=5)
        # fs_frame.pack(pady=5)
        fs_frame.grid(row=3, column=0, pady=5, sticky='ew')
        tk.Label(fs_frame,
                 text="Feature Selection",
                 justify='center',
                 font='Ebrima 14 bold').pack()
        fs_sub_frame = tk.Frame(fs_frame)
        fs_sub_frame.pack()
        tk.Label(fs_sub_frame,
                 text="Method: " +
                 text.real_type_name(str(fs_method.name))).grid(row=0,
                                                                column=0)
        if (fs_method_params is not None) and (not fs_method_params == "{}"):
            fs_params_frame = tk.Frame(fs_sub_frame)
            fs_params_frame.grid(row=1, column=0)
            tk.Label(fs_params_frame,
                     text="Parameters:",
                     font='Ebrima 10 italic').pack()
            fs_params_sub_frame = tk.Frame(fs_params_frame)
            fs_params_sub_frame.pack()
            self._print_params(fs_params_sub_frame, fs_method_params)
        if fs_algo is not None:
            fs_a_frame = tk.Frame(fs_frame)
            fs_a_frame.pack(pady=10)
            tk.Label(fs_a_frame,
                     text="Algorithm: " +
                     text.real_type_name(str(fs_algo.name))).grid(row=0,
                                                                  column=0)
            if (fs_algo_params is not None) and (not fs_algo_params == "{}"):
                fs_algo_params_frame = tk.Frame(fs_a_frame)
                fs_algo_params_frame.grid(row=1, column=0)
                tk.Label(fs_algo_params_frame,
                         text="Parameters:",
                         font='Ebrima 10 italic').pack()
                fs_algo_params_sub_frame = tk.Frame(fs_algo_params_frame)
                fs_algo_params_sub_frame.pack()
                self._print_params(fs_algo_params_sub_frame, fs_algo_params)

        if fs_eval is not None:
            fs_e_frame = tk.Frame(fs_frame)
            fs_e_frame.pack()
            tk.Label(fs_e_frame,
                     text="Evaluation: " +
                     text.real_type_name(str(fs_eval.name))).grid(row=0,
                                                                  column=0)
            if (fs_eval_params is not None) and (not fs_eval_params == "{}"):
                fs_eval_params_frame = tk.Frame(fs_e_frame)
                fs_eval_params_frame.grid(row=1, column=0)
                tk.Label(fs_eval_params_frame,
                         text="Parameters:",
                         font='Ebrima 10 italic').pack()
                fs_eval_params_sub_frame = tk.Frame(fs_eval_params_frame)
                fs_eval_params_sub_frame.pack()
                self._print_params(fs_eval_params_sub_frame, fs_eval_params)
        sf = tk.Frame(fs_frame)
        sf.pack(pady=(10, 0))
        if not (fs_method == FSMethod.NONE):
            tk.Label(sf, text="Selected Features:",
                     font='Ebrima 10 bold').pack()
            sf_sub_frame = tk.Frame(sf)
            sf_sub_frame.pack()
            r = 0
            for f in sel_feats:
                tk.Label(sf_sub_frame, text=str(f)).grid(row=r,
                                                         column=0,
                                                         sticky='w')
                r += 1

        #####################
        # PREFERENCE LEARNING
        #####################

        pl_frame = tk.Frame(self._results_sub_frame,
                            bd=2,
                            relief='groove',
                            padx=50,
                            pady=5)
        pl_frame.grid(row=4, column=0, pady=5, sticky='ew')
        tk.Label(pl_frame,
                 text="Preference Learning",
                 justify='center',
                 font='Ebrima 14 bold').pack()
        pl_a_frame = tk.Frame(pl_frame)
        pl_a_frame.pack(pady=10)
        tk.Label(pl_a_frame,
                 text="Algorithm: " +
                 text.real_type_name(str(pl_algo.name))).grid(row=0, column=0)
        if (pl_algo_params is not None) and (not pl_algo_params == "{}"):
            pl_algo_params_frame = tk.Frame(pl_a_frame)
            pl_algo_params_frame.grid(row=1, column=0)
            tk.Label(pl_algo_params_frame,
                     text="Parameters:",
                     font='Ebrima 10 italic').pack()
            pl_algo_params_sub_frame = tk.Frame(pl_algo_params_frame)
            pl_algo_params_sub_frame.pack()
            self._print_params(pl_algo_params_sub_frame, pl_algo_params)

        pl_e_frame = tk.Frame(pl_frame)
        pl_e_frame.pack()
        tk.Label(pl_e_frame,
                 text="Evaluation: " +
                 text.real_type_name(str(pl_eval.name))).grid(row=0, column=0)
        if (pl_eval_params is not None) and (not pl_eval_params == "{}"):
            pl_eval_params_frame = tk.Frame(pl_e_frame)
            pl_eval_params_frame.grid(row=1, column=0)
            tk.Label(pl_eval_params_frame,
                     text="Parameters:",
                     font='Ebrima 10 italic').pack()
            pl_eval_params_sub_frame = tk.Frame(pl_eval_params_frame)
            pl_eval_params_sub_frame.pack()
            self._print_params(pl_eval_params_sub_frame, pl_eval_params)

        ###################
        # MODEL PERFORMANCE
        ###################

        perf_frame = tk.Frame(self._results_sub_frame,
                              bd=2,
                              relief='groove',
                              padx=50,
                              pady=5)
        # perf_frame.pack(pady=5)
        perf_frame.grid(row=5, column=0, pady=5, sticky='ew')
        tk.Label(perf_frame,
                 text="Model Performance",
                 justify='center',
                 font='Ebrima 14 bold').pack()

        self._tree = None
        self._tree_scroll = None
        self._fold_metrics = fold_metrics
        if len(self._fold_metrics) > 1:
            fold_metrics_frame = tk.Frame(perf_frame, bd=2, relief='sunken')
            fold_metrics_frame.pack(pady=10)

            eval_metric_names = tuple(self._fold_metrics[0][2].keys(
            ))  # keys of eval_metrics of first fold in fold_metrics
            cols = ('Fold', ) + eval_metric_names

            self._tree = ttk.Treeview(fold_metrics_frame,
                                      columns=cols,
                                      height=4)
            for c in cols:
                self._tree.heading(c, text=c)
                self._tree.column(c, width=150)
            self._tree['show'] = 'headings'

            f = 0
            for fold in self._fold_metrics:
                f = f + 1
                fold_name = "Fold " + str(f)
                self._tree.insert("",
                                  tk.END,
                                  iid=f,
                                  values=(fold_name, ) +
                                  tuple(fold[2].values()))

            # add vertical scrollbar beside Treeview
            self._tree_scroll = ttk.Scrollbar(fold_metrics_frame,
                                              orient="vertical",
                                              command=self._tree.yview)
            self._tree_scroll.pack(side='right', fill='y')
            self._tree.configure(yscrollcommand=self._tree_scroll.set)

            # finally, pack the Treeview itself
            self._tree.pack()

        avg_metrics_frame = tk.Frame(perf_frame)
        avg_metrics_frame.pack()
        r = 0
        for e in eval_metrics:
            tk.Label(avg_metrics_frame, text=str(e) + ": ").grid(row=r,
                                                                 column=0,
                                                                 sticky='w')
            tk.Label(avg_metrics_frame,
                     text=str(eval_metrics[e]) + " %").grid(row=r,
                                                            column=1,
                                                            sticky='w')
            r += 1

        # Send additional data to Experiment for log saving
        f_norm_clean = {key: val.get() for key, val in f_norm.items()}
        self._exp._set_file_meta_data(obj_path, ranks_path, single_path,
                                      f_norm_clean)

        # Buttons to save model and/or save experiment log
        self._model_img = tk.PhotoImage(file=os.path.join(
            ROOT_PATH, "assets/buttons/save_model_128_30_01_white.png"))
        self._report_img = tk.PhotoImage(file=os.path.join(
            ROOT_PATH, "assets/buttons/save_report_128_30_01_white.png"))
        self._help_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/help.png"))
        self._fake_btn_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/fake_btn.png"))

        self._algo = self._exp.get_pl_algorithm()
        save_buttons_frame = tk.Frame(self,
                                      bd=2,
                                      relief='groove',
                                      background=colours.NAV_BAR)
        save_buttons_frame.pack(side=tk.BOTTOM, fill=tk.BOTH)

        help_btn = tk.Button(save_buttons_frame,
                             command=self._help_dialog,
                             image=self._help_img,
                             relief='flat',
                             bd=0,
                             highlightbackground=colours.NAV_BAR,
                             highlightcolor=colours.NAV_BAR,
                             highlightthickness=0,
                             background=colours.NAV_BAR,
                             activebackground=colours.NAV_BAR)
        help_btn.pack(side=tk.LEFT, padx=10, pady=10)

        # add fake button to center save buttons
        fake_btn = tk.Button(save_buttons_frame,
                             image=self._fake_btn_img,
                             relief='flat',
                             bd=0,
                             highlightbackground=colours.NAV_BAR,
                             highlightcolor=colours.NAV_BAR,
                             highlightthickness=0,
                             background=colours.NAV_BAR,
                             activebackground=colours.NAV_BAR)
        fake_btn.pack(side=tk.RIGHT, padx=10, pady=10)

        sbf = tk.Frame(save_buttons_frame, background=colours.NAV_BAR)
        sbf.pack()
        save_model_btn = tk.Button(
            sbf,
            command=lambda t=time.time(): self._save_model(t),
            image=self._model_img,
            relief='flat',
            bd=0,
            highlightbackground=colours.NAV_BAR,
            highlightcolor=colours.NAV_BAR,
            highlightthickness=0,
            background=colours.NAV_BAR,
            activebackground=colours.NAV_BAR)
        save_model_btn.grid(row=0, column=0, padx=10, pady=10)
        save_exp_log_btn = tk.Button(
            sbf,
            command=lambda t=time.time(): self._save_exp_log_with_dialog(t),
            image=self._report_img,
            relief='flat',
            bd=0,
            highlightbackground=colours.NAV_BAR,
            highlightcolor=colours.NAV_BAR,
            highlightthickness=0,
            background=colours.NAV_BAR,
            activebackground=colours.NAV_BAR)
        save_exp_log_btn.grid(row=0, column=1, padx=10, pady=10)

        # add scrollbars

        v_scroll = ttk.Scrollbar(self,
                                 orient="vertical",
                                 command=self._results_canvas.yview)
        v_scroll.pack(side='right', fill='y')
        self._results_canvas.configure(yscrollcommand=v_scroll.set)
        h_scroll = ttk.Scrollbar(self,
                                 orient="horizontal",
                                 command=self._results_canvas.xview)
        h_scroll.pack(side='bottom', fill='x')
        self._results_canvas.configure(xscrollcommand=h_scroll.set)

        # pack everything
        self._results_sub_frame.pack(fill=tk.BOTH, expand=True)
        self._results_canvas.pack(side='left', expand=True, fill=tk.BOTH)

        self._results_canvas.create_window((0, 0),
                                           window=self._results_sub_frame,
                                           anchor='n')
        self._results_canvas.config(
            scrollregion=self._results_canvas.bbox("all"))

        self._results_sub_frame.bind('<Configure>', self._on_canvas_config)

        # scroll to bottom (to show accuracy) for the first time
        self.update()
        self._results_canvas.yview(tk.MOVETO, 1)
        self.update_idletasks()
Example #4
0
    def __init__(self, parent, file_path, parent_window, is_dual_format):
        """Populates the window widget with widgets to specify loading parameters and a data set preview frame.

        :param parent: the parent widget of this window widget.
        :type parent: `tkinter widget`
        :param file_path: the path of the file to be loaded.
        :type file_path: str
        :param parent_window: the window which this window widget will be stacked on top of.
        :type parent_window: `tkinter.Toplevel`
        :param is_dual_format: specifies whether the dual file format was used to load the dataset or not (single
            file format).
        :type is_dual_format: bool
        """
        self._prev = None
        self._parent = parent
        self._separator = None
        self._has_id = None
        self._has_fnames = None
        self._preview_frame = None
        self._file_path = file_path
        self._confirmation = None
        self._parent_window = parent_window
        self._data = None

        tk.Toplevel.__init__(self, parent)
        img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, 'assets/plt_logo.png'))
        self.tk.call('wm', 'iconphoto', self._w, img)
        ws.disable_parent(self, self._parent_window, ws.Mode.OPEN_ONLY)
        ws.stack_window(self, self._parent_window)

        self.title("Processing folds file")
        self.resizable(width=False, height=False)
        self.protocol("WM_DELETE_WINDOW", self._on_closing)

        setup_frame = tk.Frame(self, relief='groove', borderwidth=2)
        setup_frame.pack(pady=15, padx=20)
        params_frame = tk.Frame(setup_frame)
        params_frame.pack()

        # Separator
        self._separator = tk.StringVar()
        self._separator.set(',')  # comma by default
        sep_frame = tk.Frame(params_frame, padx=25)
        sep_frame.grid(row=0, column=0, sticky='nw')
        sep_label = tk.Label(sep_frame, text="Separator")
        sep_label.grid(row=0, column=0, sticky='w')
        sep_opt1 = ttk.Radiobutton(sep_frame,
                                   variable=self._separator,
                                   text="Comma",
                                   value=',',
                                   command=self._update_data,
                                   style='PLT.TRadiobutton')
        sep_opt1.grid(row=1, column=0, sticky='w')
        sep_opt2 = ttk.Radiobutton(sep_frame,
                                   variable=self._separator,
                                   text="Tab",
                                   value='\t',
                                   command=self._update_data,
                                   style='PLT.TRadiobutton')
        sep_opt2.grid(row=2, column=0, sticky='w')
        sep_opt3 = ttk.Radiobutton(sep_frame,
                                   variable=self._separator,
                                   text="Space",
                                   value=' ',
                                   command=self._update_data,
                                   style='PLT.TRadiobutton')
        sep_opt3.grid(row=3, column=0, sticky='w')

        # TODO: add 'Other' option which toggles textbox which returns its value to self.objects_separator
        # sep_opt4 = ttk.Radiobutton(sep_frame, command=toggle_text_box, text="Other")

        # Check if 1st column contains IDs and if 1st row contains Feature Names
        self._has_id = tk.BooleanVar()
        self._has_id.set(True)  # true by default
        self._has_fnames = tk.BooleanVar()
        self._has_fnames.set(True)  # true by default

        other_frame = tk.Frame(params_frame, padx=25)
        other_frame.grid(row=0, column=1)
        # Check ID
        if is_dual_format:  # dual file format
            has_id_label = tk.Label(other_frame,
                                    text="Does first column contain rank ID?")
        else:  # single file format
            has_id_label = tk.Label(
                other_frame, text="Does first column contain object ID?")
        has_id_label.grid(row=0, column=0, sticky='w')
        has_id_opt1 = ttk.Radiobutton(other_frame,
                                      variable=self._has_id,
                                      text="Yes",
                                      value=True,
                                      command=self._update_data,
                                      style='PLT.TRadiobutton')
        has_id_opt1.grid(row=1, column=0, sticky='w')
        has_id_opt2 = ttk.Radiobutton(other_frame,
                                      variable=self._has_id,
                                      text="No",
                                      value=False,
                                      command=self._update_data,
                                      style='PLT.TRadiobutton')
        has_id_opt2.grid(row=2, column=0, sticky='w')

        # Check Feature Names
        fnames_text = "Does first row contain column names?"

        has_fnames_label = tk.Label(other_frame, text=fnames_text)
        has_fnames_label.grid(row=3, column=0, sticky='w', pady=(15, 0))
        has_fnames_opt1 = ttk.Radiobutton(other_frame,
                                          variable=self._has_fnames,
                                          text="Yes",
                                          value=True,
                                          command=self._update_data,
                                          style='PLT.TRadiobutton')
        has_fnames_opt1.grid(row=4, column=0, sticky='w')
        has_fnames_opt2 = ttk.Radiobutton(other_frame,
                                          variable=self._has_fnames,
                                          text="No",
                                          value=False,
                                          command=self._update_data,
                                          style='PLT.TRadiobutton')
        has_fnames_opt2.grid(row=5, column=0, sticky='w')

        # TODO: Add 'Skip Columns/Rows' feature

        # Data set preview
        preview_label = tk.Label(self,
                                 text="Preview",
                                 font=font.Font(family='Ebrima', size=14))
        preview_label.pack(pady=(0, 5))
        self._preview_frame = tk.Frame(self)
        self._preview_frame.pack(fill=tk.BOTH, expand=True)

        self._update_data()

        self._load_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/load_76_30_03.png"))
        self._cancel_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/cancel_76_30_04.png"))

        # Final loading stuff
        final_frame = tk.Frame(self, background=colours.NAV_BAR)
        final_frame.pack(fill=tk.BOTH)
        final_btns_frame = tk.Frame(final_frame, background=colours.NAV_BAR)
        final_btns_frame.pack(anchor=tk.CENTER)
        final_btn = tk.Button(final_btns_frame,
                              command=self._final_load,
                              image=self._load_img,
                              relief='flat',
                              bd=0,
                              highlightbackground=colours.NAV_BAR,
                              highlightcolor=colours.NAV_BAR,
                              highlightthickness=0,
                              background=colours.NAV_BAR,
                              activebackground=colours.NAV_BAR)
        final_btn.grid(row=0, column=0, padx=5, pady=5)
        final_btn = tk.Button(final_btns_frame,
                              command=self._on_closing,
                              image=self._cancel_img,
                              relief='flat',
                              bd=0,
                              highlightbackground=colours.NAV_BAR,
                              highlightcolor=colours.NAV_BAR,
                              highlightthickness=0,
                              background=colours.NAV_BAR,
                              activebackground=colours.NAV_BAR)
        final_btn.grid(row=0, column=1, padx=5, pady=5)
Example #5
0
    def __init__(self, parent, file_path, parent_window, file_type):
        """Populates the window widget with widgets to specify loading parameters and a data set preview frame.

        :param parent: the parent widget of this window widget.
        :type parent: `tkinter widget`
        :param file_path: the path of the file to be loaded.
        :type file_path: str
        :param parent_window: the window which this window widget will be stacked on top of.
        :type parent_window: `tkinter.Toplevel`
        :param file_type: the type of file to be loaded.
        :type file_type: :class:`pyplt.util.enums.FileType`.
        """
        self._prev = None
        self._parent = parent
        self._separator = None
        self._has_id = None
        self._has_fnames = None
        self._preview_frame = None
        self._file_path = file_path
        self._objects_confirmation = None
        self._ranks_confirmation = None
        self._single_confirmation = None
        self._parent_window = parent_window
        self._file_type = file_type
        self._data = None
        self._mdm = tk.DoubleVar(value=0.0)
        self._memory = tk.IntVar()
        self._memory_str = tk.StringVar()

        tk.Toplevel.__init__(self, parent)
        img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, 'assets/plt_logo.png'))
        self.tk.call('wm', 'iconphoto', self._w, img)
        ws.disable_parent(self, self._parent_window, ws.Mode.OPEN_ONLY)
        ws.stack_window(self, self._parent_window)

        # for validation:
        self._vcmd = (self.register(self._on_validate), '%d', '%i', '%P', '%s',
                      '%S', '%v', '%V', '%W')

        self.title("Processing " + str(self._file_type.name).lower() + " file")
        self.resizable(width=False, height=False)
        self.protocol("WM_DELETE_WINDOW", self._on_closing)

        setup_frame = tk.Frame(self, relief='groove', borderwidth=2)
        setup_frame.pack(pady=15, padx=20)
        params_frame = tk.Frame(setup_frame)
        params_frame.pack()

        # Separator
        self._separator = tk.StringVar()
        self._separator.set(',')  # comma by default
        sep_frame = tk.Frame(params_frame, padx=25)
        sep_frame.grid(row=0, column=0, sticky='nw')
        sep_label = tk.Label(sep_frame, text="Separator")
        sep_label.grid(row=0, column=0, sticky='w')
        sep_opt1 = ttk.Radiobutton(sep_frame,
                                   variable=self._separator,
                                   text="Comma",
                                   value=',',
                                   command=self._update_data,
                                   style='PLT.TRadiobutton')
        sep_opt1.grid(row=1, column=0, sticky='w')
        sep_opt2 = ttk.Radiobutton(sep_frame,
                                   variable=self._separator,
                                   text="Tab",
                                   value='\t',
                                   command=self._update_data,
                                   style='PLT.TRadiobutton')
        sep_opt2.grid(row=2, column=0, sticky='w')
        sep_opt3 = ttk.Radiobutton(sep_frame,
                                   variable=self._separator,
                                   text="Space",
                                   value=' ',
                                   command=self._update_data,
                                   style='PLT.TRadiobutton')
        sep_opt3.grid(row=3, column=0, sticky='w')

        # TODO: add 'Other' option which toggles textbox which returns its value to self.objects_separator
        # sep_opt4 = ttk.Radiobutton(sep_frame, command=toggle_text_box, text="Other")

        # Check if 1st column contains IDs and if 1st row contains Feature Names
        self._has_id = tk.BooleanVar()
        self._has_id.set(True)  # true by default
        self._has_fnames = tk.BooleanVar()
        self._has_fnames.set(True)  # true by default

        other_frame = tk.Frame(params_frame, padx=25)
        other_frame.grid(row=0, column=1)
        # Check ID
        has_id_label = tk.Label(other_frame,
                                text="Does first column contain ID?")
        has_id_label.grid(row=0, column=0, sticky='w')
        has_id_opt1 = ttk.Radiobutton(other_frame,
                                      variable=self._has_id,
                                      text="Yes",
                                      value=True,
                                      command=self._update_data,
                                      style='PLT.TRadiobutton')
        has_id_opt1.grid(row=1, column=0, sticky='w')
        has_id_opt2 = ttk.Radiobutton(other_frame,
                                      variable=self._has_id,
                                      text="No",
                                      value=False,
                                      command=self._update_data,
                                      style='PLT.TRadiobutton')
        has_id_opt2.grid(row=2, column=0, sticky='w')

        # Check Feature Names
        fnames_text = "Does first row contain feature names?"
        if self._file_type == FileType.RANKS:
            fnames_text = "Does first row contain column names?"

        has_fnames_label = tk.Label(other_frame, text=fnames_text)
        has_fnames_label.grid(row=3, column=0, sticky='w', pady=(15, 0))
        has_fnames_opt1 = ttk.Radiobutton(other_frame,
                                          variable=self._has_fnames,
                                          text="Yes",
                                          value=True,
                                          command=self._update_data,
                                          style='PLT.TRadiobutton')
        has_fnames_opt1.grid(row=4, column=0, sticky='w')
        has_fnames_opt2 = ttk.Radiobutton(other_frame,
                                          variable=self._has_fnames,
                                          text="No",
                                          value=False,
                                          command=self._update_data,
                                          style='PLT.TRadiobutton')
        has_fnames_opt2.grid(row=5, column=0, sticky='w')

        # TODO: Add 'Skip Columns/Rows' feature

        # Data set preview
        preview_label = tk.Label(self,
                                 text="Preview",
                                 font=font.Font(family='Ebrima', size=14))
        preview_label.pack(pady=(0, 5))
        self._preview_frame = tk.Frame(self)
        self._preview_frame.pack(fill=tk.BOTH, expand=True)

        self._update_data()

        # after data has been loaded (since we need self._data here)...
        if self._file_type == FileType.SINGLE:
            single_frame = tk.Frame(setup_frame, bg=colours.PL_OUTER)
            single_frame.pack(
                pady=(10, 0), fill=tk.BOTH,
                expand=True)  # .grid(row=1, column=0, sticky='ew')
            header = tk.Frame(single_frame, bg=colours.PL_OUTER)
            header.pack(pady=(10, 0))
            single_label = tk.Label(header,
                                    text="Preference Derivation Parameters",
                                    font='Ebrima 12 normal',
                                    fg='white',
                                    bg=colours.PL_OUTER)
            single_label.pack(side=tk.LEFT, padx=5)
            self._help_img = tk.PhotoImage(
                file=os.path.join(ROOT_PATH, "assets/buttons/help.png"))
            help_btn = tk.Button(header,
                                 command=self._help_dialog,
                                 image=self._help_img,
                                 relief='flat',
                                 bd=0,
                                 highlightbackground=colours.PL_OUTER,
                                 highlightcolor=colours.PL_OUTER,
                                 highlightthickness=0,
                                 background=colours.PL_OUTER,
                                 activebackground=colours.PL_OUTER)
            help_btn.pack(side=tk.RIGHT, padx=5)
            self._single_params = tk.Frame(single_frame,
                                           padx=20,
                                           pady=5,
                                           relief=tk.RAISED,
                                           bd=2)
            self._single_params.pack(side=tk.BOTTOM, pady=(10, 15))
            self._add_entry_param(self._single_params,
                                  "Minimum Distance Margin", self._mdm, 0,
                                  ParamType.FLOAT_POSITIVE.name)
            memory_label = tk.Label(self._single_params,
                                    text="Memory: ",
                                    bg=colours.BACKGROUND)
            memory_label.grid(row=1,
                              column=0,
                              sticky='w',
                              padx=(0, 10),
                              pady=5)
            memory_frame = tk.Frame(self._single_params)
            memory_frame.grid(row=1, column=1, pady=5, sticky='w')
            n_samples = self._data.shape[0]
            max_ = n_samples - 1
            self._memory.set(max_)
            self._memory_str.set(max_)
            self._memory_scale = ttk.Scale(memory_frame,
                                           from_=1,
                                           to=max_,
                                           value=max_,
                                           variable=self._memory,
                                           orient=tk.HORIZONTAL,
                                           command=self._accept_int_only,
                                           style='PLT.Horizontal.TScale')
            self._memory_scale.pack(side=tk.TOP)
            tk.Label(memory_frame, text="1").pack(side=tk.LEFT)
            tk.Label(memory_frame,
                     text=str(max_) + " (ALL)").pack(side=tk.RIGHT)
            memory_frame2 = tk.Frame(self._single_params)
            memory_frame2.grid(row=2, column=1, pady=5, sticky='ew')
            memory_entry = ttk.Entry(memory_frame2,
                                     width=7,
                                     textvariable=self._memory_str,
                                     validate="all",
                                     validatecommand=self._vcmd +
                                     ('ranged_int', ),
                                     style='PLT.TEntry')
            memory_entry.pack()

        self._load_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/load_76_30_03.png"))
        self._cancel_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/cancel_76_30_04.png"))

        # Final loading stuff
        final_frame = tk.Frame(self, background=colours.NAV_BAR)
        final_frame.pack(fill=tk.BOTH)
        final_btns_frame = tk.Frame(final_frame, background=colours.NAV_BAR)
        final_btns_frame.pack(anchor=tk.CENTER)
        final_btn = tk.Button(final_btns_frame,
                              command=self._final_load,
                              image=self._load_img,
                              relief='flat',
                              bd=0,
                              highlightbackground=colours.NAV_BAR,
                              highlightcolor=colours.NAV_BAR,
                              highlightthickness=0,
                              background=colours.NAV_BAR,
                              activebackground=colours.NAV_BAR)
        final_btn.grid(row=0, column=0, padx=5, pady=5)
        final_btn = tk.Button(final_btns_frame,
                              command=self._on_closing,
                              image=self._cancel_img,
                              relief='flat',
                              bd=0,
                              highlightbackground=colours.NAV_BAR,
                              highlightcolor=colours.NAV_BAR,
                              highlightthickness=0,
                              background=colours.NAV_BAR,
                              activebackground=colours.NAV_BAR)
        final_btn.grid(row=0, column=1, padx=5, pady=5)
Example #6
0
    def __init__(self, parent_window, q, exec_stopper):
        """Initializes the ProgressWindow widget object.

        :param parent_window: the window which this window widget will be stacked on top of.
        :type parent_window: `tkinter.Toplevel`
        :param q: the queue to be used for communication between the thread (`threading.Thread`) carrying
            out the execution of the experiment and the progress log (`tkinter.Listbox`) of this class.
        :type q: `queue.Queue`
        :param exec_stopper: an abort flag object used to abort the execution before completion
            if so instructed by the user.
        :type exec_stopper: :class:`pyplt.util.AbortFlag`
        """
        self._wait = False  # hack
        self._completed = False
        self._parent_window = parent_window
        self._queue = q
        self._exec_stopper = exec_stopper
        self._exec_thread = None

        tk.Toplevel.__init__(self, self._parent_window)
        img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, 'assets/plt_logo.png'))
        self.tk.call('wm', 'iconphoto', self._w, img)
        ws.disable_parent(self, self._parent_window, ws.Mode.OPEN_ONLY)
        ws.stack_window(self, self._parent_window)

        # set window size & position the window in centre of screen
        width = 600
        height = 450
        # get screen width and height
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        # calculate position x and y coordinates
        x = (screen_width / 2) - (width / 2)
        y = (screen_height / 2) - (height / 2)
        self.geometry('%dx%d+%d+%d' % (width, height, x, y))

        # remove window decorations (only for Windows OS)
        if os.name == 'nt':
            self.overrideredirect(True)
            self.after(10, self._setup_window)

        self.protocol("WM_DELETE_WINDOW", self._on_abort)
        self.title("Experiment Execution Progress")

        # ----- populate with remaining widgets -----
        self._main_frame = tk.Frame(self, bg=colours.PROGRESS_BACK)
        self._main_frame.pack(expand=True, fill=tk.BOTH)

        # title
        title_frame = tk.Frame(self._main_frame, bg=colours.PROGRESS_BACK)
        title_frame.grid(row=0, column=0, sticky='ew')
        tk.Label(title_frame,
                 text="Experiment Execution Progress",
                 font='Ebrima 12 bold',
                 fg='white',
                 bg=colours.PROGRESS_BACK).grid(row=0,
                                                column=0,
                                                sticky='w',
                                                padx=20,
                                                pady=20)

        # progress log Listbox
        log_frame = tk.Frame(self._main_frame,
                             bg=colours.PROGRESS_BACK,
                             padx=50)
        log_frame.grid(row=1, column=0, sticky='nsew')

        lg_frame = tk.Frame(log_frame, bd=2, relief='sunken')
        lg_frame.pack(expand=True, fill=tk.BOTH)

        self._log = tk.Listbox(lg_frame,
                               activestyle='none',
                               bg='white',
                               bd=0,
                               highlightthickness=0)

        # Listbox vertical scrollbar
        v_scroll = ttk.Scrollbar(lg_frame,
                                 orient="vertical",
                                 command=self._log.yview,
                                 style="White.PLT.Vertical.TScrollbar")
        v_scroll.pack(side='right', fill='y')
        self._log.configure(yscrollcommand=v_scroll.set)

        # Listbox horizontal scrollbar
        h_scroll = ttk.Scrollbar(lg_frame,
                                 orient="horizontal",
                                 command=self._log.xview,
                                 style="White.PLT.Horizontal.TScrollbar")
        h_scroll.pack(side='bottom', fill='x')
        self._log.configure(xscrollcommand=h_scroll.set)

        self._log.pack(expand=True, fill=tk.BOTH, padx=(2, 0), pady=(1, 0))

        self._report_img = tk.PhotoImage(file=os.path.join(
            ROOT_PATH, "assets/buttons/generate_report_128_30_01_white.png"))
        self._abort_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/abort_76_30_01.png"))
        self._close_img = tk.PhotoImage(
            file=os.path.join(ROOT_PATH, "assets/buttons/close_76_30_01.png"))

        # bottom area
        self._bottom_frame = tk.Frame(self._main_frame,
                                      bg=colours.PROGRESS_BACK)
        self._bottom_frame.grid(row=2, column=0, sticky='ew')

        # progress bar
        self._progress_bar = ttk.Progressbar(
            self._bottom_frame,
            mode='indeterminate',
            style="PLT.Horizontal.TProgressbar")
        self._progress_bar.pack(side=tk.LEFT,
                                expand=True,
                                fill=tk.X,
                                padx=20,
                                pady=20)

        # abort button
        self._abort_btn = tk.Button(self._bottom_frame,
                                    command=self._on_abort,
                                    image=self._abort_img,
                                    relief='flat',
                                    bd=0,
                                    highlightbackground=colours.PROGRESS_BACK,
                                    highlightcolor=colours.PROGRESS_BACK,
                                    highlightthickness=0,
                                    background=colours.PROGRESS_BACK,
                                    activebackground=colours.PROGRESS_BACK)
        self._abort_btn.pack(side=tk.RIGHT, padx=20, pady=20)

        # configure sizes
        self._main_frame.grid_columnconfigure(0, weight=1)
        self._main_frame.grid_rowconfigure(1, weight=1)

        # start progress bar
        self._progress_bar.start()
        # initialize the progress log
        self.log("Commenced executing experiment.")

        # init report variables
        self._experiment = None
        self._time_info = None
        self._data_info = None
        self._preproc_info = None
        self._fs_info = None
        self._fs_algo_info = None
        self._fs_eval_info = None
        self._pl_algo_info = None
        self._pl_eval_info = None
        self._eval_metrics = None
        self._fold_metrics = None
        self._shuffle_info = None

        # start polling
        self._poll()