Python: Program that picks a random word from multiple text files - python

I am trying to make a GUI program where at the press of a button, the program picks a random word out of 3 files and displays the selected word in a Label.
What is the simplest way that I could go about doing this?
Thanks!

Here's a simple example that randomly picks a 'word'(anything that is separated) in some files named 'test.txt', 'test2.txt', 'test3.py' that are in the same directory as the below code:
from secrets import choice # for cryptographically secure randomness
import tkinter as tk # for GUI
def random_file():
random_file = choice(("test.txt", "test2.txt", "test3.py"))
return random_file
def random_word(file_name):
with open(file_name) as f:
all_words_in_file = list()
for line in f:
for word in line.split():
all_words_in_file.append(word)
random_word = choice(all_words_in_file)
return random_word
def label_rnd_word():
global lbl
lbl['text'] = random_word(random_file())
if __name__ == '__main__':
root = tk.Tk()
lbl = tk.Label(root)
btn = tk.Button(root, text="Random Word", command=label_rnd_word)
# layout
lbl.pack()
btn.pack()
root.mainloop()

Make a button in tkinter - this is pretty easy... something like:
button= Button(root, text="button name", command=self.do_something)
button.grid(row=1, column=1, columnspan=1)
Import the data from the 3 text files with something like this:
load_file = os.path.join('FOLDER', 'FILENAME')
with open(load_file, 'r') as f:
FILE1= f.read()
f.close()
You could iterate this is you want, but it's hardly worth it for 3 files.
Join the 3 together....
Maybe
combined = string1 + string2 + string3
then simply select a random word
Use the random.choice() function:
import random
print(random.choice(combined))
You still need to do some work- but that's how I would do it. hope this helps!!

Related

How to save data so that is is still there after you close and reopen tkinter application?

