Python: how to open a file up to the user? - python

Good day folks,
I created a simple GUI that let's the user browse through their files with tkinter's filedialog.
After picking one, python reads the data from the (excel) file, and with that creates a new .txt file.
Now after doing that, I would like python to make that .txt file pop up, so that the user gets to see the result.
How do I do this?
Edit for the bot-moderator- he wanted code examples:
File1.py
from contextlib import nullcontext
import File2 as tp
import tkinter as tk
from tkinter import StringVar, messagebox
from tkinter import filedialog
filename = None
def pickFile():
global filename
filename = filedialog.askopenfilename()
#Creating main window
master = tk.Tk()
masterWidth = 350
masterHeight = 250
master.iconbitmap('C:\...')#directory
master.title('Title')
# get the screen dimension
screen_width = master.winfo_screenwidth()
screen_height = master.winfo_screenheight()
# find the center point
center_x = int(screen_width/2 - masterWidth / 2)
center_y = int(screen_height/2 - masterHeight / 2)-100
# set the position of the window to the center of the screen
master.geometry(f'{masterWidth}x{masterHeight}+{center_x}+{center_y}')
#Creating startbutton
startButton = tk.Button (master, text="Start", height=1, width=3, command=lambda: tp.readFile(filename))
#Creating bladerknop
browseButton = tk.Button (master, text='browse...', command=pickFile)
browseLabel = tk.Label(master, text='Choose a file')
startButton.place(x=175,y=200)
browseButton.place(x=210,y=50)
browseLabel.place (x=110,y=52)
master.mainloop()
File2.py
import pandas as pd
import tkinter as tk
from tkinter import messagebox
#declaring variables for later use
data = None
def missingValues(path):
if path is not None:
data = pd.read_excel(path, header=None)
return data
else:
messagebox.showinfo('No file chosen', 'Choose a file first.')
def readFile(path):
data = missingValues(path)
with open("C:\...\newFile.txt", 'w') as newTxt:
count = 0
for index, row in data.iterrows():
code = data.loc[count,0]
price = toEightBits(data.loc[count,1])
newTxt.write(str(code))
newTxt.write(str(price))
newTxt.write("\n")
count += 1
newTxt.close()

Related

Displaying multiple results based on similarity Python

I would like to know if anyone could help me with this problem. Im a beginner at Python, and im trying to create a program. The problem is that i want to search for a person in a stats database, and then get the result of the 5 most similar players based on stats. Now i only get one name, and cannot figure out what I am doing wrong.
This is the code that i have used, but it only displays 1 player, instead of the 5 players that are most similar.
import tkinter as tk
import pandas as pd
import os
from tkinter import filedialog
from tkinter import messagebox
from tkinter import ttk
def compare_players(player_name, data):
player = data[data['Player'] == player_name]
player_stats = player.select_dtypes(include=['float64'])
player_stats = (player_stats - player_stats.mean()) / player_stats.std()
data_stats = data.select_dtypes(include=['float64'])
data_stats = (data_stats - data_stats.mean()) / data_stats.std()
similarity = data_stats.dot(player_stats.T)
top_5 = data.iloc[similarity.iloc[0,:].sort_values(ascending=False).index[:5]]
return top_5
def run_search(folder_path, player_name, data):
result = compare_players(player_name, data)
for i, row in result[['Player', 'Team', 'Age']].iterrows():
tree.insert("", "end", values=(row['Player'], row['Team'], row['Age']))
def on_search():
player_name = entry.get()
run_search(folder_path, player_name, data)
def load_data():
global data
data = pd.DataFrame()
for file in os.listdir(folder_path):
if file.endswith(".xlsx"):
file_path = os.path.join(folder_path, file)
temp_data = pd.read_excel(file_path)
data = pd.concat([data, temp_data], axis=0)
root = tk.Tk()
root.withdraw()
folder_path = filedialog.askdirectory(initialdir = *Here i put the folder which contains many excel files*,
title = "Select folder")
load_data()
root = tk.Tk()
root.title("Player Comparison")
root.geometry("600x400")
label = tk.Label(root, text="Enter player name:")
entry = tk.Entry(root)
search_button = tk.Button(root, text="Search", command=on_search)
label.pack()
entry.pack()
search_button.pack()
tree = ttk.Treeview(root, columns=("Player", "Team", "Age"), show="headings")
tree.heading("Player", text="Player Name")
tree.heading("Team", text="Team")
tree.heading("Age", text="Age")
tree.pack(side="left", fill="y")
root.mainloop()
The code is most likely all over the place, but i try :D
Thanks for all answers in advance.

