Demo entry 6783494

William Macpherson NEA code

   

Submitted by anonymous on Feb 13, 2019 at 17:59
Language: Python 3. Code size: 29.2 kB.

########### WILLIAM MACPHERSON NEA CODE ###########
---------------------------------------------------------------------------------------

### import all the libaries i need for the program to run
from tkinter import *
import tkinter
from tkinter.scrolledtext import *
import sqlite3
import requests
import json
import random
import pprint
import io


## This Class is used to search for the events and then display them in various boxes
class Events:
    def __init__(self):
        self.q = 0
        self.on=0
        ## Connecting to the SQL database
        with sqlite3.connect("user.db") as self.db:
            self.cursor=self.db.cursor()

    ## This is my searching algorithm
    def search(self):
        ## First I concatenate the user interests into a format that can be understanded by the eventful API, they specify the format they want on their website
        string=''
        for i in range(len(self.interests)):
            if i==len(self.interests)-1:
                string=string+self.interests[i]
            else:
                string=string+self.interests[i]+'||'
            ## choosing what page number you would like, the API only understands strings so I must convert the number to a str
        self.page_n=str(self.page_n)
            ## requesting API
        r =requests.get('http://api.eventful.com/json/events/search?&app_key=WJrm5TS9WpfmhV5W&keywords='+self.keywords+'&location='+self.location+'&page_size=15&date='+self.date+'&page_count='+self.page_n+'&category='+string)
            ## I convert the page_n back into a int so I can change it later on
        self.page_n=int(self.page_n)
            ## This is error handling that says if the API returns nothing then I reload the main_viewer
        if r.text ==None:
            Main.main_viewer()

            ## This next section is saving and decoding the request
            ## Here I  save the request to a local json file, every time I send a request the file is overwritten so no extra space is used
        with io.open("data.json","w", encoding="utf-8") as f:
            f.write(r.text)
        f.close()
            ## Defining the data list
        self.data=[]
            ## Now reading the data.json file and loading it to a variable that i can manipulate
        with io.open("data.json","r", encoding="utf-8") as r:
            info=json.load(r)
        r.close()
        
            ## This section is parsing the relevent information from the 'info' variable into a list so I can parse it into the boxes
        events=info['events']['event']
        t_items=info['total_items']
            ## Error handling checks that the file has items inside and not just returned a file with no events in
        if t_items=='0':
            Main.main_viewer()
            ## Decoding the events into variables and then appending them to the 'data' list
        for i in range(15):
            event=events[i]
            description=event['description']
            venue_n=event['venue_name']
            venue_a=event['venue_address']
            city=event['city_name']
            region=event['region_name']
            post=event['postal_code']
            country=event['country_name']
            ID=event['id']
            start_time=event['start_time']
            print(type(event))
            performers=event['performers']
            if performers==None:
                performer='Sorry No Data'
                name='No name look in description'
            else:
                performer=performers['performer']
                name=performer['name']
            self.data.append((name, start_time, ID, description, venue_n, venue_a, city, region, post, country))

            ## This section is more error handling if one of the values within the 'data' list is null data type, tkinter shows a error message if so and it crashes so all null data types are replaced with a message
        for t in range(len(self.data)):
            for p in range(8):
                if self.data[t][p]==None:
                    data1=self.data[t]

                    data1=list(data1)
                    statement='Sorry for the inconvience, no data is avaliable at this time'
                    data1[p]=statement
        self.view()

    def choices(self, keywords, location, date, interests):
            ## This is the where the variables are sent after the search has been requested
        self.keywords=keywords
        self.location=location
        self.date=date
        self.interests=interests
        self.page_n=1
        Event_viewer.search()

    def page(self, page_n):
            ## This is the page counter
        self.page_n=self.page_n+1
        Event_viewer.search()

    def view(self):
            ##This next function deals with tkinter and how I format and design the boxes that will show my events
        views_frame=Frame(main, bg='light blue')
        views_frame.pack(padx=5)

        self.active=0
        
        x=50
        y=15
        ## Labels
        Label(views_frame, text='Titles', bg='light blue').grid(row=0, column=0)
        Label(views_frame, text='Time', bg='light blue').grid(row=1, column=0)
        Label(views_frame, text='Description', bg='light blue').grid(row=3, column=0)
        Label(views_frame, text='ID', bg='light blue').grid(row=2, column=0)
        ## Titles
        title_T1 = Text(views_frame, width=x, height=2, background='light green')
        title_T1.grid(row=0, column=1)
        
        title_T2 = Text(views_frame, width=x, height=2, background='light green')
        title_T2.grid(row=0, column=2)

        title_T3 = Text(views_frame, width=x, height=2, background='light green')
        title_T3.grid(row=0, column=3)

        ## Time and dates
        time_T1 = Text(views_frame, width=x, height=1, background='light green')
        time_T1.grid(row=1, column=1)
        
        time_T2 = Text(views_frame, width=x, height=1, background='light green')
        time_T2.grid(row=1, column=2)

        time_T3 = Text(views_frame, width=x, height=1, background='light green')
        time_T3.grid(row=1, column=3)
        
        ## ID's
        ID_1= Text(views_frame, width=x, height=1, background='light green')
        ID_1.grid(row=2, column=1)
        
        ID_2= Text(views_frame, width=x, height=1, background='light green')
        ID_2.grid(row=2, column=2)
        
        ID_3= Text(views_frame, width=x, height=1, background='light green')
        ID_3.grid(row=2, column=3)
        

        ## Descriptions
        description_T1 = ScrolledText(views_frame, width=x, height=y, background='light green')
        description_T1.grid(row=3, column=1)

        description_T2 = ScrolledText(views_frame, width=x, height=y, background='light green')
        description_T2.grid(row=3, column=2)

        description_T3 = ScrolledText(views_frame, width=x, height=y, background='light green')
        description_T3.grid(row=3, column=3)
            ## To get two arrows pointing in different directions to view more events I had to look up the Unicode equivelent of arrows and implement them into a variable
        arrowL='\U000027A1'
        arrowR='\U00002B05'
            ## I put all the widgets into a list called 'boxes' this means I implement them into recursive algorithms
        boxes = [[title_T1, time_T1, ID_1, description_T1], [title_T2, time_T2, ID_2, description_T2], [title_T3, time_T3, ID_3, description_T3]]
            ## These are all the buttons that you see in the interface4
        next_button=Button(views_frame, text=arrowL, font=50, width=1, height=23, command= lambda: self.forward(boxes),bg='light green').grid(row=0, column=6, rowspan=4)
        back_button=Button(views_frame, text=arrowR, font=50, width=1, height=23, command= lambda: self.backwards(boxes), bg='light green').grid(row=0, column=5, rowspan=4)
        view_more_1=Button(views_frame, text='View', width=40, height=1, command=self.info_1 ).grid(row=4, column=1, sticky=S)
        view_more_2=Button(views_frame, text='View', width=40, height=1, command=self.info_2).grid(row=4, column=2, sticky=S)
        view_more_3=Button(views_frame, text='View', width=40, height=1, command=self.info_3).grid(row=4, column=3, sticky=S)
        
        self.clear_boxes(boxes)

    def forward(self, boxes):
            ## When the next arrow is clicked it calls this function that adds 3 to the counter, it also goes back to the start when the max length is reached
        if self.q == 15:
            self.q=0
        self.q=self.q+3
        if self.active==1:
            self.quit_info()
        self.clear_boxes(boxes) 
        
    def backwards(self, boxes):
            ##  Same as forwards function yet backwards
        if self.q==-15:
            self.q =15
        self.q=self.q-3
        if self.active==1:
            self.quit_info()
        self.clear_boxes(boxes)

    def clear_boxes(self, boxes):
            ## This clears the boxes when the forward/backwards buttons are clicked meaning the infomation won't pile up in a box
        for x in boxes:
            x[0].delete(0.0, END)
            x[1].delete(0.0, END)
            x[2].delete(0.0, END)
            x[3].delete(0.0, END)
        self.parse(boxes)
        
    def parse(self, boxes):
            ## The parse function inserts the 'data' list to a assigned variable and then inserts that variable with the corresponding widget within the 'boxes' list
        d = 0
        for i in range(self.q, (self.q+3)):
            if d == 3:
                d=0
            title = self.data[i][0]
            time = self.data[i][1]
            ID= self.data[i][2]
            description = self.data[i][3]
            
            boxes[d][0].insert(END, title)
            boxes[d][1].insert(END, time)
            boxes[d][2].insert(END, ID)
            boxes[d][3].insert(END, description)
            d+=1
    def quit_info(self):
            ## Quit function
        self.info.withdraw()
        self.info.quit()
        
        self.active=0

    def more_info(self, p):
            ## To view an event in more detail you can click the button 'view more' it calls this function which pulls up more data on the event like the address that was not shown before
        self.info=Tk()
        self.info.title('More Info')
        self.info.configure(bg='light blue')
        
        Label(self.info, text='Titles', bg='light blue').grid(row=0, column=0)
        Label(self.info, text='Time', bg='light blue').grid(row=1, column=0)
        Label(self.info, text='ID', bg='light blue').grid(row=2, column=0)
        Label(self.info, text='Description', bg='light blue').grid(row=3, column=0)
        Label(self.info, text='Address', bg='light blue').grid(row=4, column=0)
            ## It also shows the event in a larger windows so it is easier to read
        w=72
        h=1
        
        title=Text(self.info, width=w, height=h, bg='light blue')
        title.grid(row=0, column=1)

        time=Text(self.info, width=w, height=h, bg='light blue')
        time.grid(row=1, column=1)
        
        ID=Text(self.info, width=w, height=h, bg='light blue')
        ID.grid(row=2, column=1)
        
        desc=ScrolledText(self.info, width=70, height=15, bg='light blue')
        desc.grid(row=3, column=1)
        
        Address=Text(self.info, width=w, height=6, bg='light blue')
        Address.grid(row=4, column=1)

        text=[title, time, ID, desc]
            ## This is error handling if any of the data contains null type variables
        add=''
        for x in range(0,4):
            text[x].insert(END, self.data[p][x])
        for i in range(4,10):
            if self.data[p][i]==None:
                add=' \n'
            else:
                add=add+self.data[p][i]+'\n'
        Address.insert(END, add)
        
        self.active=1
        save_spef_button=Button(self.info, text='Save', width=67, height=1, bg='green', command=lambda: self.save(p)).grid(row=5, column=0, columnspan=2)
        quit_button=Button(self.info, text='Back', width=67, height=1, bg='yellow', command= lambda: self.quit_info()).grid(row=6, column=0, columnspan=2)

        ## The next three functions are to the corresponding 'view more' buttons, all call the more_info function however with different values of 'self.q' which corresponds the event that has been selected
    def info_1(self):
        p=self.q
        if self.active==1:
            self.quit_info()
        self.more_info(p)
        
    def info_2(self):
        if self.active==1:
            self.quit_info()
        p=self.q+1
        self.more_info(p)
        
    def info_3(self):
        p=self.q+2
        if self.active==1:
            self.quit_info()
        self.more_info(p)
        
    def save(self, p):
            ## The save button saves the specific event to the sql database so it can be viewed later by the user
            ## 'p' corresponds to the event and the concantiation of address so the whole address can be viewed in one widget
        title=self.data[p][0]
        date=self.data[p][1]
        ID=self.data[p][2]
        desc=self.data[p][3]
        address=self.data[p][4]+'\n'+self.data[p][5]+'\n'+self.data[p][6]+'\n'+self.data[p][7]+'\n'+self.data[p][8]+'\n'+self.data[p][9]
        query=('''INSERT INTO event(
                    people_ID, event_ID, name, time, description, address)
                    VALUES (?, ?, ?, ?, ?, ?)''')
        self.cursor.execute(query, [(self.personal_id),(ID),(title),(date),(desc),(address)])
        
    def id_check(self, id_2):
            ## This is just pulling the id that was used to login
        self.personal_id=id_2

    ## This class includes the widgets that are used by the user to insert their independent search
