4
\$\begingroup\$

I am new to Python software development, especially using Tkinter. I just wanted some pointers to help my code look and operate in a more clean manner. I posted this code which is a mini risk management tool for work, so that I can run some reports automatically.

from tkinter import *
from tkinter import ttk
import tabula
import csv
import pandas as pd
import numpy as np
from pandas import ExcelWriter
from tkinter import *
from tkinter import filedialog
from tkinter.messagebox import showinfo
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showerror
import smtplib
from datetime import datetime
import time

import datetime as dt
import matplotlib.pyplot as plt
from matplotlib import style
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mdates
import pandas as pd
import pandas_datareader.data as web
from googlefinance import getQuotes
import json
from datetime import datetime
from yahoo_finance import Share
from forex_python.converter import CurrencyRates

def SecurityData():
    condition = True

    while (condition):

        print("\n")

        security = input('Security: $')

        if (security != "Q"):

            share = Share(security)
            style.use('ggplot')
            print(share.get_price())

            #      print ('Date format: YEAR,MO,DA')
            #     s = input('Start date: ')
            #    e = input('End date: ')

            start = dt.datetime.strptime('2016,07,14', '%Y,%m,%d')
            end = dt.datetime.strptime('2017,07,14', '%Y,%m,%d')
            #  start = dt.datetime.strptime(s, '%Y,%m,%d')
            # end = dt.datetime.strptime(e, '%Y,%m,%d')

            df = web.DataReader(security, 'google', start, end)
            df.to_csv('' + security + '.csv')

            # df['Close'].plot()
            # df['100ma'] = df['Close'].rolling(window=100, min_periods=0).mean()

            # RESAMPLING DATA
            # df_ohlc = df['Close'].resample('10D').ohlc()
            # df_volume = df['Volume'].resample('10D').sum()

            # df_ohlc.reset_index(inplace=True)

            # df_ohlc['Date'] = df_ohlc['Date'].map(mdates.date2num)
            print(df['Close'].tail(n=1))
            print(df['Close'].head(n=1))

        else:

            break


def ForexData():

    date_time = time.strftime('%b %d %Y')

    c = CurrencyRates()
    usd_eur = c.get_rate('EUR','USD')
    usd_gbp = c.get_rate('GBP','USD')
    usd_yen = c.get_rate('JPY','USD')
    usd_aud = c.get_rate('AUD','USD')
    eur_gbp = c.get_rate('GBP','EUR')


    popup = Tk()
    popup.wm_title("Complete")
    label = ttk.Label(popup, text="Key Currencies Data " + date_time + ": ", font=("Arial bold", 12))
    label.pack(side="top", fill=X, expand=1, pady=10)

    B1 = ttk.Button(popup, text="Close", command=popup.destroy)
    B1.pack()

    t1 = Text(popup, width=50, height=20)
    t1.pack()

    class PrintToT1(object):
        def write(self, s):
            t1.insert(END, s)

    sys.stdout = PrintToT1()

    print("EUR-USD: " + str(usd_eur))
    print("GBP-USD: " + str(usd_gbp))
    print("YEN-USD: " + str(usd_yen))
    print("AUD-USD: " + str(usd_aud))
    print("EUR-GBP: " + str(eur_gbp))

    popup.mainloop()