Python tkinter Pop Up Progress Bar

I have created a simple program to download from a private azure container and rename a series of .jpg files listed in a csv file. I'm still learning python so I am sure the code is a bit on the rough side! That said, the code works fine and the files download correctly. However, I would like to display a pop up progress bar showing the current progress. I have looked at a number of examples but I'm not sure how best to approach this. Could anyone offer some pointers on the best way? Thanks.
from tkinter import messagebox
import urllib.request
import csv
from datetime import datetime, timedelta
from azure.storage.blob import BlockBlobService
from azure.storage.blob.models import BlobPermissions
from azure.storage.blob.sharedaccesssignature import BlobSharedAccessSignature
account_name = '***'
account_key = '***'
top_level_container_name = '***'
blob_service = BlockBlobService(account_name, account_key)
blob_shared = BlobSharedAccessSignature(account_name, account_key)
root = Tk()
root.withdraw()
csvDir = filedialog.askopenfilename(initialdir="/", title="SELECT CSV FILE", filetypes=(("CSV files", "*.csv"), ("all files", "*.*")))
imageDir = filedialog.askdirectory()
with open(csvDir) as images:
images = csv.reader(images)
img_count = 1
for image in images:
sas = blob_shared.generate_blob(container_name=top_level_container_name, blob_name=image[0], permission=BlobPermissions.READ, start=datetime.now(), expiry=datetime.now() + timedelta(hours=1))
sas_url = 'https://' + account_name + '.blob.core.windows.net' + '/' + top_level_container_name + '/' + image[0] + '?' + sas
print(sas_url)
urllib.request.urlretrieve(sas_url, imageDir + "/{}.jpg".format(image[1]))
img_count += 1
messagebox.showinfo("Complete", "Print images have been downloaded")
root.mainloop()
The Base Code
The base code that this project uses as its baseline is Shichao's Blog Post, Progress/speed indicator for urlretrieve() in Python and my version of it is simply a tkinter wrapper is big props to Shichao for the amazing Blog Post.
The Tkinter Code
If you merely wish to see the code without the breakdown, you simply see it and copy and paste the given example:
import time
import urllib.request
import tkinter as tk
import tkinter.ttk as ttk
class download_toplevel:
def __init__(self, master):
self.master = master
self.download_button = tk.Button(self.master, text="Download", command=self.download)
self.download_button.grid(row=0, column=0)
self.root = tk.Toplevel(self.master)
self.progress_bar = ttk.Progressbar(self.root, orient="horizontal",
length=200, mode="determinate")
self.progress_bar.grid(row=0, column=0)
self.progress_bar.grid_rowconfigure(0, weight=1)
self.progress_bar.grid_columnconfigure(0, weight=1)
self.progress_bar["maximum"] = 100
self.root.withdraw()
# See https://blog.shichao.io/2012/10/04/progress_speed_indicator_for_urlretrieve_in_python.html
def reporthook(self, count, block_size, total_size):
print(count, block_size, total_size)
if count == 0:
self.start_time = time.time()
return
duration = time.time() - self.start_time
progress_size = int(count * block_size)
speed = int(progress_size / (1024 * duration))
percent = min(int(count*block_size*100/total_size), 100)
print(percent)
self.progress_bar["value"] = percent
self.root.update()
def save(self, url, filename):
urllib.request.urlretrieve(url, filename, self.reporthook)
def download(self):
self.progress_bar["value"] = 0
self.root.deiconify()
self.save("https://files02.tchspt.com/storage2/temp/discord-0.0.9.deb", "discord-0.0.9.deb")
self.root.withdraw()
def main():
root = tk.Tk()
#root.withdraw()
downloader = download_toplevel(root)
root.mainloop()
if __name__ == '__main__':
main()
The Breakdown
The imports
import time
import urllib.request
import tkinter as tk
import tkinter.ttk as ttk
The import of tkinter.ttk is important as the Progress Bar widget is not found in the default tkinter module.
The main loop
def main():
root = tk.Tk()
downloader = download_toplevel(root)
root.mainloop()
if __name__ == '__main__':
main()
The line if __name__ == '__main__' means if the code is run directly without being imported by another python program execute the following statement, so on you running $ python3 main.py, the code will run the main function.
The main function works by creating the main window root, and passing the window into a variable within the class download_toplevel. This is a neater way of writing python code and is more versatile when working with tkinter as it simplifies the code when looking at it in the future.
The Download Button
self.master = master
self.download_button = tk.Button(self.master, text="Download", command=self.download)
self.download_button.grid(row=0, column=0)
This code adds a button labelled download bound to the command download
The Toplevel Window
self.root = tk.Toplevel(self.master)
This creates a toplevel window that appears on top of the master window
The Progress Bar
self.progress_bar = ttk.Progressbar(self.root, orient="horizontal",
length=200, mode="determinate")
self.progress_bar.grid(row=0, column=0)
self.progress_bar.grid_rowconfigure(0, weight=1)
self.progress_bar.grid_columnconfigure(0, weight=1)
self.progress_bar["maximum"] = 100
This creates a ttk.Progressbar onto the Toplevel window, oriented in the x plane, and is 200px long. The grid_*configure(0, weight=1) means that the progress bar should grow to fit the given space, to make sure this happens you should also include , sticky='nsew' in the grid command. self.progress_bar["maximum"] = 100 means that the max value is 100%.
Withdraw
self.root.withdraw()
This withdraws the Toplevel window until it is actually required, i.e. when the download button is pressed.
The Report Hook
def reporthook(self, count, block_size, total_size):
print(count, block_size, total_size)
if count == 0:
self.start_time = time.time()
return
duration = time.time() - self.start_time
progress_size = int(count * block_size)
speed = int(progress_size / (1024 * duration))
percent = min(int(count*block_size*100/total_size), 100)
This code is taken directly from Shichao's Blog Post, and simply works out the percentage completed.
self.progress_bar["value"] = percent
self.root.update()
The Progress Bar is then set to the current percentage and the Toplevel is updated, otherwise it remains as a black window (tested on Linux).
The save function
def save(self, url, filename):
urllib.request.urlretrieve(url, filename, self.reporthook)
This bit of code has been straight up taken from the Blog Post and simply downloads the file and on each block being downloaded and written the progress is sent to the self.reporthook function.
The Download Function
def download(self):
self.progress_bar["value"] = 0
self.root.deiconify()
self.save("https://files02.tchspt.com/storage2/temp/discord-0.0.9.deb", "discord-0.0.9.deb")
self.root.withdraw()
The download function resets the Progress Bar to 0%, and then the root window is raised (outside of the withdraw). Then the save function is run, you may wish to rewrite the self.save call to read self.after(500, [the_function]) so that your main window is still updated as this program is run. Then the Toplevel window is withdrawn.
Hope this helps,
James