class Front_end:
    def __init__(self):
        with sqlite3.connect("user.db") as self.db:
            self.cursor=self.db.cursor()
    def main_viewer(self):
            ## The main_viewer is where the widgets are defined
        global main
        main = Tk()
        main.title('Event Finder')
        main.configure(bg='light blue')
            ##  Here is where I pull the ID off a local file I had created when you login
        with open('C_id', 'r') as f:
            ID=json.load(f)
            ## The ID then goes though several diffent changes of state due to json classifing it as a dictionary and then a list
        id_1=ID[0]
        id_2=id_1[0]
        self.ID=int(id_2)
        id_2=int(id_2)
        
        Event_viewer.id_check(id_2)
            ## The ID is then used to pull the users name from the database
        values=('SELECT name FROM people WHERE unique_ID=?')
        self.cursor.execute(values, [(id_2)])
        name=self.cursor.fetchall()
        name1=name[0]
        name2=name1[0]
        name2=str(name2)
            ## By changing the data structures I can finally get a string
            ## I can concantenate it all to a long string to get a intro statement with the users name apart of it. A more personalised experience
        text='Hello '+name2+', would you like to: '        

        b='light blue'
        # Create frames
        frame_search_query = Frame(main, bg=b)
        frame_search_query.pack(pady=10, padx=10)

        frame_buttons=Frame(main, bg=b)
        frame_buttons.pack(pady=10, padx=10)
        
        # Add labels
        Label(frame_search_query, text='Narrow your search', bg=b).grid(row=1, column=0, columnspan=2, sticky=NW)
        Label(frame_search_query, text='Enter Keywords: ', bg=b).grid(row=2, column=0, sticky=NW)
        Label(frame_search_query, text='Enter Location: ', bg=b).grid(row=3, column=0, sticky=NW)
        Label(frame_search_query, text='Enter Date: ', bg=b).grid(row=4, column=0, sticky=NW)
        Label(frame_search_query, text=text, bg=b, font=10).grid(row=0, column=0)
        Label(frame_search_query, text='Choose your Interests: ', bg=b).grid(row=1, column=3, sticky=N, padx=15)
        Label(frame_search_query, text='View the database: ', bg=b).grid(row=3, column=3, sticky=SW, padx=15)
        Label(frame_search_query, text='Look at your already saved events:', bg=b).grid(row=1, column=4, padx=15)
        
        # Create database name box
        g='light green'
        keywords_entry = Text(frame_search_query, width=15, height= 2)
        keywords_entry.grid(row=2, column=1, sticky=NW)
        location_entry = Text(frame_search_query, width=15, height= 2)
        location_entry.grid(row=3, column=1, sticky=NW)
        date_entry = Text(frame_search_query, width=15, height= 2)
        date_entry.grid(row=4, column=1, sticky=NW)
        
        # Add buttons
        button_quit = Button(frame_search_query, text="Quit", width=10, command=self.quit_tool, bg='red')
        button_quit.grid(row=5, column=0, sticky=NW)
        button_search = Button(frame_search_query, text="Search", width=15, command= lambda : self.fetch(keywords_entry, location_entry, date_entry), bg='light green')
        button_search.grid(row=5, column=1, sticky=N)
        button_lb_window=Button(frame_search_query, text="Interests", command=self.listbox, bg='yellow', padx=10)
        button_lb_window.grid(row=2, column=3, sticky=N)
        test=Button(frame_search_query, text='Database', command=self.data, padx=10)
        test.grid(row=4, column=3, sticky=N)
        saved_events=Button(frame_search_query, text='Saved Events', command=self.saved_events, bg='orange')
        saved_events.grid(row=2, column=4, sticky=N)
            ##
        self.chosen_interests=[]
        
    def quit_tool(self):
        ## Closes the window and then quits
        self.main.withdraw()
        self.main.quit()
        
    def data(self):
            ## This function was only for my personal use to see the database and check its contents. In reality if this was not a prototype i would remove this to get rid of security risks 
        values=('''SELECT * FROM people''')
        self.cursor.execute(values)
        result=self.cursor.fetchall()
        pp = pprint.PrettyPrinter(indent=4)
        pp.pprint(result)
        
    def saved_events(self):
            ## This function shows the saved events of the user
        self.saved=Tk()
        self.saved.title('Saved Events')

        Label(self.saved, text='Titles', bg='light blue').grid(row=0, column=0)
        Label(self.saved, text='Time', bg='light blue').grid(row=1, column=0)
        Label(self.saved, text='ID', bg='light blue').grid(row=2, column=0)
        Label(self.saved, text='Description', bg='light blue').grid(row=3, column=0)
        Label(self.saved, text='Address', bg='light blue').grid(row=4, column=0)

        w=72
        h=1
        
        name=Text(self.saved, width=w, height=h, bg='light blue')
        name.grid(row=0, column=1)

        date=Text(self.saved, width=w, height=h, bg='light blue')
        date.grid(row=1, column=1)
        
        ID=Text(self.saved, width=w, height=h, bg='light blue')
        ID.grid(row=2, column=1)
        
        desc=ScrolledText(self.saved, width=70, height=15, bg='light blue')
        desc.grid(row=3, column=1)
        
        Address=Text(self.saved, width=w, height=6, bg='light blue')
        Address.grid(row=4, column=1)

        text=[name, date, ID, desc]
 '''I am yet to complete this section as i ran out of time'''
