sithara
sithara

Reputation: 97

Create relationship among the functions of buttons in Python

I want to import 3 csv files using 3 buttons separately and merge them into one csv file and save it using a button click. This is my code:

    from Tkinter import *
from Tkinter import Tk
from tkFileDialog import askopenfilename
import pandas as pd
from tkFileDialog import asksaveasfilename
import time

class Window(Tk):
    def __init__(self, parent):
        Tk.__init__(self, parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.geometry("600x400+30+30")

        self.wButton = Button(self, text='Product Price List', command = self.OnButtonClick)
        self.wButton.pack()


    def OnButtonClick(self):
        self.top = Toplevel()
        self.top.title("Product Price List")
        self.top.geometry("300x150+30+30")
        self.top.transient(self)
        self.wButton.config(state='disabled')

        self.topButton = Button(self.top, text="Import Price list CSV", command = self.OnImport1)
        self.topButton.pack()

        self.topButton = Button(self.top, text="Import Price Adjustment CSV", command = self.OnImport2)
        self.topButton.pack()

        self.topButton = Button(self.top, text="Import Price Adjustment CSV", command = self.OnImport3)
        self.topButton.pack()

        self.topButton = Button(self.top, text="Save As", command = self.OnSaveAs)
        self.topButton.pack()

        self.topButton = Button(self.top, text="CLOSE", command = self.OnChildClose)
        self.topButton.pack()

        def OnImport1(self):
            a = askopenfilename()
        def OnImport2(self):
            b = askopenfilename()
            c = a.OnImport1.merge(b, how='left', left_on='Dynamic_spcMatrix', right_on='Dynamic_spcMatrix' )
        def OnImport3(self):
            d = askopenfilename()
            d = d.dropna(axis=0)
            g = d.groupby('Dynamic_spcMatrix')['Attribute_spcName'].apply(lambda x: ', '.join(x.astype(str))) #join attributes usin commas
            c['Attribute_spcName'] = c['Dynamic_spcMatrix'].map(g)
            c = c[['Type', 'Name', 'Currency_spcCode', 'Product_spcCfg_spcModel_spcId', 'Product_spcName', 'Attribute_spcName', 'Matrix_spcType', 'Start_spcDate', 'End_spcDate', 'Original_spcList_spcPrice', 'Max_spcSale_spcPrice', 'Min_spcSale_spcPrice', 'String_spcMatrix_spcColumn_spc1', 'String_spcMatrix_spcColumn_spc2', 'String_spcMatrix_spcColumn_spc3', 'String_spcMatrix_spcColumn_spc4','Number_spcMatrix_spcColumn_spc1']]
        def OnSaveAs(self):
            dlg = asksaveasfilename(confirmoverwrite=False)
            fname = dlg
            if fname != '':
                f = open(fname, "a")
                new_text = time.time()
                f.write(str(new_text)+'\n')
                f.close()     
            c.to_csv(fname, index=False)


    def OnChildClose(self):
        self.wButton.config(state='normal')
        self.top.destroy()

if __name__ == "__main__":
    window = Window(None)

    window.title("Create Csv")

    window.mainloop()

I want to import 3 csv files using 3 buttons separately and merge them into one csv file and save it using a button click. When I run this following error occurs.

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\tt20172129\AppData\Local\Continuum\anaconda2\lib\lib-tk\Tkinter.py", line 1541, in __call__
    return self.func(*args)
  File "<ipython-input-15-64436dd12913>", line 51, in OnImport2
    c = a.OnImport1.merge(b, how='left', left_on='Dynamic_spcMatrix', right_on='Dynamic_spcMatrix' )
NameError: global name 'a' is not defined

I am new to python and also to coding. Hopefully there is someone that can help me so that I can learn. :)

Upvotes: 0

Views: 67

Answers (2)

Erik Bethke
Erik Bethke

Reputation: 594

Shripal Gandhi is fundamenatally correct, a does not have scope outside of the method on Import1. That is why the code does not work.

His solution - a global - works - but is crude and a great antipattern of why to use a global.

You have to make a architectural decision here.

You have to store the results of a = askopenfilename(), instead of dropping into the global scope, simply keep it at the class scope. Simply had self. in front of a, b, and c, and then you can reference them from any of your other class methods including when you want to write it out (the next time this bug would have showed up)

def OnImport1(self): self.a = askopenfilename()

def OnImport2(self):
    self.b = askopenfilename()

def OnImport3(self):

    self.c = self.a.OnImport1.merge(self.b, how='left', left_on='Dynamic_spcMatrix', right_on='Dynamic_spcMatrix' )

Upvotes: 2

Shripal Gandhi
Shripal Gandhi

Reputation: 126

It is because scope of a is:

def OnImport1(self):
    a = askopenfilename()

and in the scope, a is not defined.:

def OnImport2(self):
    b = askopenfilename()
    c = a.merge(b, how='left', left_on='Dynamic_spcMatrix', right_on='Dynamic_spcMatrix' )

Update the code as:

a = #Use askopenfilename() return type object to initialize
def OnImport1(self):
    global a
    a = askopenfilename()
def OnImport2(self):
    global a
    b = askopenfilename()
    c = a.merge(b, how='left', left_on='Dynamic_spcMatrix', right_on='Dynamic_spcMatrix' )

It will be able to find a in scope of OnImport2.

Upvotes: 0

Related Questions