I have created a simple application where you can enter a word and press a button, and each time you press the button, an image and 2 labels are packed onto the screen, 1 label containing the words you have typed. I want to make it so that if you close the application and reopen it, the images and labels you have placed by pressing the button are still there. How could this be done?
from tkinter import *
import pickle
import calendar
from tkcalendar import *
import calendar
from tkcalendar import *
from datetime import datetime
from datetime import date
from time import strftime
from datetime import timedelta, datetime, date
from ttkthemes import ThemedTk, THEMES
import pickle
self = Tk()
self.title('Storing data')
self.geometry("850x800")
x = 200
y = 250
c = 460
d = 290
e = 325
f = 355
g = 390
h = 420
i = 460
j = 490
LARGE_FONT= ("Verdana", 24)
SMALL_FONT=("Verdana", 12)
def get_text(file):
with open(file, "r") as MyFile:
return MyFile.read()
def edit_text(file, text, img_dir):
with open(file, "w") as MyFile:
MyFile.write(text + "\n" + "apple.png")
def step(self):
my_progress['value']+= 5
def display():
global x , y , c , d , e , f , g, h, i, j
box_image = PhotoImage(file='apple.png')
panel2 = Label(self, image=box_image, bg='#f7f6f6')
panel2.image = box_image
panel2.place(x=x, y=y)
x=x
y = y+260
#assessment name
n = Label(self, text="", bg="#e0f6fc", font=60)
n.configure(text=assessment_name.get())
n.pack()
#due date
d = Label(self, text="Due:", bg="#e0f6fc", font=SMALL_FONT)
d.pack()
#cal date
c= Label(self, text="", bg="#e0f6fc", font=SMALL_FONT)
c.pack()
button = Button(self, text="place", command=display)
button.pack()
save = Button(self, text="save", command=edit_text)
save.pack()
open_button =Button(self, text="open", command=get_text)
open_button.pack()
edit_text("textfile.txt", "label contents", "apple.png")
assessment_name = Entry(self)
assessment_name.place(relx=0.5, y=220, anchor='center')
global cal2
cal2 = Calendar(self, background="#e0f6fc", disabledbackground="white", bordercolor="light blue", headersbackground="light blue", normalbackground="#e0f6fc", foreground="black", normalforeground='black', headersforeground='white', selectmode="day", year=2021, month=8, day=9)
cal2.place(relx=0.5, y=400, anchor='center')
due_date = Button(self, text="Submit")
due_date.place(relx=0.5, y=510, anchor='center')
self.mainloop()
If you want to save something for later, you can save it to a text file. You can save the text and the directory for the image
First, create a .txt file where you want ( within the same folder as the code is best ).
Next, create a function which gets the text from the file:
def get_text(file):
with open(file, "r") as MyFile:
return MyFile.read()
This code will return a string containing what is in the text file.
Next, create a function which can edit the file. It is best to do this by deleting it and re-writing it again
def edit_text(file, text, img_dir):
with open(file "w") as MyFile:
MyFile.write(text + "\n" + img_dir)
When calling this function, it will change the contents of the file to what is inputted. For example:
edit_text("textfile.txt", "label contents", "apple.png")
This would change the contents of "textfile.txt" to:
label contents
apple.png
You can use this to store data for your application. I hope this helped!
While you could save data into a txt, it is much easier imo to store it as JSON. With JSON, you could store a dictionary of values and recall them quickly and easily. You could then take these values and set them to the various parameters within your app.
Python also has a built in JSON library, so all you have to do is import json. You can find the documentation here
Here is a more detailed explanation:
To accomplish this you will need to store the saved data in an external file. This will require knowledge of the .open() , .read() , json.loads() , and json.dumps() functions
We will first start by creating the json file we want to store out data in, ex: myJson.json.
In this file, create a dictionary with the value you want to store, ex: {"entryVal": "Hello World!"}
The following is a basic GUI that we will build on:
from tkinter import *
import json
root = Tk()
toSave = StringVar()
Entry(root, textvariable = toSave) .pack()
Button(root, text = "save value!") .pack()
root.mainloop()
Next, we need to define two functions: one to open the Json, and one to save the Json.
def openJson():
with open('myJson.json', 'r') as f:
value = json.loads(f.read())["entryVal"]
toSave.set(value)
def saveJson():
with open('myJson.json', 'w') as f:
currentVal = json.dumps({"entryVal":toSave.get()})
f.write(currentVal)
openJson() will open the Json file, decode from Json, take the key-value of 'entryVal' and set our entry box to have the text it found.
saveJson() will take the value from our entry, put it in a dictionary under the key 'entryVal', encode to Json, and then write it into the save file.
Now we just need to call openJson() when we start the program, and create a button to trigger saveJson():
from tkinter import *
import json
root = Tk()
def openJson():
with open('myJson.json', 'r') as f:
value = json.loads(f.read())["entryVal"]
toSave.set(value)
def saveJson():
with open('myJson.json', 'w') as f:
currentVal = json.dumps({"entryVal":toSave.get()})
f.write(currentVal)
toSave = StringVar()
Entry(root, textvariable = toSave) .pack()
Button(root, text = "save value!", command = saveJson) .pack()
openJson()
root.mainloop()

Merging Files in Tkinter Search Files Application

I am trying to build a simple application using Tkinter wherein I should be able to search files in my local folders and display them. For example, if I am searching a 'test.txt' file, it will return me that file plus all txt files. Now the second part of the problem is, I have to merge all the files that was returned to me in my search into one single file (I know it sounds absurd but please forgive me). I have successfully achieved the first part but not able to implement the second part. Quite new to functions and OOPs concepts. Pasting my code below in the hope for some guidance. Please forgive me for the code quality as I am quite new.
import pandas as pd
from tkinter import *
import os
from docx import Document
doc1 = Document()
def search_file():
file_entry_name = entry.get()
answer.delete(1.0,END)
extension = file_entry_name.split('.')[1]
file_name = file_entry_name.split('.')[0]
file_entry_name = file_entry_name.lower()
for r,d,f in os.walk('/Users/kausthab/Documents/Documents – Kausthab’s MacBook Air/DSBA'):
for file in f:
file.split()
if file.startswith(file_entry_name) or file.endswith(extension):
answer.insert(INSERT,file + '\n')
def merge_file():
# files = os.listdir('/Users/kausthab/Documents/Documents – Kausthab’s MacBook Air/DSBA')
# global answer
# for i in answer:
# if i != '.DS_Store': # i kept getting an error for a hidden file. So excluded it
# doc1.add_heading(i, 2)
# doc2 = Document(i)
# for para in doc2.paragraphs:
# para_in_doc = doc1.add_paragraph(para.text)
# doc1.add_page_break()
# doc1.save('search.docx')
return
root = Tk()
root.title('Docu Search')
topframe = Frame(root)
entry = Entry(topframe)
entry.pack()
button = Button(topframe, text="search",command =search_file)
button.pack()
topframe.pack(side = TOP)
bottomframe = Frame(root)
scroll = Scrollbar(bottomframe)
scroll.pack(side=RIGHT, fill=Y)
answer = Text(bottomframe, width=80, height=50, yscrollcommand = scroll.set,wrap= WORD)
scroll.config(command=answer.yview)
merge_button = Button(bottomframe, text="merge",command =merge_file)
merge_button.pack()
answer.pack()
bottomframe.pack()
root.mainloop()

