0

I am trying to create a little GUI to convert Parquet to XLSX files. In my code, I am currently using tkinter to create a GUI and then using a function to convert from Parquet to XLSX.

When I run the below code though, I am still getting an error that "myfunc() missing 3 required positional arguments: 'txt_file', 'txt_name', and 'txt_dir'" any idea why they are not getting assigned?

import os
import pandas as pd
from tkinter import *
import pyarrow
import shutil
from pathlib import Path

window = Tk()
window.title("Convertor")
#Sets the size of the window
window.geometry('550x200')

#Adds a header to the window and configures the size 
lbl = Label(window, text="Convert Parquet to CSV", font=("Arial Bold", 18))

#Configures where the label message will appear
lbl.grid(column=0, row=0)

#asks for parquet file
lbl2 = Label(window, text="Where is the parquet file currently located?", font=("Arial", 12))
lbl2.grid(column=0, row=1)

#adds a field for an input text message
txt_file = Entry(window,width = 30)
txt_file.grid(column=1, row=1)

#asks for name of xlsx file
lbl3 = Label(window, text="What would you like to call the new xlsx file?", font=("Arial", 12))
lbl3.grid(column=0, row=2)

txt_name = Entry(window,width = 30)
txt_name.grid(column=1, row=2)

#asks where you want to put the new xlsx file
lbl3 = Label(window, text="Where would you like to ouput the xlsx file?", font=("Arial", 12))
lbl3.grid(column=0, row=3)

txt_dir = Entry(window,width = 30)
txt_dir.grid(column=1, row=3)

def myfunc(txt_file, txt_name, txt_dir):
    file = txt_file
    df1 = pd.read_parquet(file)
    df = df1.append(df1, ignore_index=True)
    dirout = txt_dir
    name = txt_name
    cfile = os.path.join(dirout, name + "." + "xlsx")
    df.to_excel(cfile)


#Adding a button
btn = Button(window, text="Convert", command=myfunc)
btn.grid(column=1, row = 4)

#The mainloop causes the window to remain open until someone interacts with it
window.mainloop()
  • You're not passing any parameter to the function that's called by the button. Check this answer to understand how to do it: https://stackoverflow.com/questions/6920302/how-to-pass-arguments-to-a-button-command-in-tkinter – toti08 Jan 15 '20 at 14:50
  • I think you should try to learn the way how the `functions` their `parameters` and `arguments` work. – DaniyalAhmadSE Jan 16 '20 at 15:17
  • @YusufCattaneo Your question is answered by @BryanOakley and that would work fine for you but if you are dealing with a function in another `class` or `module` then you should pass the `arguments` at the point where it is called or referred. Like in your case you should use: ```command=lambda:myfunc(txt_file,txt_name,txt_dir))``` – DaniyalAhmadSE Jan 16 '20 at 15:25
  • @YusufCattaneo You don't need to name the `parameters` of the functions the same as the `arguments` which you are going to give to it. For Example, you have a function `def add(): print(a+b)` and you want to add '1' and '2'. All you need to do is: `add(1,2)` – DaniyalAhmadSE Jan 16 '20 at 15:36
  • `lambda` is used to stop the function from being called where it is given as a `command` to the `Button`. So you can pass it the arguments like in your case `(txt_file, txt_name, txt_dir)`. – DaniyalAhmadSE Jan 17 '20 at 11:10

1 Answers1

1

Instead of passing values into your function, have your function retrieve the values from the UI. In your case you're saving the widgets in global variables which makes that easy to do.

For example:

def my_func():
    file = txt_file.get()
    name = txt_name.get()
    dir_out = txt_dir.get()

    df1 = pd.read_parquet(file)
    df = df1.append(df1, ignore_index=True)
    cfile = os.path.join(dirout, name + "." + "xlsx")
    df.to_excel(cfile)

...

btn = Button(window, text="Convert", command=my_func)

If you want to make your code easier to test by having the code that does the work be in a function that accepts parameters, simply move that code to a separate function.

def my_func():
    file = txt_file.get()
    name = txt_name.get()
    dir_out = txt_dir.get()

    do_conversion(file, name, dir_out)

def do_conversion(file, name, dir_out):

    df1 = pd.read_parquet(file)
    df = df1.append(df1, ignore_index=True)
    cfile = os.path.join(dirout, name + "." + "xlsx")
    df.to_excel(cfile)

With that, you can use do_conversion with or without a GUI, making it easier to write a unit test for the code that performs the actual conversion.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685