def SecurityRisk():

    root = Tk()
    root.fileName = filedialog.askopenfilename(filetypes=(("PDF Files", "*.pdf"), ("All files", "*.*")))
    root.destroy()

    date_time = time.strftime('%b %d %Y')

    # for x in range (1, 100):
    tabula.convert_into(root.fileName, "_ExportedPDF-" + date_time + ".csv", output_format="csv", pages="all")
    pd.set_option('display.float_format', lambda x: '%.3f' % x)
    pd.set_option('display.height', 1000)
    pd.set_option('display.max_rows', 500)
    pd.set_option('display.max_columns', 500)
    pd.set_option('display.width', 1000)
    df = pd.read_csv('_ExportedPDF-' + date_time + '.csv')
    # df[~df["Unnamed: 0"].isin(['Total','Currency:',''])].T.shift().T.fillna('').comb‌​i‌​ne_first(df)

    df['Unnamed: 0'] = df['Unnamed: 0'].fillna('X')
    df = df.values.tolist()
    for row in df:
        if row[0] not in ['Total', 'Currency:', 'X']:
            row.insert(0, '')

    df = pd.DataFrame(df, columns=['A', 'Security', 'Ticker', 'Cusip', '*Yesterday*', 'Today', 'Tomorrow', 'Next 1D',
                                   'Next 2D', 'Next 3D'])
    # df.to_csv("_FullDataFrame-" + date_time + ".csv", sep=',')
    df = df.drop('A', 1)
    df = df.drop('Cusip', 1)
    # df.to_csv("_MainDataFrame-" + date_time + ".csv", sep=',')
    df = df.drop('Today', 1)
    df = df.drop('Tomorrow', 1)
    df = df.drop('Next 1D', 1)
    df = df.drop('Next 2D', 1)
    df = df.drop('Next 3D', 1)
    df = df.dropna(subset=['*Yesterday*'])
    df = df.dropna(subset=['Security'])
    df = df[df['Security'] != 'Security Description']
    df['*Yesterday*'] = pd.to_numeric(df['*Yesterday*'].str.replace(',', ''), errors='coerce')

    df['Ticker'] = df['Ticker'].fillna('X')
    df['Currency'] = np.where(df['Ticker'] == "X", df['Security'], np.nan)
    df['Currency'] = df['Currency'].fillna(method='bfill')
    df['Currency Total'] = np.where(df['Ticker'] == "X", df['*Yesterday*'], np.nan)
    df['Currency Total'] = df['Currency Total'].fillna(method='bfill')
    df = df[df['Ticker'] != 'X']
    df['Currency'] = df['Currency'].fillna('US Dollar')
    df = df.drop('Currency Total', 1)
    df = df.reset_index(drop=True)

    sums = df.groupby('Currency')['*Yesterday*'].sum().reset_index()
    nth_security = df.sort_values('*Yesterday*', ascending=False).reset_index()
    big_security = df[(df['*Yesterday*'] >= 42500000)].reset_index()
    big_security = big_security.sort_values('*Yesterday*', ascending=False).reset_index()
    big_security.__delitem__('level_0')
    sums_sort = sums.sort_values('*Yesterday*', ascending=False).reset_index()
    total_sum = df['*Yesterday*'].sum()
    tot_mean = df['*Yesterday*'].mean()
    tot_std = df['*Yesterday*'].std()
    sums['Percentage'] = sums['*Yesterday*'] / total_sum
    sums_sort['Percentage'] = sums_sort['*Yesterday*'] / total_sum

    df.to_csv("_ReportDataFrame-" + date_time + ".csv", sep=',')

    writer = pd.ExcelWriter("UnsettledSec-" + date_time + ".xlsx", engine='xlsxwriter')
    df.to_excel(writer, 'DataFrame-' + date_time)
    sums.to_excel(writer, 'TotalByCurrency-' + date_time)
    sums_sort.to_excel(writer, 'SortedRank-' + date_time)
    big_security.to_excel(writer, 'TopSecurities-' + date_time)

    workbook = writer.book
    worksheet1 = writer.sheets['DataFrame-' + date_time]
    worksheet2 = writer.sheets['TotalByCurrency-' + date_time]
    worksheet3 = writer.sheets['SortedRank-' + date_time]
    worksheet4 = writer.sheets['TopSecurities-' + date_time]

    format1 = workbook.add_format({'num_format': '#,##0.00'})
    format2 = workbook.add_format({'align': 'right'})
    format3 = workbook.add_format({'align': 'center'})
    format4 = workbook.add_format({'num_format': '0.000%'})

    worksheet1.set_column('B:B', 35)
    worksheet1.set_column('C:C', 30)
    worksheet1.set_column('D:D', 25, format1)
    worksheet1.set_column('E:E', 30, format2)
    worksheet2.set_column('B:B', 35, format1)
    worksheet2.set_column('C:C', 35, format1)
    worksheet2.set_column('D:D', 20, format4)
    worksheet3.set_column('B:B', 10, format3)
    worksheet3.set_column('C:C', 35, format1)
    worksheet3.set_column('D:D', 25, format1)
    worksheet3.set_column('E:E', 20, format4)
    worksheet4.set_column('B:B', 10, format3)
    worksheet4.set_column('C:C', 55)
    worksheet4.set_column('D:D', 15)
    worksheet4.set_column('E:E', 25, format1)
    worksheet4.set_column('F:F', 35, format2)
    writer.save()

    import os
    import subprocess

    if sys.platform == "win32":
        os.startfile("UnsettledSec-" + date_time + ".xlsx")
    else:
        subprocess.call(("open", "UnsettledSec-" + date_time + ".xlsx"))

    popup = Tk()
    popup.wm_title("Complete")
    label = ttk.Label(popup, text="Unsettled Security Data for " + date_time + ": ", font=("Arial bold", 12))
    label.pack(side="top", fill=X, expand=1, pady=10)

    B1 = ttk.Button(popup, text="Close", command=popup.destroy)
    B1.pack()

    t1 = Text(popup, width=100, height=50)
    t1.pack()

    class PrintToT1(object):
        def write(self, s):
            t1.insert(END, s)

    sys.stdout = PrintToT1()

    #sums_sort['*Yesterday*'] = df.apply(lambda x: "{:,}".format(x['*Yesterday*']), axis=1)
    #big_security['*Yesterday*'] = df.apply(lambda x: "{:,}".format(x['*Yesterday*']), axis=1)
    sums_sort['*Yesterday*'] = sums_sort['*Yesterday*'].map('{:,.2f}'.format)
    big_security['*Yesterday*'] = big_security['*Yesterday*'].map('{:,.2f}'.format)
    total_sum = '{:0,.2f}'.format(total_sum)
    sums_sort['Percentage'] = pd.Series(["{0:.2f}%".format(val * 100) for val in sums_sort['Percentage']])


    print('****************** Top Unsettled by Currency ******************')
    print('')
    print(sums_sort.head(n=20))
    print('')
    print('****************** Top Unsettled by Security ******************')
    print('')
    print(big_security)
    print('')
    print('Total Unsettled: $ ' + str(total_sum) + ' USD')
    print('')
    print('*** Author: @mitchbregs ***')

    popup.mainloop()



