I am creating a window with two buttons - one to import excel files and another to close the window after excel sheets are selected. I can choose the excel files, but when I click Okay, I get an error that I have an invalid file path.
using python 2.7
import Tkinter, tkFileDialog
import pandas as pd
root= Tkinter.Tk()
canvas = Tkinter.Canvas(root, width = 300, height = 300, bg = 'PowderBlue')
canvas.pack()
def getExcel ():
global df
import_file_path = tkFileDialog.askopenfilenames(title = 'Select file(s)',filetypes = (('Excel','*.xlsx'),('Comma Delimited','*.csv'),('xls', '*.xls')))
df = pd.read_excel (import_file_path)
print (df)
okay = Tkinter.Button(text='Okay', command=root.destroy, bg='blue', fg='white', font=('Arial', 10, 'bold'))
canvas.create_window(150, 200, window=okay)
browse_excel = Tkinter.Button(text='Import Excel File(s)', command = getExcel, bg='gray23', fg='white', font=('helvetica', 12, 'bold'))
canvas.create_window(150, 150, window = browse_excel)
root.mainloop()
the error I get it
raise ValueError(msg.format(_type=type(filepath_or_buffer)))
ValueError: Invalid file path or buffer object type: <type 'tuple'>
tkFileDialog.askopenfilenames(...) returns a tuple of one or more filenames. You can't pass this tuple directly to read_excel(); you'd have to loop over the contents of the tuple and call that function once per filename:
filenames = tkFileDialog.askopenfilenames(...)
for filename in filenames:
df = pd.read_excel(filename)
print(df)
Or you can call askopenfilename() (note there is no s on the end) for a single filename.
Related
first of all, I'm a beginner. I have a basic script (get grades()) that takes a .csv file and specific class sections (min 1, max 3). I wrote this function to clean courses grades, and the output is a .txt containing only the student number, class section and grade. This text file is then ready to be upload to a system at my uni.
I'm trying to create a GUI for this script, but I'm stuck. Googling around, I managed to get a basic GUI, but even though I can enter the class sections and browse for a file, I cannot make it run my function. When I click on the button to the get the grades, the GUI crashes. Could you please point me in the right direction? Thank you in advance.
tkinter code
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
import tkinter
from tkinter import *
from tkinter import filedialog as fd
from get_grades import get_grades
from functools import partial
# root window
root = tk.Tk()
root.geometry("500x450")
root.title('Grades')
# store sections
sections = tk.StringVar()
file_name = tk.StringVar()
def save_sections():
""" callback when the sections button clicked
"""
msg = f'You entered sections: {sections.get()}'
showinfo(
title='Information',
message=msg
)
# Sign in frame
signin = ttk.Frame(root)
signin.pack(padx=10, pady=10, fill='x', expand=True)
# sections
sections_label = ttk.Label(signin, text="sections:")
sections_label.pack(fill='x', expand=True)
sections_entry = ttk.Entry(signin, textvariable=sections)
sections_entry.pack(fill='x', expand=True)
sections_entry.focus()
# login button
section_button = ttk.Button(signin, text="save sections", command=save_sections)
section_button.pack(fill='x', expand=True, pady=10)
def get_file_name(file_entry):
file_name = fd.askopenfilename(title="Select file", filetypes=(("CSV Files", "*.csv"),))
file_entry.delete(0, END)
file_entry.insert(0, file_name)
entry_csv = Entry(root, text="", width=50)
entry_csv.pack(fill='x', expand=True)
file_label = ttk.Label(root, text="Input CSV")
file_button = ttk.Button(root, text="Browse...", width=10, command=lambda: get_file_name(entry_csv))
file_button.pack(fill='x', expand=True, pady=10)
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv, sections))
grades_button.pack(fill='x', expand=True, pady=10)
# infinite loop
root.mainloop()
get_grades.py
import pandas as pd
from datetime import datetime
def get_grades(file, section1=True, section2=False, section3=False):
sections = []
if section1:
sections.append(section1)
if section2:
sections.append(section2)
if section3:
sections.append(section3)
else:
return "missing sections"
# get file
df = pd.read_csv(file)
# delete the first two rows
df = df.drop([df.index[0], df.index[1]])
# important columns are "SIS User ID", "Section", and the name of the test, which changes by course
# first, rename the assignment column
df = df.rename(columns={df.columns[5]: "Grade"})
df = df[df.Student != "Student, Test"]
# select columns
df = df[["SIS User ID", "Section", "Grade"]]
df = df[df['Section'].isin(sections)]
# cleaning
df = df.replace("0.0", "NVD")
df = df.fillna("NA")
# deleting decimal
df['SIS User ID'] = df['SIS User ID'].astype(str).apply(lambda x: x.replace('.0', ''))
# save to txt and csv
# file name
date_time = datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p")
filename = str(date_time) + "_" + str(sections)
df.to_csv(str(filename + ' .txt'), sep='\t', index=False)
print("done! file " + str(filename) + ".txt saved")
You are passing an Entry widget and a StringVar to your function. But your function expects string objects.
You have to get the values of your entry box and StringVar. Luckily, the method is called the same for both cases. It's the .get() method.
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv.get(), sections.get()))
This should pass the correct values to get_grades(). But to be sure, you should print the values to console, just to check. This would also have hinted at the problem you had with your code.
In the following code I get to select an excel file using a tkinter button.
I'm using a function to read the excel file and import data and convert to dataframe.
The problem is I don't have access to the dataframe outside the function although it's a global variable, therefore I can't continue with the rest of stuff.
I can now access the df variable, but not as a DataFrame which appears to be empty.
What is best to do to get around this ?
import tkinter as tk
from tkinter import filedialog, ttk
import pandas as pd
root=tk.Tk()
root.title("THIS IS MY FIRST APPLICATION")
root.geometry("600x300")
text_import = ("Choose your file: ")
df = pd.DataFrame()
# browse file and import data
def getExcel ():
global df
import_file_path = filedialog.askopenfilename()
data1 = pd.read_excel(import_file_path)
df = pd.DataFrame(data1)
print(df)
# create button
my_button = tk.Button(root, text = text_import, width = 15, height = 2,
command = getExcel)
my_button.pack(pady=10)
my_button.place(x = 200, y = 75)
print(df.dtypes)
root.mainloop()
When print(df.dtypes) is executed, no file is loaded yet and so it is empty. You should call it inside a function which should be called after a file is loaded:
import tkinter as tk
from tkinter import filedialog, ttk
import pandas as pd
root = tk.Tk()
root.title("THIS IS MY FIRST APPLICATION")
root.geometry("600x300")
text_import = "Choose your file: "
df = None
# browse file and import data
def getExcel():
global df
import_file_path = filedialog.askopenfilename()
if import_file_path:
df = pd.read_excel(import_file_path)
print(df)
# create button
my_button = tk.Button(root, text=text_import, width=15, height=2, command=getExcel)
#my_button.pack(pady=10)
my_button.place(x=200, y=75)
def showExcel():
if df is not None:
# a file is loaded
print(df.dtypes)
tk.Button(root, text="Show File Data", width=15, height=2, command=showExcel).place(x=200, y=150)
root.mainloop()
When i write this in my python code, it display the next error. What can i do to repair it?
filename = tkinter.StringVar()
entry_function = tkinter.Entry(parent, textvariable=filename, bg="black", font=("Hacker", 15, "normal"),fg= "white", width = 18)
tkinter.Entry.insert(0,'keylogger')
tkinter.Entry.pack(default)
Error
Messaggio=insert() missing 1 required positional argument: 'string'
Origine=D:\finale\Homework.py
Analisi dello stack:
File "D:\finale\Homework.py", line 138, in <module>
tkinter.Entry.insert(0,'keylogger')
First define a Entry widget, and then insert a value.
Here is an example:
import tkinter as tk
window = tk.Tk()
ent = tk.Entry(window, width=20)
ent.grid(row=0, column=0)
# insert value
ent.insert(0,'keylogger')
window.mainloop()
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()
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.
So I'm trying to create a very basic python UI where a user uploads a CSV with a list of cities and the program creates an inner join with a pre-existing database of zip codes returns a list of cities and their corresponding zip codes. My code is functional so far. I'd just like the user to be able to upload a CSV from anywhere in their system. Right now, the program only reads from the python directory. I don't want to have to specify the file path of the input file. Is there any way this can be done? Here's the code I have right now -
import tkinter as tk
from tkinter import filedialog
import pandas as pd
root= tk.Tk()
canvas1 = tk.Canvas(root, width = 300, height = 300, bg = 'lightsteelblue2', relief = 'raised')
canvas1.pack()
def getCSV():
global cities
import_file_path = filedialog.askopenfilename()
cities = pd.read_csv('cities.csv')
zips = pd.read_csv('zips.csv')
output = pd.merge(cities, zips, on='state' and 'county', how='inner')
output.to_csv('output.csv', encoding='utf-8', index=False)
browseButton_CSV = tk.Button(text=" Upload City Data & Close ", command=getCSV, bg='green', fg='white',
font=('helvetica', 12, 'bold'))
canvas1.create_window(150, 150, window=browseButton_CSV)
root.mainloop()
I'm kinda new to python and programming in general. Just been learning it over the past month or 2. Any help is appreciated!
Thanks,
DJ
#gingerhaze's answer -
import tkinter as tk
from tkinter import filedialog
import pandas as pd
root= tk.Tk()
canvas1 = tk.Canvas(root, width = 300, height = 300, bg = 'lightsteelblue2', relief = 'raised')
canvas1.pack()
def getCSV():
global cities
import_file_path = filedialog.askopenfilename()
cities = pd.read_csv(import_file_path)
zips = pd.read_csv('zips.csv')
output = pd.merge(cities, zips, on='state' and 'county', how='inner')
output.to_csv('output.csv', encoding='utf-8', index=False)
browseButton_CSV = tk.Button(text=" Upload City Data & Close ", command=getCSV, bg='green', fg='white',
font=('helvetica', 12, 'bold'))
canvas1.create_window(150, 150, window=browseButton_CSV)
root.mainloop()