예제 #1
0
 def __init__(self, parent, controller):
     tk.Frame.__init__(self, parent)
     df = self.get_cryptocurrency()
     tb_m = TableModel(dataframe=df)
     table = Table(self, model=tb_m)
     table.show()
     table.redraw()
예제 #2
0
 def __init__(self, parent, controller):
     tk.Frame.__init__(self, parent)
     df = self.get_history()
     tb_m = TableModel(dataframe=df)
     table = Table(self, model=tb_m)
     table.show()
     #alter the DataFrame in some way, then update
     table.redraw()
예제 #3
0
def open_file():
    file = filedialog.askopenfilename(
        initialdir="/home/pi/Desktop/AutomatedCableTester",
        title="Select file",
        filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
    if len(file) != 0 and ".csv" in file:
        t = tk.Toplevel()
        pt = Table(t)
        pt.importCSV(file)
        pt.redraw()
        pt.show()
예제 #4
0
class Standings(tk.Frame):
    def __init__(self, df, parent=None):
        self.parent = parent
        tk.Frame.__init__(self)
        self.main = self.master
        f = tk.Frame(self.main)
        f.pack(fill=tk.BOTH, expand=1)
        self.table = Table(f, dataframe=df, read_only=True, showstatusbar=True)
        self.table.show()

    def update(self, standings) -> None:
        self.table.updateModel(TableModel(standings))
        self.table.redraw()
예제 #5
0
class DataPanel():
    def __init__(self, root):
        self.frame3 = Tk.Frame(root)
        self.frame3.__init__()
        self.frame3.pack(fill=Tk.BOTH, expand=1)
        df = pandas.DataFrame()
        self.table = Table(self.frame3,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)
        self.table.show()

    def update(self, file_path):

        self.table.importCSV(file_path)
        self.table.redraw()
예제 #6
0
def Table_It():
    All_Data = requests.get("https://api.covid19api.com/summary")
    All_Data = All_Data.json()
    All_Data = All_Data["Countries"]
    countries = []
    Tot_Case5 = []
    Tot_Case7 = []
    Tot_Case9 = []
    Tot_Case11 = []
    for i in All_Data:
        countries.append(i["Country"])
    for i in All_Data:
        Tot_Case5.append(i["TotalConfirmed"])
    for i in All_Data:
        Tot_Case7.append(i["TotalDeaths"])
    for i in All_Data:
        Tot_Case9.append(i["TotalRecovered"])
    for i in All_Data:
        Tot_Case11.append(i["Date"])
    frame = Frame(pencere)
    frame.place(x=1000, y=0, height=652, width=900)
    df1 = {
        "Country": countries,
        "Confirmed": Tot_Case5,
        "Deaths": Tot_Case7,
        "Recovered": Tot_Case9,
        "Date": Tot_Case11
    }
    df = DataFrame(df1)
    table = Table(frame, dataframe=df)

    table.columncolors["Confirmed"] = "#ff6666"
    table.columncolors["Deaths"] = "#8c8c8c"
    table.columncolors["Recovered"] = "#94ff9b"
    table.redraw()

    table.show()
예제 #7
0
def show_details():
    # declares that showing will refer to the global variable mentioned above instead of to a local variable for this function
    global showing

    # toggles on or off by testing whether or not the details are already showing
    if showing == False:
        # flips the switch to on.
        showing = True

        # declares all of these future variables as global ones so they can be refered to the next time the function runs.
        global dt
        # Simply creates a block of text and appends it to the Mainframe(See below for more details) for each variable.
        # .grid just forces a positon for the newly created label.
        dt = Table(mainframe, dataframe=StockQuotesCall())
        dt.grid(column=10, row=0, sticky=(N, W, E, S))
        dt.show()
        dt.redraw()

    else:
        # No matter what I use, dt.close(), dt.grid_forget, dt.pack_forget, dt.pack_remove, dt.grid_remove, dt.destroy, none of them works properly with the table.
        # Must be mod error
        showing = False
        #
        dt.grid_forget()
예제 #8
0
class DataFrame(tk.Frame):
    label = "View Data"

    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.columnconfigure(index=0, weight=1)
        self.rowconfigure(index=1, weight=1)

        self.create_widgets()

    def show(self):
        self.tkraise()

    def create_widgets(self):
        # Create buttons to manage the DB.
        self.toolbar = tk.Frame(self)
        self.toolbar.grid(row=0, column=0, padx=12, pady=3, sticky="NSEW")
        for col in range(12):
            self.toolbar.columnconfigure(index=col, weight=1)

        self.save_button = tk.Button(
            self.toolbar, text="Save Data To DB", command=self.save_to_db)
        self.export_button = tk.Button(
            self.toolbar, text="Export Data to File", command=self.export_data)
        self.import_button = tk.Button(
            self.toolbar, text="Import Data from CSV", command=self.import_csv)
        self.refresh_button = tk.Button(
            self.toolbar, text="Refresh Data from DB", command=self.refresh_table_data)

        self.save_button.grid(row=0, column=12)
        self.export_button.grid(row=0, column=11)
        self.import_button.grid(row=0, column=10)
        self.refresh_button.grid(row=0, column=9)

        self.table_container = tk.Frame(self)
        self.table_container.grid(row=1, column=0, sticky="NSEW")
        # Create table to display data
        data_df = DataStore.data

        self.data_table = Table(self.table_container, dataframe=data_df)
        self.data_table.autoResizeColumns()
        self.data_table.show()

    def refresh_table_data(self):
        res = tkMessageBox.askyesno(title="Are you sure you want to refresh the DB.",
                                    message="Are you sure that you want to refresh the DB.\n"
                                    "This will undo any changes that you made before saving your data. This includes CSV file that you have imported")

        if res == tkMessageBox.NO:
            return

        data_df = get_db_data()

        DataStore.data = data_df
        self.data_table.updateModel(TableModel(data_df))
        self.data_table.redraw()

    def export_data(self):
        output_file = tkFileDialog.askopenfilename()
        if not output_file:
            tkMessageBox.showerror(title="Export Failed",
                                   message="Export failed as no file was selected.")
            return

    def save_to_db(self):
        add_df_to_db(DataStore.data)

    def import_csv(self):
        # Get file to import
        input_file = tkFileDialog.askopenfilename()
        if not input_file.strip():
            tkMessageBox.showerror(title="Import Failed",
                                   message="Import failed as no file was selected.")
            return

        try:
            import_df = pd.read_csv(input_file)
        except ParserError:
            tkMessageBox.showerror(
                "The supplied file is not a valid CSV file, could not import.")

        if len(import_df) > 0:
            # Data was loaded.
            DataStore.data.reset_index(level=["id_product"], inplace=True)
            table_df = DataStore.data.append(import_df, ignore_index=False)
            table_df.set_index("id_product", inplace=True)

            DataStore.data = table_df
            self.data_table.updateModel(TableModel(table_df))
            self.data_table.redraw()

            tkMessageBox.showinfo(title="Import Successful",
                                  message="Import Completed Successfully!")
        else:
            tkMessageBox.showinfo(title="Import Failed",
                                  message="Input file did not have any CSV data so no data was added.")
예제 #9
0
def run_algo():
    print("run")
    global node_file, edge_file

    node_file = pd.read_csv(ent_node_loc.get())
    edge_file = pd.read_csv(ent_edge_loc.get())
    sample_size = int(ent_sample_size.get()) / 100

    adjacency_list = fileProcessor(edge_file, node_file)
    edge_list = adjtoedgelist(adjacency_list)

    global n
    n = len(adjacency_list)
    m = len(edge_list)

    print("Original Graph")
    print("len of al = ", n)
    print("len of el = ", m)

    rnAdj, rnEdge = randomNode(adjacency_list, sample_size)
    reAdj, reEdge = randomEdge(edge_list, sample_size)
    rwAdj, rwEdge = randomWalk(adjacency_list, sample_size)

    org = dig(adjacency_list)
    re = dig(reAdj)
    rn = dig(rnAdj)
    rw = dig(rwAdj)

    frm_dist = tk.Frame(frm_preview)
    frm_dist.pack(expand=tk.TRUE, fill=tk.BOTH)

    dist.clear()
    canvas = FigureCanvasTkAgg(fig, frm_dist)

    dist.plot(list(org.keys()), list(org.values()), label='Original Graph')
    dist.plot(list(rn.keys()), list(rn.values()), label="Random Node")
    dist.plot(list(re.keys()), list(re.values()), label="Random Edge")
    dist.plot(list(rw.keys()), list(rw.values()), label="Random Walk")
    dist.set_title("Smaple size : " + str(sample_size))
    dist.set_xlabel("Degree")
    dist.set_ylabel("Number of nodes")
    fig.legend(loc='upper right')
    canvas.draw()
    canvas.get_tk_widget().pack(side=tk.TOP, expand=tk.TRUE, fill=tk.BOTH)

    toolbar = NavigationToolbar2Tk(canvas, frm_dist)
    toolbar.update()
    canvas._tkcanvas.pack(side=tk.TOP, expand=tk.TRUE, fill=tk.BOTH)

    ## Generating reports

    g = {}
    # algorithms = ["Original graph","Random Node", "Random Edge", "Random Walk"]
    g["Original graph"] = (adjacency_list, edge_list)
    g["Random Node"] = (rnAdj, rnEdge)
    g["Random Edge"] = (reAdj, reEdge)
    g["Random Walk"] = (rwAdj, rwEdge)

    total_node = {}
    total_edge = {}
    max_degree = {}
    min_degree = {}
    avg_degree = {}

    for gr in g:
        adj, edge = g[gr]
        total_node[gr] = len(adj)
        total_edge[gr] = len(edge)
        d = cal_degree(adj)
        max_degree[gr] = max(d.values())
        min_degree[gr] = min(d.values())
        avg_degree[gr] = sum(list(d.values())) / len(d.values())
        # print("d : ", d)
        # print("avg_degree ", gr, " : ", avg_degree[gr])
        # print(gr, " -- ", len(adj), " -- ", len(edge))
    report["Total Nodes"] = report['Algorithm'].map(total_node)
    report["Total Edges"] = report['Algorithm'].map(total_edge)
    report["Average_Degree"] = report['Algorithm'].map(avg_degree)
    report["Maximum_Degree"] = report['Algorithm'].map(max_degree)
    report["Minimum_Degree"] = report['Algorithm'].map(min_degree)

    lbl_res = tk.LabelFrame(frm_result, text="Result")
    lbl_res.pack(expand=tk.TRUE, fill=tk.BOTH)

    pt = Table(lbl_res, dataframe=report)
    pt.show()
    pt.autoResizeColumns()
    pt.redraw()
class JobSearch:
    def __init__(self, tk_parent, linkedin_conn):

        self.parent = tk_parent
        self.linkedin_conn = linkedin_conn

        self.search_results_df = pd.DataFrame()
        self.search_thread = None
        self.quick_search = True

        # Paned Window
        self.search_paned_window = ttk.PanedWindow(tk_parent, orient='horizontal')
        self.search_paned_window.pack(side='top', fill="both", expand=True, padx=10)

        ## Search fields Canvas/ScrolledFrame
        search_fields_canvas = ttk.Canvas(self.search_paned_window)

        search_fields_frame = ScrolledFrame(search_fields_canvas)
        search_fields_frame.pack(side='top', fill='both', expand=True, padx=5)
        search_fields_frame.hide_scrollbars()

        ### Load/Save search
        load_save_btn_frame = ttk.Frame(search_fields_frame)
        load_save_btn_frame.pack(pady=5, side='top', fill="x")

        load_search_btn = ttk.Button(load_save_btn_frame, text="Load param.")
        load_search_btn.pack(side='left')
        load_search_btn['command'] = self.load_search_config

        save_search_btn = ttk.Button(load_save_btn_frame, text="Save param.")
        save_search_btn.pack(side='right', padx=10)
        save_search_btn['command'] = self.save_search_config

        ### KW-Frame
        kw_frame = ttk.Frame(search_fields_frame)
        kw_frame.pack(pady=5, side='top', fill="x")
        ttk.Label(kw_frame, text="Keywords").pack(side='left')
        self.entry_keywords = ttk.Entry(kw_frame)
        self.entry_keywords.pack(side='left', padx=10, fill='x', expand=True)

        ttk.Separator(search_fields_frame, orient='horizontal').pack(side='top', fill='x', pady=5)
        
        ### Radio Frame
        radio_frame = ttk.Frame(search_fields_frame)
        radio_frame.pack(side='top', fill="x", pady=5, expand=True)
        radio_frame.grid_columnconfigure(0,weight=0)
        radio_frame.grid_columnconfigure(1,weight=0)
        radio_frame.grid_columnconfigure(2,weight=1)

        #### Sort by
        ttk.Label(radio_frame, text="Sort by").grid(row=0, column=0, sticky='nwse')

        self.sort_by = ttk.StringVar(value="R")
        ttk.Radiobutton(radio_frame, text='Most recent', variable=self.sort_by, value="DD").grid(row=0, column=1, padx=10, sticky='nwse')
        ttk.Radiobutton(radio_frame, text='Most relevant', variable=self.sort_by, value="R").grid(row=0, column=2, padx=10, sticky='nwse')

        ttk.Separator(radio_frame, orient='horizontal').grid(row=1, columnspan=3, pady=5, sticky='nwse')

        #### Date Posted
        ttk.Label(radio_frame, text="Date Posted").grid(row=2, column=0, sticky='nwse', pady=5)

        self.date_posted = ttk.IntVar(value=365) # Days since job was posted
        ttk.Radiobutton(radio_frame, text='Past 24h', variable=self.date_posted,
                        value=1).grid(row=3, column=1, padx=10, pady=4, sticky='nwse')
        ttk.Radiobutton(radio_frame, text='Past Week', variable=self.date_posted,
                        value=7).grid(row=3, column=2, padx=10, pady=4, sticky='nwse')
        ttk.Radiobutton(radio_frame, text='Past Month', variable=self.date_posted,
                        value=30).grid(row=4, column=1, padx=10, pady=4, sticky='nwse')
        ttk.Radiobutton(radio_frame, text='Any Time', variable=self.date_posted,
                        value=365).grid(row=4, column=2, padx=10, pady=4, sticky='nwse')

        ttk.Separator(search_fields_frame, orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Experience
        exp_frame = ttk.Frame(search_fields_frame)
        exp_frame.pack(side='top', fill="x")
        exp_frame.grid_columnconfigure(0,weight=0)
        exp_frame.grid_columnconfigure(1,weight=0)
        exp_frame.grid_columnconfigure(2,weight=1)
        ttk.Label(exp_frame, text="Experience").grid(row=0, column=0, pady=4, sticky='nwse')

        intern_lvl_bool = ttk.BooleanVar()
        entry_lvl_bool = ttk.BooleanVar()
        associate_bool = ttk.BooleanVar()
        mid_senior_bool = ttk.BooleanVar()
        director_bool = ttk.BooleanVar()
        executive_bool = ttk.BooleanVar()

        self.exp_dict_list = [
                {'bool_val': intern_lvl_bool, 'name': '1'},
                {'bool_val': entry_lvl_bool, 'name': '2'},
                {'bool_val': associate_bool, 'name': '3'},
                {'bool_val': mid_senior_bool, 'name': '4'},
                {'bool_val': director_bool, 'name': '5'},
                {'bool_val': executive_bool, 'name': '6'},
        ]

        ttk.Checkbutton(exp_frame, text="Internship",
                variable=intern_lvl_bool).grid(row=1, column=0, padx=5, pady=4, sticky='nwse')
        ttk.Checkbutton(exp_frame, text="Entry level",
                variable=entry_lvl_bool).grid(row=1, column=1, padx=5, pady=4, sticky='nwse')
        ttk.Checkbutton(exp_frame, text="Associate",
                variable=associate_bool).grid(row=1, column=2, padx=5, pady=4, sticky='nwse')
        ttk.Checkbutton(exp_frame, text="Mid-Senior level",
                variable=mid_senior_bool).grid(row=2, column=0, padx=5, pady=4, sticky='nwse')
        ttk.Checkbutton(exp_frame, text="Director",
                variable=director_bool).grid(row=2, column=1, padx=5, pady=4, sticky='nwse')
        ttk.Checkbutton(exp_frame, text="Executive",
                variable=executive_bool).grid(row=2, column=2, padx=5, pady=4, sticky='nwse')

        ttk.Separator(search_fields_frame, orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Company frame
        self.comp_frame = SearchFrame(search_fields_frame, title='Company',
                    fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(linkedin_conn[0].get_company_urn_ids, x))
        self.comp_frame.pack(side='top', fill="x")

        ttk.Separator(search_fields_frame, orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Job Type
        job_type_frame = ttk.Frame(search_fields_frame)
        job_type_frame.pack(side='top', fill="x")
        job_type_frame.grid_columnconfigure(0,weight=0)
        job_type_frame.grid_columnconfigure(1,weight=0)
        job_type_frame.grid_columnconfigure(2,weight=1)
        ttk.Label(job_type_frame, text="Job Type").grid(row=0, column=0, pady=4, sticky='nwse')

        full_time_bool = ttk.BooleanVar()
        part_time_bool = ttk.BooleanVar()
        temporary_bool = ttk.BooleanVar()
        contract_bool = ttk.BooleanVar()
        volunteer_bool = ttk.BooleanVar()
        intern_type_bool = ttk.BooleanVar()
        other_type_bool = ttk.BooleanVar()

        self.job_type_dict_list = [
                {'bool_val': full_time_bool, 'name': 'F'},
                {'bool_val': part_time_bool, 'name': 'P'},
                {'bool_val': temporary_bool, 'name': 'T'},
                {'bool_val': contract_bool, 'name': 'C'},
                {'bool_val': volunteer_bool, 'name': 'V'},
                {'bool_val': intern_type_bool, 'name': 'I'},
                {'bool_val': other_type_bool, 'name': 'O'},
        ]

        ttk.Checkbutton(job_type_frame, text="Other",
                variable=other_type_bool).grid(row=0, column=2, padx=10, pady=4, sticky='nwse')
        ttk.Checkbutton(job_type_frame, text="Full-time",
                variable=full_time_bool).grid(row=1, column=0, padx=10, pady=4, sticky='nwse')
        ttk.Checkbutton(job_type_frame, text="Part-time",
                variable=part_time_bool).grid(row=1, column=1, padx=10, pady=4, sticky='nwse')
        ttk.Checkbutton(job_type_frame, text="Temporary",
                variable=temporary_bool).grid(row=1, column=2, padx=10, pady=4, sticky='nwse')
        ttk.Checkbutton(job_type_frame, text="Contract",
                variable=contract_bool).grid(row=2, column=0, padx=10, pady=4, sticky='nwse')
        ttk.Checkbutton(job_type_frame, text="Volunteer",
                variable=volunteer_bool).grid(row=2, column=1, padx=10, pady=4, sticky='nwse')
        ttk.Checkbutton(job_type_frame, text="Internship",
                variable=intern_type_bool).grid(row=2, column=2, padx=10, pady=4, sticky='nwse')
        
        ttk.Separator(search_fields_frame, orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Location Fallback
        self.loc_fallback_frame = SearchFrame(search_fields_frame, title='General Location', single_choice=True,
                    fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(linkedin_conn[0].get_geo_urn_ids, x),
                    tooltip="Restrict the geographical area of the results. In the browser, your location will be recognized automatically and shown at the top of the search page close to the keyword field.")
        self.loc_fallback_frame.pack(side='top', fill="x")

        ### Location Frame
        self.loc_frame = SearchFrame(search_fields_frame, title='Location',
                    fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(linkedin_conn[0].get_geo_urn_ids, x))
        self.loc_frame.pack(side='top', fill="x")

        ttk.Separator(search_fields_frame, orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Industry frame
        self.industry_frame = SearchFrame(search_fields_frame, title='Industry',
                    fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(linkedin_conn[0].get_industry_urn_ids, x))
        self.industry_frame.pack(side='top', fill="x", pady=5)

        self.search_paned_window.add(search_fields_canvas)

        ## Table frame
        self.table_main_frame = ttk.Frame(tk_parent)
        # pandastable
        self.table_frame = ttk.Frame(self.table_main_frame, bootstyle="secondary", borderwidth=2)
        self.table_frame.pack(side="top", fill="both", expand=True)
        self.table = Table(self.table_frame, dataframe=pd.DataFrame(), showtoolbar=False, showstatusbar=True)
        utils.fit_table_style_to_theme(self.table, ttk.Style())
        self.table.unbind_all("<Tab>")
        self.table.unbind_all("<Return>")
        self.table.show()

        self.search_paned_window.add(self.table_main_frame)

        # Buttons frame
        btn_frame = ttk.Frame(tk_parent)
        btn_frame.pack(padx=10, pady=10, side='top', fill="x")

        quick_search_btn = ttk.Button(btn_frame, text="Quick search")
        quick_search_btn.pack(side='left', padx=10)
        quick_search_btn['command'] = self.start_quick_search
        ToolTip(quick_search_btn, "This is a single request that will yield the same results as in the linkedin search bar. \
\nIt doesn't contain any personal details (only public IDs) \
\nYou're not likely to reach any search limit using this mode.")


        btn_sub_frame = ttk.Frame(btn_frame)
        btn_sub_frame.pack(side="left", fill="none", expand=True)

        start_search_btn = ttk.Button(btn_sub_frame, text="Deep Search", bootstyle='danger')
        start_search_btn.pack(side='left', padx=10)
        start_search_btn['command'] = self.start_deep_search
        ToolTip(start_search_btn, "Each search result will be fetched for additional information. \
            \nDepending on the number of results and search frequency, this can trigger the linkedin limit \
after which you'll only be able to get 3 results per search until the end of the month.")

        # self.get_contact_info = ttk.BooleanVar()
        # contact_info_chk_btn = ttk.Checkbutton(btn_sub_frame, text="Fetch contact info",
        #                             variable=self.get_contact_info, bootstyle="danger")
        # contact_info_chk_btn.pack(side='left', padx=10)
        # ToolTip(contact_info_chk_btn, text=f"Fetch contact info by running one additional request per result.")

        self.export_to_file_btn = ttk.Button(btn_frame, text="Export to File", state="disabled")
        self.export_to_file_btn.pack(side='left', padx=10)
        self.export_to_file_btn['command'] = self.prepare_dataframe_and_save_to_xsl

        # Status frame
        self.status_frame = ttk.Frame(tk_parent)
        self.status_frame.pack(padx=10, pady=2, side='bottom', expand=False, fill="x")
        self.status_str = ttk.StringVar(value="")
        ttk.Label(self.status_frame, textvariable=self.status_str).pack(side='left', expand=False)

        ttk.Separator(tk_parent, orient='horizontal').pack(side='bottom', fill='x')

    def save_search_config(self):
        chosen_file = filedialog.asksaveasfile(mode='w', filetypes=[("JSON", ".json")], defaultextension=".json")
        if chosen_file is None:
            return
        config_dict = {
            'job_search' : {
                'keywords': self.entry_keywords.get(),
                'sort_by' : self.sort_by.get(),
                'listed_at' : 24 * 3600 * self.date_posted.get(),
                'experience' : [x['name'] for x in self.exp_dict_list if x['bool_val'].get()],
                'companies' : [[x.lbl_name.get(), x.value] for x in self.comp_frame.get_current_selection()],
                'job_type' : [x['name'] for x in self.job_type_dict_list if x['bool_val'].get()],
                'location' : [[x.lbl_name.get(), x.value] for x in self.loc_frame.get_current_selection()],
                'industries' : [[x.lbl_name.get(), x.value] for x in self.industry_frame.get_current_selection()]
            }
        }
        with open(chosen_file.name, 'w') as f:
            json.dump(config_dict, f, indent=4)
        
        self.status_str.set(f"Search config successfully saved at {chosen_file.name}!")

    def load_search_config(self):
        chosen_file = filedialog.askopenfile(mode='r', filetypes=[("JSON", ".json")], defaultextension=".json")
        if chosen_file is None:
            return
        try:
            with open(chosen_file.name, 'r') as f:
                config_dict = json.load(f)
            config = config_dict['job_search']
        except:
            self.status_str.set(f"Please select a valid job search configuration!")

        self.entry_keywords.delete(0,'end')
        self.entry_keywords.insert(0, config['keywords'])
        self.sort_by.set(config['sort_by'])
        self.date_posted.set(config['listed_at']//(24 * 3600))

        utils.set_bools_from_list(self.exp_dict_list, config['experience'])
        self.comp_frame.load_name_val_from_list(config['companies'])
        utils.set_bools_from_list(self.job_type_dict_list, config['job_type'])
        self.loc_frame.load_name_val_from_list(config['location'])
        self.industry_frame.load_name_val_from_list(config['industries'])

        self.status_str.set(f"Config loaded succesfully!")        


    def run_search(self):
        self.search_results_df = pd.DataFrame()
        self.table.updateModel(TableModel(self.search_results_df))
        self.table.redraw()
        self.status_str.set("Running search...")
        self.parent.update()
        loc_fallback = None
        if self.loc_fallback_frame.get_current_selection():
            loc_fallback = self.loc_fallback_frame.get_current_selection()[0].lbl_name.get()
        
        try:
            # see doc under https://linkedin-api.readthedocs.io/en/latest/api.html
            search_result = self.linkedin_conn[0].search_jobs(
                    keywords=self.entry_keywords.get(),
                    sort_by=self.sort_by.get(),
                    listed_at=24 * 3600 * self.date_posted.get(),
                    companies=[x.value for x in self.comp_frame.get_current_selection()],
                    experience=[x['name'] for x in self.exp_dict_list if x['bool_val'].get()],
                    job_type=[x['name'] for x in self.job_type_dict_list if x['bool_val'].get()],
                    location_name = loc_fallback,
                    geo_urn_ids=[x.value for x in self.loc_frame.get_current_selection()],
                    industries=[x.value for x in self.industry_frame.get_current_selection()],
                )

            if self.quick_search:
                self.search_results_df = pd.DataFrame(search_result)
                try:
                    self.search_results_df.drop(['dashEntityUrn', '$recipeTypes', '$type'],
                                 axis=1, inplace=True)
                    self.search_results_df['companyDetails'] = self.search_results_df['companyDetails'].apply(
                            lambda x: x.get('company', '').rsplit(':', 1)[-1]
                    )
                    self.search_results_df.rename(columns={'companyDetails': 'companyUrn'}, inplace=True)
                    self.search_results_df['entityUrn'] = self.search_results_df['entityUrn'].str.rsplit(':', 1, expand=True)[1]
                    self.search_results_df['listedAt'] = self.search_results_df['listedAt'].apply(
                                                            lambda x : datetime.fromtimestamp(x/1000).date()
                    )
                except Exception as e:
                    print(repr(e))
                self.table.updateModel(TableModel(self.search_results_df))
                self.table.redraw()

            else:
                result_size = len(search_result)
                self.status_str.set("Found " + str(result_size) + " results! Searching jobs details... This can take a while...")
                self.parent.update()

                if result_size > 999:
                    answer_is_yes = messagebox.askyesno("Too many results!",
                            "This search yields more than 1000 results (upper limit for this app).\nProceed anyway?",
                            icon="warning")
                    if not answer_is_yes:
                        self.status_str.set("Search cancelled.")
                        self.parent.update()
                        return

                row = 1

                for job in search_result:
                    job_obj = self.linkedin_conn[0].get_job(job['dashEntityUrn'].rsplit(':',1)[1])
                    if job_obj != {}:

                        job_dict = {
                            'Title': job_obj['title'],
                            'Company': job_obj['companyDetails']
                                             .get('com.linkedin.voyager.deco.jobs.web.shared.WebCompactJobPostingCompany', {},
                                            ).get('companyResolutionResult', {}
                                            ).get('name', ''),
                            'Location': job_obj['formattedLocation'],
                            'Description': job_obj.get('description', {}).get('text', ''),
                            #'Remote': job_obj['workRemoteAllowed'],
                            'Work Place': job_obj.get('workplaceTypesResolutionResults', {})
                                            .get('urn:li:fs_workplaceType:1', {})
                                            .get('localizedName', ''),
                            'Posted On': datetime.fromtimestamp(job_obj['listedAt']/1000).date(),
                            'LinkedIn Link': f"https://www.linkedin.com/jobs/view/{job_obj['jobPostingId']}",
                            'Direct Link': job_obj.get('applyMethod',{})
                                                 .get('com.linkedin.voyager.jobs.OffsiteApply', {}
                                                ).get('companyApplyUrl', '').split('?', 1)[0]
                        }

                        # if self.get_contact_info.get():
                        #     contact_info = self.linkedin_conn[0].get_profile_contact_info(urn_id=job['urn_id'])
                        #     contact_info = {k: [v] for k,v in contact_info.items()}
                        #     job_dict.update(contact_info)
                        
                        self.search_results_df = pd.concat([self.search_results_df,
                                                pd.DataFrame([job_dict.values()], columns=job_dict.keys())])

                        self.table.updateModel(TableModel(self.search_results_df))
                        self.table.redraw()
                        self.status_str.set("Scanned " + str(row) + " out of " + str(result_size) + " profiles")
                        self.parent.update()

                        row += 1

            self.export_to_file_btn.configure(state="normal")
            self.status_str.set("Done")
            self.parent.update()
        except Exception as e:
            utils.show_exception(e)
            self.status_str.set("Something went wrong! Check console output for more details.")
            self.parent.update()


    def create_search_thread(self):
        if not self.linkedin_conn[0]:
            messagebox.showinfo("Error", "First log into Linkedin!", icon="error")
            return
        if self.search_thread and self.search_thread.is_alive():
            messagebox.showinfo("Search in progress",
                        "Another search is still running.\nWait until it finishes or restart the program.",
                        icon="warning")
            return
        self.search_thread = threading.Thread(target=self.run_search)
        self.search_thread.daemon = True
        self.search_thread.start()

    def start_quick_search(self):
        self.quick_search = True
        self.create_search_thread()

    def start_deep_search(self):
        self.quick_search = False
        self.create_search_thread()

    def prepare_dataframe_and_save_to_xsl(self):
        self.status_str.set("Exporting to File...")
        export_file = utils.save_dataframe_to_file(self.search_results_df)

        if export_file is not None:
            self.status_str.set("Table saved under " + export_file)
        else:
            self.status_str.set("Table could not be saved!")
예제 #11
0
class CallScreenerOptions(tk.ttk.Frame):
    def __init__(self, root):
        super().__init__()
        self.tk_root = root
        self.close_button = None
        self.status_label = None
        self.call_screener_frame = None
        self.popup_expiration_menu = None
        self.expiration_var = tk.StringVar(self)
        self.otm_strike_var = tk.StringVar(self)
        self.otm_list = ["15%", "5%", "ATM", "10%", "20%"]

        self.request_queue = Queue()
        self.response_queue = Queue()

        self.status_var = tk.StringVar(self)

        self.init_ui()
        self.logger = self.create_logger()
        # self.web = FinanceWeb(self.logger)

        self.options_db = FinanceDB()
        self.options_db.initialize()
        self.companies = OptionsScreenerWatch()
        self.init_table()
        self.clear_expiration_menu()
        self.clear_otm_strike_menu()
        config = OptionsConfiguration()
        look_a_heads = (
            config.get_configuration())["screener_look_ahead_expirations"]
        expiration_list = self.get_expirations(look_a_heads)
        self.update_expiration(expiration_list)
        self.expiration_var.set(expiration_list[0])
        self.update_otm_strike(self.otm_list)
        self.otm_strike_var.set(self.otm_list[0])
        self.temp()
        self.options_fetch = OptionsFetch(self.request_queue,
                                          self.response_queue, self.logger)
        self.options_fetch.start()
        self.update_options()

        self.tk_root.protocol("WM_DELETE_WINDOW", self.quit_app)

    @staticmethod
    def get_expirations(count):
        expiration_date = datetime.datetime.now()
        result = []
        while count > 0:
            date_str = expiration_date.strftime('%Y-%m-%d')
            (is_third_friday, date_time) = Utilities.is_third_friday(date_str)
            if is_third_friday:
                result.append(date_time.strftime('%Y-%m-%d'))
                count -= 1
            expiration_date += datetime.timedelta(days=1)
        return result

    # noinspection PyUnusedLocal
    def quit_app(self, event=None):
        print("Exit command")
        with self.request_queue.mutex:
            self.request_queue.queue.clear()

        self.request_queue.put("QUIT")
        self.options_fetch.join()
        sys.exit()

    def clear_call_screener_frame(self):
        for widget in self.call_screener_frame.winfo_children():
            widget.destroy()

    def create_logger(self):
        # noinspection SpellCheckingInspection
        log_format = "%(asctime)s %(levelname)s %(module)s - %(funcName)s: %(message)s"
        date_fmt = "%m-%d %H:%M"

        for handler in logging.root.handlers[:]:
            logging.root.removeHandler(handler)

        logging.basicConfig(filename="screen_options.log",
                            level=logging.INFO,
                            filemode="w",
                            format=log_format,
                            datefmt=date_fmt)

        stream_handler = logging.StreamHandler(sys.stderr)
        stream_handler.setFormatter(
            logging.Formatter(fmt=log_format, datefmt=date_fmt))

        logger = logging.getLogger("screen_options")
        logger.addHandler(stream_handler)
        logger.setLevel(logging.DEBUG)

        return logger

    def init_ui(self):
        self.master.title("Option Screener")

        # frame2 = Frame(self, relief=RAISED, borderwidth=1, style='My.TFrame')
        tool_bar = tk.ttk.Frame(self, relief=tk.RAISED, borderwidth=1)
        tool_bar.pack(fill=tk.X, side=tk.TOP, expand=False)

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

        start_date_label = tk.ttk.Label(tool_bar, text="Expiration")
        start_date_label.pack(side=tk.LEFT, padx=5, pady=5)

        self.popup_expiration_menu = tk.OptionMenu(tool_bar,
                                                   self.expiration_var, *{''})
        self.popup_expiration_menu.config(width=16)
        self.popup_expiration_menu.pack(side=tk.LEFT, padx=5, pady=5)
        self.expiration_var.trace('w', self.expiration_var_selection_event)

        otm_label = tk.ttk.Label(tool_bar, text="OTM Strike delta (%)")
        otm_label.pack(side=tk.LEFT, padx=10, pady=5)

        self.otm_strike_menu = tk.OptionMenu(tool_bar, self.otm_strike_var,
                                             *{''})
        self.otm_strike_menu.config(width=10)
        self.otm_strike_menu.pack(side=tk.LEFT, padx=5, pady=5)
        self.otm_strike_var.trace('w', self.otm_strike_var_selection_event)

        self.close_button = tk.ttk.Button(tool_bar, text="Close")
        self.close_button.pack(side=tk.RIGHT, padx=5, pady=5)
        self.close_button.bind('<Button-1>', self.quit_app)

        tool_bar_style = Style()
        tool_bar_style.theme_use("default")
        tool_bar_style.configure('My.TFrame', background='lightsteelblue')

        self.call_screener_frame = tk.ttk.Frame(self,
                                                relief=tk.RAISED,
                                                borderwidth=1)
        self.call_screener_frame.pack(fill=tk.BOTH, side=tk.TOP, expand=True)

        self.status_var.set("Status")
        self.status_label = tk.ttk.Label(self,
                                         textvariable=self.status_var,
                                         background="lightsteelblue")
        self.status_label.pack(side=tk.BOTTOM,
                               fill=tk.X,
                               expand=False,
                               ipadx=10,
                               ipady=5)

    # noinspection PyAttributeOutsideInit
    def init_table(self):
        table_dict = {}
        for company in self.companies.get_companies():
            table_dict[company["symbol"]] = [
                company["symbol"], math.nan, math.nan, math.nan, math.nan,
                math.nan, math.nan, math.nan, math.nan, math.nan, math.nan
            ]

        self.data_frame = pd.DataFrame.from_dict(
            table_dict,
            orient='index',
            columns=[
                'Ticker', 'Stock Price', 'Strike', '%(OTM)', 'Bid', 'Ask',
                'ROI(%) (Bid/Stock Price)', 'Annual ROI(%)',
                'Implied Volatility', 'Delta', 'Theta'
            ])
        self.table = Table(self.call_screener_frame,
                           dataframe=self.data_frame,
                           showtoolbar=False,
                           showstatusbar=True)
        self.table.show()
        self.check_response()

    def clear_expiration_menu(self):
        self.expiration_var.set('')
        self.popup_expiration_menu['menu'].delete(0, 'end')

    def clear_otm_strike_menu(self):
        self.otm_strike_var.set('')
        self.otm_strike_menu['menu'].delete(0, 'end')

    def update_expiration(self, choices):
        for choice in choices:
            self.popup_expiration_menu['menu'].add_command(
                label=choice,
                command=lambda value=choice: self.expiration_var.set(value))

    def update_otm_strike(self, choices):
        for choice in choices:
            self.otm_strike_menu['menu'].add_command(
                label=choice,
                command=lambda value=choice: self.otm_strike_var.set(value))

    # noinspection PyUnusedLocal
    def expiration_var_selection_event(self, *args):
        if self.expiration_var.get():
            self.__clear_table()
            self.table.redraw()

    def otm_strike_var_selection_event(self, *args):
        if self.otm_strike_var.get():
            numbers = [i for i in self.otm_strike_var.get() if i.isdigit()]
            strings = [str(integer) for integer in numbers]
            a_string = "".join(strings)
            self.otm_percent = 0 if len(a_string) == 0 else int(a_string)
            self.__clear_table()
            self.table.redraw()

    def __clear_table(self):
        with self.request_queue.mutex:
            self.request_queue.queue.clear()

        for index, row in self.data_frame.iterrows():
            self.data_frame.loc[row['Ticker'], 'Stock Price'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Strike'] = math.nan
            self.data_frame.loc[row['Ticker'], '%(OTM)'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Bid'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Ask'] = math.nan
            self.data_frame.loc[row['Ticker'],
                                'ROI(%) (Bid/Stock Price)'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Annual ROI(%)'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Implied Volatility'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Delta'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Theta'] = math.nan

    def update_options(self):
        if self.request_queue.empty():
            self.status_var.set("Updating...")
            for company in self.companies.get_companies():
                company["expiration"] = self.expiration_var.get()
                self.request_queue.put(company)
            self.status_var.set("")
        else:
            if self.logger:
                self.logger.info("Request Queue not empty yet")

        self.tk_root.after(15000, self.update_options)

    def check_response(self):
        if not self.response_queue.empty():
            response = self.response_queue.get()
            if self.logger:
                if bool(response['options']):
                    self.logger.info("Options received for {0}".format(
                        response['company']['symbol']))
                else:
                    self.logger.warning("No Options received for {0}".format(
                        response['company']['symbol']))
            self.update_company_in_table(response)

        self.tk_root.after(500, self.check_response)

    def update_company_in_table(self, response) -> None:
        try:
            display_chain = response['options']
            if bool(display_chain):
                company = display_chain["ticker"]
                best_index, otm_percent_actual = self.find_best_index(
                    display_chain, self.otm_percent)
                if best_index != -1:
                    self.data_frame.loc[
                        company,
                        'Stock Price'] = display_chain['current_value']
                    self.data_frame.loc[company, 'Strike'] = display_chain[
                        'options_chain']['calls'].iloc[best_index]['strike']
                    self.data_frame.loc[company, '%(OTM)'] = otm_percent_actual
                    self.data_frame.loc[company, 'Bid'] = display_chain[
                        'options_chain']['calls'].iloc[best_index]['bid']
                    self.data_frame.loc[company, 'Ask'] = display_chain[
                        'options_chain']['calls'].iloc[best_index]['ask']
                    roi_percent = round((display_chain['options_chain']
                                         ['calls'].iloc[best_index]['bid'] /
                                         display_chain['current_value'] * 100),
                                        2)
                    self.data_frame.loc[
                        company, 'ROI(%) (Bid/Stock Price)'] = roi_percent
                    self.data_frame.loc[company, 'Implied Volatility'] = \
                        round(display_chain['options_chain']['calls'].iloc[best_index]['impliedVolatility'] * 100, 2)
                    now = datetime.datetime.now()
                    expiration = datetime.datetime.strptime(
                        self.expiration_var.get(), '%Y-%m-%d')
                    delta = (expiration - now).days + 1
                    annual_roi = 365 / delta * roi_percent
                    self.data_frame.loc[company, 'Annual ROI(%)'] = round(
                        annual_roi, 2)
                    if 'delta' in display_chain['options_chain'][
                            'calls'].columns:
                        self.data_frame.loc[company, 'Delta'] = \
                            display_chain['options_chain']['calls'].iloc[best_index]['delta']
                    if 'theta' in display_chain['options_chain'][
                            'calls'].columns:
                        self.data_frame.loc[company, 'Theta'] = \
                            display_chain['options_chain']['calls'].iloc[best_index]['theta']
                else:
                    if self.logger:
                        self.logger.error(
                            "No option available for {0}".format(company))
            else:
                if self.logger:
                    self.logger.error("No option available")
        except Exception as err:
            if self.logger:
                self.logger.error(err)

        self.table.redraw()

    def find_best_index(self, chain: {}, otm_percent) -> (int, float):
        best_index = 0
        otm_percent_actual = math.nan
        index = 0
        current_delta = 100
        if len(chain['options_chain']['calls']) > 0:
            while index < len(chain['options_chain']['calls']):
                diff = chain['options_chain']['calls'].iloc[index][
                    'strike'] - chain['current_value']
                percent_diff = (diff / chain['current_value'] * 100)
                delta = otm_percent - percent_diff
                if abs(delta) < current_delta:
                    current_delta = delta
                    best_index = index
                    otm_percent_actual = round(percent_diff, 2)
                index += 1
            return best_index, otm_percent_actual
        else:
            return -1, 0

    def temp(self):
        web = Utilities.get_options_API(self.logger)
        # response_dict = web.get_quote("MAR")
        # if response_dict != {}:
        #     print("pass")
        # else:
        #     print("fail")
        #
        # expirations_dict = web.get_expirations("MAR")
        # if expirations_dict != {}:
        #     print("pass")
        # else:
        #     print("fail")

        options_dict = web.get_options_for_symbol_and_expiration(
            "MAR", "2021-02-19")
        if options_dict != {}:
            print("pass")
        else:
            print("fail")
예제 #12
0
class DataViewer(Frame):
  def __init__(self, parent=None, filename='Diet.xlsx', modelDir="model/"):
    self.parent = parent
    self.__filename = filename
    self.__modelDirectory = modelDir
    Frame.__init__(self)
    self.main = self.master
    self.main.title('Diet Editor')
    if not os.path.isfile(filename):
      self.createInitialExcelFile(filename)

    self.df = pd.read_excel(filename, sheet_name="data")
    self.uf = pd.read_excel(filename, sheet_name="bounds")
    self.table = Table(self, dataframe=self.df)
    self.table.show()

    buttonsFrame = Frame(self)
    buttonsFrame.grid(column=0, columnspan=2)
    self.__progress=Progressbar(buttonsFrame, orient=HORIZONTAL, length=100,\
      mode='determinate')
    self.__saveButton = Button(buttonsFrame, text="Save",\
      command=self.saveData)
    self.__runButton = Button(buttonsFrame, text="Run",\
      command=self.runModel)
    self.__userButton = Button(buttonsFrame, text="User",\
      command=self.userData)
    self.__foodButton = Button(buttonsFrame, text="Food",\
      command=self.foodData)
    self.__closeButton = Button(buttonsFrame, text="Close",\
      command=self.destroy)

    self.__progress.pack(side=BOTTOM, fill=X)
    self.__saveButton.pack(fill=X, side=LEFT)
    self.__runButton.pack(fill=X, side=LEFT)
    self.__userButton.pack(fill=X, side=LEFT)
    self.__foodButton.pack(fill=X, side=LEFT)
    self.__closeButton.pack(fill=X, side=LEFT)
    self.__foodButton['state'] = DISABLED
    self.__selectedState = Sheets.FOOD

    return

  def createInitialExcelFile(self, filename):
    workbook = xlsxwriter.Workbook(filename)
    datasheet = workbook.add_worksheet('data')
    boundssheet = workbook.add_worksheet('bounds')
    # food entry
    datasheet.write('A1', 'Name')
    datasheet.write('B1', 'Price')
    datasheet.write('C1', 'Energy (kcal)')
    datasheet.write('D1', 'Protien (g)')
    datasheet.write('E1', 'Sodium (mg)')
    datasheet.write('F1', 'Carbohydrates (g)')
    datasheet.write('G1', 'Saturated Fat (g)')
    datasheet.write('H1', 'Fibre (g)')
    datasheet.write('I1', 'Vitamin A (ug)')
    datasheet.write('J1', 'Vitamin C (mg)')
    datasheet.write('K1', 'Calcium (mg)')
    datasheet.write('L1', 'Iron (mg)')
    datasheet.write('A2', 'Cake')
    datasheet.write('B2', '25')
    datasheet.write('C2', '59')
    datasheet.write('D2', '1')
    datasheet.write('E2', '110')
    datasheet.write('F2', '9.4')
    datasheet.write('G2', '2.2')
    datasheet.write('H2', '0.3')
    datasheet.write('I2', '0')
    datasheet.write('J2', '0')
    datasheet.write('K2', '20')
    datasheet.write('L2', '0.2')

    # user entry
    boundssheet.write('B1', 'Energy (kcal)')
    boundssheet.write('C1', 'Protien (g)')
    boundssheet.write('D1', 'Sodium (mg)')
    boundssheet.write('E1', 'Carbohydrates (g)')
    boundssheet.write('F1', 'Saturated Fat (g)')
    boundssheet.write('G1', 'Fibre (g)')
    boundssheet.write('H1', 'Vitamin A (ug)')
    boundssheet.write('I1', 'Vitamin C (mg)')
    boundssheet.write('J1', 'Calcium (mg)')
    boundssheet.write('K1', 'Iron (mg)')
    boundssheet.write('A2', 'LowerBound')
    boundssheet.write('B2', '1')
    boundssheet.write('C2', '1')
    boundssheet.write('D2', '1')
    boundssheet.write('E2', '1')
    boundssheet.write('F2', '1')
    boundssheet.write('G2', '1')
    boundssheet.write('H2', '1')
    boundssheet.write('I2', '1')
    boundssheet.write('J2', '1')
    boundssheet.write('K2', '1')
    boundssheet.write('A3', 'UpperBound')
    boundssheet.write('B3', '1')
    boundssheet.write('C3', '1')
    boundssheet.write('D3', '1')
    boundssheet.write('E3', '1')
    boundssheet.write('F3', '1')
    boundssheet.write('G3', '1')
    boundssheet.write('H3', '1')
    boundssheet.write('I3', '1')
    boundssheet.write('J3', '1')
    boundssheet.write('K3', '1')
    workbook.close()

  def foodData(self):
    self.__foodButton['state'] = DISABLED
    self.__userButton['state'] = NORMAL
    self.__selectedState = Sheets.FOOD
    self.uf = self.table.model.df
    self.table.updateModel(TableModel(self.df))
    self.table.redraw()

  def userData(self):
    self.__foodButton['state'] = NORMAL
    self.__userButton['state'] = DISABLED
    self.__selectedState = Sheets.USER
    self.df = self.table.model.df
    self.table.updateModel(TableModel(self.uf))
    self.table.redraw()

  def charRange(self, c1, c2):
    for c in range(ord(c1), ord(c2) + 1):
        yield chr(c)

  def saveData(self):
    if self.__selectedState == Sheets.FOOD:
      self.df = self.table.model.df

    if self.__selectedState == Sheets.USER:
      self.uf = self.table.model.df
    indices = len(self.df.index)
    setData=[]
    for v in self.charRange('A', 'L'):
      setData.append(v + '2:' + v + str(indices + 1))
    modelSets=pd.DataFrame(setData)
    writer = pd.ExcelWriter(self.__filename, engine='xlsxwriter')
    self.df.to_excel(writer, sheet_name='data', index=False)
    self.uf.to_excel(writer, sheet_name='bounds', index=False)
    modelSets.to_excel(writer, sheet_name='metadata', index=False, header=False)
    saved = writer.save()

  def runModel(self):
    firstRun = True
    config = ConfigParser()
    config.read('config.ini')
    dss = edss.Service(config['elytica']['apiKey'])
    dss.login()

    self.__progress['value']=20
    self.update_idletasks()

    if len(list(filter(lambda x : x.name == "DIET",\
      dss.getProjects()))) > 0:
      dss.selectProjectByName("DIET")
      dss.selectJobByName("Basic Job")
      firstRun=False
    else:
      app = dss.selectApplicationByName("MIP Interpreter with Python")
      dss.createProject("DIET", "The diet problem.", app)
      dss.createJob("Basic Job", 100)

    self.__progress['value']=40
    self.update_idletasks()

    md = self.__modelDirectory
    libDir = self.__modelDirectory + '/libraries/'
    modelFiles = [f for f in listdir(md) if isfile(join(md, f))]
    libraries = [f for f in listdir(libDir) if isfile(join(libDir, f))]

    firstRun = True
    if firstRun:
      for f in modelFiles:
        modelFile = open(md + f,  "rb", buffering=0)
        uf = dss.uploadFileContents(f, modelFile);
        dss.assignFile(uf, 1)
      arg = 2
      for f in libraries:
        libraryFile = open(libDir + f,  "rb", buffering=0)
        uf = dss.uploadFileContents(f, libraryFile);
        dss.assignFile(uf, arg)
        arg += 1

    self.__progress['value']=60
    self.update_idletasks()

    countInputFiles = len(dss.getInputFiles())
    excelData = open(self.__filename,  "rb", buffering=0)
    dataFile = dss.uploadFileContents(self.__filename, excelData)
    dss.assignFile(dataFile, countInputFiles)

    self.__progress['value']=80
    self.update_idletasks()

    dss.queueJob()

    self.__progress['value']=100
    self.update_idletasks()
예제 #13
0
class TestApp(Frame):
    def __init__(self, parent=None):
        self.root = tk()
        root = self.root
        self.parent = parent
        Frame.__init__(self)
        top_frame = Frame(root)
        bottom = Frame(root)
        box_frame = Frame(top_frame)
        label_frame = Frame(box_frame)
        input_frame = Frame(box_frame)
        bottom.pack(side=BOTTOM, fill=BOTH, expand=True)
        # Packings
        top_frame.pack(side=TOP)
        bottom.pack(side=BOTTOM, fill=BOTH, expand=True)
        box_frame.pack(side=LEFT)
        label_frame.pack(side=TOP)
        input_frame.pack(side=BOTTOM)

        # create the widgets for the top part of the GUI,
        # and lay them out
        self.ticker_field = Text(top_frame, width=5, height=1)
        self.time_range = Text(top_frame, width=2, height=1)
        ticker_label = Label(top_frame, text="Ticker:", width=5, height=1)
        time_label = Label(top_frame, text="Hrs", width=2, height=1)

        button1 = Button(root,
                         text="Recent Posts",
                         width=10,
                         height=2,
                         command=self.recent_posts)
        button3 = Button(root,
                         text="Summary",
                         width=10,
                         height=2,
                         command=self.trending_posts)
        button2 = Button(root,
                         text="All Posts",
                         width=10,
                         height=2,
                         command=self.all_posts)
        button4 = Button(root,
                         text="Open Url",
                         width=10,
                         height=2,
                         command=self.open_url)

        button1.pack(in_=top_frame, side=LEFT)
        button3.pack(in_=top_frame, side=LEFT)
        button2.pack(in_=top_frame, side=LEFT)
        button4.pack(in_=top_frame, side=LEFT)

        ticker_label.pack(in_=label_frame, side=LEFT)
        time_label.pack(in_=label_frame, side=LEFT)
        self.ticker_field.pack(in_=input_frame, side=LEFT)
        self.time_range.pack(in_=input_frame, side=LEFT)
        self.main = self.master
        self.main.geometry('1200x800+200+100')
        self.main.title('Table app')

        # btn2 = Button(self.root, text="Ticker Post History", command=self.button2)
        # btn2.pack()
        # urlbtn = Button(self.root, text="Open url", command=self.open_url)
        # urlbtn.pack()

        self.f = Frame(self.main)
        self.f.pack(fill=BOTH, expand=1)
        # df = panda_db.get_trending()
        df = panda_db.get_all_posts("8")
        # df = panda_db.get_posts_by_ticker("AI")

        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)

        self.table.show()

        return

    def all_posts(self):
        date_range = str(self.time_range.get("1.0", END))
        df = panda_db.get_all_posts(date_range)
        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)
        self.table.show()
        self.table.redraw()

    def recent_posts(self):
        ticker = str(self.ticker_field.get("1.0", END))
        print(ticker)
        date_range = str(self.time_range.get("1.0", END))
        self.f.pack_forget()
        df = panda_db.get_posts_by_ticker(ticker.upper(), date_range)
        self.f.pack(fill=BOTH, expand=1)
        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)
        self.table.show()
        self.table.redraw()

    def trending_posts(self):
        self.f.pack_forget()
        date_range = str(self.time_range.get("1.0", END))
        df = panda_db.get_trending(date_range)
        self.f.pack(fill=BOTH, expand=1)
        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)
        self.table.show()
        self.table.redraw()

    def open_url(self):
        url = self.table.selection_get()
        webbrowser.register(
            'chrome', None,
            webbrowser.BackgroundBrowser(
                "C://Users//awgra//AppData//Local//Google//Chrome//Application//chrome.exe"
            ))
        webbrowser.get('chrome').open(url)
예제 #14
0
class ImporterGUI:
    """
    This class is the main gui and shows the import window, it also contains the main methods which uses other helper classes

    Attributes:
        root = the root tk
        previewFrame = the frame that shows the preview of the dataframe
        XMLList = the 2D list which holds the xml filepath on the index 0 and the xsl filepath on index 1
    """
    def __init__(self, root: Tk):
        self.root = root
        self.previewFrame = Frame(root)
        self.pt = Table(self.previewFrame)
        self.dialect = detector.Dialect()
        self.XMLList = []
        self.DialectList = []
        self.hasHeaderVar = BooleanVar()
        self.currentPath = ""

        h1 = Label(self.root, text="Imported Files", bg="#eee")
        h1.pack(padx=5, pady=5, fill="x")

        # Dialog Frame
        dialogFrame = Frame(self.root)
        dialogFrame.grid_columnconfigure(1, weight=1)
        Button(dialogFrame,
               text="Import Files",
               command=self.openFileDialog,
               width=20).grid(row=0, column=0)
        Button(dialogFrame,
               text="Delete selected File",
               command=self.deleteSelectedFile,
               width=20).grid(row=1, column=0)
        Button(dialogFrame,
               text="Delete all",
               command=self.deleteAllFiles,
               width=20).grid(row=2, column=0)

        # the outside frame for the files listbox (it holds the listbox and the scrollbar)
        listbox_border = Frame(dialogFrame,
                               bd=2,
                               relief="sunken",
                               background="white")
        listbox_border.grid(row=0, column=1, rowspan=3, padx=3, sticky="nsew")

        # the actual listbox
        self.importedFiles = Listbox(listbox_border,
                                     selectmode=SINGLE,
                                     height=4,
                                     borderwidth=0,
                                     highlightthickness=0,
                                     relief=SUNKEN,
                                     background="white")
        self.importedFiles.bind("<<ListboxSelect>>", self.selectionChanged)

        # the scrollbar inside the listbox_border frame
        vsb = Scrollbar(listbox_border,
                        orient="vertical",
                        command=self.importedFiles.yview)
        self.importedFiles.configure(yscrollcommand=vsb)
        vsb.pack(side="right", fill="y")
        self.importedFiles.pack(padx=2, pady=2, fill="both", expand=True)
        dialogFrame.pack(fill="x", padx=10)

        # XSL File Frame (its disabled when a csv file is selected in the listbox,
        # and set to "normal" when a xml is selected
        h1 = Label(root, text="XSL File", bg="#eee")
        h1.pack(padx=5, pady=5, fill="x")
        xslFrame = Frame(root)
        self.importXSL_btn = Button(xslFrame,
                                    state=DISABLED,
                                    text="Import XSL File",
                                    command=self.openXSLFileDialog,
                                    width=20)
        self.importXSL_btn.grid(row=0, column=0)
        self.XSLPath_text = Text(xslFrame,
                                 height=1,
                                 borderwidth=2,
                                 relief=SUNKEN)
        self.XSLPath_text.grid(row=0, column=1)
        xslFrame.pack(fill="x", padx=10, pady=5)

        # Detector Frame
        h1 = Label(root, text="Detector", bg="#eee")
        h1.pack(padx=5, pady=5, fill="x")
        detectorFrame = Frame(root)

        Label(detectorFrame,
              text="Encoding:",
              width=20,
              anchor="w",
              justify="left").grid(row=0)
        self.encodingText = Text(detectorFrame,
                                 height=1,
                                 borderwidth=2,
                                 relief=SUNKEN,
                                 width=10)
        self.encodingText.grid(row=0, column=1)

        Label(detectorFrame,
              text="Has Header:",
              width=20,
              anchor="w",
              justify="left").grid(row=1)
        self.hasHeaderCheckbutton = Checkbutton(detectorFrame,
                                                var=self.hasHeaderVar,
                                                onvalue=1,
                                                offvalue=0)
        self.hasHeaderCheckbutton.grid(sticky="W", row=1, column=1)

        Label(detectorFrame,
              text="Seperator:",
              width=20,
              anchor="w",
              justify="left").grid(row=2)
        self.seperatorText = Text(detectorFrame,
                                  height=1,
                                  borderwidth=2,
                                  relief=SUNKEN,
                                  width=10)
        self.seperatorText.grid(row=2, column=1)

        Label(detectorFrame,
              text="Quote Char:",
              width=20,
              anchor="w",
              justify="left").grid(row=3)
        self.quoteCharText = Text(detectorFrame,
                                  height=1,
                                  borderwidth=2,
                                  relief=SUNKEN,
                                  width=10)
        self.quoteCharText.grid(row=3, column=1)

        Button(detectorFrame,
               text="Save Dialect Changes",
               command=self.saveDialectChanges,
               width=20).grid(row=4, column=0)

        detectorFrame.pack(fill="x", padx=10, pady=5)

        # dataframe preview frame
        preview = Label(root, text="Preview", bg="#eee")
        preview.pack(expand=TRUE, fill="x", padx=5, side=TOP)
        self.pt.show()
        self.previewFrame.pack(pady=10, padx=10, fill="both", side=TOP)

        # the bottom most centered export button which leads to the export window
        exportBtn = Button(root,
                           text="Export",
                           command=self.export,
                           width=20,
                           padx=0)
        exportBtn.pack(fill="x", padx=10, pady=10)

    def saveDialectChanges(self):
        """
        saves the Dialect changes made by the user
        """
        dialect = detector.Dialect()
        dialect.encoding = self.encodingText.get(1.0, 'end-1c')
        dialect.hasHeader = self.hasHeaderVar.get()
        dialect.delimiter = self.seperatorText.get(1.0, 'end-1c')
        dialect.quoteChar = self.quoteCharText.get(1.0, 'end-1c')
        if not self.currentPath:
            files = self.getImportedFiles()
            self.currentPath = files[0]
        path = self.currentPath
        print(path)
        if not any(path in x for x in self.DialectList):
            self.DialectList.append([path, dialect])
        elif any(path in x for x in self.DialectList):
            x = [x for x in self.DialectList if path in x][0]
            self.DialectList[self.DialectList.index(x)][1] = dialect
        self.updateDf(self.getImportedFiles())

    def selectionChanged(self, event):
        """
        this is an event which is triggered by selection changed inside the listbox widget
        it checks if the selected file is a xml, if so it sets the textbox intractable for the user

        :param event: the event which called it
        """
        selection = event.widget.curselection()
        if selection:
            data = event.widget.get(selection[0])
            self.currentPath = data
            if data.endswith(".xml"):
                # disable encoding changes
                self.encodingText.delete(1.0, END)
                self.hasHeaderVar.set(False)
                self.seperatorText.delete(1.0, END)
                self.quoteCharText.delete(1.0, END)
                self.encodingText["state"] = "disabled"
                self.hasHeaderCheckbutton["state"] = "disabled"
                self.seperatorText["state"] = "disabled"
                self.quoteCharText["state"] = "disabled"
                self.importXSL_btn["state"] = "normal"

                if any(data in x for x in self.XMLList):
                    x = [x for x in self.XMLList if data in x][0]
                    self.XSLPath_text.delete(1.0, END)
                    self.XSLPath_text.insert(
                        1.0, self.XMLList[self.XMLList.index(x)][1])
                else:
                    self.XSLPath_text.delete(1.0, END)
                    self.XSLPath_text.insert(1.0, "please import a XSL File!")
            else:
                self.encodingText.delete(1.0, END)
                self.hasHeaderVar.set(False)
                self.seperatorText.delete(1.0, END)
                self.quoteCharText.delete(1.0, END)
                self.encodingText["state"] = "normal"
                self.hasHeaderCheckbutton["state"] = "normal"
                self.seperatorText["state"] = "normal"
                self.quoteCharText["state"] = "normal"
                self.importXSL_btn["state"] = "disabled"
                self.XSLPath_text.delete(1.0, END)

                if any(data in x for x in self.DialectList):
                    x = [x for x in self.DialectList if data in x][0]
                    dialect = self.DialectList[self.DialectList.index(x)][1]
                    self.updateDialect(dialect)

    def openXSLFileDialog(self):
        """
        this function is called if the user wants to import a xsl file in the xsl file frame
        it opens the filedialog and appends the xsl to the according xml into the XMLList attribute
        after that, it try's to update the dataframe and its preview by calling the update function
        """
        file = askopenfilename(parent=self.root,
                               title='Choose a file',
                               filetypes=[("Extensible Stylesheet Language",
                                           "*.xsl"), ("All files", "*.*")])
        self.XMLList.append(
            [self.importedFiles.get(self.importedFiles.curselection()), file])
        self.XSLPath_text.delete(1.0, END)
        self.XSLPath_text.insert(1.0, file)
        self.updateDf(self.getImportedFiles())

    def openFileDialog(self):
        """
        this function opens the file dialog and imports the selected filepaths into the listbox and also
        calls the update function to redraw the new dataframe
        """
        files = list(
            askopenfilenames(parent=self.root,
                             title='Choose a file',
                             filetypes=[("Excel files", ".xml .csv")]))
        self.updateSelectedFiles(files)
        self.updateDf(self.getImportedFiles())

    def deleteSelectedFile(self):
        """
        deletes the selected file from the listbox and redraws the dataframe since one of its source is deleted
        also if a xml file is deleted, it also deletes the corresponding xsl file from the XMLList
        """
        path = self.importedFiles.get(self.importedFiles.curselection())
        if path is self.currentPath:
            self.currentPath = ""
        # delete from dialect list
        if any(path in x for x in self.DialectList):
            x = [x for x in self.DialectList if path in x][0]
            self.DialectList.pop(self.DialectList.index(x))

        index = self.importedFiles.get(0, END).index(path)
        self.importedFiles.delete(index)

        # delete from xml list
        if path.endswith(".xml"):
            x = [x for x in self.XMLList if path in x][0]
            self.XMLList.pop(self.XMLList.index(x))
        self.updateDf(self.getImportedFiles())

    def deleteAllFiles(self):
        """
        deletes all imported filepaths from the listbox and also from the dataframe
        """
        self.importedFiles.delete(0, END)
        self.currentPath = ""
        self.XMLList = []
        self.DialectList = []

    def getImportedFiles(self):
        """
        :return: returns the selected filepath from the listbox
        """
        return self.importedFiles.get(0, END)

    def updateSelectedFiles(self, files):
        """
        after opening a file dialog, this method is called to pass the new imported filepaths into the listbox

        :param files: filespaths from the filedialog
        """
        startIndex = self.importedFiles.size()
        for index, file in enumerate(files):
            self.importedFiles.insert(index + startIndex, file)

    def export(self):
        """
        opens the export window and passes the dataframe from the preview frame
        """
        importer.setDataFrame(self.pt.model.df)
        ExporterGUI(self.root, importer, self.dialect)

    def updateDf(self, files: list):
        """
        checks if the dataframe can be updated by the newly imported filepaths
        calls the merge function if there is more than 1 file inside the filelist
        also udpates the detector frame (displaying dialect data)

        :param files: the whole filepath list
        """
        if len(files) > 1 or len(self.XMLList) > 0:
            canMerge = merger.prepareMerge(files, self.XMLList,
                                           self.DialectList)
            self.DialectList = merger.dialectList
            if canMerge:
                newDataFrame = merger.mergeFiles()
                importer.setDataFrame(newDataFrame)
                self.pt.updateModel(TableModel(newDataFrame))
                self.pt.redraw()
        elif len(files) > 0 and files[0].endswith(".csv"):
            if not any(files[0] in x for x in self.DialectList):
                self.dialect.guessDialectCSV(files[0])
                self.DialectList.append([files[0], self.dialect])
            else:
                x = [x for x in self.DialectList if files[0] in x][0]
                self.dialect = self.DialectList[self.DialectList.index(x)][1]
            importer.importCSV(files[0], self.dialect)
            updatedDataframe = importer.getDataFrame()
            self.pt.updateModel(TableModel(updatedDataframe))
            self.pt.redraw()
            self.updateDialect(self.dialect)

    def updateDialect(self, dialect: detector.Dialect):
        """
        updates the dialect text fields from the gui
        :param dialect: the new changed dialect
        """
        # updates the dialect data
        self.encodingText.delete(1.0, END)
        self.encodingText.insert(1.0, dialect.encoding)

        self.hasHeaderVar.set(dialect.hasHeader)

        self.seperatorText.delete(1.0, END)
        self.seperatorText.insert(1.0, dialect.delimiter)

        self.quoteCharText.delete(1.0, END)
        self.quoteCharText.insert(1.0, dialect.quoteChar)
class Program:
    """Exampleprogram to show possible usage of the module csvxmlImporter"""
    __importer: CsvXmlImporter
    __settings: dict

    def __init__(self):
        """__init__ creates the tkinter gui"""
        self.__settings = {}
        self.__importer = CsvXmlImporter()

        # ***--*** main window and menu band ***---***
        self.__root = ThemedTk(theme=theme)
        self.__root.title("Csv/Xml Importer")
        self.__root.minsize(560, 1)
        menu = Menu(self.__root)
        self.__root.config(menu=menu)

        filemenu = Menu(menu, tearoff=0)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Add Files", command=self.add_files)
        filemenu.add_command(label="Remove All", command=self.remove_all)
        filemenu.add_separator()
        filemenu.add_command(label="Add xsl File", command=self.add_xslfile)
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.exit)

        helpmenu = Menu(menu, tearoff=0)
        menu.add_cascade(label="Help", menu=helpmenu)
        helpmenu.add_command(label="?", command=self.ask_help)
        helpmenu.add_command(label="About", command=self.ask_about)

        # ***---*** source file frame dialog ***---***
        srcfilesframe = LabelFrame(self.__root, text="Sourcefiles")
        buttonframe = Frame(srcfilesframe)
        addbutton = Button(buttonframe,
                           text="Add Files",
                           command=self.add_files)
        addbutton.pack(fill=X)
        removefilesbutton = Button(buttonframe,
                                   text="Remove Selected",
                                   command=self.remove_files)
        removefilesbutton.pack(fill=X)
        removeallbutton = Button(buttonframe,
                                 text="Remove All",
                                 command=self.remove_all)
        removeallbutton.pack(fill=X)
        buttonframe.grid(column=1, row=1)
        self.__srcfileslistbox = Listbox(srcfilesframe,
                                         selectmode="extended",
                                         width=100,
                                         height=5)
        self.__srcfileslistbox.grid(column=2, row=1)

        Label(srcfilesframe, text="Encoding").grid(column=1, row=2, sticky=E)
        self.__settings["encoding"] = StringVar()
        self.__settings["encoding"].trace_add("write", self.update_settings)
        encCombobox = Combobox(srcfilesframe,
                               textvariable=self.__settings["encoding"],
                               values=encodings,
                               state="readonly")
        encCombobox.bind("<FocusOut>", self.update_settings)
        encCombobox.grid(column=2, row=2, pady=10)
        srcfilesframe.pack(fill=X)

        # ***---*** xsl file dialog ***---***
        xslfileframe = LabelFrame(self.__root, text="XSL-File")
        Button(xslfileframe, text="Add .xsl",
               command=self.add_xslfile).grid(column=1, row=1)
        self.__xsllistbox = Listbox(xslfileframe, width=100, height=1)
        self.__xsllistbox.grid(column=2, row=1, sticky="w")
        buttonframe = Frame(xslfileframe)
        Button(buttonframe,
               text="Apply Parameter",
               command=self.apply_xslparameter).pack(fill=X)
        Button(buttonframe,
               text="Restore Default",
               command=self.reset_xslparameter).pack(fill=X)
        buttonframe.grid(column=1, row=2)
        box = Frame(xslfileframe)
        self.__xslparametertext = Text(box, height=3, width=75)
        self.__xslparametertext.grid(column=0, row=1, sticky="nsew")
        scrollbar = Scrollbar(box, command=self.__xslparametertext.yview)
        scrollbar.grid(column=0, row=1, sticky="nse")
        box.grid(column=2, row=2, sticky="we")
        self.__xslparametertext["yscrollcommand"] = scrollbar.set
        xslfileframe.pack(fill=X)

        # ***---*** file format settings dialog ***---***
        # small help function
        def limit_character(entry_text):
            """limit_characters cuts down the characters of an entry text to one"""
            if len(entry_text.get()) > 0:
                # take only last input character and throw away the rest
                entry_text.set(entry_text.get()[-1])

        fileformatsettingsframe = LabelFrame(self.__root,
                                             text="File Format Settings")

        Label(fileformatsettingsframe, text="Delimiter").grid(column=1,
                                                              row=1,
                                                              sticky=E)
        self.__settings["delimiter"] = StringVar()
        seperatorentry = Entry(fileformatsettingsframe,
                               textvariable=self.__settings["delimiter"],
                               width=1)
        self.__settings["delimiter"].trace_add(
            "write", lambda *_: limit_character(self.__settings["delimiter"]))
        seperatorentry.bind("<Return>", self.update_settings)
        seperatorentry.bind("<FocusOut>", self.update_settings)
        seperatorentry.grid(column=2, row=1, sticky=W, padx=15)

        Label(fileformatsettingsframe, text="Quotechar").grid(column=1,
                                                              row=2,
                                                              sticky=E)
        self.__settings["quotechar"] = StringVar()
        quotecharentry = Entry(fileformatsettingsframe,
                               textvariable=self.__settings["quotechar"],
                               width=1)
        self.__settings["quotechar"].trace_add(
            "write", lambda *_: limit_character(self.__settings["quotechar"]))
        quotecharentry.bind("<Return>", self.update_settings)
        quotecharentry.bind("<FocusOut>", self.update_settings)
        quotecharentry.grid(column=2, row=2, sticky=W, padx=15)

        Label(fileformatsettingsframe, text="Doublequote").grid(column=1,
                                                                row=3,
                                                                sticky=E)
        self.__settings["doublequote"] = BooleanVar()
        Checkbutton(fileformatsettingsframe,
                    variable=self.__settings["doublequote"],
                    command=self.update_settings).grid(column=2,
                                                       row=3,
                                                       sticky=W,
                                                       padx=10)

        Label(fileformatsettingsframe, text="Quoting").grid(column=1,
                                                            row=5,
                                                            sticky=E)
        quotingopt = {"minimal": 0, "all": 1, "non numeric": 2, "none": 3}
        self.__settings["quoting"] = IntVar()
        for i, (key, value) in enumerate(quotingopt.items()):
            Radiobutton(
                fileformatsettingsframe,
                text=key,
                value=value,
                variable=self.__settings["quoting"],
                command=self.update_settings,
            ).grid(
                column=2 + i,
                row=5,
                padx=10,
                sticky=W,
            )

        Label(fileformatsettingsframe,
              text="Ignore spaces at beginning").grid(column=1,
                                                      row=6,
                                                      sticky=E)
        self.__settings["skipinitialspace"] = BooleanVar()
        self.__settings["skipinitialspace"].set(False)
        Checkbutton(fileformatsettingsframe,
                    variable=self.__settings["skipinitialspace"],
                    command=self.update_settings).grid(column=2,
                                                       row=6,
                                                       sticky=W,
                                                       padx=10)

        fileformatsettingsframe.pack(fill=X)

        # ***---*** preview frame ***---***
        previewframe = LabelFrame(self.__root, text="Preview")
        self.__pdtable = Table(parent=previewframe,
                               dataframe=self.__importer.dfx)
        self.__pdtable.show()
        previewframe.pack(fill="both", expand=True)

        # ***---*** export button ***---***
        exportframe = LabelFrame(self.__root, text="Export")
        Button(exportframe, text="Export",
               command=self.create_exportdialog).pack()
        exportframe.pack(fill="both", expand=True)

        # save settings to check for changes on update
        self.__prevsettings = self.__unpack_settings(self.__settings)

    def run(self):
        """run starts the mainloop of tkinter gui"""
        self.__root.mainloop()

    def exit(self):
        """exit closes tkinter application"""
        self.__root.destroy()

    def add_files(self):
        """add_files called by user to add files via dialog"""
        names = askopenfilenames(title="Select .csv or .xml files",
                                 filetypes=(("any", "*.*"),
                                            ("Csv File", "*.csv"), ("Xml File",
                                                                    "*.xml")))
        if names:
            try:
                self.__srcfileslistbox.insert(END, *names)
                self.__importer.update_files(
                    *self.__srcfileslistbox.get(0, END))
            except AttributeError as e:
                showerror(title="Error", message="No .xsl file set")
            except ValueError as _:
                showerror(title="Error", message="Could not open files")
                self.__srcfileslistbox.delete(0, END)

            self.__update_table()
            self.__update_dialog()

    def remove_files(self):
        """remove_files called by user to remove in listbox selected files"""
        itemstodelete = self.__srcfileslistbox.curselection()
        if itemstodelete:
            for i in itemstodelete:
                self.__srcfileslistbox.delete(i)

            x = self.__srcfileslistbox.get(0, END)
            if x:
                self.__importer.update_files(*x)
            else:
                self.__importer.reset()
            self.__update_table()

    def remove_all(self):
        """remove_all called by user to remove all imported files"""
        self.__srcfileslistbox.delete(0, END)
        self.__importer.reset()
        self.__update_table()

    def add_xslfile(self):
        """add_xslfile called to open .xsl file via dialog"""
        filename = askopenfilename(title="Select .xsl file",
                                   filetypes=(("Xsl File", "*.xsl"), ))
        if filename:
            self.__importer.set_xslfile(filename)
            self.__xsllistbox.insert(0, filename)
            self.reset_xslparameter()

    def apply_xslparameter(self):
        """apply_xslparameter reads userinput from textbox and parses input in dict"""
        param = self.__xslparametertext.get("1.0", END)
        with StringIO(param) as f:
            lines = [line[:-1] for line in f.readlines()]
            # escape_decode removes extra escapes added through reading the text
            d = {
                x.split("=")[0]: escape_decode(x.split("=")[1])[0]
                for x in lines if x
            }
            self.__importer.set_xslparameter(**d)
        if not self.__importer.dfx.empty:
            self.__importer.update_files()
            self.__update_table()

    def reset_xslparameter(self):
        """reset_xslparameter restores default values for xslparameters"""
        self.__xslparametertext.delete("1.0", END)
        param = self.__importer.get_xslparameter(default=True)
        s = ""
        for key, item in param.items():
            s += repr(key + "=" + item)[1:-1] + '\n'
        self.__xslparametertext.insert("1.0", s)

    @staticmethod
    def __unpack_settings(settings):
        """__unpack_settings takes settings in form of dict with tkinter variables and unpacks them"""
        return dict((key, settings[key].get()) for key in settings)

    def __update_table(self):
        """__update_table updates pandastable to display the actual dataframe"""
        self.__pdtable.updateModel(TableModel(self.__importer.dfx))
        self.__pdtable.redraw()

    def __update_dialog(self):
        """__update_dialog updates the input fields with settings from the importer"""
        importersettings = self.__importer.get_settings()
        for key in self.__settings:
            if key in importersettings:
                self.__settings[key].set(importersettings[key])

    def update_settings(self, *_):
        """update_settings reads input fields and applies the user input to the importer"""
        newsettings = self.__unpack_settings(self.__settings)
        if newsettings != self.__prevsettings:
            # figure out which settings changed
            changedsettings = dict(newsettings.items() -
                                   self.__prevsettings.items())

            self.__importer.set_settings(**changedsettings)
            self.__prevsettings = newsettings
            if not self.__importer.dfx.empty:
                self.__update_table()

    def ask_help(self):
        showinfo(title="Help",
                 message="""\
    To import files select Add Files
    For .xml import first add a .xsl file.
    To export select Export and set desired parameters\
    """)

    def ask_about(self):
        showinfo(
            title="About",
            message="Projektarbeit Python\nAuthor: Leo Schurrer\nDate: 19/12/20"
        )

    def create_exportdialog(self):
        ExportDialog(self.__importer.dfx).run()
예제 #16
0
class DataFrame(tk.Frame):
    label = "Data"

    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.columnconfigure(index=0, weight=1)
        self.rowconfigure(index=1, weight=1)

        self.create_widgets()

    def show(self):
        self.tkraise()

    def create_widgets(self):
        self.toolbar = tk.Frame(self)
        self.toolbar.grid(row=0, column=0, padx=12, pady=3, sticky="NSEW")
        for col in range(12):
            self.toolbar.columnconfigure(index=col, weight=1)

        self.save_button = tk.Button(
            self.toolbar, text="Store in vault", command=self.save_to_db)
        self.export_button = tk.Button(
            self.toolbar, text="Export File", command=self.export_data)
        self.import_button = tk.Button(
            self.toolbar, text="Import CSV", command=self.import_csv)
        self.refresh_button = tk.Button(
            self.toolbar, text="Refresh DB", command=self.refresh_table_data)

        self.save_button.grid(row=0, column=12)
        self.export_button.grid(row=0, column=11)
        self.import_button.grid(row=0, column=10)
        self.refresh_button.grid(row=0, column=9)

        self.table_container = tk.Frame(self)
        self.table_container = tk.Frame(self) self.table_container.grid(row=1, column=0, sticky="")
        
        data_df = Vault.data

        self.data_table = Table(self.table_container, dataframe=data_df)
        self.data_table.autoResizeColumns()
        self.data_table.show()

    def refresh_table_data(self):
        res = tkMessageBox.askyesno(title="Ready to reboot DB.",
                                    message="Ready to reboot DB.\n"
                                    "Undo")

        if res == tkMessageBox.NO:
            return

        data_df = get_db_data()

        Vault.data = data_df
        self.data_table.updateModel(TableModel(data_df))
        self.data_table.redraw()

    def export_data(self):
        output_file = tkFileDialog.askopenfilename()
        if not output_file:
            tkMessageBox.showerror(title="Error, Failed!", message="...")
            return

    def save_to_db(self):
        add_df_to_db(Vault.data)

    def import_csv(self):
        input_file = tkFileDialog.askopenfilename()
        if not input_file.strip():
            tkMessageBox.showerror(title="Error, Failed!", message="...")
            return

        try:
            import_df = pd.read_csv(input_file)
        except ParserError:
            tkMessageBox.showerror("Failed, Try again!.")

        if len(import_df) > 0:
            Vault.data.reset_index(level=["id_product"], inplace=True)
            table_df = Vault.data.append(import_df, ignore_index=False)
            table_df.set_index("id_product", inplace=True)

            Vault.data = table_df
            self.data_table.updateModel(TableModel(table_df))
            self.data_table.redraw()

            tkMessageBox.showinfo(title="Done",message="Pass")
        else:
            tkMessageBox.showinfo(title="Error, Failed!", message="...")
예제 #17
0
class UI(tk.Tk):
    def __init__(self):
        super().__init__()

        __width_label_lc = 16

        self.result_type_dict = [('mass', 'mass'),
                                 ('mass density', 'mass_density'),
                                 ('stiffness', 'stf'),
                                 ('shear capacity', 's_c'), ('drift', 'drift')]

        self.result_type_dict_right = [('displacement ratio', 'dsp_r'),
                                       ('drift ratio', 'dft_r'),
                                       ('spectrum of time history curve',
                                        'thc'),
                                       ('base shear of time history', 'sth'),
                                       ('drift of time history', 'dth')]

        self.result_type_dict_added = [('period', 'period'),
                                       ('seismic shear coefficient', 's_s_c'),
                                       ('seismic shear adjust factor', 's_a_f')
                                       ]

        # variables of app
        self.file_path = FilePath()
        self.yjk_dir = tk.StringVar()
        self.etabs_name = tk.StringVar()
        self.result_type = tk.StringVar()
        self.result_type.set('drift')
        self.cur_tower_number = tk.StringVar()
        self.cur_merge_df = None
        self.tower_number = None
        self.position = None
        self.cur_result_type = None
        self.font = dict(family='KaiTi',
                         color='black',
                         weight='normal',
                         size=10.5)

        # variables of YJK
        self.cur_yjk_class = None
        self.cur_yjk_dic = None
        self.cur_yjk_df = None
        self.df_yjk_export = None
        self.cur_yjk_lc = tk.StringVar()
        self.cur_yjk_tow_num_name = tk.StringVar()
        self.cur_yjk_flr_num_name = tk.StringVar()
        self.cur_yjk_content_name = tk.StringVar()
        self.lbl_yjk_tree_content = tk.StringVar()

        # variables of ETABS
        self.cur_etabs_dic = None
        self.cur_etabs_df = None
        self.df_etabs_export = None
        self.cur_etabs_lc = tk.StringVar()
        self.cur_etabs_tow_num_name = tk.StringVar()
        self.cur_etabs_flr_num_name = tk.StringVar()
        self.cur_etabs_content_name = tk.StringVar()
        self.lbl_etabs_tree_content = tk.StringVar()

        self.yjk_disp = None

        # GUI
        self.minsize(1280, 800)
        self.title('ARP_AnalysisResultProcessing')

        # start widget in frame_yjk_path
        self.frame_yjk_path = Frame(self)
        self.entry_yjk_path = Entry(self.frame_yjk_path,
                                    textvariable=self.yjk_dir)
        self.entry_yjk_path.pack(side=tk.LEFT,
                                 padx=5,
                                 pady=5,
                                 expand=tk.YES,
                                 fill=tk.X)
        self.btn_yjk_path = Button(self.frame_yjk_path,
                                   text='YJK',
                                   width=16,
                                   command=self.get_path)
        self.btn_yjk_path.pack(side=tk.LEFT, padx=5, pady=5)
        self.frame_yjk_path.pack(side=tk.TOP, fill=tk.X)
        # end widget in frame_yjk_path

        # start widget in frame_etabs_name
        self.frame_etabs_name = Frame(self)
        self.entry_etabs_name = Entry(self.frame_etabs_name,
                                      textvariable=self.etabs_name)
        self.entry_etabs_name.pack(side=tk.LEFT,
                                   padx=5,
                                   pady=5,
                                   expand=tk.YES,
                                   fill=tk.X)
        self.btn_etabs_path = Button(self.frame_etabs_name,
                                     text='ETABS',
                                     width=16,
                                     command=self.get_file_name)
        self.btn_etabs_path.pack(side=tk.LEFT, padx=5, pady=5)
        self.frame_etabs_name.pack(side=tk.TOP, fill=tk.X)
        # end widget in frame_etabs_name

        # start widget in frame_result_list
        self.frame_result_list = Frame(self)

        # option buttons of results
        self.lf_result_name = tk.LabelFrame(self.frame_result_list,
                                            text='Result to processing')

        self.frame_result_name_left = Frame(self.lf_result_name)
        for name, value in self.result_type_dict:
            _ = tk.Radiobutton(self.frame_result_name_left,
                               text=name,
                               value=value,
                               anchor=tk.W,
                               command=self.get_type,
                               variable=self.result_type)
            _.pack(side=tk.TOP, fill=tk.X, padx=5)
        self.frame_result_name_left.pack(side=tk.LEFT,
                                         expand=tk.YES,
                                         fill=tk.X)

        self.frame_result_name_right = Frame(self.lf_result_name)
        for name, value in self.result_type_dict_right:
            _ = tk.Radiobutton(self.frame_result_name_right,
                               text=name,
                               value=value,
                               anchor=tk.W,
                               command=self.get_type,
                               variable=self.result_type)
            _.pack(side=tk.TOP, fill=tk.X, padx=5)
        self.frame_result_name_right.pack(side=tk.LEFT,
                                          expand=tk.YES,
                                          fill=tk.X)

        self.frame_result_name_added = Frame(self.lf_result_name)
        for name, value in self.result_type_dict_added:
            _ = tk.Radiobutton(self.frame_result_name_added,
                               text=name,
                               value=value,
                               anchor=tk.NW,
                               command=self.get_type,
                               variable=self.result_type)
            _.pack(side=tk.TOP, fill=tk.X, padx=5)
        self.frame_result_name_added.pack(side=tk.LEFT,
                                          expand=tk.YES,
                                          fill=tk.X,
                                          anchor=tk.N)

        self.lf_result_name.pack(side=tk.TOP, fill=tk.X)

        # labelframe of yjk results
        self.lf_yjk = tk.LabelFrame(self.frame_result_list, text='YJK')

        # load combination cmb
        self.frame_yjk_lc = tk.Frame(self.lf_yjk)
        self.lbl_yjk_lc = tk.Label(self.frame_yjk_lc,
                                   width=__width_label_lc,
                                   text='Load Combination',
                                   anchor=tk.W)
        self.lbl_yjk_lc.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_yjk_lc = ttk.Combobox(self.frame_yjk_lc,
                                       state="readonly",
                                       height=1,
                                       textvariable=self.cur_yjk_lc)
        self.cmb_yjk_lc.pack(side=tk.LEFT,
                             expand=tk.YES,
                             fill=tk.X,
                             padx=5,
                             pady=5)
        self.frame_yjk_lc.pack(side=tk.TOP, fill=tk.X)

        # tower number cmb
        self.frame_yjk_tower = tk.Frame(self.lf_yjk)
        self.lbl_yjk_tower = tk.Label(self.frame_yjk_tower,
                                      width=__width_label_lc,
                                      text='Tower Number',
                                      anchor=tk.W)
        self.lbl_yjk_tower.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_yjk_tower = ttk.Combobox(
            self.frame_yjk_tower,
            state="readonly",
            height=1,
            textvariable=self.cur_yjk_tow_num_name)
        self.cmb_yjk_tower.pack(side=tk.LEFT,
                                expand=tk.YES,
                                fill=tk.X,
                                padx=5,
                                pady=5)
        self.frame_yjk_tower.pack(side=tk.TOP, fill=tk.X)

        # floor number cmb
        self.frame_yjk_floor = tk.Frame(self.lf_yjk)
        self.lbl_yjk_floor = tk.Label(self.frame_yjk_floor,
                                      width=__width_label_lc,
                                      text='Floor Number',
                                      anchor=tk.W)
        self.lbl_yjk_floor.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_yjk_floor = ttk.Combobox(
            self.frame_yjk_floor,
            state="readonly",
            height=1,
            textvariable=self.cur_yjk_flr_num_name)
        self.cmb_yjk_floor.pack(side=tk.LEFT,
                                expand=tk.YES,
                                fill=tk.X,
                                padx=5,
                                pady=5)
        self.frame_yjk_floor.pack(side=tk.TOP, fill=tk.X)

        # result content cmb
        self.frame_yjk_content = tk.Frame(self.lf_yjk)
        self.lbl_yjk_content = tk.Label(self.frame_yjk_content,
                                        width=__width_label_lc,
                                        text='Content',
                                        anchor=tk.W)
        self.lbl_yjk_content.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_yjk_content = ttk.Combobox(
            self.frame_yjk_content,
            state="readonly",
            height=1,
            textvariable=self.cur_yjk_content_name)
        self.cmb_yjk_content.pack(side=tk.LEFT,
                                  expand=tk.YES,
                                  fill=tk.X,
                                  padx=5,
                                  pady=5)
        self.frame_yjk_content.pack(side=tk.TOP, fill=tk.X)

        # self.yjk_tree
        self.yjk_tree = ttk.Treeview(self.lf_yjk, show='headings')
        self.yjk_tree['column'] = ['a', 'b', 'c']
        self.yjk_tree.column('a', width=18)
        self.yjk_tree.column('b', width=18)
        self.yjk_tree.column('c', width=18)
        self.yjk_tree.heading('a', text='Tower No.')
        self.yjk_tree.heading('b', text='Floor No.')
        self.yjk_tree.heading('c', text='content')
        self.yjk_tree.pack(side=tk.TOP, expand=tk.YES, fill=tk.BOTH)

        self.scr_yjk_tree = tk.Scrollbar(self.yjk_tree)
        self.scr_yjk_tree.pack(side=tk.RIGHT, fill=tk.Y)

        self.yjk_tree.config(yscrollcommand=self.scr_yjk_tree.set)
        self.scr_yjk_tree.config(command=self.yjk_tree.yview)

        # self.lbl_yjk_tree
        self.lbl_yjk_tree = tk.Label(self.lf_yjk,
                                     anchor=tk.W,
                                     textvariable=self.lbl_yjk_tree_content)
        self.lbl_yjk_tree.pack(side=tk.TOP, fill=tk.X)

        self.lf_yjk.pack(side=tk.TOP, expand=tk.YES, fill=tk.BOTH)
        # end of labelframe yjk results

        # labelframe of etabs results
        self.lf_etabs = tk.LabelFrame(self.frame_result_list, text='ETABS')

        # load combination cmb
        self.frame_etabs_lc = tk.Frame(self.lf_etabs)
        self.lbl_etabs_lc = tk.Label(self.frame_etabs_lc,
                                     width=__width_label_lc,
                                     text='Load Combination',
                                     anchor=tk.W)
        self.lbl_etabs_lc.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_etabs_lc = ttk.Combobox(self.frame_etabs_lc,
                                         state="readonly",
                                         height=1,
                                         textvariable=self.cur_etabs_lc)
        self.cmb_etabs_lc.pack(side=tk.LEFT,
                               expand=tk.YES,
                               fill=tk.X,
                               padx=5,
                               pady=5)
        self.frame_etabs_lc.pack(side=tk.TOP, fill=tk.X)

        # tower number cmb
        self.frame_etabs_tower = tk.Frame(self.lf_etabs)
        self.lbl_etabs_tower = tk.Label(self.frame_etabs_tower,
                                        width=__width_label_lc,
                                        text='Tower Number',
                                        anchor=tk.W)
        self.lbl_etabs_tower.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_etabs_tower = ttk.Combobox(
            self.frame_etabs_tower,
            state="readonly",
            height=1,
            textvariable=self.cur_etabs_tow_num_name)
        self.cmb_etabs_tower.pack(side=tk.LEFT,
                                  expand=tk.YES,
                                  fill=tk.X,
                                  padx=5,
                                  pady=5)
        self.frame_etabs_tower.pack(side=tk.TOP, fill=tk.X)

        # floor number cmb
        self.frame_etabs_floor = tk.Frame(self.lf_etabs)
        self.lbl_etabs_floor = tk.Label(self.frame_etabs_floor,
                                        width=__width_label_lc,
                                        text='Floor Number',
                                        anchor=tk.W)
        self.lbl_etabs_floor.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_etabs_floor = ttk.Combobox(
            self.frame_etabs_floor,
            state="readonly",
            height=1,
            textvariable=self.cur_etabs_flr_num_name)
        self.cmb_etabs_floor.pack(side=tk.LEFT,
                                  expand=tk.YES,
                                  fill=tk.X,
                                  padx=5,
                                  pady=5)
        self.frame_etabs_floor.pack(side=tk.TOP, fill=tk.X)

        # result content cmb
        self.frame_etabs_content = tk.Frame(self.lf_etabs)
        self.lbl_etabs_content = tk.Label(self.frame_etabs_content,
                                          width=__width_label_lc,
                                          text='Content',
                                          anchor=tk.W)
        self.lbl_etabs_content.pack(side=tk.LEFT, fill=tk.X)
        self.cmb_etabs_content = ttk.Combobox(
            self.frame_etabs_content,
            state="readonly",
            height=1,
            textvariable=self.cur_etabs_content_name)
        self.cmb_etabs_content.pack(side=tk.LEFT,
                                    expand=tk.YES,
                                    fill=tk.X,
                                    padx=5,
                                    pady=5)
        self.frame_etabs_content.pack(side=tk.TOP, fill=tk.X)

        # self.etabs_tree
        self.etabs_tree = ttk.Treeview(self.lf_etabs, show='headings')
        self.etabs_tree['column'] = ['a', 'b', 'c']
        self.etabs_tree.column('a', width=18)
        self.etabs_tree.column('b', width=18)
        self.etabs_tree.column('c', width=18)
        self.etabs_tree.heading('a', text='Tower No.')
        self.etabs_tree.heading('b', text='Floor No.')
        self.etabs_tree.heading('c', text='content')
        self.etabs_tree.pack(side=tk.TOP, expand=tk.YES, fill=tk.BOTH)

        self.scr_etabs_tree = tk.Scrollbar(self.etabs_tree)
        self.scr_etabs_tree.pack(side=tk.RIGHT, fill=tk.Y)

        self.etabs_tree.config(yscrollcommand=self.scr_etabs_tree.set)
        self.scr_etabs_tree.config(command=self.etabs_tree.yview)

        # self.lbl_etabs_tree
        self.lbl_etabs_tree = tk.Label(
            self.lf_etabs,
            anchor=tk.W,
            textvariable=self.lbl_etabs_tree_content)
        self.lbl_etabs_tree.pack(side=tk.TOP, fill=tk.X)

        self.lf_etabs.pack(side=tk.TOP, expand=tk.YES, fill=tk.BOTH)

        # self.lf_data_import
        self.lf_data_import = tk.LabelFrame(self.frame_result_list,
                                            text='action')

        # button yjk import
        self.btn_yjk_import = Button(self.lf_data_import,
                                     text='add YJK data',
                                     width=18,
                                     command=self.import_yjk)
        self.btn_yjk_import.pack(side=tk.LEFT, anchor=tk.W, padx=36)

        # button etabs import
        self.btn_etabs_import = Button(self.lf_data_import,
                                       text='add ETABS data',
                                       width=18,
                                       command=self.import_etabs)
        self.btn_etabs_import.pack(side=tk.LEFT, anchor=tk.CENTER, padx=36)

        # button merge and import
        self.btn_merge = Button(self.lf_data_import,
                                text='merge and add',
                                width=18,
                                command=self.merge_import)
        self.btn_merge.pack(side=tk.LEFT, anchor=tk.E, padx=36)

        self.lf_data_import.pack(side=tk.TOP, fill=tk.X)

        self.frame_result_list.pack(side=tk.LEFT,
                                    expand=tk.YES,
                                    fill=tk.BOTH,
                                    padx=5,
                                    pady=5)
        # end widget in frame_result_list

        # start widget in frame_data_table
        self.frame_data_table = Frame(self)
        self.frame_table = Frame(self.frame_data_table)
        self.data_table = Table(self.frame_table,
                                rows=50,
                                cols=10,
                                showstatusbar=True)
        self.data_table.show()
        self.frame_table.pack(side=tk.TOP, expand=tk.YES, fill=tk.BOTH)
        self.frame_tower = Frame(self.frame_data_table)
        self.lbl_tower = Label(self.frame_data_table,
                               text='tower No.').pack(side=tk.BOTTOM)
        self.tower_scale = Scale(self.frame_data_table,
                                 orient=tk.HORIZONTAL,
                                 length=300,
                                 width=16,
                                 sliderlength=10,
                                 from_=0,
                                 to=10,
                                 tickinterval=1,
                                 variable=self.cur_tower_number,
                                 command=self.tower_select)
        self.tower_scale.pack(side=tk.BOTTOM, fill=tk.BOTH)
        self.frame_tower.pack(side=tk.TOP, fill=tk.X)
        self.frame_data_table.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
        # end widget in frame_data_table

        # start widget in frame_image
        self.frame_image = Frame(self)
        self.fig = Figure(figsize=(3.378, 4.331), dpi=150)
        self.ax = self.fig.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame_image)
        self.canvas.get_tk_widget().pack(side=tk.TOP)
        self.canvas.draw()
        toolbar = NavigationToolbar2Tk(self.canvas, self.frame_image)
        toolbar.update()
        self.canvas.get_tk_widget().pack(side=tk.TOP)

        self.lf_plot_control = tk.LabelFrame(self.frame_image, text='plot')

        self.lbl = Label(self.lf_plot_control, text='none').pack(side=tk.LEFT,
                                                                 fill=tk.X)
        self.btn_batch_plot = Button(self.lf_plot_control,
                                     text='batch plot',
                                     command=self.batch_plot)
        self.btn_batch_plot.pack(side=tk.RIGHT)

        self.lf_plot_control.pack(side=tk.BOTTOM, fill=tk.X)

        self.frame_image.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
        # end widget in frame_image

        self.data_table.zoomOut()
        self.data_table.zoomOut()

        self.action_bind()

    def action_bind(self):
        # action when yjk cmb selected
        self.cmb_yjk_lc.bind("<<ComboboxSelected>>", self.update_yjk_cmb)
        self.cmb_yjk_tower.bind("<<ComboboxSelected>>", self.update_yjk_tree)
        self.cmb_yjk_floor.bind("<<ComboboxSelected>>", self.update_yjk_tree)
        self.cmb_yjk_content.bind("<<ComboboxSelected>>", self.update_yjk_tree)

        # action when etabs cmb selected
        self.cmb_etabs_lc.bind("<<ComboboxSelected>>", self.update_etabs_cmb)
        self.cmb_etabs_tower.bind("<<ComboboxSelected>>",
                                  self.update_etabs_tree)
        self.cmb_etabs_floor.bind("<<ComboboxSelected>>",
                                  self.update_etabs_tree)
        self.cmb_etabs_content.bind("<<ComboboxSelected>>",
                                    self.update_etabs_tree)

    def get_path(self):
        """
        get path of yjk result by FilePath class.
        update yjk widgets.
        :return:
        """
        self.file_path.get_path()
        self.entry_yjk_path.delete(0, tk.END)
        self.entry_yjk_path.insert(tk.END, self.file_path.yjk_path)
        self.yjk_update()

    def get_file_name(self):
        """
        get filename of etabs result in excel format by FilePath class.
        update etabs widgets.
        :return:
        """
        self.file_path.get_path(openfile=True)
        self.entry_etabs_name.delete(0, tk.END)
        self.entry_etabs_name.insert(tk.END, self.file_path.etabs_name)
        if self.file_path.etabs_name is not None and self.file_path.etabs_name != '':
            self.etabs_update()

    def get_type(self):
        self.yjk_update()
        self.etabs_update()

    def yjk_update(self):
        if self.file_path.yjk_path is not None and os.path.exists(
                self.file_path.yjk_path) is True:
            self.cur_result_type = self.result_type.get()
            if self.cur_result_type == 'drift':
                with open(self.file_path.full_name('Wdisp.out'), 'r') as f:
                    self.cur_yjk_class = Wdisp.Wdisp(f.read())
                    self.cmb_yjk_lc['values'] = self.cur_yjk_class.cqc
                    self.cmb_yjk_lc.current(0)
                    self.cmb_yjk_lc.configure(
                        height=len(self.cur_yjk_class.cqc))
            elif self.cur_result_type == 'dsp_r' or self.result_type.get(
            ) == 'dft_r':
                with open(self.file_path.full_name('Wdisp.out'), 'r') as f:
                    self.cur_yjk_class = Wdisp.Wdisp(f.read())
                    self.cmb_yjk_lc['values'] = self.cur_yjk_class.spc_lateral
                    self.cmb_yjk_lc.current(0)
                    self.cmb_yjk_lc.configure(
                        height=len(self.cur_yjk_class.spc_lateral))
            elif self.cur_result_type == 'mass':
                with open(self.file_path.full_name('wmass.out'), 'r') as f:
                    self.cur_yjk_class = Wmass.Wmass(f.read())
                    self.cmb_yjk_lc['values'] = ['mass_info']
                    self.cmb_yjk_lc.current(0)
            elif self.cur_result_type == 'mass_density':
                with open(self.file_path.full_name('wmass.out'), 'r') as f:
                    self.cur_yjk_class = Wmass.Wmass(f.read())
                    self.cmb_yjk_lc['values'] = ['mass_density_detail']
                    self.cmb_yjk_lc.current(0)
            elif self.cur_result_type == 'stf':
                with open(self.file_path.full_name('wmass.out'), 'r') as f:
                    self.cur_yjk_class = Wmass.Wmass(f.read())
                    self.cmb_yjk_lc['values'] = ['stiffness_detail']
                    self.cmb_yjk_lc.current(0)
            elif self.cur_result_type == 's_c':
                with open(self.file_path.full_name('wmass.out'), 'r') as f:
                    self.cur_yjk_class = Wmass.Wmass(f.read())
                    self.cmb_yjk_lc['values'] = ['storey_shear_capacity_info']
                    self.cmb_yjk_lc.current(0)
            elif self.cur_result_type == 'period':
                with open(self.file_path.full_name('wzq.out'), 'r') as f:
                    self.cur_yjk_class = Wzq.Wzq(f.read())
                    self.cmb_yjk_lc['values'] = ['period']
                    self.cmb_yjk_lc.current(0)
            elif self.cur_result_type == 's_a_f':
                with open(self.file_path.full_name('wzq.out'), 'r') as f:
                    self.cur_yjk_class = Wzq.Wzq(f.read())
                    self.cmb_yjk_lc['values'] = ['shear_adjust_factor']
                    self.cmb_yjk_lc.current(0)
            elif self.cur_result_type == 's_s_c':
                with open(self.file_path.full_name('wzq.out'), 'r') as f:
                    self.cur_yjk_class = Wzq.Wzq(f.read())
                    self.cmb_yjk_lc['values'] = self.cur_yjk_class.s_s_c
                    self.cmb_yjk_lc.current(0)

            self.read_yjk_df()
            self.update_yjk_cmb(None)

    def read_yjk_df(self):
        if len(self.cmb_yjk_lc['values']) != 0:
            self.cur_yjk_df = getattr(self.cur_yjk_class,
                                      self.cur_yjk_lc.get())

    def update_yjk_cmb(self, event):
        self.read_yjk_df()
        _columns = self.cur_yjk_df.columns.tolist()
        if self.result_type.get() == 'drift':
            self.position = (1, 0, len(_columns) - 3)
        elif self.result_type.get() == 'dsp_r':
            self.position = (1, 0, len(_columns) - 1)
        elif self.result_type.get() == 'dft_r':
            self.position = (1, 0, 5)
        elif self.result_type.get() == 'mass':
            self.position = (1, 0, 5)
        elif self.result_type.get() == 'mass_density':
            self.position = (1, 0, 3)
        elif self.result_type.get() == 'stf':
            self.position = (1, 0, len(_columns) - 3)
        elif self.result_type.get() == 's_c':
            self.position = (1, 0, len(_columns) - 2)
        elif self.cur_result_type == 'period':
            self.position = (0, 1, 3)
        elif self.cur_result_type == 's_a_f':
            self.position = (1, 0, 2)
        elif self.cur_result_type == 's_s_c':
            self.position = (1, 0, 4)
        self.cmb_yjk_tower['values'] = _columns
        self.cmb_yjk_tower.configure(height=len(_columns))
        self.cmb_yjk_tower.current(self.position[0])
        self.cmb_yjk_floor['values'] = _columns
        self.cmb_yjk_floor.configure(height=len(_columns))
        self.cmb_yjk_floor.current(self.position[1])
        self.cmb_yjk_content['values'] = _columns
        self.cmb_yjk_content.configure(height=len(_columns))
        self.cmb_yjk_content.current(self.position[2])
        self.update_yjk_tree(None)

    def update_yjk_tree(self, event):
        if self.cur_yjk_tow_num_name.get() is not None and\
                self.cur_yjk_flr_num_name.get() is not None and \
                self.cmb_yjk_content.get() is not None:
            self.df_yjk_export = self.cur_yjk_df[[
                self.cur_yjk_tow_num_name.get(),
                self.cur_yjk_flr_num_name.get(),
                self.cur_yjk_content_name.get()
            ]]

            _content = self.yjk_tree.get_children()
            for _ in _content:
                self.yjk_tree.delete(_)

            for _ in range(len(self.df_yjk_export) - 1, -1, -1):
                self.yjk_tree.insert(
                    '', 0, values=self.df_yjk_export.iloc[_].tolist())

            self.lbl_yjk_tree_content.set(
                '%d row, %d columns' %
                (self.df_yjk_export.shape[0], self.df_yjk_export.shape[1]))

    def etabs_update(self):
        pass

    def update_etabs_cmb(self, event):
        pass

    def update_etabs_tree(self, event):
        pass

    def import_yjk(self):
        self.data_table.model.df = self.df_yjk_export
        number_groups = self.df_yjk_export.groupby(
            self.df_yjk_export.columns.tolist()[0]).ngroups
        self.tower_scale.config(to=number_groups)
        self.cur_tower_number.set(0)
        self.data_table.redraw()
        self.plot()

    def import_etabs(self):
        self.plot()
        pass

    def merge_import(self):
        self.plot()
        pass

    def tower_select(self, tower_number):
        group_by_tower = self.df_yjk_export.groupby(
            self.df_yjk_export.columns.tolist()[0])
        tower_number = int(tower_number)
        if tower_number == 0:
            self.data_table.model.df = self.df_yjk_export
        else:
            self.data_table.model.df = group_by_tower.get_group(tower_number)
        self.data_table.redraw()
        self.plot()

    def plot(self):
        self.ax.clear()
        tower_number = int(self.cur_tower_number.get())
        if tower_number == 0 and tower_number > 1:
            pass
        elif tower_number > 0:
            if self.result_type.get() == 'drift':
                self.ax.plot(1 / self.data_table.model.df.iloc[:, 2] * 1000,
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('位移角(1/1000)', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.result_type.get() == 'dsp_r':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('位移比', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.result_type.get() == 'dft_r':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('层间位移比', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.result_type.get() == 'mass':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('楼层质量', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.result_type.get() == 'mass_density':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('单位面积楼层质量', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.result_type.get() == 'stf':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('抗侧刚度(v/d)', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.result_type.get() == 's_c':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('楼层受剪承载力', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.cur_result_type == 'period':
                pass
            elif self.cur_result_type == 's_a_f':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('地震剪力放大系数', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            elif self.cur_result_type == 's_s_c':
                self.ax.plot(self.data_table.model.df.iloc[:, 2],
                             self.data_table.model.df.iloc[:, 1],
                             marker='o')
                self.ax.grid(alpha=0.5, linestyle="-.", linewidth=0.3)
                self.ax.set_xlabel('剪重比(%)', fontdict=self.font)
                self.ax.set_ylabel('楼层', fontdict=self.font)
                self.fig.tight_layout(pad=0.3)
            self.canvas.draw()
            pass

    def figure_save(self, fig_name=None):
        if fig_name is None:
            fig_name = '%s.png' % self.cur_yjk_lc.get()
        self.fig.savefig(self.file_path.result_name(fig_name),
                         transparent=True,
                         dpi=300,
                         format='png')

    def batch_plot(self):
        result_type_dict = self.result_type_dict + self.result_type_dict_right + self.result_type_dict_added
        if self.yjk_dir.get() != '' or self.etabs_name.get() != '':
            for name, result_type in result_type_dict:
                self.result_type.set(result_type)
                self.yjk_update()
                for ct, lc_name in enumerate(self.cmb_yjk_lc['values']):
                    self.cur_yjk_lc.set(lc_name)
                    self.update_yjk_cmb(None)
                    self.import_yjk()
                    self.cur_tower_number.set(1)
                    self.tower_select(1)
                    f_name = '%s-%d-%s.png' % (name, ct, lc_name)
                    self.figure_save(f_name)
예제 #18
0
class PeopleSearch:
    def __init__(self, tk_parent, linkedin_conn):

        self.parent = tk_parent
        self.linkedin_conn = linkedin_conn

        self.search_results_df = pd.DataFrame()
        self.search_thread = None
        self.quick_search = True

        # Paned Window
        self.search_paned_window = ttk.PanedWindow(tk_parent,
                                                   orient='horizontal')
        self.search_paned_window.pack(side='top',
                                      fill="both",
                                      expand=True,
                                      padx=10)

        ## Search fields Canvas/ScrolledFrame
        search_fields_canvas = ttk.Canvas(self.search_paned_window)

        search_fields_frame = ScrolledFrame(search_fields_canvas)
        search_fields_frame.pack(side='top', fill='both', expand=True, padx=5)
        search_fields_frame.hide_scrollbars()

        ### Load/Save search
        load_save_btn_frame = ttk.Frame(search_fields_frame)
        load_save_btn_frame.pack(pady=5, side='top', fill="x")

        load_search_btn = ttk.Button(load_save_btn_frame, text="Load param.")
        load_search_btn.pack(side='left')
        load_search_btn['command'] = self.load_search_config

        save_search_btn = ttk.Button(load_save_btn_frame, text="Save param.")
        save_search_btn.pack(side='right', padx=10)
        save_search_btn['command'] = self.save_search_config

        ### Connections
        conn_frame = ttk.Frame(search_fields_frame)
        conn_frame.pack(pady=10, side='top', fill='x')
        conn_lbl = ttk.Label(conn_frame, text="Connections")
        conn_lbl.pack(side='left', expand=False)
        ToolTip(conn_lbl,
                text=f"Degree of Connection with the logged in user.")

        first_con = ttk.BooleanVar()
        second_con = ttk.BooleanVar()
        third_con = ttk.BooleanVar()

        self.con_dict_list = [{
            'bool_val': first_con,
            'name': 'F'
        }, {
            'bool_val': second_con,
            'name': 'S'
        }, {
            'bool_val': third_con,
            'name': 'O'
        }]

        ttk.Checkbutton(conn_frame,
                        text="1st",
                        variable=first_con,
                        bootstyle="primary").pack(side='left', padx=10)
        ttk.Checkbutton(conn_frame,
                        text="2nd",
                        variable=second_con,
                        bootstyle="primary").pack(side='left', padx=10)
        ttk.Checkbutton(conn_frame,
                        text="3rd+",
                        variable=third_con,
                        bootstyle="primary").pack(side='left', padx=10)

        ttk.Separator(search_fields_frame,
                      orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Connection of
        self.conn_of_frame = SearchFrame(
            search_fields_frame,
            title='Connection of',
            single_choice=True,
            fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(
                linkedin_conn[0].get_contact_urn_ids, x))
        self.conn_of_frame.pack(side='top', fill="x")

        ttk.Separator(search_fields_frame,
                      orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Location Frame
        self.loc_frame = SearchFrame(
            search_fields_frame,
            title='Location',
            fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(
                linkedin_conn[0].get_geo_urn_ids, x))
        self.loc_frame.pack(side='top', fill="x")

        ttk.Separator(search_fields_frame,
                      orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Current Company frame
        self.current_comp_frame = SearchFrame(
            search_fields_frame,
            title='Current Company',
            fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(
                linkedin_conn[0].get_company_urn_ids, x))
        self.current_comp_frame.pack(side='top', fill="x")

        ttk.Separator(search_fields_frame,
                      orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Past Company frame
        self.past_comp_frame = SearchFrame(
            search_fields_frame,
            title='Past Company',
            fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(
                linkedin_conn[0].get_company_urn_ids, x))
        self.past_comp_frame.pack(side='top', fill="x", pady=5)

        ttk.Separator(search_fields_frame,
                      orient='horizontal').pack(side='top', fill='x', pady=5)

        ### School frame
        self.school_frame = SearchFrame(
            search_fields_frame,
            title='School',
            fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(
                linkedin_conn[0].get_school_urn_ids, x))
        self.school_frame.pack(side='top', fill="x", pady=5)

        ttk.Separator(search_fields_frame,
                      orient='horizontal').pack(side='top', fill='x', pady=5)

        ### Industry frame
        self.industry_frame = SearchFrame(
            search_fields_frame,
            title='Industry',
            fetch_fct=lambda x: utils.extract_urn_dict_from_query_results(
                linkedin_conn[0].get_industry_urn_ids, x))
        self.industry_frame.pack(side='top', fill="x", pady=5)

        ### KW-Header
        kw_header_frame = ttk.Frame(search_fields_frame)
        kw_header_frame.pack(pady=5, side='top', fill="x")
        ttk.Label(kw_header_frame, text="Keywords").pack(side='left')
        ttk.Separator(kw_header_frame, orient='horizontal').pack(side='left',
                                                                 fill='x',
                                                                 expand=True)

        ### KW-Frame
        kw_frame = ttk.Frame(search_fields_frame)
        kw_frame.pack(pady=5, side='top', fill="x")
        kw_frame.grid_columnconfigure(0, weight=1)
        kw_frame.grid_columnconfigure(1, weight=1)
        kw_frame.grid_rowconfigure(0, weight=1)
        kw_frame.grid_rowconfigure(1, weight=1)
        kw_frame.grid_rowconfigure(2, weight=1)

        #### General
        self.entry_keywords = PlaceholderEntry(kw_frame, 'General')
        self.entry_keywords.grid(row=0,
                                 column=0,
                                 sticky='nwse',
                                 padx=5,
                                 pady=4)

        #### First Name
        self.entry_keywords_first_name = PlaceholderEntry(
            kw_frame, 'First Name')
        self.entry_keywords_first_name.grid(row=0,
                                            column=1,
                                            sticky='nwse',
                                            padx=5,
                                            pady=4)

        #### Last Name
        self.entry_keywords_last_name = PlaceholderEntry(kw_frame, 'Last Name')
        self.entry_keywords_last_name.grid(row=1,
                                           column=0,
                                           sticky='nwse',
                                           padx=5,
                                           pady=4)

        #### Title
        self.entry_keywords_title = PlaceholderEntry(kw_frame, 'Title')
        self.entry_keywords_title.grid(row=1,
                                       column=1,
                                       sticky='nwse',
                                       padx=5,
                                       pady=4)

        #### Company
        self.entry_keywords_company = PlaceholderEntry(kw_frame, 'Company')
        self.entry_keywords_company.grid(row=2,
                                         column=0,
                                         sticky='nwse',
                                         padx=5,
                                         pady=4)

        #### School
        self.entry_keywords_school = PlaceholderEntry(kw_frame, 'School')
        self.entry_keywords_school.grid(row=2,
                                        column=1,
                                        sticky='nwse',
                                        padx=5,
                                        pady=4)

        self.search_paned_window.add(search_fields_canvas)

        ## Table frame
        self.table_main_frame = ttk.Frame(tk_parent)
        # pandastable
        self.table_frame = ttk.Frame(self.table_main_frame,
                                     bootstyle="secondary",
                                     borderwidth=2)
        self.table_frame.pack(side="top", fill="both", expand=True)
        self.table = Table(self.table_frame,
                           dataframe=pd.DataFrame(),
                           showtoolbar=False,
                           showstatusbar=True)
        utils.fit_table_style_to_theme(self.table, ttk.Style())
        self.table.unbind_all("<Tab>")
        self.table.unbind_all("<Return>")
        self.table.show()

        self.search_paned_window.add(self.table_main_frame)

        # Buttons frame
        btn_frame = ttk.Frame(tk_parent)
        btn_frame.pack(padx=10, pady=10, side='top', fill="x")

        quick_search_btn = ttk.Button(btn_frame, text="Quick search")
        quick_search_btn.pack(side='left', padx=10)
        quick_search_btn['command'] = self.start_quick_search
        ToolTip(
            quick_search_btn,
            "This is a single request that will yield the same results as in the linkedin search bar. \
\nIt doesn't contain any personal details (only public IDs) \
\nYou're not likely to reach any search limit using this mode.")

        btn_sub_frame = ttk.Frame(btn_frame)
        btn_sub_frame.pack(side="left", fill="none", expand=True)

        start_search_btn = ttk.Button(btn_sub_frame,
                                      text="Deep Search",
                                      bootstyle='danger')
        start_search_btn.pack(side='left', padx=10)
        start_search_btn['command'] = self.start_deep_search
        ToolTip(
            start_search_btn,
            "Each search result will be fetched for additional information. \
            \nDepending on the number of results and search frequency, this can trigger the linkedin limit \
after which you'll only be able to get 3 results per search until the end of the month."
        )

        self.get_skills = ttk.BooleanVar()
        skills_chk_btn = ttk.Checkbutton(btn_sub_frame,
                                         text="Fetch skills",
                                         variable=self.get_skills,
                                         bootstyle="danger")
        skills_chk_btn.pack(side='left', padx=10)
        ToolTip(
            skills_chk_btn,
            text=f"Fetch skills by running one additional request per result.")

        self.get_contact_info = ttk.BooleanVar()
        contact_info_chk_btn = ttk.Checkbutton(btn_sub_frame,
                                               text="Fetch contact info",
                                               variable=self.get_contact_info,
                                               bootstyle="danger")
        contact_info_chk_btn.pack(side='left', padx=10)
        ToolTip(
            contact_info_chk_btn,
            text=
            f"Fetch contact info by running one additional request per result."
        )

        self.export_to_file_btn = ttk.Button(btn_frame,
                                             text="Export to File",
                                             state="disabled")
        self.export_to_file_btn.pack(side='left', padx=10)
        self.export_to_file_btn[
            'command'] = self.prepare_dataframe_and_save_to_xsl

        # Status frame
        self.status_frame = ttk.Frame(tk_parent)
        self.status_frame.pack(padx=10,
                               pady=2,
                               side='bottom',
                               expand=False,
                               fill="x")
        self.status_str = ttk.StringVar(value="")
        ttk.Label(self.status_frame,
                  textvariable=self.status_str).pack(side='left', expand=False)

        ttk.Separator(tk_parent, orient='horizontal').pack(side='bottom',
                                                           fill='x')

    def save_search_config(self):
        chosen_file = filedialog.asksaveasfile(mode='w',
                                               filetypes=[("JSON", ".json")],
                                               defaultextension=".json")
        if chosen_file is None:
            return
        config_dict = {
            'people_search': {
                'connections':
                [x['name'] for x in self.con_dict_list if x['bool_val'].get()],
                'connection_of':
                [[x.lbl_name.get(), x.value]
                 for x in self.conn_of_frame.get_current_selection()],
                'location': [[x.lbl_name.get(), x.value]
                             for x in self.loc_frame.get_current_selection()],
                'current_company':
                [[x.lbl_name.get(), x.value]
                 for x in self.current_comp_frame.get_current_selection()],
                'past_company':
                [[x.lbl_name.get(), x.value]
                 for x in self.past_comp_frame.get_current_selection()],
                'school': [[x.lbl_name.get(), x.value]
                           for x in self.school_frame.get_current_selection()],
                'industries':
                [[x.lbl_name.get(), x.value]
                 for x in self.industry_frame.get_current_selection()],
                'general_kw':
                self.entry_keywords.get(),
                'first_name_kw':
                self.entry_keywords_first_name.get(),
                'last_name_kw':
                self.entry_keywords_last_name.get(),
                'title_kw':
                self.entry_keywords_title.get(),
                'company_kw':
                self.entry_keywords_company.get(),
                'school_kw':
                self.entry_keywords_school.get(),
            }
        }
        with open(chosen_file.name, 'w') as f:
            json.dump(config_dict, f, indent=4)

        self.status_str.set(
            f"Search config successfully saved at {chosen_file.name}!")

    def load_search_config(self):
        chosen_file = filedialog.askopenfile(mode='r',
                                             filetypes=[("JSON", ".json")],
                                             defaultextension=".json")
        if chosen_file is None:
            return
        try:
            with open(chosen_file.name, 'r') as f:
                config_dict = json.load(f)
            config = config_dict['people_search']
        except:
            self.status_str.set(
                f"Please select a valid people search configuration!")

        utils.set_bools_from_list(self.con_dict_list, config['connections'])
        self.conn_of_frame.load_name_val_from_list(config['connection_of'])
        self.loc_frame.load_name_val_from_list(config['location'])
        self.current_comp_frame.load_name_val_from_list(
            config['current_company'])
        self.past_comp_frame.load_name_val_from_list(config['past_company'])
        self.school_frame.load_name_val_from_list(config['school'])
        self.industry_frame.load_name_val_from_list(config['industries'])

        self.entry_keywords.replace_text(config['general_kw'])
        self.entry_keywords_first_name.replace_text(config['first_name_kw'])
        self.entry_keywords_last_name.replace_text(config['last_name_kw'])
        self.entry_keywords_title.replace_text(config['title_kw'])
        self.entry_keywords_company.replace_text(config['company_kw'])
        self.entry_keywords_school.replace_text(config['school_kw'])

        self.status_str.set(f"Config loaded succesfully!")

    def run_search(self):
        self.search_results_df = pd.DataFrame()
        self.table.updateModel(TableModel(self.search_results_df))
        self.table.redraw()
        self.status_str.set("Running search...")
        self.parent.update()
        try:
            # see doc under https://linkedin-api.readthedocs.io/en/latest/api.html
            search_result = self.linkedin_conn[0].search_people(
                network_depths=[
                    x['name'] for x in self.con_dict_list
                    if x['bool_val'].get()
                ],
                connection_of=next(
                    (x.value
                     for x in self.conn_of_frame.get_current_selection()),
                    None),
                regions=[
                    x.value for x in self.loc_frame.get_current_selection()
                ],
                current_company=[
                    x.value
                    for x in self.current_comp_frame.get_current_selection()
                ],
                past_companies=[
                    x.value
                    for x in self.past_comp_frame.get_current_selection()
                ],
                schools=[
                    x.value for x in self.school_frame.get_current_selection()
                ],
                industries=[
                    x.value
                    for x in self.industry_frame.get_current_selection()
                ],
                keywords=self.entry_keywords.get(),
                keyword_first_name=self.entry_keywords_first_name.get(),
                keyword_last_name=self.entry_keywords_last_name.get(),
                keyword_title=self.entry_keywords_title.get(),
                keyword_company=self.entry_keywords_company.get(),
                keyword_school=self.entry_keywords_school.get(),
            )

            if self.quick_search:
                self.search_results_df = pd.DataFrame(search_result)
                self.table.updateModel(TableModel(self.search_results_df))
                self.table.redraw()

            else:
                result_size = len(search_result)
                self.status_str.set(
                    "Found " + str(result_size) +
                    " results! Searching contact details... This can take a while..."
                )
                self.parent.update()

                if result_size > 999:
                    answer_is_yes = messagebox.askyesno(
                        "Too many results!",
                        "This search yields more than 1000 results (upper limit for this app).\nProceed anyway?",
                        icon="warning")
                    if not answer_is_yes:
                        self.status_str.set("Search cancelled.")
                        self.parent.update()
                        return

                row = 1

                for people in search_result:
                    profile = self.linkedin_conn[0].get_profile(
                        urn_id=people['urn_id'])
                    if profile != {}:
                        if 'geoLocationName' in profile.keys():
                            geolocation = profile['geoLocationName']
                        else:
                            geolocation = ""

                        profile_dict = {
                            'First Name': [profile['firstName']],
                            'Last Name': [profile['lastName']],
                            'Title': [profile['experience'][0]['title']],
                            'Company':
                            [profile['experience'][0]['companyName']],
                            'Location': [geolocation],
                            'Headline': [profile['headline']],
                            'Profile Link': [
                                'https://www.linkedin.com/in/' +
                                profile['profile_id']
                            ]
                        }

                        if self.get_skills.get():
                            skills_raw = self.linkedin_conn[
                                0].get_profile_skills(urn_id=people['urn_id'])
                            skills = [dic['name'] for dic in skills_raw]
                            profile_dict.update({'Skills': [skills]})

                        if self.get_contact_info.get():
                            contact_info = self.linkedin_conn[
                                0].get_profile_contact_info(
                                    urn_id=people['urn_id'])
                            contact_info = {
                                k: [v]
                                for k, v in contact_info.items()
                            }
                            profile_dict.update(contact_info)

                        self.search_results_df = pd.concat([
                            self.search_results_df,
                            pd.DataFrame(profile_dict)
                        ])

                        self.table.updateModel(
                            TableModel(self.search_results_df))
                        self.table.redraw()
                        self.status_str.set("Scanned " + str(row) +
                                            " out of " + str(result_size) +
                                            " profiles")
                        self.parent.update()

                        row += 1

            self.export_to_file_btn.configure(state="normal")
            self.status_str.set("Done")
            self.parent.update()
        except Exception as e:
            utils.show_exception(e)
            self.status_str.set(
                "Something went wrong! Check console output for more details.")
            self.parent.update()

    def create_search_thread(self):
        if not self.linkedin_conn[0]:
            messagebox.showinfo("Error",
                                "First log into Linkedin!",
                                icon="error")
            return
        if self.search_thread and self.search_thread.is_alive():
            messagebox.showinfo(
                "Search in progress",
                "Another search is still running.\nWait until it finishes or restart the program.",
                icon="warning")
            return
        self.search_thread = threading.Thread(target=self.run_search)
        self.search_thread.daemon = True
        self.search_thread.start()

    def start_quick_search(self):
        self.quick_search = True
        self.create_search_thread()

    def start_deep_search(self):
        self.quick_search = False
        self.create_search_thread()

    def prepare_dataframe_and_save_to_xsl(self):
        self.status_str.set("Exporting to File...")
        export_file = utils.save_dataframe_to_file(self.search_results_df)

        if export_file is not None:
            self.status_str.set("Table saved under " + export_file)
        else:
            self.status_str.set("Table could not be saved!")
예제 #19
0
class Application(tk.Frame):
    
    def __init__(self, master=None):
        super().__init__(master)

        self.main = self.master
        self.main.geometry('600x400+200+100')
        self.main.title('Budgeting Project')
        f = tk.Frame(self.main)
        f.pack()

        self.df = readInCSV('budget.csv')

        self.table = Table(f, dataframe=self.df,
                                showtoolbar=False, showstatusbar=False)
    
        self.table.show()

        self.pack()
        self.createWidgets()

    def ts(self):
        timeseries(self.df)

    def pies(self):
        pie(self.df)

    def createWidgets(self): # creates buttons for each function
        self.modifyButton = tk.Button(self)
        self.modifyButton["text"] = "Modify Entry"
        self.modifyButton["command"] = self.modifyRowEntry
        self.modifyButton.pack(side="top")

        self.addButton = tk.Button(self)
        self.addButton["text"] = "Add New Expense"
        self.addButton["command"] = self.addNewExpense
        self.addButton.pack(side="top")

        self.deleteButton = tk.Button(self)
        self.deleteButton["text"] = "Delete Expense"
        self.deleteButton["command"] = self.delete
        self.deleteButton.pack(side="top")

        self.graphButton = tk.Button(self)
        self.graphButton["text"] = "Scatter Plot Graph"
        self.graphButton["command"] = self.ts
        self.graphButton.pack(side="top")

        self.graphButton = tk.Button(self)
        self.graphButton["text"] = "Pie Graph"
        self.graphButton["command"] = self.pies
        self.graphButton.pack(side="top")  

        self.quit = tk.Button(self, text="QUIT", fg="red", # calls savefile before ending program 
                              command= lambda:[self.savefile(),root.destroy()])
        self.quit.pack(side="bottom")

 

    def savefile(self): # rewrites CSV file with updated data
        f = open("budget.csv","w")
        self.df.to_csv(f, index = False, header = True)
        print("oo")
        f.close

    # Adds a new expense to the dataframe
    def addNewExpense(self):

        top = tk.Toplevel()
        top.title("Add New Expense")

        dateLabel = tk.Label(top, text='Date', font=('Times', 12))
        typeLabel = tk.Label(top, text='Category', font=('Times', 12))
        amountLabel = tk.Label(top, text='Amount', font=('Times', 12))

        dateLabel.grid(row=0,column=0)
        typeLabel.grid(row=1,column=0)
        amountLabel.grid(row=2,column=0)

        dateEntry = tk.Entry(top)
        typeEntry = tk.Entry(top)
        amountEntry = tk.Entry(top)

        dateEntry.grid(row=0,column=1)
        typeEntry.grid(row=1,column=1)
        amountEntry.grid(row=2,column=1)

        addButton = tk.Button(top,text="Add Expense",
                    command=lambda:[self.addExpenseToDf(dateEntry.get(),
                                    typeEntry.get(),
                                    amountEntry.get()),
                                    top.destroy()])

        addButton.grid(row=3,column=0)
    # Helper method to add expense to dataframe
    def addExpenseToDf(self, date, category, amount):
        self.df = newexpense(df=self.df, amount=amount, category=category, date=date)
        self.table.redraw()
        self.table.sortTable(0) # Sort by column index 0, which is date

    # Modify a row entry 
    def modifyRowEntry(self):

        top = tk.Toplevel()
        top.title("Modify Row Entry")

        rowLabel = tk.Label(top, text='Row to Modify', font=('Times', 12))
        dateLabel = tk.Label(top, text='Date (Optional)', font=('Times', 12))
        typeLabel = tk.Label(top, text='Category (Optional)', font=('Times', 12))
        amountLabel = tk.Label(top, text='Amount (Optional)', font=('Times', 12))

        rowLabel.grid(row=0,column=0)
        dateLabel.grid(row=1,column=0)
        typeLabel.grid(row=2,column=0)
        amountLabel.grid(row=3,column=0)

        rowEntry = tk.Entry(top)
        dateEntry = tk.Entry(top)
        typeEntry = tk.Entry(top)
        amountEntry = tk.Entry(top)

        rowEntry.grid(row=0, column=1)
        dateEntry.grid(row=1,column=1)
        typeEntry.grid(row=2,column=1)
        amountEntry.grid(row=3,column=1)

        addButton = tk.Button(top,text="Modify Expense",
                    command=lambda:[self.modifyExpenseToDf(rowEntry.get(),
                                    dateEntry.get(),
                                    typeEntry.get(),
                                    amountEntry.get()),
                                    top.destroy()])

        addButton.grid(row=4,column=0)

    # Helper method to modify row entry
    def modifyExpenseToDf(self, row, date, category, amount):
        try:
            row = int(row)
            row = row - 1 # Reduce row value by 1 to match with index value
        except: 
            print("Please enter an integer for the row value")
            return

        if row < 0 or row >= self.df.shape[0]:
            print("Please enter a valid integer value")
            return

        if date == "":
            date = None
        if category == "":
            category = None
        if amount == "":
            amount = None
        self.df = modifyEntry(df=self.df, row=row, date=date, category=category, amount=amount)
        self.table.redraw()
        self.table.sortTable(0) # Sort by column index 0, which is date

    # Delete row entry 
    def delete(self):    
        d = tk.Toplevel()

        l = tk.Label(d, text = "Row: ")
        l.pack()
        
        row = tk.Entry(d)
        row.pack()

        dButton = tk.Button(d, text = "Delete", command = lambda: [self.deleteRow(row.get()), d.destroy()])
        dButton.pack()

    # Helper method to delete a row in the dataframe
    def deleteRow(self, row):
        try:
            x = int(row) - 1
            if x < self.df.shape[0] and x >= 0:
                self.df = deleteRowEntry(df=self.df, row=x)
                self.table.model.df = self.df
                self.table.redraw()
                self.table.sortTable(0)
            else:
                print("Please enter a valid row number")
                return
        except ValueError:
            print("Please enter a number")
예제 #20
0
class Window:
    # Initialize PanedWindow widget
    def __init__(self):
        # Creates the root window
        self.root = Tk()

        # Creates size of the window
        self.root.geometry("1000x600")

        # Set the title of our master widget
        self.root.title("Data Science GUI")

        # Width and height for window
        self.width = 1280
        self.height = 720

        # Creates a menu instance
        menu = Menu(self.root)
        self.root.config(menu=menu)

        # Creates a file object for "File" option
        # Adds several commands to the "File" option
        fileMenu = Menu(menu, tearoff=0)
        fileMenu.add_command(label="Open File", command=self.openFile)
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self.client_exit)

        # Creates a help object for "Help" option
        # Adds a command to "Help" option
        helpMenu = Menu(menu, tearoff=0)
        helpMenu.add_command(label="View parameter descriptions",
                             command=self.displayParameterDesc)

        # Adds the options to the menu
        menu.add_cascade(label="File", menu=fileMenu)
        menu.add_cascade(label="Help", menu=helpMenu)

        # Paned window for Top (main stuff) and Bottom (mainLog)
        main = PanedWindow(self.root,
                           orient=VERTICAL,
                           sashpad=1,
                           sashrelief=RAISED)
        main.pack(fill=BOTH, expand=1)

        # Paned window for left (choosing features/label and parameters/algorithm) and right (displaying csv log and results log)
        top = PanedWindow(main,
                          orient=HORIZONTAL,
                          sashpad=1,
                          sashrelief=RAISED)

        # Log for main stuff
        bottom = PanedWindow(main,
                             orient=HORIZONTAL,
                             sashpad=1,
                             sashrelief=RAISED)

        # Adds top and bottom panedwindows
        main.add(top, height=440)
        main.add(bottom, height=200)

        # Paned Window for choosing features/label and parameters/algorithm
        left = PanedWindow(top,
                           orient=HORIZONTAL,
                           sashpad=1,
                           sashrelief=RAISED)

        # LabelFrame for Main Frame
        labelFrameForMainFrame = LabelFrame(left, text="Main Frame")
        self.mainFrame = Frame(labelFrameForMainFrame)
        self.mainFrame.pack()

        # Add the label frame
        left.add(labelFrameForMainFrame)

        # Paned window for CSV File and Results
        right = PanedWindow(top, orient=VERTICAL, sashpad=1, sashrelief=RAISED)

        # Add left and right panedwindows
        top.add(left, width=500)
        top.add(right, width=300)

        # LabelFrame for CSV log
        self.labelFrameForCSVFile = LabelFrame(top, text="CSV not specified")
        # Table for CSV file
        self.df = None
        self.csvTable = Table(self.labelFrameForCSVFile,
                              dataframe=self.df,
                              showstatusbar=True)
        self.csvTable.show()

        # LabelFrame for Results log
        self.labelFrameForResult = LabelFrame(top,
                                              text="results not specified")
        # Log for Results
        self.resultLog = Text2(self.labelFrameForResult,
                               width=self.width,
                               height=self.height - 300)
        self.resultLog.pack()

        # Add the two labelframes for displaying CSV file and Result Log
        right.add(self.labelFrameForCSVFile, height=220)
        right.add(self.labelFrameForResult, height=220)

        # Show this at the beginning of the GUI
        label = Label(self.mainFrame,
                      text="To start, click 'File' and open a CSV file.")
        label.pack()

        # Labelframe for Main log
        labelFrameForMainLog = LabelFrame(bottom, text="Main log")
        # Log for main frame
        self.mainLog = Text2(labelFrameForMainLog,
                             width=self.width,
                             height=self.height - 300)
        self.mainLog.insert("Started the Data Science GUI!\n")
        self.mainLog.pack()

        # Add Labelframe for main log
        bottom.add(labelFrameForMainLog)

        self.root.mainloop()

    # Open the link
    def openHyperlinkCallback(self, event):
        webbrowser.open_new(event.widget.cget("text"))

    def displayParameterDesc(self):
        # Destroy if result window and log exists.
        try:
            self.window.destroy()
            self.parameterDescLog.destroy()
        except (NameError, AttributeError):
            pass

        try:
            # Create a new frame/window from root window to display parameter descriptions
            self.window = Toplevel(self.root)
            self.window.geometry("640x300")
            self.window.title("Parameters of " + self.algorithm)

            # Display link to documentation url
            hyperlinkLabel = Label(self.window,
                                   text=self.paramDesc["link"],
                                   fg="blue",
                                   cursor="hand2")
            hyperlinkLabel.pack()
            hyperlinkLabel.bind("<Button-1>", self.openHyperlinkCallback)

            # Parameter descriptions
            self.parameterDescLog = Text2(self.window,
                                          width=self.width,
                                          height=self.height)
            self.parameterDescLog.pack()

            # Print out the results
            for key, value in self.paramDesc.items():
                if key == "link":
                    pass
                else:
                    self.parameterDescLog.insert(
                        str(key) + ": " + str(value) + "\n\n")

        except (NameError, AttributeError):
            # Display this if user hasn't open a CSV file and select an algorithm
            label = Label(
                self.window,
                text=
                "You need to open a CSV file and select an algorithm before displaying this!"
            )
            label.pack()
            pass

    # Display the csv file in text
    def displayFile(self):
        self.csvTable.model.df = pd.concat([self.X, self.y], axis=1)
        self.csvTable.redraw()

    # Display results of selected algorithm and parameters
    def displayResult(self, dict):
        # Notify the user that training is done
        self.mainLog.insert("Done computing.\n")

        # Clear result log and change label frame
        self.resultLog.delete()
        self.labelFrameForResult.config(text="Results for " + self.filename +
                                        " using " + self.algorithm)

        # Print out the results
        for key, value in dict.items():
            self.resultLog.insert(str(key) + ": " + str(value) + "\n")

    def displayPredictionWindow(self):
        # Create a new frame/window from root window to display parameter descriptions
        self.predictionWindow = Toplevel(self.root)
        self.predictionWindow.geometry("480x240")
        self.predictionWindow.title("Prediction Window of " + self.algorithm)

        # Width and height for window
        width = 480
        height = 240

        # Paned window for left and right
        main = PanedWindow(self.predictionWindow,
                           orient=HORIZONTAL,
                           sashpad=1,
                           sashrelief=RAISED)
        main.pack(fill=BOTH, expand=1)

        # Paned window for left  and right
        left = PanedWindow(main, orient=VERTICAL, sashpad=1, sashrelief=RAISED)

        # Log for prediction stuff
        right = PanedWindow(main,
                            orient=VERTICAL,
                            sashpad=1,
                            sashrelief=RAISED)

        main.add(left, width=int(width / 2))
        main.add(right, width=int(width / 2))

        # LabelFrame for Left Frame
        labelFrameForLeftFrame = LabelFrame(left, text="Prediction Frame")

        # Object containing feature columns and their datatypes
        self.datatypes = self.X.dtypes

        # Validation command
        # %d = Type of action (1=insert, 0=delete, -1 for others)
        # %P = value of the entry if the edit is allowed (all, focusin, focusout, forced)
        vcmdForInt = (self.predictionWindow.register(self.validateInt2), '%d',
                      '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        vcmdForFloat = (self.predictionWindow.register(self.validateFloat),
                        '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        vcmdForFloat2 = (self.predictionWindow.register(self.validateFloat2),
                         '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')

        # Contains entries
        arrayOfEntries = []

        # Counter for row
        counterForRow = 0

        # Go through an object that contains the feature columns and their datatypes
        for attr, value in self.datatypes.items():
            Label(labelFrameForLeftFrame, text=attr).grid(row=counterForRow,
                                                          sticky=W)

            entry = None
            if (value == "int64"):
                entry = Entry(labelFrameForLeftFrame,
                              width=30,
                              validate="all",
                              validatecommand=vcmdForInt)
                entry.insert(0, 1)
            elif (value == "float64"):
                entry = Entry(labelFrameForLeftFrame,
                              width=30,
                              validate="all",
                              validatecommand=vcmdForFloat2)
                entry.insert(0, 1.0)

            entry.grid(row=counterForRow, column=1, sticky=E)
            arrayOfEntries.append(entry)
            counterForRow = counterForRow + 1

        button = Button(labelFrameForLeftFrame,
                        text="Predict",
                        command=lambda: self.predict(arrayOfEntries))
        button.grid(row=counterForRow, columnspan=2, sticky=W + E)

        left.add(labelFrameForLeftFrame, width=int(width / 2), height=height)

        # LabelFrame for Right Frame
        labelFrameForRightFrame = LabelFrame(right, text="Prediction Frame")
        # Table for Predictions
        self.prediction_df = pd.DataFrame(
            columns=self.X.columns.values.tolist())
        self.predictionTable = Table(labelFrameForRightFrame,
                                     dataframe=self.prediction_df,
                                     showstatusbar=True)
        self.predictionTable.show()

        right.add(labelFrameForRightFrame, width=int(width / 2), height=height)

    # For user-input predictions
    def predict(self, entries):
        for entry in entries:
            if not entry.get().strip():
                self.predictionWindow.bell()
                self.mainLog.insert(
                    "Check the parameters! You may have entered nothing or 0 for an input!\n"
                )
                return

        counter = 0
        arrayForUserInput = []
        dict = {}
        for attr, datatype in self.datatypes.items():
            if (datatype == "int64"):
                arrayForUserInput.append(int(entries[counter].get()))
            elif (datatype == "float64"):
                arrayForUserInput.append(float(entries[counter].get()))

            dict[attr] = entries[counter].get()

            counter = counter + 1

        arrayForUserInput = np.array(arrayForUserInput).reshape(1, -1)

        prediction = self.classifier.predict(arrayForUserInput)[0]
        dict['Prediction'] = prediction

        self.prediction_df = self.prediction_df.append(dict, ignore_index=True)
        self.predictionTable.model.df = self.prediction_df
        self.predictionTable.redraw()

    # Remove features from label listbox when user selects the features
    def removeFeatures(self, event):
        # Note here that Tkinter passes an event object
        w = event.widget

        # Indexes of selected features
        indexes = w.curselection()

        # Columns of dataframe
        cols = list(self.df.columns.values)

        selected_features = [cols[item] for item in indexes]

        self.list_of_label.delete(0, END)

        for col in cols:
            if col not in selected_features:
                self.list_of_label.insert(0, col)

    # Prompts the user to open a CSV File
    def openFile(self):
        # The full path of the file
        file = filedialog.askopenfilename(initialdir=getcwd() + "/csv",
                                          title="Select file",
                                          filetypes=(("csv files", "*.csv"), ))

        if file:
            # Actual filename
            self.filename = os.path.basename(file)

            # Notify user that program is reading off the csv
            self.mainLog.insert("Reading '" + self.filename + "' from '" +
                                file + "'.\n")

            # Clear the selection_Frame
            # Clear the widgets in the selection frame after you selected features and labels
            for widget in self.mainFrame.winfo_children():
                widget.destroy()

            # Change LabelFrame text to filename
            self.labelFrameForCSVFile.config(text=self.filename)

            # Clear Results log
            self.resultLog.delete()

            # Dataframe created from the file
            self.df = pd.read_csv(file, sep=',')

            # Draw the CSV table
            self.csvTable.model.df = self.df
            self.csvTable.redraw()

            # Columns of dataframe
            cols = list(self.df.columns.values)

            # Create a listbox
            self.list_of_features = Listbox(self.mainFrame,
                                            selectmode=MULTIPLE,
                                            width=30,
                                            height=10,
                                            exportselection=0)
            self.list_of_features.bind('<<ListboxSelect>>',
                                       self.removeFeatures)
            self.list_of_label = Listbox(self.mainFrame,
                                         selectmode=SINGLE,
                                         width=30,
                                         height=10,
                                         exportselection=0)

            # Show a list of columns for user to check
            for column in cols:
                self.list_of_features.insert(END, column)
                self.list_of_label.insert(END, column)

            # Display label, listbox, and button
            Label(self.mainFrame,
                  text="Select the feature columns",
                  relief=RIDGE).pack()
            self.list_of_features.pack()

            Label(self.mainFrame, text="Select the label", relief=RIDGE).pack()
            self.list_of_label.pack()

            ok = Button(self.mainFrame,
                        text="Okay",
                        command=self.setUpMatrixes)
            ok.pack()

    # Set up the feature matrix and label vector
    def setUpMatrixes(self):
        # The selections of feature columns and labels
        columns = self.list_of_features.get(0, END)
        indexesForFeatureCols = self.list_of_features.curselection()
        selected_features = [columns[item] for item in indexesForFeatureCols]
        selected_label = self.list_of_label.get(ANCHOR)

        # Clear the widgets in the selection frame after you selected features and labels
        for widget in self.mainFrame.winfo_children():
            widget.destroy()

        # Notify user of selected features and label
        self.mainLog.insert("You have selected " + str(selected_features) +
                            " as features.\n")
        self.mainLog.insert("You have selected " + str(selected_label) +
                            " as the label.\n")

        # Feature matrix and label vector
        self.X = self.df[selected_features]
        self.y = self.df[selected_label]

        # Labels
        self.labels = self.df[selected_label].unique()

        # Number of features and labels
        self.numberOfFeatures = len(selected_features)
        self.numberOfLabels = len(self.labels)

        # Option Menu for choosing machine learning algorithms
        algorithms = [
            "K-Nearest Neighbors", "Decision Tree", "Random Forest",
            "Linear Regression", "Logistic Regression", "Linear SVC",
            "Multilayer Perceptron"
        ]
        self.default = StringVar()
        self.default.set("Select an algorithm.")
        self.options = OptionMenu(self.mainFrame,
                                  self.default,
                                  *algorithms,
                                  command=self.selectedAlgorithm)
        self.options.pack()

        # Display the csv file
        self.displayFile()

    # Display parameters for the selected algorithm
    def selectedAlgorithm(self, algorithm):
        # Clear the widgets in the selection frame when changing algorithm
        for widget in self.mainFrame.winfo_children():
            widget.destroy()

        # Option Menu for choosing machine learning algorithms
        algorithms = [
            "K-Nearest Neighbors", "Decision Tree", "Random Forest",
            "Linear Regression", "Logistic Regression", "Linear SVC",
            "Multilayer Perceptron"
        ]
        self.default = StringVar()
        self.default.set(algorithm)
        self.options = OptionMenu(self.mainFrame,
                                  self.default,
                                  *algorithms,
                                  command=self.selectedAlgorithm)
        self.options.pack()

        # Validation command
        # %d = Type of action (1=insert, 0=delete, -1 for others)
        # %P = value of the entry if the edit is allowed (all, focusin, focusout, forced)
        vcmdForInt = (self.mainFrame.register(self.validateInt), '%d', '%i',
                      '%P', '%s', '%S', '%v', '%V', '%W')
        vcmdForFloat = (self.mainFrame.register(self.validateFloat), '%d',
                        '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        vcmdForFloat2 = (self.mainFrame.register(self.validateFloat2), '%d',
                         '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        vcmdForHiddenLayerSizes = (self.mainFrame.register(
            self.validateHiddenLayerSizes), '%d', '%i', '%P', '%s', '%S', '%v',
                                   '%V', '%W')

        self.algorithm = algorithm

        # Load image
        load = Image.open("img/" + algorithm + ".png")

        # Load image
        load = load.resize((100, 100), Image.ANTIALIAS)
        render = ImageTk.PhotoImage(load)

        # Labels can be text or images
        img = Label(self.mainFrame, image=render)
        img.image = render
        img.pack()

        self.paramDesc = {}
        parameters = []

        Label(self.mainFrame, text="test_size", relief=RIDGE).pack()
        self.test_size = Entry(self.mainFrame,
                               validate="all",
                               validatecommand=vcmdForFloat)
        self.test_size.insert(0, 0.3)
        self.test_size.pack()
        parameters.append(self.test_size)

        Label(self.mainFrame, text="random_state", relief=RIDGE).pack()
        self.random_state = Entry(self.mainFrame,
                                  validate="all",
                                  validatecommand=vcmdForInt)
        self.random_state.insert(0, 2)
        self.random_state.pack()
        parameters.append(self.random_state)

        Label(self.mainFrame, text="cv", relief=RIDGE).pack()
        self.cv = Entry(self.mainFrame,
                        validate="all",
                        validatecommand=vcmdForInt)
        self.cv.insert(0, 10)
        self.cv.pack()
        parameters.append(self.cv)

        self.paramDesc[
            "test_size"] = "float, int or None, optional (default=0.25)\nIf float, should be between 0.0 and 1.0 and represent the proportion of the dataset to include in the test split. If int, represents the absolute number of test samples. If None, the value is set to the complement of the train size. By default, the value is set to 0.25. The default will change in version 0.21. It will remain 0.25 only if train_size is unspecified, otherwise it will complement the specified train_size."
        self.paramDesc[
            "random_state"] = "int, RandomState instance or None, optional (default=None)\nIf int, random_state is the seed used by the random number generator; If RandomState instance, random_state is the random number generator; If None, the random number generator is the RandomState instance used by np.random."
        self.paramDesc[
            "cv"] = " int, cross-validation generator or an iterable, optional\nDetermines the cross-validation splitting strategy. Possible inputs for cv are:\nNone, to use the default 3-fold cross validation,\ninteger, to specify the number of folds in a (Stratified)KFold,\nAn object to be used as a cross-validation generator.\nAn iterable yielding train, test splits."

        if self.algorithm == "K-Nearest Neighbors":
            Label(self.mainFrame, text="n_neighbors", relief=RIDGE).pack()
            self.n_neighbors = Entry(self.mainFrame,
                                     validate="all",
                                     validatecommand=vcmdForInt)
            self.n_neighbors.insert(0, 5)
            self.n_neighbors.pack()
            parameters.append(self.n_neighbors)

            self.paramDesc[
                "link"] = "https:////scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html"
            self.paramDesc[
                "n_neighbors"] = "int, optional (default = 5)\nNumber of neighbors to use by default for kneighbors queries."

        elif algorithm == "Decision Tree":
            self.paramDesc[
                "link"] = "https////scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html"

        elif algorithm == "Random Forest":
            Label(self.mainFrame, text="n_estimators", relief=RIDGE).pack()
            self.n_estimators = Entry(self.mainFrame,
                                      validate="all",
                                      validatecommand=vcmdForInt)
            self.n_estimators.insert(0, 19)
            self.n_estimators.pack()
            parameters.append(self.n_estimators)

            self.paramDesc[
                "link"] = "https:////scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html"
            self.paramDesc[
                "n_estimators"] = "integer, optional (default=10)\nThe number of trees in the forest."

        elif algorithm == "Linear Regression":
            self.paramDesc[
                "link"] = "https:////scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html"

        elif algorithm == "Logistic Regression":
            self.paramDesc[
                "link"] = "https:////scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html"

        elif algorithm == "Linear SVC":
            Label(self.mainFrame, text="C", relief=RIDGE).pack()
            self.c = Entry(self.mainFrame,
                           validate="all",
                           validatecommand=vcmdForFloat2)
            self.c.insert(0, 1.0)
            self.c.pack()
            parameters.append(self.c)

            Label(self.mainFrame, text="max_iter", relief=RIDGE).pack()
            self.max_iter = Entry(self.mainFrame,
                                  validate="all",
                                  validatecommand=vcmdForInt)
            self.max_iter.insert(0, 100)
            self.max_iter.pack()
            parameters.append(self.max_iter)

            self.paramDesc[
                "link"] = "https:////scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html"
            self.paramDesc[
                "C"] = "float, optional (default=1.0)\nPenalty parameter C of the error term."
            self.paramDesc[
                "max_iter"] = "int, (default=1000)\nThe maximum number of iterations to be run."

        elif algorithm == "Multilayer Perceptron":
            Label(self.mainFrame, text="max_iter", relief=RIDGE).pack()
            self.max_iter = Entry(self.mainFrame,
                                  validate="all",
                                  validatecommand=vcmdForInt)
            self.max_iter.insert(0, 100)
            self.max_iter.pack()
            parameters.append(self.max_iter)

            Label(self.mainFrame, text="alpha", relief=RIDGE).pack()
            self.alpha = Entry(self.mainFrame,
                               validate="all",
                               validatecommand=vcmdForFloat2)
            self.alpha.insert(0, 0.005)
            self.alpha.pack()
            parameters.append(self.alpha)

            Label(self.mainFrame, text="hidden_layer_sizes",
                  relief=RIDGE).pack()
            self.hidden_layer_sizes = Entry(
                self.mainFrame,
                validate="all",
                validatecommand=vcmdForHiddenLayerSizes)
            self.hidden_layer_sizes.insert(0, 2)
            self.hidden_layer_sizes.pack()
            parameters.append(self.hidden_layer_sizes)

            self.paramDesc[
                "link"] = "https:////scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPClassifier.html"
            self.paramDesc[
                "max_iter"] = "int, (default=1000)\nThe maximum number of iterations to be run."
            self.paramDesc[
                "alpha"] = "float, optional, default 0.0001\nL2 penalty (regularization term) parameter."
            self.paramDesc[
                "hidden_layer_sizes"] = "tuple, length = n_layers - 2, default (100,)\nThe ith element represents the number of neurons in the ith hidden layer."

        # Compute using the specified parameters
        # Lambda means that the method won't be called immediately (only when button is pressed)
        submit = Button(self.mainFrame,
                        text="Submit",
                        command=lambda: self.validateAllInputs(parameters))
        submit.pack()

        # Notify user that program is reading off the csv
        self.mainLog.insert(self.algorithm + " has been selected!\n")

    # Validate integer inputs (don't allow user to enter anything else)
    def validateInt(self, d, i, P, s, S, v, V, W):
        # print("end", "OnValidate:\n")
        # print("end", "d='%s'\n" % d)
        # print("end", "i='%s'\n" % i)
        # print("end", "P='%s'\n" % P)
        # print("end", "s='%s'\n" % s)
        # print("end", "S='%s'\n" % S)
        # print("end", "v='%s'\n" % v)
        # print("end", "V='%s'\n" % V)
        # print("end", "W='%s'\n" % W)

        # Accept Integer values and empty string (for erasing the one only number)
        if (P.isdigit() and int(P) > 0) or P == "":
            return True
        else:
            self.mainLog.insert(
                "Please enter an integer (if the field is empty, enter an integer greater than 0).\n"
            )
            self.mainFrame.bell()
            return False

    # Validate integer inputs (don't allow user to enter anything else)
    def validateInt2(self, d, i, P, s, S, v, V, W):
        # Accept Integer values and empty string (for erasing the one only number)
        if (P.isdigit() and int(P) >= 0) or P == "":
            return True
        else:
            self.mainLog.insert(
                "Please enter an integer (if the field is empty, enter an integer greater than 0).\n"
            )
            self.mainFrame.bell()
            return False

    # Validate float inputs (don't allow user to enter anything else)
    def validateFloat(self, d, i, P, s, S, v, V, W):
        # Accept Float values and empty string (for erasing the one only number)
        if P == "":
            return True
        elif S == " ":
            self.mainLog.insert("No spaces! Enter a digit!\n")
            self.mainFrame.bell()
            return False

        try:
            number = float(P)

            if (0.0 <= number and number <= 1.0):
                return True
            else:
                self.mainLog.insert(
                    "Float numbers must be between 0.0 and 1.0 (inclusive)!\n")
                self.mainFrame.bell()
                return False
        except ValueError:
            self.mainLog.insert(
                "Float numbers are only allowed (ex: 0.3 or .3)!\n")
            self.mainFrame.bell()
            return False

    # Vaidate float inputs (don't allow user to enter anything else)
    def validateFloat2(self, d, i, P, s, S, v, V, W):
        # Accept Float values and empty string (for erasing the one only number)
        if P == "":
            return True
        elif S == " ":
            self.mainLog.insert("No spaces! Enter a digit!\n")
            self.mainFrame.bell()
            return False

        try:
            number = float(P)

            if (0.0 <= number and number <= 1000.0):
                return True
            else:
                self.mainLog.insert(
                    "Float numbers must be between 0.00001 and 1000.0 (inclusive)!\n"
                )
                self.mainFrame.bell()
                return False
        except ValueError:
            self.mainLog.insert(
                "Float numbers are only allowed (ex: 0.00001 or .00001)!\n")
            self.mainFrame.bell()
            return False

    # Vaidate hidden layer sizes inputs (don't allow user to enter anything else)
    def validateHiddenLayerSizes(self, d, i, P, s, S, v, V, W):
        # Accept Float values and empty string (for erasing the one only number)
        if P == "":
            return True

        try:
            if S.isdigit() or S == "," or S == "":
                return True
            else:
                self.mainLog.insert(
                    "Hidden layer sizes should be separated by commas (ex: 2,3,4). This means there are 2 nodes in first hidden layer, 3 nodes in second hidden layer, and 4 nodes in the third hidden layer.!\n"
                )
                self.mainFrame.bell()
                return False
        except ValueError:
            self.mainLog.insert(
                "Hidden layer sizes should be separated by commas (ex: 2,3,4). This means there are 2 nodes in first hidden layer, 3 nodes in second hidden layer, and 4 nodes in the third hidden layer.!\n"
            )
            self.mainFrame.bell()
            return False

    # Final validation of inputs (doesn't compute anything if a parameter is field or is 0
    def validateAllInputs(self, parameters):
        for parameter in parameters:
            if not parameter.get().strip() or parameter.get() == "0":
                self.mainFrame.bell()
                self.mainLog.insert(
                    "Check the parameters! You may have entered nothing or 0 for an input!\n"
                )
                return

        self.compute()

    # Compute the results of
    def compute(self):
        self.mainLog.insert("Computing...\n")
        self.classifier = None

        # Split the dataframe dataset.
        X_train, X_test, y_train, y_test = train_test_split(
            self.X,
            self.y,
            test_size=float(self.test_size.get()),
            random_state=int(self.random_state.get()))

        if self.algorithm == "K-Nearest Neighbors":
            # Instantiating KNN object
            self.classifier = KNeighborsClassifier(
                n_neighbors=int(self.n_neighbors.get()))
        elif self.algorithm == "Decision Tree":
            # Instantiating DecisionTreeClassifier object
            self.classifier = DecisionTreeClassifier()
        elif self.algorithm == "Random Forest":
            # Instantiating RandomForestClassifier object
            self.classifier = RandomForestClassifier(n_estimators=int(
                self.n_estimators.get()),
                                                     bootstrap=True)
        elif self.algorithm == "Linear Regression":
            # Instantiating Linear Regression object
            self.classifier = LinearRegression()
        elif self.algorithm == "Logistic Regression":
            # Instantiating Logistic Regression object
            self.classifier = LogisticRegression()
        elif self.algorithm == "Linear SVC":
            # LinearSVC classifier
            self.classifier = LinearSVC()
        elif self.algorithm == "Multilayer Perceptron":
            # Turn the string (containing commas) into a list
            modified_hidden_layer_sizes = self.hidden_layer_sizes.get().split(
                ",")

            # Remove any empty string in the list
            modified_hidden_layer_sizes = [
                item.strip() for item in modified_hidden_layer_sizes
                if item.strip()
            ]

            # Turn the list of strings into a tuple of int
            modified_hidden_layer_sizes = tuple(
                [int(i) for i in modified_hidden_layer_sizes])

            # Instantiate MLP classifier
            self.classifier = MLPClassifier(
                activation='logistic',
                solver='adam',
                max_iter=int(self.max_iter.get()),
                learning_rate_init=0.002,
                alpha=float(self.alpha.get()),
                hidden_layer_sizes=modified_hidden_layer_sizes)

        # fit the model with the training set
        self.classifier.fit(X_train, y_train)

        # Predict method is used for creating a prediction on testing data
        y_predict = self.classifier.predict(X_test)

        # Accuracy of testing data on predictive model
        accuracy = accuracy_score(y_test, y_predict)

        # Add #-fold Cross Validation with Supervised Learning
        accuracy_list = cross_val_score(self.classifier,
                                        self.X,
                                        self.y,
                                        cv=int(self.cv.get()),
                                        scoring='accuracy')

        # # Report
        # report = classification_report(y_test, y_predict, target_names=self.labels)

        # Dictionary containing information
        dict = {
            "Training Set Size": 1.00 - float(self.test_size.get()),
            "Testing Set Size": float(self.test_size.get()),
            "Training Set Shape": X_train.shape,
            "Testing Set Shape": X_test.shape,
            "Classifier": self.classifier,
            "Accuracy for " + self.algorithm: str(accuracy),
            "Cross Validation for " + self.algorithm: accuracy_list.mean()
        }

        self.displayResult(dict)
        self.displayPredictionWindow()

    # Exit the client
    def client_exit(self):
        exit()
예제 #21
0
class CAPE_UI:
    def __init__(self, parent, conn, config, frame_color='light yellow'):
        self.conn = conn
        self.config = config
        self.cur = self.conn.cursor()
        self.frame_color = frame_color
        # self.assigned_local_table = assigned_local_table
        # self.assigned_global_table = assigned_global_table

        style = ttk.Style()
        style.map('TCombobox', fieldbackground=[('readonly', 'white')])
        style.theme_use("clam")
        style.configure("Treeview",
                        background=self.frame_color,
                        fieldbackground=self.frame_color)

        #----------------------------main frame----------------------------------------#

        self.parent = parent
        self.main_frame = Frame(self.parent, bg=self.frame_color)

        self.main_frame.columnconfigure(0, weight=1)
        self.main_frame.columnconfigure(1, weight=8, uniform=1)
        self.main_frame.columnconfigure(2, weight=7, uniform=1)

        self.main_frame.rowconfigure(0, weight=3)
        self.main_frame.rowconfigure(1, weight=2)
        self.main_frame.rowconfigure(2, weight=2)
        self.main_frame.rowconfigure(3, weight=2)
        self.main_frame.rowconfigure(4, weight=2)
        self.main_frame.rowconfigure(5, weight=2)
        self.main_frame.rowconfigure(6, weight=2)
        self.main_frame.rowconfigure(7, weight=2)
        self.main_frame.rowconfigure(8, weight=2)
        self.main_frame.rowconfigure(9, weight=2)

        #----------------------------------place frames----------------------------------#

        self.main_frame.grid(column=0,
                             row=0,
                             columnspan=3,
                             rowspan=10,
                             sticky='nsew')

        self.table_frame = Frame(self.main_frame,
                                 borderwidth=5,
                                 relief="sunken",
                                 bg=self.frame_color)
        self.table_frame.grid(column=0,
                              row=0,
                              columnspan=1,
                              rowspan=10,
                              sticky='nsew')

        self.table_frame.rowconfigure(0, weight=1)
        self.table_frame.rowconfigure(1, weight=14)

        self.query_frame = Frame(self.main_frame,
                                 borderwidth=5,
                                 relief="ridge",
                                 bg=self.frame_color)
        self.query_frame.grid(column=1,
                              row=0,
                              columnspan=1,
                              rowspan=2,
                              sticky='nsew')

        self.query_frame.rowconfigure(0, weight=5)
        self.query_frame.rowconfigure(1, weight=1)

        self.query_template_frame = Frame(self.query_frame,
                                          bg=self.frame_color)
        self.query_template_frame.grid(row=0, sticky='nsew')

        self.query_button_frame = Frame(self.query_frame, bg=self.frame_color)
        self.query_button_frame.grid(row=1, sticky='nsew')

        self.query_result = Frame(self.main_frame,
                                  borderwidth=5,
                                  relief="sunken",
                                  bg=self.frame_color)
        self.query_result.grid(column=1,
                               row=2,
                               columnspan=1,
                               rowspan=8,
                               sticky='nsew')

        self.local_pattern = Frame(self.main_frame,
                                   borderwidth=5,
                                   relief="sunken",
                                   bg=self.frame_color)
        self.local_pattern.grid(column=2,
                                row=0,
                                columnspan=2,
                                rowspan=5,
                                sticky='nsew')

        self.explanation_frame = Frame(self.main_frame,
                                       borderwidth=5,
                                       relief="sunken",
                                       bg=self.frame_color)
        self.explanation_frame.grid(column=2,
                                    row=5,
                                    columnspan=2,
                                    rowspan=5,
                                    sticky='nsew')

        #---------------------------table frame-----------------------------------------

        self.table_info = Label(self.table_frame,
                                text="Database Information",
                                font=('Times New Roman bold', 15),
                                bg=self.frame_color,
                                borderwidth=5,
                                relief=RIDGE)
        self.table_info.grid(column=0, row=0, sticky='nsew')

        self.tree_view_frame = Frame(self.table_frame)
        self.tree_view_frame.grid(column=0, row=1, sticky='nsew')
        self.table_view = ttk.Treeview(self.tree_view_frame)
        self.table_view.pack(side='left', fill=BOTH)

        self.tree_view_scroll = ttk.Scrollbar(self.tree_view_frame,
                                              orient="vertical",
                                              command=self.table_view.yview)
        self.tree_view_scroll.pack(side='right', fill='y')

        self.table_view.configure(yscrollcommand=self.tree_view_scroll.set)

        self.db_info = DBinfo(conn=self.conn)
        self.db_info_dict = self.db_info.get_db_info()

        table_index = 0
        for key, value in self.db_info_dict.items():
            self.table_view.insert('',
                                   'end',
                                   'item' + str(table_index),
                                   text=key)
            for n in value:
                self.table_view.insert('item' + str(table_index),
                                       'end',
                                       text=n)
            table_index += 1

        # self.pub_dict = {"dict_name":"pub",
        # "global_name":"dev.pub_global",
        # "local_name":"dev.pub_local"
        # }

        # self.crime_dict = {"dict_name":"crime",
        # "global_name": "dev.crime_global",
        # "local_name":"dev.crime_local"
        # }

#----------------------------Query frame----------------------------------------#

        self.query_temp = User_Query_Frame(conn=self.conn,
                                           table_dict=self.db_info_dict,
                                           parent=self.query_frame)

        self.query_button = Button(self.query_button_frame,
                                   text="Run Query",
                                   font=('Times New Roman bold', 12),
                                   command=self.run_query)
        self.query_button.pack(side=RIGHT)
        self.show_global_pattern_button = Button(
            self.query_button_frame,
            text="Show Global Pattern",
            font=('Times New Roman bold', 12),
            command=self.show_global_pattern)
        self.show_global_pattern_button.pack(side=RIGHT)
        self.show_local_pattern_button = Button(
            self.query_button_frame,
            text="Show Local Pattern",
            font=('Times New Roman bold', 12),
            command=self.show_local_pattern)
        self.show_local_pattern_button.pack(side=RIGHT)

        #----------------------------Query result frame --------------------------------#
        self.query_result.columnconfigure(0, weight=6)
        self.query_result.columnconfigure(1, weight=1)
        self.query_result.rowconfigure(0, weight=1)
        self.query_result.rowconfigure(1, weight=10)
        self.query_result.rowconfigure(2, weight=10)

        self.result_label = Label(self.query_result,
                                  text='Query Result',
                                  font=('Times New Roman bold', 20),
                                  borderwidth=5,
                                  relief=RIDGE,
                                  bg=self.frame_color)
        self.result_label.grid(row=0, column=0, sticky='nsew')

        self.high_low_frame = Frame(self.query_result, bg=self.frame_color)
        self.high_low_frame.grid(column=1, row=1, rowspan=2, sticky='nsew')

        self.high_low_frame.columnconfigure(0, weight=1)
        self.high_low_frame.rowconfigure(0, weight=1)
        self.high_low_frame.rowconfigure(1, weight=1)
        self.high_low_frame.rowconfigure(2, weight=1)
        self.high_low_frame.rowconfigure(3, weight=1)
        self.high_low_frame.rowconfigure(4, weight=1)
        self.high_low_frame.rowconfigure(5, weight=1)
        self.high_low_frame.rowconfigure(6, weight=1)
        self.high_low_frame.rowconfigure(7, weight=1)

        self.high_button = Button(self.high_low_frame,
                                  text='High',
                                  font=('Times New Roman bold', 12),
                                  command=self.handle_high)
        self.high_button.grid(column=0, row=1)

        self.low_button = Button(self.high_low_frame,
                                 text='Low',
                                 font=('Times New Roman bold', 12),
                                 command=self.handle_low)
        self.low_button.grid(column=0, row=2)

        self.show_results = Frame(self.query_result)
        self.show_results.grid(column=0, row=1, sticky='nsew')

        self.show_global = Frame(self.query_result)
        self.show_global.grid(column=0, row=2, sticky='nsew')

        self.query_result_table = Table(self.show_results)
        self.query_result_table.show()

        self.parent.columnconfigure(0, weight=1)
        self.parent.rowconfigure(0, weight=1)

        #---------------------------Global Pattern Frame -----------------------------------#

        self.show_global.rowconfigure(0, weight=1)
        self.show_global.rowconfigure(1, weight=10)
        self.show_global.columnconfigure(0, weight=1)

        self.global_pattern_label = Label(self.show_global,
                                          text="Global Patterns",
                                          font=('Times New Roman bold', 20),
                                          borderwidth=5,
                                          bg=self.frame_color,
                                          relief=RIDGE)
        self.global_pattern_label.grid(column=0, row=0, sticky='nsew')

        self.show_global_patterns = Frame(self.show_global)
        self.show_global_patterns.grid(column=0, row=1, sticky='nsew')

        self.global_description_button = Button(
            self.high_low_frame,
            text='Describe\nGlobal',
            font=('Times New Roman bold', 12),
            command=self.global_description)
        self.global_description_button.grid(column=0, row=5)

        self.global_pattern_filter_button = Button(
            self.high_low_frame,
            text='Filter \nLocal\n Pattern',
            font=('Times New Roman bold', 12),
            command=self.use_global_filter_local)
        self.global_pattern_filter_button.grid(column=0, row=6)

        self.global_pattern_table = Table(self.show_global_patterns)
        self.global_pattern_table.show()

        # create a sql function for sorting the array in order to be used for filtering

        sort_array_function = "CREATE OR REPLACE FUNCTION array_sort(anyarray) RETURNS anyarray AS $$"+\
        "SELECT array_agg(x order by x) FROM unnest($1) x;"+\
        "$$ LANGUAGE sql;"

        # logger.debug(sort_array_function)
        self.cur.execute(sort_array_function)

        #------------------------------- local pattern frame---------------------------------------#
        self.local_pattern.rowconfigure(0, weight=1)
        self.local_pattern.rowconfigure(1, weight=20)
        self.local_pattern.rowconfigure(2, weight=1)
        self.local_pattern.columnconfigure(0, weight=1)
        self.local_pattern.columnconfigure(1, weight=1)
        self.local_pattern.columnconfigure(2, weight=1)
        self.local_pattern.columnconfigure(3, weight=1)
        self.local_pattern.columnconfigure(4, weight=1)

        self.local_show_patterns = Frame(self.local_pattern)
        self.local_show_patterns.grid(column=0, row=1, sticky='nsew')
        self.local_pattern_label = Label(self.local_pattern,
                                         text="Local Patterns",
                                         font=('Times New Roman bold', 20),
                                         borderwidth=5,
                                         bg=self.frame_color,
                                         relief=RIDGE)
        self.local_pattern_label.grid(column=0,
                                      row=0,
                                      columnspan=5,
                                      sticky='nsew')
        self.local_pattern_filter_button = Button(self.local_pattern,
                                                  text='Reset Query Output',
                                                  font=('Times New Roman bold',
                                                        12),
                                                  command=self.reset_output)
        self.local_pattern_filter_button.grid(column=0, row=2)
        self.local_pattern_filter_button = Button(
            self.local_pattern,
            text='Filter Output',
            font=('Times New Roman bold', 12),
            command=self.show_updated_output)
        self.local_pattern_filter_button.grid(column=2, row=2)
        self.draw_pattern_button = Button(self.local_pattern,
                                          text='Draw Pattern',
                                          font=('Times New Roman bold', 12),
                                          command=self.pop_up_pattern)
        self.draw_pattern_button.grid(column=4, row=2)

        self.local_pattern_table_frame = Frame(self.local_pattern)
        self.local_pattern_table_frame.grid(row=1,
                                            column=0,
                                            columnspan=5,
                                            sticky='nsew')
        self.local_pattern_table = Table(self.local_pattern_table_frame)
        self.local_pattern_table.show()

        #---------------------------------explanation frame-----------------------------#

        self.explanation_frame.rowconfigure(0, weight=1)
        self.explanation_frame.rowconfigure(1, weight=10)
        self.explanation_frame.rowconfigure(2, weight=1)
        self.explanation_frame.columnconfigure(0, weight=10)
        self.exp_label = Label(self.explanation_frame,
                               text="Top Explanations",
                               font=('Times New Roman bold', 20),
                               borderwidth=5,
                               bg=self.frame_color,
                               relief=RIDGE)
        self.exp_label.grid(column=0, row=0, sticky='nsew')
        self.exp_table_frame = Frame(self.explanation_frame)
        self.exp_table_frame.grid(row=1, column=0, sticky='nsew')
        self.exp_table = Table(self.exp_table_frame)
        self.exp_table.show()
        self.describe_exp_button = Button(self.explanation_frame,
                                          text="Describe Explanation",
                                          font=('Times New Roman bold', 12),
                                          command=self.pop_up_explanation)
        self.describe_exp_button.grid(row=2, column=0)


#----------------------------------Functions----------------------------------------#

    def run_query(self):

        self.user_query, self.query_group_str, self.agg_function, self.user_agg, self.agg_name, self.cur_table_name = self.query_temp.get_query(
        )
        # logger.debug(self.user_query)
        self.handle_view ="\nDROP VIEW IF EXISTS user_query;"+\
        "\nCREATE VIEW user_query as "+ self.user_query
        # logger.debug(self.handle_view)
        try:
            self.cur.execute(self.handle_view)
        except:
            tkinter.messagebox.showinfo("Info",
                                        "Invalid Query, Please Doublecheck!")

        self.original_query_result_df = pd.read_sql(self.user_query, self.conn)
        self.query_result_df = self.original_query_result_df

        self.plot_data_convert_dict, self.query_data_convert_dict = self.db_info.get_db_data_type(
            self.cur_table_name)
        self.plot_data_convert_dict[self.agg_name] = 'numeric'
        self.query_data_convert_dict[self.agg_name] = 'float'

        self.assigned_global_table = 'dev.{}_global'.format(
            self.cur_table_name)
        self.assigned_local_table = 'dev.{}_local'.format(self.cur_table_name)

        model = TableModel(dataframe=self.original_query_result_df)
        self.query_result_table.updateModel(model)
        self.query_result_table.redraw()

        # if(self.cur_table_name.lower()==self.pub_dict['dict_name']):
        # 	self.table_dict = self.pub_dict
        # elif(self.cur_table_name.lower()==self.crime_dict['dict_name']):
        # 	self.table_dict = self.crime_dict

    def show_global_pattern(self):

        global_query = "select array_to_string(fixed,',') as Partition,array_to_string(variable,',') as Predictor,agg,"+\
        "round((lambda)::numeric(4,2),2) as Support,model from "+self.assigned_global_table+\
        " where array_to_string(array_sort(fixed||variable),',')='"+self.query_group_str+"';"
        # logger.debug(global_query)
        self.global_pattern_df = pd.read_sql(global_query, self.conn)
        # logger.debug(self.global_pattern_df.head())
        # logger.debug(list(self.global_pattern_df))

        pattern_model = TableModel(dataframe=self.global_pattern_df)
        self.global_pattern_table.updateModel(pattern_model)
        self.global_pattern_table.redraw()

    def show_local_pattern(self):

        local_query = "select array_to_string(fixed,',') as Partition,array_to_string(variable,',') as Predictor,"+\
        "array_to_string(fixed_value,',') as partition_values,agg,model,fixed,fixed_value,variable,"+\
        "theta,param,stats,dev_pos,dev_neg from "+self.assigned_local_table+\
        " where array_to_string(array_sort(fixed||variable),',')='"+self.query_group_str+"';"

        for n in self.local_pattern_table.multiplerowlist:
            self.chosen_local_pattern = self.global_pattern_table.model.df.iloc[
                int(n)]

        self.local_output_pattern_df = pd.read_sql(local_query, self.conn)

        local_shown = self.local_output_pattern_df[[
            'partition', 'partition_values', 'predictor', 'agg'
        ]]

        pattern_model = TableModel(local_shown)
        self.local_pattern_table.updateModel(pattern_model)
        self.local_pattern_table.redraw()

    def use_global_filter_local(self):

        pattern_df_lists = []

        for n in self.global_pattern_table.multiplerowlist:
            model_name = self.global_pattern_table.model.df.iloc[int(
                n)]['model']
            # logger.debug("model_name"+model_name)
            global_partition = self.global_pattern_table.model.df.iloc[int(
                n)]['partition']
            global_predictor = self.global_pattern_table.model.df.iloc[int(
                n)]['predictor']

            g_filter_l_query = " select array_to_string(fixed,',') as Partition,array_to_string(variable,',') as Predictor,"+\
            "array_to_string(fixed_value,',') as partition_values,agg,model,fixed,fixed_value,variable,"+\
            "theta,param,stats,dev_pos,dev_neg from "+self.assigned_local_table+\
            " where array_to_string(fixed,',')='"+global_partition+\
            "' and array_to_string(variable,',')='"+global_predictor+\
            "' and model = '"+model_name+"';"
            self.local_output_pattern_df = pd.read_sql(g_filter_l_query,
                                                       self.conn)
            # logger.debug(g_filter_l_query)

            local_shown = self.local_output_pattern_df[[
                'partition', 'partition_values', 'predictor', 'agg'
            ]]
        model = TableModel(dataframe=local_shown)
        self.local_pattern_table.updateModel(model)
        self.local_pattern_table.redraw()

    def global_description(self):

        for n in self.global_pattern_table.multiplerowlist:
            fixed_attribute = self.global_pattern_table.model.df.iloc[int(
                n)]['partition']
            aggregation_function = self.global_pattern_table.model.df.iloc[int(
                n)]['agg']
            modeltype = self.global_pattern_table.model.df.iloc[int(
                n)]['model']
            variable_attribute = self.global_pattern_table.model.df.iloc[int(
                n)]['predictor']
            Lambda = self.global_pattern_table.model.df.iloc[int(n)]['support']

        fixed_attribute = fixed_attribute.replace(",", ", ")

        global_desc = "For each ("+fixed_attribute+'), the '+aggregation_function +' is '+modeltype+'\n in '+variable_attribute+'.'+\
        'This pattern holds for '+str(Lambda*100)+ ' % of the '+fixed_attribute
        desc_win = Toplevel()
        x = self.parent.winfo_x()
        y = self.parent.winfo_y()
        w = 540
        h = 120
        desc_win.geometry("%dx%d+%d+%d" % (w, h, x + 450, y + 500))
        desc_win.wm_title("Global Pattern Description")
        desc_frame = Frame(desc_win)
        desc_frame.pack(fill=BOTH, expand=True)
        desc_label = Label(desc_frame,
                           text=global_desc,
                           font=('Times New Roman bold', 12),
                           borderwidth=5,
                           relief=SOLID,
                           justify=LEFT)
        desc_label.pack(fill=BOTH, expand=True)

    def use_local_filter_output(
        self
    ):  # given partition attributes and partition values, get explanation(query on user query)
        l_filter_o_query = None

        for n in self.local_pattern_table.multiplerowlist:
            chosen_row = self.local_pattern_table.model.df.iloc[int(n)]
            logger.debug(chosen_row)
            partition_attr_list = self.local_pattern_table.model.df.iloc[int(
                n)]['partition'].split(',')
            partition_value_list = self.local_pattern_table.model.df.iloc[int(
                n)]['partition_values'].split(',')

        where_clause_list = []
        where_clause = None

        for n in range(len(partition_attr_list)):
            if (self.query_data_convert_dict[partition_attr_list[n]] == 'str'):
                condition = "{} =\'{}\'".format(partition_attr_list[n],
                                                partition_value_list[n])
            elif (self.query_data_convert_dict[partition_attr_list[n]] ==
                  'float'):
                condition = "{} = {}::float".format(partition_attr_list[n],
                                                    partition_value_list[n])
            else:
                condition = "{} = {}::int".format(partition_attr_list[n],
                                                  partition_value_list[n])

            where_clause_list.append(condition)

        if (len(where_clause_list) == 1):
            where_clause = where_clause_list[0]
        else:
            where_clause = " and ".join(where_clause_list)

        l_filter_o_query = "select user_query.* from user_query where " + where_clause + ";"
        # logger.debug("filter_output_query:")
        # logger.debug(l_filter_o_query)
        filtered_result_df = pd.read_sql(l_filter_o_query, self.conn)

        return chosen_row, filtered_result_df

    def show_updated_output(self):

        filtered_result_df = self.use_local_filter_output()[1]
        self.query_result_df = filtered_result_df
        model = TableModel(dataframe=filtered_result_df)
        self.query_result_table.updateModel(model)
        self.query_result_table.redraw()

    def handle_question(self, direction):

        self.question_tuple = ''
        config = ExplConfig()
        config.conn = self.config.conn
        config.cur = self.config.cur
        config.query_table_name = self.cur_table_name
        eg = ExplanationGenerator(
            config, {
                'pattern_table': 'dev.{}'.format(self.cur_table_name),
                'query_result_table': self.cur_table_name
            })
        eg.initialize()
        col_name = [
            'Explanation_Tuple', "Score", 'From_Pattern', "Drill_Down_To",
            "Distance", "Outlierness", "Denominator", "relevent_model",
            "relevent_param", "refinement_model", "drill_param"
        ]
        exp_df = pd.DataFrame(columns=[
            "From_Pattern", "Drill_Down_To", "Score", "Distance",
            "Outlierness", "Denominator", "relevent_model", "relevent_param",
            "refinement_model", "drill_param"
        ])
        for n in self.query_result_table.multiplerowlist:

            self.question = self.query_result_table.model.df.iloc[[int(n)]]
            self.original_question = self.question.copy(deep=True)
            self.question.rename(columns={self.agg_name: self.user_agg},
                                 inplace=True)
            self.question_tuple = self.query_result_df.iloc[[int(n)]]
            # logger.debug(self.question)
            self.question['direction'] = direction
            self.question['lambda'] = 0.2
            question = self.question.iloc[0].to_dict()
            # logger.debug(question)
            elist = eg.do_explain_online(question)

            exp_list = []
            for e in elist:
                tuple_list = []
                # print(str(e.tuple_value))
                # print(str(e.tuple_value.keys()))
                # e_tuple_str = ','.join(map(str, e.tuple_value.values()))
                e_tuple_str = e.ordered_tuple_string()
                tuple_list.append(e_tuple_str)

                score = round(e.score, 2)
                tuple_list.append(score)

                if e.expl_type == 1:
                    local_pattern=(
                     '[' + ','.join(e.relevent_pattern[0]) +\
                     '=' + ','.join(list(map(str, e.relevent_pattern[1]))) +']:'+ \
                     ','.join(list(map(str, e.relevent_pattern[2])))+' \u2933 '+self.agg_name
                     )
                    relevent_model = e.relevent_pattern[4]
                    if e.relevent_pattern[4] == 'const':
                        relevent_param = str(
                            round(
                                float(e.relevent_pattern[6].split(',')[0][1:]),
                                2))
                    else:
                        # relevent_param = 'Intercept=' + str(e.relevent_pattern[7]['Intercept'])+', '+str(list(e.relevent_pattern[7])[1])+'='+str(round(e.relevent_pattern[7][list(e.relevent_pattern[7])[1]],2))
                        relevent_param = e.relevent_pattern[7]

                    drill_down_to = ','.join([
                        x for x in e.refinement_pattern[0]
                        if x not in e.relevent_pattern[0]
                    ])
                    refinement_model = e.refinement_pattern[4]
                    if e.refinement_pattern[4] == 'const':

                        drill_param = str(
                            round(
                                float(
                                    e.refinement_pattern[6].split(',')[0][1:]),
                                2))
                    else:
                        drill_param = e.refinement_pattern[7]
                else:
                    relevent_model = e.relevent_pattern[4]
                    local_pattern=(
                     '[' + ','.join(e.relevent_pattern[0]) +\
                     '=' + ','.join(list(map(str, e.relevent_pattern[1]))) +']:'+ \
                     ','.join(list(map(str, e.relevent_pattern[2])))+' \u2933 '+self.agg_name
                     )
                    if e.relevent_pattern[4] == 'const':
                        relevent_param = str(
                            round(
                                float(e.relevent_pattern[6].split(',')[0][1:]),
                                2))
                    else:
                        # relevent_param = 'Intercept=' + str(e.relevent_pattern[7]['Intercept'])+', '+str(list(e.relevent_pattern[7])[1])+'='+str(e.relevent_pattern[7][list(e.relevent_pattern[7])[1]])
                        relevent_param = e.relevent_pattern[7]

                    refinement_model = ''
                    drill_down_to = ''
                    drill_param = ''
                tuple_list.append(local_pattern)
                tuple_list.append(drill_down_to)
                distance = round(e.distance, 2)
                tuple_list.append(distance)
                outlierness = round(e.deviation, 2)
                tuple_list.append(outlierness)
                denominator = round(e.denominator, 2)
                tuple_list.append(denominator)
                tuple_list.append(relevent_model)
                tuple_list.append(relevent_param)
                tuple_list.append(refinement_model)
                tuple_list.append(drill_param)
                exp_list.append(tuple_list)

            df_exp = pd.DataFrame(exp_list, columns=col_name)
            exp_df = exp_df.append(df_exp, ignore_index=True)

        self.exp_df = exp_df[col_name]
        model = TableModel(dataframe=self.exp_df)
        self.exp_table.updateModel(model)
        self.exp_table.redraw()

    def handle_low(self):
        self.user_direction = 'low'
        self.handle_question(self.user_direction)

    def handle_high(self):
        self.user_direction = 'high'
        self.handle_question(self.user_direction)

    def reset_output(self):

        model = TableModel(dataframe=self.original_query_result_df)
        self.query_result_table.updateModel(model)
        self.query_result_table.redraw()

        self.query_result_df = self.original_query_result_df

    def pop_up_pattern(self):

        chosen_row, pattern_data_df = self.use_local_filter_output()
        fetch_full_chosen_row_info = "select array_to_string(fixed,',') as Partition,array_to_string(variable,',') as Predictor,"+\
        "array_to_string(fixed_value,',') as partition_values,agg,model,fixed,fixed_value,variable,"+\
        "theta,param,stats,dev_pos,dev_neg from "+self.assigned_local_table+\
        " where array_to_string(fixed_value,',')='"+chosen_row['partition_values']+"'"+\
        " and array_to_string(variable,',')='"+chosen_row['predictor']+"';"

        full_chosen_row = pd.read_sql(fetch_full_chosen_row_info, self.conn)

        full_chosen_row['stats'] = full_chosen_row['stats'].str.split(
            ',', expand=True)[0]
        full_chosen_row['stats'] = full_chosen_row['stats'].str.strip('[')
        full_chosen_row['stats'] = pd.to_numeric(full_chosen_row['stats'])
        full_chosen_row['stats'] = full_chosen_row['stats'].round(2)

        logger.debug(full_chosen_row)
        self.local_pattern_detail = Local_Pattern_Frame(
            chosen_row=full_chosen_row.iloc[0],
            pattern_data_df=pattern_data_df,
            agg_alias=self.agg_name,
            data_convert_dict=self.plot_data_convert_dict)

        self.local_pattern_detail.load_pattern_description()
        self.local_pattern_detail.load_pattern_graph()

    def get_pattern_result(
        self,
        partition_attr_list=None,
        partition_value_list=None,
        pred_attr_list=None
    ):  # given partition attributes and partition values, get explanation(query on table)

        where_clause_list = []
        where_clause = None

        # logger.debug("partition_attr_list is ")
        # logger.debug(partition_attr_list)

        # logger.debug("partition_value_list is ")
        # logger.debug(partition_value_list)

        for n in range(len(partition_attr_list)):
            if (self.query_data_convert_dict[partition_attr_list[n]] == 'str'):
                condition = "{} =\'{}\'".format(partition_attr_list[n],
                                                partition_value_list[n])
            elif (self.query_data_convert_dict[partition_attr_list[n]] ==
                  'float'):
                condition = "{} = {}::float".format(partition_attr_list[n],
                                                    partition_value_list[n])
            else:
                condition = "{} = {}::int".format(partition_attr_list[n],
                                                  partition_value_list[n])
            where_clause_list.append(condition)

        if (len(where_clause_list) == 1):
            where_clause = where_clause_list[0]
        else:
            where_clause = " and ".join(where_clause_list)

        if (pred_attr_list is not None):

            Pattern_Q = "SELECT "+self.agg_function+" as "+self.agg_name+","+','.join(partition_attr_list)+","+','.join(pred_attr_list)+\
            " FROM " +self.cur_table_name+" WHERE " + where_clause+\
            " GROUP BY "+','.join(partition_attr_list)+","+','.join(pred_attr_list)
        else:
            Pattern_Q = "SELECT "+self.agg_function+" as "+self.agg_name+","+','.join(partition_attr_list)+\
            " FROM " +self.cur_table_name + " WHERE " + where_clause+\
            " GROUP BY "+','.join(partition_attr_list)

        # logger.debug("Pattern_Q")
        # logger.debug(Pattern_Q)

        exp_pattern_df = pd.read_sql(Pattern_Q, self.conn)

        # logger.debug('exp_pattern_df is :')
        # logger.debug(exp_pattern_df)

        return exp_pattern_df

    def pop_up_explanation(self):

        for n in self.exp_table.multiplerowlist:
            exp_chosen_row = self.exp_table.model.df.iloc[int(n)]
            relevent_pattern = self.exp_table.model.df.iloc[int(
                n)]['From_Pattern']
            rel_pattern_part = relevent_pattern.split(':')[0].split(
                '=')[0].strip('[')
            rel_pattern_part_value = relevent_pattern.split(':')[0].split(
                '=')[1].split(']')
            rel_pattern_pred = relevent_pattern.split(':')[1].split(
                ' \u2933 ')[0]
            agg_name = relevent_pattern.split(':')[1].split(' \u2933 ')[1]
            rel_pattern_model = self.exp_df.iloc[int(n)]['relevent_model']
            rel_param = self.exp_df.iloc[int(n)]['relevent_param']
            rel_pattern_part_list = rel_pattern_part.split(',')
            rel_pattern_pred_list = rel_pattern_pred.split(',')
            rel_pattern_part_value_list = rel_pattern_part_value[0].split(',')
            exp_tuple = self.exp_df.iloc[int(n)]['Explanation_Tuple']
            exp_tuple_list = exp_tuple.split(',')[:-1]
            exp_tuple_score = float(self.exp_df.iloc[int(n)]['Score'])
            drill_attr_list = self.exp_df.iloc[int(n)]['Drill_Down_To'].split(
                ',')

            if (drill_attr_list != ['']):
                exp_tuple_col = rel_pattern_part_list + rel_pattern_pred_list + drill_attr_list
                exp_tuple_col.sort()
            else:
                exp_tuple_col = rel_pattern_part_list + rel_pattern_pred_list
                exp_tuple_col.sort()

        # logger.debug('exp_tuple_col is:')
        # logger.debug(exp_tuple_col)

        # logger.debug('exp_tuple_list is:')
        # logger.debug(exp_tuple_list)

        exp_tuple_df_list = [exp_tuple_list]
        exp_tuple_df = pd.DataFrame(exp_tuple_df_list)
        logger.debug("exp_tuple_df:")
        exp_tuple_df.columns = exp_tuple_col
        logger.debug(exp_tuple_df)

        if (drill_attr_list != ['']):

            drill_values = []
            for n in drill_attr_list:
                drill_value = exp_tuple_df[n].to_string(index=False)
                drill_values.append(drill_value)

            # logger.debug('rel_pattern_part_list')
            # logger.debug(rel_pattern_part_list)

            # logger.debug('rel_pattern_part_value_list')
            # logger.debug(rel_pattern_part_value_list)

            drill_pattern_df = self.get_pattern_result(
                partition_attr_list=rel_pattern_part_list + drill_attr_list,
                partition_value_list=rel_pattern_part_value_list +
                drill_values,
                pred_attr_list=rel_pattern_pred_list)

            # logger.debug("drill_pattern_df is")
            # logger.debug(drill_pattern_df)

            rel_pattern_df = self.get_pattern_result(
                partition_attr_list=rel_pattern_part_list,
                partition_value_list=rel_pattern_part_value_list,
                pred_attr_list=rel_pattern_pred_list)

            question_df = self.original_question

            explanation_df = self.get_pattern_result(
                partition_attr_list=exp_tuple_col,
                partition_value_list=exp_tuple_list,
                pred_attr_list=None)
            logger.debug(explanation_df)
            exp_selected = exp_chosen_row

            data_convert_dict = self.plot_data_convert_dict

            self.Explainer = Exp_Frame(
                input_question_df=question_df,
                input_explanation_df=explanation_df,
                input_exp_chosen_row=exp_selected,
                input_none_drill_down_df=rel_pattern_df,
                input_drill_down_df=drill_pattern_df,
                input_data_convert_dict=data_convert_dict)

            self.Explainer.load_exp_graph()
            self.Explainer.load_exp_description(
                user_direction=self.user_direction)

        else:
            rel_pattern_df = self.get_pattern_result(
                partition_attr_list=rel_pattern_part_list,
                partition_value_list=rel_pattern_part_value_list,
                pred_attr_list=rel_pattern_pred_list)

            question_df = self.original_question

            explanation_df = self.get_pattern_result(
                partition_attr_list=exp_tuple_col,
                partition_value_list=exp_tuple_list,
                pred_attr_list=None)
            exp_selected = exp_chosen_row

            data_convert_dict = self.plot_data_convert_dict

            self.Explainer = Exp_Frame(
                input_question_df=question_df,
                input_explanation_df=explanation_df,
                input_exp_chosen_row=exp_selected,
                input_none_drill_down_df=rel_pattern_df,
                input_drill_down_df=None,
                input_data_convert_dict=data_convert_dict)

            self.Explainer.load_exp_graph()
            self.Explainer.load_exp_description(
                user_direction=self.user_direction)
예제 #22
0
class ImageLabelingForm(object):
    def __init__(self):
        self.img_col_title = 'image'
        self.lbl_col_title = 'label'
        self.df = self.empty_df()

        # All folders
        self.folder_name_list = []
        self.folder_list = []
        
        # Current folder
        self.dirname = ''
        self.folder_idx = 0
        self.folder_name = None
        self.img_list = []
        self.data_file = ''
        
        # Current Image
        self.current_idx = 0
        self.max_idx = 0
        self.image_name = None
        self.image_path = None
        
        self.window = tk.Tk()
        self.window.title("Image Labeling Program")
    
        # Folder Selection
        self.frm_folder = tk.Frame(master=self.window, relief=tk.FLAT)
        
        self.btn_browse = tk.Button(
            master=self.frm_folder, 
            text="Browse",
            command=self.browseFiles,
        )
        self.btn_prev = tk.Button(
            master=self.frm_folder, 
            text="Previous",
            command=self.prev_folder,
        )
        self.btn_next = tk.Button(
            master=self.frm_folder, 
            text="Next",
            command=self.next_folder,
        )
        
        self.btn_browse.pack(side=tk.TOP, padx=2, pady=2)
        self.btn_next.pack(side=tk.RIGHT, padx=2, pady=2)
        self.btn_prev.pack(side=tk.LEFT, padx=2, pady=2)
    
    
        # Label Submission
        self.frm_input = tk.Frame(master=self.window, relief=tk.FLAT)
        
        self.btn_submit = tk.Button(
            master=self.frm_input, 
            text="Submit & Next",
            command=self.submit,
        )
        self.btn_back = tk.Button(
            master=self.frm_input, 
            text="Back",
            command=self.back,
        )
        self.btn_save = tk.Button(
            master=self.frm_input, 
            text="Save",
            command=self.save,
        )
        self.btn_reset = tk.Button(
            master=self.frm_input, 
            text="RESET",
            fg="red",
            command=self.reset,
        )
        self.lbl_cow = tk.Label(master=self.frm_input, text="Image label: ")
        self.ent_label = tk.Entry(master=self.frm_input, width=6)
        
        self.lbl_cow.grid(row=0, column=0, padx=2, pady=2)
        self.ent_label.grid(row=0, column=1, padx=2, pady=2)
        self.btn_back.grid(row=1, column=1, padx=2, pady=2)
        self.btn_submit.grid(row=1, column=0, padx=2, pady=2)
        self.btn_save.grid(row=2, column=0, padx=2, pady=2)
        self.btn_reset.grid(row=2, column=1, padx=2, pady=2)
        
        
        # Dialogue
        self.frm_dialogue = tk.Frame(master=self.window, relief=tk.RIDGE, borderwidth=5)
        
        self.lbl_dialogue = tk.Label(master=self.frm_dialogue, text="Please browse for a folder")
        self.lbl_dialogue.pack(side=tk.BOTTOM, padx=2, pady=2)
        
        
        #Image
        self.frm_image = tk.Frame(master=self.window, relief=tk.SUNKEN)
        
        self.lbl_folder = tk.Label(master=self.frm_image, text="No folder selected")
        self.lbl_folder.pack()
        
        img = ImageTk.PhotoImage(Image.open(".\\src\\noimage_placeholder.png"))
        self.img_image = tk.Label(master=self.frm_image, image=img)
        self.img_image.pack()
        
        self.lbl_file = tk.Label(master=self.frm_image, text="No file...")
        self.lbl_file.pack()
        
        
        #Tables
        self.frm_data = tk.Frame(master=self.window, relief=tk.FLAT)
        
        self.pt = Table(self.frm_data, dataframe=self.df)
        self.pt.show()
        
        
        # Frames
        self.frm_image.pack(side=tk.LEFT)
        self.frm_dialogue.pack(side=tk.BOTTOM, pady=60)
        self.frm_folder.pack(pady=30)
        self.frm_input.pack(pady=30)
        self.frm_data.pack(pady=30)
        
        
        # Handlers
        self.pt.rowheader.bind("<Button-1>", self.select_row_handler)
        self.pt.bind("<Button-1>", self.select_row_handler)
        self.window.bind("<Return>", self.return_row_handler)
        self.window.bind("<Tab>", self.return_row_handler)
        self.window.bind("<Left>", self.return_row_handler)
        self.window.bind("<Right>", self.return_row_handler)
        self.window.bind("<Up>", self.return_row_handler)
        self.window.bind("<Down>", self.return_row_handler)
        self.window.mainloop()
        
        
    def browseFiles(self):
        self.dirname = filedialog.askdirectory(initialdir = "./images", 
                                      title = "Select the directory containing the data") 
        if not self.dirname:
            return -1
        
        self.folder_name_list = [ name for name in os.listdir(os.path.dirname(self.dirname)) if os.path.isdir(os.path.join(os.path.dirname(self.dirname), name)) ]
        self.folder_list = [ os.path.join(os.path.dirname(self.dirname), name) for name in os.listdir(os.path.dirname(self.dirname)) if os.path.isdir(os.path.join(os.path.dirname(self.dirname), name)) ]
        self.folder_idx = self.folder_name_list.index(os.path.basename(self.dirname))
        self.load_set()
        

    def next_folder(self):
        if self.folder_idx < len(self.folder_list)-1:
            self.folder_idx += 1
            self.dirname = self.folder_list[self.folder_idx]
            self.load_set()
        else:
            pass
            # self.reinitiate()
    
    def prev_folder(self):
        if self.folder_idx > 0:
            self.folder_idx -= 1
            self.dirname = self.folder_list[self.folder_idx]
            self.load_set() 
        else:
            pass
    
    def submit(self):
        # Reads the input label
        input_label = self.ent_label.get()
        self.df.at[self.current_idx, self.lbl_col_title] = input_label
        
        self.pt.redraw()
        
        if self.current_idx == self.max_idx:
            self.df.to_csv(self.data_file, index=False)
            self.ent_label.delete(0, tk.END)
            self.lbl_dialogue.configure(text="(AUTO SAVE) No more images remaining")
            self.next_folder()
        else:
            self.current_idx += 1
            self.load_image()
            
    
    def back(self):
        if self.current_idx > 0:
            self.current_idx -= 1
        
        # Place the highlight on the current row in the table
        self.pt.setSelectedRow(self.current_idx)
        self.pt.redraw()
        
        self.load_image()
        
    
    def save(self):
        self.df.to_csv(self.data_file, index=False)
        self.lbl_dialogue.configure(text="Progress saved")
        
    
    def reset(self):
        self.df.drop(columns=self.lbl_col_title, inplace=True)
        self.df[self.lbl_col_title] = np.nan
        self.df = self.df.astype(dtype={self.lbl_col_title: object})
        self.pt.redraw()
        self.ent_label.delete(0, tk.END)
        self.lbl_dialogue.configure(text="Progress reset")
    
    
    def reinitiate(self):
        self.df = self.empty_df()

        self.current_idx = 0
        self.max_idx = 0
        self.image_name = None
        self.image_path = None
        
        self.pt.model.df = self.df
        self.pt.setSelectedRow(self.current_idx)
        self.pt.redraw()  
        
        self.lbl_folder.configure(text="No folder selected")
        
        self.lbl_file.configure(text='No file...')
        
        img = ImageTk.PhotoImage(Image.open(".\\src\\noimage_placeholder.png"))
        self.img_image.configure(image=img)
        self.img_image.image = img
    
    
    def empty_df(self):
        return pd.DataFrame({self.img_col_title:[np.nan], self.lbl_col_title:[np.nan]})
    
    def select_row_handler(self, e):
        rowclicked_single = self.pt.get_row_clicked(e)
    
        if rowclicked_single <= self.max_idx:
            self.current_idx = rowclicked_single
            self.load_image()
    
    # TODO: This method is not functioning properly (Possibly a bug with pandas table)
    def return_row_handler(self, e):
        rowclicked_single = self.pt.getSelectedRow()

        if rowclicked_single <= self.max_idx:
            self.current_idx = rowclicked_single
            self.load_image()
            
    def load_set(self):
        self.data_file = '{}/labels.csv'.format(self.dirname)
        self.folder_name = os.path.basename(self.dirname)

        if os.path.isfile(self.data_file): 
            # Load the dataframe
            self.df = pd.read_csv(self.data_file, dtype={self.lbl_col_title: object})
            # Read image list from dataframe
            self.img_list = list(self.df['image'])
        else:
            # Create dataframe
            self.df = self.empty_df()
            # Create image list
            self.img_list = glob.glob(self.dirname + "//*.jpg")
            self.fill_image_column()
            self.df.to_csv(self.data_file, index=False)
        
        # Update current folder label
        self.lbl_folder.configure(text=self.folder_name)
        
        # Set image properties
        self.max_idx = len(self.df) - 1
        self.current_idx = self.find_first_unlabeled()
        
        self.load_image()
        self.update_button_status()
        self.lbl_dialogue.configure(text="Woking on folder '{}'".format(self.folder_name))
        
    
    def load_image(self):
        self.image_name = self.img_list[self.current_idx]
        self.image_path = os.path.join(self.dirname, self.image_name)
        
        # Update image label
        self.lbl_file.configure(text=self.image_name)
        
        # Update the table and place the highlight on the current row
        self.pt.model.df = self.df      
        self.pt.setSelectedRow(self.current_idx)
        self.pt.redraw()            

        # Set the default value for the text box    
        tb_value = self.determine_text_box_value()
        self.ent_label.delete(0, tk.END)
        self.ent_label.insert(0, tb_value)        
        
        # Load the image
        img = ImageTk.PhotoImage(Image.open(self.image_path).resize((960, 540)))
        self.img_image.configure(image=img)
        self.img_image.image = img
        
        self.update_button_status()
 
    def callback(self, event):
        self.ent_label.selection_range(0, tk.END)
    
    def fill_image_column(self):
        col1 = [os.path.basename(x) for x in self.img_list]
        col2 = np.nan
        temp_dict = {self.img_col_title:col1, self.lbl_col_title:col2}
        self.df = pd.DataFrame(temp_dict)
        self.df = self.df.astype(dtype={self.lbl_col_title: object})

    
    def find_first_unlabeled(self):
        first_null = 0
        nulls = self.df.index[self.df[self.lbl_col_title].isnull()]
        if nulls.any():
            first_null = nulls[0]
        return first_null
    
    
    def determine_text_box_value(self):
        current_value = self.ent_label.get()
        df_value = self.df[self.lbl_col_title][self.current_idx]
        
        if pd.isnull(df_value):
            return current_value
        else:
            return df_value
    
    
    def update_button_status(self):
        if self.folder_idx == 0:
            self.btn_prev["state"] = "disabled"
        else:
            self.btn_prev["state"] = "active"
            
        if self.folder_idx == len(self.folder_list)-1:
            self.btn_next["state"] = "disabled"
        else:
            self.btn_next["state"] = "active"
            
        if self.current_idx == 0:
            self.btn_back["state"] = "disabled"
        else:
            self.btn_back["state"] = "active"
             
        # if (self.current_idx == self.max_idx) and (self.folder_idx == len(self.folder_list)-1):
        #     self.btn_submit["state"] = "disabled"
        # else:
        #     self.btn_submit["state"] = "active"   
예제 #23
0
class MainFrame(Tk):
    def __init__(self):
        super().__init__()
        #  Create DataFrame
        self.df = pd.DataFrame({'': ['']})
        self.frame = Frame(self, relief=RAISED, borderwidth=1)
        self.table = Table(self.frame,
                           dataframe=self.df,
                           showtoolbar=True,
                           showstatusbar=True)
        #self.parent = parent
        self.mycompany = company.Company()
        self.initUI()
        self.style = Style()
        print(self.style.theme_names())
        self.style.theme_use('winnative')
        self.closeButton = Button(self, text="Закрыть", command=self.quit)
        self.closeButton.pack(side=RIGHT, padx=5, pady=5)
        self.loadButton = Button(self,
                                 text="Загрузить",
                                 command=self.loadCompany)
        self.loadButton.pack(side=RIGHT)
        self.modelButton = Button(self,
                                  text="Модель",
                                  command=self.createModel)
        self.modelButton.pack(side=RIGHT)
        self.prognosisButton = Button(self,
                                      text="Прогноз",
                                      command=self.prognosis)
        self.prognosisButton.pack(side=RIGHT)
        self.l1 = Label(self, text='От')
        self.l2 = Label(self, text='До')
        self.entry_from = Entry(self,
                                width=4,
                                textvariable=StringVar(self, '2021'))
        self.entry_to = Entry(self,
                              width=4,
                              textvariable=StringVar(self, '2026'))
        self.entry_to.pack(side=RIGHT, padx=5)
        self.l2.pack(side=RIGHT)
        self.entry_from.pack(side=RIGHT, padx=5)
        self.l1.pack(side=RIGHT)

    def initUI(self):
        self.title("Fluger Investor 1.00 2021")
        #self.pack(fill=BOTH, expand=1)
        self.centerWindow()
        self.frame.pack(fill=BOTH, expand=True)
        #  Специальная таблица для DataFrame
        self.table.show()
        #self.pack(fill=BOTH, expand=True)

    def centerWindow(self):
        w = 1200
        h = 800
        sw = self.winfo_screenwidth()
        sh = self.winfo_screenheight()
        x = (sw - w) / 2
        y = (sh - h) / 2
        self.geometry('%dx%d+%d+%d' % (w, h, x, y))

    def loadCompany(self):
        Tk().withdraw(
        )  # we don't want a full GUI, so keep the root window from appearing
        # show an "Open" dialog box and return the path to the selected file
        filename = askopenfilename(initialdir=os.getcwd(),
                                   title="Открыть компанию",
                                   filetypes=(("json", "*.json"), ("all files",
                                                                   "*.*")))
        self.mycompany = company.Company()
        self.mycompany.load_company_from_file(filename)
        self.mycompany.load_financials_from_file()
        self.df = self.mycompany.get_financials()
        print(self.df)
        self.table.model.df = self.df
        self.table.redraw()
        self.title("Fluger Investor 1.00 2021 - " + self.mycompany.ticker)

    def createModel(self):
        modelgen = model_generator.ModelGenerator()
        modelgen.set_financials(self.mycompany.get_financials())
        model, score = modelgen.build_linear_regression_model('Price')
        self.mycompany.set_price_model(model)
        messagebox.showinfo("Модель", "Модель создана, score = " + str(score))

    def prognosis(self):
        f = self.entry_from.get()
        t = self.entry_to.get()
        years = [i for i in range(int(f), int(t))]
        fin = self.mycompany.get_financials()
        fin = fin.drop(["Price"], axis=1)
        modelgen = model_generator.ModelGenerator()
        features, predictions = modelgen.predict(
            self.mycompany.get_price_model(), fin, years)
        print(features)
        prognosis_frame.PrognosisFrame(self, predictions, years)
예제 #24
0
class processingFrame(Frame):       
    def __init__(self, master):     
        # 1 is csv, 2 is file with correct fields

        # txt,xls,append file names
        self.filename1=""
        self.filename2=""
        self.filename3=""

        self.trouble=[]
        self.maxwordlen=[]
        self.checklabel= StringVar()
        self.countlabel= StringVar()
        self.neglabel=StringVar() 
        # make frames for each step
        self.processing = Frame(master, bg="#DAF7A6" )
        Frame.__init__(self,self.processing)
        self.processing.grid(column=0,row=1)
        
                
        # Make Frames for tables, buttons and output
        self.stuffframe = Frame(self.processing,bg="#DAF7A6")
        self.stuffframe.grid(column = 0,row = 0, sticky=W+N)
        
        # Frames for tables
        tableframe1 = Frame(self.processing,bg="#DAF7A6")
        tableframe1.grid(column=2,row = 0, sticky = N)
        self.stuffframe2 = Frame(tableframe1)
        self.stuffframe2.grid(row=0,column=0, sticky=E)
        
        # This is the Table Frame for showing data
        self.f1 = Frame(tableframe1)
        self.f1.grid(row = 0, column = 3, columnspan=25, rowspan=15, sticky = N)
        
        #tableframe2 = Frame(self.processing,bg="#DAF7A6")
        #tableframe2.grid(column=2,row = 1, sticky = N)
        self.stuffframe3 = Frame(tableframe1)
        self.stuffframe3.grid(row=1,column=0, sticky=E)

        # This is the table frame for negatives
        self.f2 = Frame(tableframe1, bg="#DAF7A6")
        self.f2.grid(row = 1, column = 3, columnspan=25, rowspan=15,pady=(320,0),
                sticky = S)
        
         
        #self.toplevel = Toplevel()
        
        #Buttons/Text
        self.title2 = Label(self.stuffframe,text="Cleaning & Processing Data",
                font = "-weight bold")
        self.title2.grid(row=0,column=0,sticky=W+N)
        
        self.title3 = Label(self.stuffframe,text="Visit Github.com/ljstrnadiii")
        self.title3.grid(row=1,column=0,sticky=W+N)
        

        self.text1 = Label(self.stuffframe, text="Choose files:")
        self.text1.grid(row=2,column=0, pady =(10,0),sticky=W)
 
        self.button1= Button(self.stuffframe, text="Scanned txt", 
                command = self.browsecsv)
        self.button1.grid(row=3, column=0, sticky=W)

        self.button7= Button(self.stuffframe, text="amend data",
                command = self.ammend)
        self.button7.grid(row=4, column=0, sticky=W)

        self.button2= Button(self.stuffframe, text="Valid xls", 
                command = self.browsevalid)
        self.button2.grid(row=5, column=0, sticky = W)

        self.text2 = Label(self.stuffframe, text="Process:")
        self.text2.grid(row=7,column=0, pady =(10,0), sticky = W)
        
        self.button3= Button(self.stuffframe, text="Correct",
                command = self.check ) 
        self.button3.grid(row=8, column=0,sticky=W+N )
        
        self.button4= Button(self.stuffframe, text="Get Count", 
                command = self.count)
        self.button4.grid(row=9, column=0, sticky = W+N)
        label1 = Label(self.processing,text ="")

        
        self.title_instr = Label(self.stuffframe,text="Procedure: show negative, edit, update, repeat")
        self.title_instr.grid(row=15,column=0,sticky=W+N)

        
        self.button5 = Button(self.stuffframe, text="show negatives", 
                command = self.fixnegs)

        self.button5.grid(row=16, column = 0, sticky = W)
        
        self.button6 = Button(self.stuffframe, text="update", 
                command = self.update)

        self.button6.grid(row=17, column = 0, sticky = W)

                # setting tables up 
        self.pt1 = Table(self.f1, rows=14,column=24,
                                showtoolbar=False, showstatusbar=False) 
        self.pt2 = Table(self.f2, rows=17, column=24,
                                showtoolbar=False, showstatusbar=False) 
        self.pt1.show()
        self.pt2.show()
        
        self.processing.config(bd=5)
        

    # functions made for Window
    
    def browsecsv(self):
        Tk().withdraw() 
        self.filename1 = askopenfilename()
        filename = ntpath.basename(self.filename1)
        Label(self.stuffframe,text=filename, wraplength = 200
                , justify = LEFT).grid(row=10, column=0, sticky=W)
    
    def ammend(self):
        Tk().withdraw()
        self.filename3 = askopenfilename()
        filename = ntpath.basename(self.filename3)
        Label(self.stuffframe,text=filename, wraplength = 200
                 , justify = LEFT).grid(row=11, column=0, sticky=W)

    

    def browsevalid(self):
        Tk().withdraw() 
        self.filename2 = askopenfilename()
        filename = ntpath.basename(self.filename2)
        Label(self.stuffframe,text=filename ).grid(row=12, column=0, sticky = W)

    def check(self):
        text1 = proc.correctfields(self.filename1, self.filename2)
        proc.ammend(self.filename1,self.filename3)
        self.checklabel.set(text1)
        #label1 = Label(self.stuffframe,textvariable = self.checklabel, \
         #   wraplength=250, justify=LEFT)
        #label1.grid(row=13,column=0,  sticky = W)
        
    def count(self):
        self.corrected, self.trouble, self.text2 = \
        proc.getcount(self.filename1) 
               # self.pt1, \
        self.countlabel.set(self.text2)
        Label2 = Label(self.stuffframe, text = self.countlabel.get(), \
            wraplength = 250,justify=LEFT)
        Label2.grid(row = 14, column = 0, sticky =W)
        self.corrected = self.corrected.fillna(0)
        self.pt1.model.df = self.corrected
        self.pt1.redraw()
        
    def fixnegs(self):
        if len(self.trouble)>0:
            dq = self.corrected.ix[self.corrected[ \
                    "Account_Number"]==self.trouble[-1][-1],:]
            print(list(dq))
            dq = dq[["Store","Inv_Type","Date",self.trouble[-1][-2]]]
            
            # where is the neg value and what it is. append it in a column
            where = self.trouble[-1][-3]
            negcol=np.zeros(len(dq))
            negcol[where-1]=self.trouble[-1][-6]
            dq["value"]=negcol
            
            # uncomment for label of neg value
            # self.n = (self.trouble[-1][-5].isoformat()[0:10],self.trouble[-1][-6])
            #self.neglabel.set(str(self.n))
            #Label3 = Label(self.stuffframe, text = self.neglabel.get(), \
             #   wraplength = 250,justify=LEFT)
            #Label3.grid(row=15,column=0,sticky=W)
            
            dq = pd.DataFrame(dq)
            dq = dq.fillna(0)
            dq[list(dq)[-2]]= dq[list(dq)[-2]].astype(int)
            dq[list(dq)[-1]]= dq[list(dq)[-1]].astype(int)
            dq[list(dq)[-4]]= dq[list(dq)[-4]].astype(int)

            self.pt2.model.df = dq#.loc[:last+1,:]
            self.pt2.redraw()
        # pop last element from list assuming user will update before fixnegs again
            self.trouble.pop() 
        else:
            self.pt2.clearTable()
            self.pt2.redraw()
         
        
    def update(self): #note: i dont think i need a child table:
        # try to just create a table in fixnegs and below in update call on the 
        # df o update accordingly. consider the indexes though
        
        self.pt1.model.df.update(self.pt2.model.df)
        self.pt1.redraw()

        #uncomment to save 
        self.pt1.model.df.to_csv(self.filename1, index=False)