##        events=('''SELECT * FROM event WHERE people_ID=?''')
##       self.cursor.execute(events,[(self.ID)])
        events=('''SELECT * FROM event''')
        self.cursor.execute(events)
        result=self.cursor.fetchall()
        print(result)
        
    def save(self):
            ## This is the function called when the save button is clicked on the listbox selection
        results=self.listbox1.curselection()
            ##This is error handling in case nothing is selected yet the listbox is still saved
        if results==():
            self.chosen_interests.insert(0, '')
        else:
            results=list(results)
            y=len(results)
            x=0
            for i in range (y):
                var=(results[i])
                chosen=(self.interests[var])
                self.chosen_interests.insert(0, chosen)
                x=x+1

        self.window2.withdraw()
        self.window2.quit()
        
    def fetch(self, key, loc, date):
            ## fetch pulls the data within each text widget send it to the choices function within the Event_viewer class
        keywords=key.get("1.0", "end-1c")
        location=loc.get('1.0', 'end-1c')
        date=date.get('1.0', 'end-1c')
        
        interests=self.chosen_interests
            ##Error handling in case interests where not chosen
        if interests==():
            print('done')
            interests.insert(0,'')
            
        Event_viewer.choices(keywords, location, date, interests)
        
    def listbox(self):
            ## The listbox function defines the listbox within tkinter
        self.window2=Tk()
        self.window2.title('Choose Your Interests')
            ##Defining the listbox
        self.listbox1 = Listbox(self.window2,
                          selectmode=MULTIPLE,
                          bg='light blue',
                          selectbackground='yellow',
                          bd=20,
                          font='Calibri',
                          width=25,)

        self.listbox1.grid(row=0, column=0)
            ## A list of the interests that will be used and defined by Eventful as compatable with the API search
        self.interests=[
            "Concerts/Music",
            "Comedy",
            "Festivals",
            "Film",
            "Food",
            "Art",
            "Museums",
            "Nightlife",
            "University",
            "Performing Arts",
            "Science",
            "Sports",
            ]
            ## Inserting the interests into the listbox as choices
        for item in self.interests:
            self.listbox1.insert(END, item)
       
        save_button=Button(self.window2, text='Save', width=20, command=self.save).grid(row=1, column=0)
        