main = Tk()
main.iconbitmap(r'favicon.ico')
main.title('Risk Management')
main.geometry('850x300')

w = Label(main, text="Risk - Management Tool", font=("Arial bold", 12), pady=20)
y = Label(main, text="Made by Mitch", font=("Arial italic", 8))
w.grid(row=0, column=2)
y.grid(row=0, column=3)

# gives weight to the cells in the grid
rows = 0
while rows < 50:
    main.rowconfigure(rows, weight=1)
    main.columnconfigure(rows, weight=1)
    rows += 1

# Defines and places the notebook widget
nb = ttk.Notebook(main)
nb.grid(row=1, column=0, columnspan=100, rowspan=49, padx=25, sticky='NESW')

page0 = ttk.Frame(nb)
nb.add(page0, text='RETRIEVE REPORTS')

page01 = ttk.Frame(nb)
nb.add(page01, text='UPLOAD TO DATABASE')

# Adds tab 1 of the notebook
page1 = ttk.Frame(nb)
nb.add(page1, text='Competitor Stock Price')
frame1= Frame(page1)
frame1.pack()
one =Label(frame1, text="Competitor Stock Price Performance - Weekly Update", font=("Arial bold", 10), bg="red", fg="white", padx=15, pady=15)
one.pack(side=TOP, fill=X)
printBtn = Button(frame1, text="Retrieve Competitor Stock Prices", command=SecurityData, pady=5, padx=10, bg='#ffffff')
printBtn.pack(pady=20)



# Adds tab 2 of the notebook
page2 = ttk.Frame(nb)
nb.add(page2, text='Key Currencies')
frame2= Frame(page2)
frame2.pack()
two =Label(frame2, text="Key Currencies - Weekly Update", font=("Arial bold", 10), bg="blue", fg="white", padx=15, pady=15)
two.pack(side=TOP, fill=X)
printBtn = Button(frame2, text="Retrieve Latest Price Conversions", command=ForexData, pady=5, padx=10, bg='#ffffff')
printBtn.pack(pady=20)

# Adds tab 1 of the notebook
page3 = ttk.Frame(nb)
nb.add(page3, text='Unsettled Securities Risk')
frame3= Frame(page3)
frame3.pack()
three=Label(frame3, text="Unsettled Securities Trades, Top Emerging Markets - Daily Update", font=("Arial bold", 10), bg="green", fg="white", padx=15, pady=15)
three.pack(side=TOP, fill=X)
printBtn = Button(frame3, text="Upload File...", command=SecurityRisk, pady=5, padx=10, bg='#ffffff')
printBtn.pack(pady=20)

#test = Label(page3, text="Unsettled Securities", font=("Arial bold", 10))
#test.grid(row=10, column=2)
#page3.bind("<Button-1>", SecurityRisk)
page4 = ttk.Frame(nb)
nb.add(page4, text='Broker Risk')

# Adds tab 2 of the notebook
page5 = ttk.Frame(nb)
nb.add(page5, text='Risk Summary')

# Adds tab 2 of the notebook




main.mainloop()

I understand that you are supposed to setup and design Tkinter applications using classes and such, but I am having a hard time understanding that concept for what I am trying to do. The way I have it set up right now works the way I would like it to, but obviously there are ways I can do things that would be cleaner and much more "user friendly". I am not so good at the user interface, user experience side of things.

If anyone can give me some tips on how I can improve my code so that it looks more "professional" and clean, I would really appreciate it.

Any examples and advice helps.

\$\endgroup\$
3
\$\begingroup\$

If you want to get more familiar with classes and OOP in general, I suggest reading Python 3 Object Oriented Programming. Along with solid information about OOP concepts and practices, it also discusses some of the design patterns. Alternatively, you can scour the web for information on the subject.

As for the GUI apps in general, I'd recommend looking into Model-View-Controller architecture, and it's example in Tkinter here.

The basic idea of MVC is to separate program into 3 components, a model which contains business logic and data, a view which contains layout and other UI related stuff and a controller which acts as a kind of proxy between the two in a sense that it controls them.

Because each component has it's own responsibility, program logic and visual design is separated, resulting in a much more contained and maintnanable code.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.