Display output of print in python GUI?

Hello I created this function that allows you to count the top X words in the Macbeth play however I want to display the results in a gui of my creation and was wondering if someone could show me how to? I already created the function and tested it but I don't understand python gui and whenever I try to create it, I run into a host of errors.
#Imports
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from collections import Counter
import collections
# Initialize the dictionary
wordcount = {}
#Function
#open Macbeth text file
file = open('Macbeth Entire Play.txt', encoding="utf8")
a= file.read()
n_print = int(input("How many most common words are: "))
print("\nThe {} most common words are as follows\n".format(n_print))
word_counter = collections.Counter(wordcount)
for word, count in word_counter.most_common(n_print):
print(word, ": ", count)
# Close the file
file.close()
#Graphics
fullString = ""
root = tk.Tk()
root.title("Count words")
root.geometry('400x400')
#Background Image Label
bg = PhotoImage(file = "./guibackground.gif")
# Show image using label
label1 = Label( root, image = bg)
label1.place(relx=0.5, rely=0.5, anchor=CENTER)
#Class Window
class Window:
def __init__(self):
self.root = tk.Tk()
self.btn = tk.Button(text='Open File', command=self.open_file)
self.btn.pack()
self.btn = tk.Button(text='Exit', command=root.quit)
self.btn.pack()
self.lbl.pack()
self.root.mainloop()
def open_file(self):
file = open('Macbeth Entire Play.txt', encoding="utf8")
a= file.read()
def word_count(self):
for word in a.lower().split():
word = word.replace(".","")
word = word.replace(",","")
word = word.replace(":","")
word = word.replace("\"","")
word = word.replace("!","")
word = word.replace("“","")
word = word.replace("‘","")
word = word.replace("*","")
if word not in wordcount:
wordcount[word] = 1
else:
wordcount[word] += 1
if __name__ == '__main__':
mainWindow = Window()
# root.mainloop()
I'll present a general example for you to start with in building your GUI. There are a few items I'd like to comment.
It's not a good idea to import tkinter as tk as well as from tkinter import * as this may lead to confuson later in the development. In general it's preferred to import tkinter as tk as you then always can see which module a widget comes from.
I would advise against the mix of flat and OOP programming styles. As above, it may lead to confusion later.
It's a good idea to use descriptive names, even if you just create and forget widgets, because an error message will tell you the name of the offending object. And also just in general it's easier to get a grip of the application with descriptive names. For example the GUI Buttons could instead be called: self.open_btn and self.exit_btn.
When you are working with files you may consider using the with statement as this adds a layer of security; it won't leave files open even if there is an error.
My example uses a program structure which I often use myself, depending on how I intend to use the program. Pros and cons for different structures are discussed in the thread Best way to structure a tkinter application?
Below is an example you can use as a cornerstone for your efforts if you wish.
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master):
super().__init__() # Call __init__() method in parent (tk.Frame)
self.bg_image = tk.PhotoImage(file = "images/pilner.png")
self.background = tk.Label( root, image=self.bg_image)
self.background.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
self.open_btn = tk.Button(text='Open File', command=self.open_file)
self.open_btn.pack(pady=(30,10))
self.exit_btn = tk.Button(text='Exit', command=master.destroy)
self.exit_btn.pack()
def open_file(self):
with open('Macbeth Entire Play.txt', encoding="utf8") as file:
self.file_text = file.read()
# Etc, etc.
if __name__ == '__main__':
root = tk.Tk()
root.title("Count words")
root.geometry('400x400+900+50')
app = Application(root)
app.pack(expand=True, fill='both')
root.mainloop()
Hope this is of help.

How to create an array of tkinter text input, where every line in text is an element in array