class Login:
        ## The Login class is what you see when you first login or register
    def __init__(self):
        with sqlite3.connect("user.db") as self.db:
            self.cursor=self.db.cursor()

    def close(self, username_entry, name_entry, surname_entry, pass_entry, pass_verif, age_entry):
            ## This is the function that is called when the register function's button 'ok_button' is pressed
            ## It pulls the information through a lambda function and saves them to variables
        
        username=username_entry.get("1.0", "end-1c")
        name=name_entry.get('1.0', 'end-1c')
        surname=surname_entry.get('1.0', 'end-1c')
        p_entry=pass_entry.get('1.0', 'end-1c')
        p_verif=pass_verif.get('1.0', 'end-1c')
        age=age_entry.get('1.0', 'end-1c')
            ## loading the ID's so we don't get a duplica when creating the new user's ID
        with open('ID_file', 'r') as f:
            list_id= json.load(f)
        f.close()

            ## If the passwords match this algorithm with run
        if p_entry == p_verif:
                ## By generating a random number between 0-10000 and making it a string so it can be compaired against the other ID's
            k1=random.randint(0,10000)
            k1=str(k1)
            for i in range(len(list_id)):
                    ## This is where if one of the ID's match another random ID will be created 
                if k1 ==list_id[i]:
                    k1=random.randint(0,10000)
                ## The newly created ID is appended to the list and then the ID_file is update with the new ID within it
            list_id.append(k1)
            with open('ID_file', 'w') as f:
                json.dump(list_id, f)
            f.close()

                ## The data which has been inserted into the text boxes is now uploaded to the database
            insert=("INSERT INTO people "
                    "(unique_ID, username, name, surname, password, age) "
                    "VALUES (?, ?, ?, ?, ?, ?)")
            self.cursor.execute(insert, [(k1),(username),(name),(surname),(p_entry),(age)])
            self.db.commit()

            self.register_window.withdraw()
            self.register_window.quit()

            ## If the passwords didn't match an error message is inputed
        else:
            Label(self.register_window, text="Sorry, the passwords you have entered don't match, please try again", bg='yellow').grid(row=8, column=0, columnspan=2)
        
    def register(self):
            ## This is the function that creates the window used to register
        self.register_window=Tk()
        self.register_window.title('Register')
        
        Label(self.register_window, text='Username: ').grid(row=0, column=0, sticky=NE)
        Label(self.register_window, text='Name: ').grid(row=1, column=0, sticky=NE)
        Label(self.register_window, text='Surname: ').grid(row=2, column=0, sticky=NE)
        Label(self.register_window, text='Password: ').grid(row=4, column=0, sticky=NE)
        Label(self.register_window, text='Re-Enter Password: ').grid(row=5, column=0, sticky=NE)
        Label(self.register_window, text='Age: ').grid(row=6, column=0, sticky=NE)
        
        username_entry=Text(self.register_window, width=20, height=1, bg='#99ff66')
        username_entry.grid(row=0, column=1)
        name_entry=Text(self.register_window, width=20, height=1, bg='#99ff66', padx=0)
        name_entry.grid(row=1, column=1)
        surname_entry=Text(self.register_window, width=20, height=1, bg='#99ff66')
        surname_entry.grid(row=2, column=1)
        pass_entry=Text(self.register_window, width=20, height=1, bg='#99ff66')
        pass_entry.grid(row=4, column=1)
        pass_verif=Text(self.register_window, width=20, height=1, bg='#99ff66')
        pass_verif.grid(row=5, column=1)
        age_entry=Text(self.register_window, width=5, height=1, bg='#99ff66')
        age_entry.grid(row=6, column=1)

        ok_button=Button(self.register_window, text='OK', width=5, height=1, command=lambda: self.close(username_entry, name_entry, surname_entry, pass_entry, pass_verif, age_entry)).grid(row=7, column=1)
                        
    def login(self):
            ## The function used to create a login window
        self.start_window.withdraw()
        self.start_window.quit()

        bullet = "\u2022"
        
        self.login_window=Tk()
        self.login_window.title('Login')

        Label(self.login_window, text='Username:').grid(row=0, column=0)
        Label(self.login_window, text='Password:').grid(row=1, column=0)

        v=StringVar()
        user_entry=Text(self.login_window, width=20, height=1)
        user_entry.grid(row=0, column=1)
        
        pass_entry=Entry(self.login_window, width=20, textvariable=v, show=bullet)
        pass_entry.focus_set()
        pass_entry.grid(row=1, column=1)

        login_button=Button(self.login_window, text='Login', width=6, height=1, command=lambda: self.verif(user_entry, pass_entry)).grid(row=3, column=1, sticky=E)

    def verif(self, user_entry, pass_entry):
            ## Verif certifies that the password and username is within the database
            ## Pulling the data from the inputted login credentials within the login function
        user=user_entry.get('1.0', 'end-1c')
        password=pass_entry.get('1.0', 'end-1c')
            ## Finding the user within the database
        find_user=('SELECT * FROM people WHERE username= ? AND password= ?')
        self.cursor.execute(find_user, [(user),(password)])
        results=self.cursor.fetchall()

        if results:
                ## If the results are correct then the user's ID is saved to a file that will be later used to identify which user is currently login in
            identification=('SELECT unique_ID FROM people WHERE username=? AND password=?')
            self.cursor.execute(identification, [(user),(password)])
            current_id=self.cursor.fetchall()
            with open('C_id', 'w') as f:
                json.dump(current_id, f)
            f.close()
            
            Main.main_viewer()
            self.login_window.withdraw()
            self.login_window.quit()
            
        else:
                ## Error message that shows if the password or username is incorrect
            Label(self.login_window, text="Incorrect username \n or password", bg='yellow').grid(row=3, column=0, columnspan=2, sticky=NW)

    def start(self):
            ## Initial start window
        self.start_window=Tk()
        self.start_window.title('?')

        button_login=Button(self.start_window, text='Login', width=13, height=7,bg='light green', command=self.login).grid(row=0, column=0, sticky=NE)
        button_register=Button(self.start_window, text='Register', width=13, height=7,bg='#FF3636', command=self.register).grid(row=0, column=1, sticky=NW)

## I define all my classes to their variables so I can call them later 
Event_viewer = Events()
Main=Front_end()
Init=Login()
## The program is initially started with 'start' and the rest of the program follows though it
Init.start()

This snippet took 0.05 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).