How to give the location of "Input" and "Output" for a python code using User Interface and run the code from UI itself?

I have a python code :
import gdal
import numpy
from skimage.filters import threshold_otsu
ds = gdal.Open('A:\\algo\\f2.tif')
In this code, line 4 gives the location/path of "input file" and line 10 gives the location of "output file".
I want to create a user interface to give this location in the user interface itself and run the code from user interface itself.
I have tried making a user interface using "tkinter" module :
from tkinter import *
from tkinter import filedialog
def input():
file1 = filedialog.askopenfile()
label = Label(text=file1).pack()
def input2():
file2 = filedialog.asksaveasfile(mode="w", defaultextension=".tif")
label = Label(text=file2).pack()
w = Tk()
w.geometry("500x500")
w.title("FLOOD_MAPPER")
h = Label(text = "S1A FLOOD MAPPER", bg = "yellow", fg = "black", height = "3", width = "500")
h.pack()
i1 = Label(text = "Input*")
i1.place(x=10, y=70)
i1b = Button(w, text = "Select File", command =input)
i1b.place(x=250, y=70)
i2 = Label(text = "Intermediate Product*")
i2.place(x=10, y=140)
i2b = Button(w, text = "Save as", command =input2)
i2b.place(x=250, y=140)
button = Button(w, text="Generate Map", bg = "red", fg = "black", height = "2", width="30")
button.place(x=150, y=400)
w.mainloop()
But I didn't understand how to link these two codes.
The moment I click on button "generate map" in the user interface I want the location/path of Input and output given in the user interface box to move to their respective places in the 1st code and then run the same code aumoatically.
Kindly, help me to achieve my requirement.
It can look like this. I removed keep only important elements in tkinter.
I put code in your_code and it can get filenames as paramaters. So this code looks similar as before.
I create function gen_map which get run your_code with filenames which are assigned to global variables input_filename, `output_filename.
I assing gen_map to button Button( command=gen_map) so it will run it when you press button.
Other buttons open dialog to get file names and assign to global variables input_filename, output_filename.
from tkinter import *
from tkinter import filedialog
import gdal
import numpy
from skimage.filters import threshold_otsu
def your_code(input_file, output_file):
#ds = gdal.Open('A:\\algo\\f2.tif')
ds = gdal.Open(input_file)
band = ds.GetRasterBand(1)
arr = band.ReadAsArray()
thresh = threshold_otsu(arr,16)
binary = arr > thresh
driver = gdal.GetDriverByName("GTiff")
#outdata = driver.Create("A:\\algo\\test11.tif", 14823, 9985, 1, gdal.GDT_UInt16)
outdata = driver.Create(output_file, 14823, 9985, 1, gdal.GDT_UInt16)
outdata.SetGeoTransform(ds.GetGeoTransform())
outdata.SetProjection(ds.GetProjection())
outdata.GetRasterBand(1).WriteArray(binary)
outdata.GetRasterBand(1).SetNoDataValue(10000)
outdata.FlushCache() ##saves to disk!!
#outdata = None
#band = None
#ds = None
def get_input_filename():
global input_filename
# `askopenfilename` instead of `askopenfile` to get filename instead of object file
input_filename = filedialog.askopenfilename()
input_label['text'] = input_filename
def get_output_filename():
global output_filename
# `asksaveasfilename` instead of `asksaveasfile` to get filename instead of object file
output_filename = filedialog.asksaveasfilename(defaultextension=".tif")
output_label['text'] = output_filename
def gen_map():
#global input_filename
#global output_filename
print('input:', input_filename)
print('output:', output_filename)
your_code(input_filename, output_filename)
#---------------------------------------------
# global variables with default values at start
input_filename = 'A:\\algo\\f2.tif'
output_filename = "A:\\algo\\test11.tif"
root = Tk()
#input_label = Label(root, text=input_filename)
input_label = Label(root, text="Input*")
input_label.pack()
input_button = Button(root, text="Select File", command=get_input_filename)
input_button.pack()
#output_label = Label(root, text=output_filename)
output_label = Label(root, text="Intermediate Product*")
output_label.pack()
output_button = Button(root, text="Save as", command=get_output_filename)
output_button.pack()
gen_map_button = Button(root, text="Generate Map", command=gen_map)
gen_map_button.pack()
root.mainloop()

Getting missing required dependencies Numpy while using Pyinstaller

I have created a mini app that is used for combining a bunch of excel files, but I cant execute the exe due to this error. What I find strange is that I am not even using Numpy in my script. I have installed and reinstalled numpy, but that did not fix the issue.
I created a virtual environment which has the following libraries installed.
Error on Executing exe
Here is my code:
import tkinter as tk
from tkinter.simpledialog import askstring, askinteger
from tkinter.messagebox import showerror
from tkinter import messagebox
from tkinter import filedialog
from tkinter import ttk
import os
from os import path
import pandas as pd
import fnmatch
import glob
import datetime
from datetime import datetime
import time
import calendar
class Splash(tk.Toplevel):
def __init__(self, parent, width=0.8, height=0.6, useFactor=True):
tk.Toplevel.__init__(self, parent)
self.title("Splash")
w = 300
h = 200
x = 50
y = 100
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
lbl = tk.Label(self,text="Combine Excel\n Version 1.0", bg = 'lightgrey' )
lbl.place(x=25, y=30)
self.master.overrideredirect(True)
self.lift()
## required to make window show before the program gets to the mainloop
self.update()
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.withdraw()
splash = Splash(self)
## simulate a delay while loading
time.sleep(1)
## finished loading so destroy splash
splash.destroy()
def getfiles():
listbox.delete(0,tk.END)
beginput = entry_1.get()
endinput = entry_2.get()
timefmt = "%m/%d/%y"
start = calendar.timegm(datetime.strptime(beginput, timefmt).timetuple())
end = calendar.timegm(datetime.strptime(endinput, timefmt).timetuple())
year = datetime.strptime(beginput, timefmt).strftime('%Y')
monthyr = datetime.strptime(beginput, timefmt).strftime('%m-%y') + ' Daily Collection'
yearmm = 'CA_LoanLvl_' + time.strftime("%Y%m%d")
yrnmsum = 'CA_Sum_' + time.strftime("%Y%m%d")
frame = pd.DataFrame()
list_ = []
cols = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,37,39,40,41,43,44,45,46,47,49,50,51,52,53,54,55,56,57]
path1 = path.join(r'\\corp.int\cms\DeptData\Monthly Reporting'
'\Daily Collection',year,monthyr,'Data')
pathexpt = path.join(r'\\corp.int\cms\DeptData\XX\DS\DataDownloads\Combine',yearmm)
pathexptsum = path.join(r'\\corp.int\cms\DeptData\XX\DS\DataDownloads\Combine',yrnmsum)
mypath = path1
def test(f):
if (not os.path.isfile(f)):
return 0
(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(f)
return start<=ctime and end>=ctime
files = [f for f in glob.glob(os.path.join(mypath, "adv*")) if test(f)]
for item in files:
listbox.insert(tk.END, os.path.basename(item))
if __name__ == "__main__":
App()
# Create the main window
root = tk.Tk()
s = ttk.Style(root)
s.theme_use('clam')
root.title("Combine GNMA Files")
# set the root window's height, width and x,y position
# x and y are the coordinates of the upper left corner
w = 600
h = 400
x = 50
y = 100
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("%dx%d+%d+%d" % (w, h, x, y))
# use a colorful frame
frame = tk.Frame(root, bg='darkblue')
frame.pack(fill='both', expand='yes')
label = tk.Label(frame, text="Start Date-mm/dd/yy", bg = 'lightblue')
label.place(x=20, y=30)
label2 = tk.Label(frame, text="End Date-mm/dd/yy", bg = 'lightblue')
label2.place(x=20, y=100)
entry_1 = tk.Entry(root)
entry_1.place(x=20,y=60)
entry_2 = tk.Entry(root)
entry_2.place(x=20,y=130)
btn_1 = tk.Button(root,text="Get Files", bg='light grey', command = getfiles)
btn_1.place(x=400, y=15)
listbox = tk.Listbox(root)
listbox.place(x=20, y=160, width = 400)
def on_closing():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
root.destroy()
root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()
If anyone runs across this, it seems it has to do with the version of Numpy that is causing errors with Pyinstaller. Take a look at the link below.
[How to fix 'Missing required dependencies ['numpy']' when running packaged app made with PyInstaller?

Creating Graphs in Python GUI

I have created a GUI in which I read a CSV file and calculate the liquid output from the data. Now I want to do two things:
1) I want to generate the output based on time just like date
2) I want to generate graphs on a separate window in my GUI for a user specific time or date
This is my code:
import csv
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showwarning, showinfo
import datetime
#csv_file = csv.reader(open("C:\Users\Lala Rushan\Downloads\ARIF Drop Monitoring Final\ARIF Drop Monitoring Final\DataLog.csv"))
from Tools.scripts.treesync import raw_input
class App(Frame):
def __init__(self, master):
Frame.__init__(self, master)
button1 = Button(self, text="Browse for a file", command=self.askfilename)
button2 = Button(self, text="Count the file", command=self.takedate)
button3 = Button(self, text="Exit", command=master.destroy)
button1.grid()
button2.grid()
button3.grid()
self.userInputFromRaw = Entry(self)
self.userInputFromRaw.grid()
self.userInputToRaw = Entry(self)
self.userInputToRaw.grid()
self.grid()
def askfilename(self):
in_file = askopenfilename()
if not in_file.endswith(('.CSV')):
showwarning('Are you trying to annoy me?', 'How about giving me a CSV file, genius?')
else:
self.in_file=in_file
def CsvImport(self,csv_file):
dist = 0
for row in csv_file:
_dist = row[0]
try:
_dist = float(_dist)
except ValueError:
_dist = 0
dist += _dist
print ("Urine Volume is: %.2f" % (_dist*0.05))
def takedate(self):
from_raw = self.userInputFromRaw.get()
from_date = datetime.date(*map(int, from_raw.split('/')))
print ('From date: = ' + str(from_date))
to_raw = self.userInputToRaw.get()
to_date = datetime.date(*map(int, to_raw.split('/')))
in_file = ("H:\DataLog.csv")
in_file= csv.reader(open(in_file,"r"))
for line in in_file:
_dist = line[0]
try:
file_date = datetime.date(*map(int, line[1].split(' ')[1].split('/')))
if from_date <= file_date <= to_date:
self.CsvImport(in_file)
except IndexError:
pass
root = Tk()
root.title("Urine Measurement")
root.geometry("500x500")
app = App(root)
root.mainloop()
How can I achieve the above 2 tasks?
I must agree with Jacques de Hooge, you should be using matplotlib for that.
At the beggining of your file, import it:
import matplotlib.pyplot as plt
As you only want to open a new window with the plot, a matplotlib window should suffice. You can use a scatter plot:
plt.scatter(X, Y)
Where X is an iteratable with the x coordinates and Y an iteratable with the y coordinates. Since you want to do something with a constant change in time, you can, having a values list with the values to plot, do the following:
plt.scatter(range(len(values)), values)
plt.show()
You might also want to run this inside a thread, so that the rest of the program doesn't "freeze" while the matplotlib window is open. There are plenty of places where this is explained.

Categories

Resources