I have this code:
def full_function():
options=text.get(1.0, END)
print options
from Tkinter import *
root = Tk()
text = Text(root,font=("Purisa",12))
text.pack()
button=Button(root, text ="Button", command =lambda: full_function())
button.pack()
root.mainloop()
How could I make this program to create an array of text input, so every line of text would be an element in array. For example, if input is:
I am here.
They are there.
Then i want my app to create following list=["I am here.", "They are there."]
from Tkinter import *
#Below should pack to class
class MyWindow:
def __init__(self, wname=""):
self.root = Tk()
self.root.title(wname)
self.text = Text(self.root,font=("Purisa",12))
self.text.pack()
self.button=Button(self.root, text ="Button", command=self.prn)
self.button.pack()
self.root.mainloop()
def get_words_list(self, widget):
"""Return list of words"""
options=widget.get(1.0, END)# get lines into string
#Remove spaces in list of lines
return [i.strip() for i in options.splitlines()]
def prn(self):
"""Testing get_words_list"""
print self.get_words_list(self.text)
if __name__ == "__main__":
w = MyWindow("My window")
Use split to make a list of the input and use str(text.get(1.0, END)) to remove unicode "u":
def full_function():
options = str(text.get(1.0, END))
lines = options.strip().split("\n")
print lines
['I am here.', 'They are there.']

How to open another window and get data from it, then save to a file?

I'm trying to create a program in python using tkinter, and this program is supposed to have a list of books created by the user. On the main window (the one with the list), there should be a menubar with the option to add a book to the list. When clicked, this option should open another window, this time with one entrybox, where the user should enter the book's title and an add button, to add the button to the list.
The list is saved in a .txt file.
This is the program I wrote so far:
import sys
from tkinter import *
def newBook():
def add():
BookTitle = v.get()
bookTitle = '\n' + BookTitle
books = open('c:/digitalLibrary/books.txt', 'a')
books.write(bookTitle)
books.close()
addWindow = Tk()
v = StringVar()
addWindow.geometry('250x40+500+100')
addWindow.title('digitalLibrary - Add Book')
newBookEntry = Entry(addWindow,textvariable=v)
newBookEntry.pack()
addButton = Button(addWindow, text='ADD', command=add)
addButton.pack()
def refresh():
books = open('c:/digitalLibrary/books.txt', 'r')
bookList = books.readlines()
books.close()
for i in range (0, len(bookList)):
bookOne = Label(text=bookList[i])
bookOne.grid(row=i, column=0, sticky=W)
def quitProgram():
tfQuit = messagebox.askyesno(title='Close Program', message='Are you sure?')
if tfQuit:
window.destroy()
window = Tk()
menubar = Menu(window)
window.geometry('400x400+200+100')
window.title('digitalLibrary')
booksmenu = Menu(menubar, tearoff=0)
booksmenu.add_command(label='Add Book', command=newBook)
booksmenu.add_command(label='Delete Book')
booksmenu.add_command(label='Close Program', command=quitProgram)
menubar.add_cascade(label='digitalLibrary', menu=booksmenu)
books = open('c:/digitalLibrary/books.txt', 'r')
bookList = books.readlines()
books.close()
for i in range (0, len(bookList)):
bookOne = Label(window, text=bookList[i])
bookOne.grid(row=i, column=0, sticky=W)
refreshButton = Button(window, text='Refresh', command=refresh)
refreshButton.grid(row=0, column=1)
window.config(menu=menubar)
window.mainloop()
It seems logical to me that this should work, but it just doesn't. When I click the ADD button on the Add Book window, all it does is add the line break to the .txt file.
I know that it works if I use the OS library and create a separate python file for the add book window, but I'd rather put it all in one code, if possible.
I've tried many things, and tried searching it in the web, but I got nowhere.
The root cause of your problem is that you are creating more than once instance of Tk. You cannot do this. If you want to create a popup window, create an instance of Toplevel. A proper Tkinter application creates exactly once instance of Tk with exactly one invocation of mainloop.
If your main goal is to simply get input from the user (versus learning how to write your own dialog), you might want to consider using one of the built-in dialogs.
For example:
import tkinter.simpledialog as tkSimpleDialog # python 3.x
...
def newBook():
BookTitle = tkSimpleDialog.askstring("Add Book","What is the name of the book?")
if BookTitle is not None:
bookTitle = '\n' + BookTitle
books = open('/tmp/books.txt', 'a')
books.write(bookTitle)
books.close()

Categories

Resources