Problem when export csv using Pandas (file cannot read chinese char) - python

I am trying to create flashcard game, but I have problem when trying to export dict to csv using pandas.
My dictionary has contained some Chinese letters and pinyin.
When I have played with multiple encodings, seem sometime Chinese letter can be read but pinyin is unreadable, sometimes its vice versa.
I'm not sure what is the issue about my code. please help me.
Thank you very much
Remark
for pinyin Im using slash or back-slash or dash to indicate tone
Ex. bàn tiān,
when import to csv, the program still can read those tone symbol, but not when export.
Example
export csv is on line 109-110
import random
import pandas as pd
from tkinter import *
from PIL import Image, ImageTk
windows = Tk()
windows.geometry(r"300x360")
windows.config(bg='#f7f5dd')
my_pic = Image.open(r"C:\\Users\\xx\\PycharmProjects\\flashcard\\Picture1.png")
scale_factor = 0.3
resized = my_pic.resize((int(712 * scale_factor), int(667 * scale_factor)))
img = ImageTk.PhotoImage(resized)
canvas = Canvas(width=235, height=235, bg="#f7f5dd", highlightthickness=0)
canvas.create_image(120, 120, image=img)
canvas.grid(column=1, row=1, pady=20, padx=30, columnspan=3)
know_button = Button()
dont_know_button = Button()
already_know_list = []
pix1 = Image.open(r"C:\Users\xx\PycharmProjects\flashcard\correct.png")
pix2 = Image.open(r"C:\Users\xx\PycharmProjects\flashcard\wrong.png")
scale_factor2 = 0.15
resized1 = pix1.resize((int(274 * scale_factor2), int(275 * scale_factor2)))
resized2 = pix2.resize((int(274 * scale_factor2), int(275 * scale_factor2)))
img1 = ImageTk.PhotoImage(resized1)
img2 = ImageTk.PhotoImage(resized2)
know_button.config(image=img1, bg="#f7f5dd", highlightthickness=0)
dont_know_button.config(image=img2, bg="#f7f5dd", highlightthickness=0)
know_button.grid(column=0, row=2, columnspan=2)
dont_know_button.grid(column=3, row=2, columnspan=2)
data = pd.read_csv(r"C:\\Users\\xx\\PycharmProjects\\flashcard\\hsk_vocabs_1_5.csv")
custom_data = data
number = random.randint(0, len(data))
chn_obj = canvas.create_text(120, 140, text=f"{data['Chinese'][number]}\n{data['Pinyin'][number]}", fill="white",
font=('Dosis SemiBold', 20, 'bold'), anchor='center')
five_sec_label = Label()
five_sec_label.config(text="3", font=('Dosis SemiBold', 20, 'bold'), bg="#f7f5dd")
five_sec_label.grid(column=1, row=2, columnspan=3)
init_sec = 3
timer = None
def clock(total_second):
global chn_obj, timer, init_sec
if total_second >= 0:
timer = windows.after(1000, clock, total_second - 1)
five_sec_label.config(text=f"{total_second}", font=('Corrier', 20, 'bold'))
else:
canvas.itemconfig(chn_obj, text="")
chn_obj = canvas.create_text(120, 140, text=f"{data['English'][number]}", fill="black",
font=('Dosis SemiBold', 15, 'bold'), anchor='center')
init_sec = 0
def next_word():
global number, chn_obj, timer, init_sec
init_sec = 3
canvas.itemconfig(chn_obj, text="")
chn_obj = canvas.create_text(120, 140, text=f"{data['Chinese'][number]}\n{data['Pinyin'][number]}", fill="white",
font=('Dosis SemiBold', 20, 'bold'), anchor='center')
windows.after_cancel(timer)
five_sec_label.config(text="")
clock(init_sec)
unknown_word = []
def already_know():
global already_know_list, number
already_know_list.append(number)
while number in already_know_list:
number = random.randint(0, len(data))
next_word()
def append_unknown_words():
global number, init_sec
if init_sec != 0:
return
else:
unknown_word.append(data['Chinese'][number])
number = random.randint(0, len(data))
next_word()
chinese_list = []
pinyin_list = []
english_list = []
def export_when_finished():
global unknown_word, chinese_list, pinyin_list, english_list
unknown_file = {
"Chinese": chinese_list,
"Pinyin": pinyin_list,
"English": english_list
}
for item in unknown_word:
chinese_list.append(data[data["Chinese"] == item]["Chinese"].values[0])
pinyin_list.append(data[data["Chinese"] == item]["Pinyin"].values[0])
english_list.append(data[data["Chinese"] == item]["English"].values[0])
df = pd.DataFrame(unknown_file)
df.to_csv('Unknown_Words.csv', encoding="utf-8")
exit()
know_button.config(command=already_know)
dont_know_button.config(command=append_unknown_words)
stop_game_n_export = Button()
stop_game_n_export.config(text="Stop and Export Unknown Words", font=('Dosis SemiBold', 10, 'bold'),
command=export_when_finished)
stop_game_n_export.grid(column=0, row=0, columnspan=3, rowspan=1)
clock(init_sec)
windows.mainloop()

Related

How to clear a Label Text of tkinter

I want to clear the output result of the equation. But when I press the clear button it gives an error
"NameError: name 'CalculationOutput' is not defined"
How do I solve this problem.
import tkinter as tk
compression = ""
GuiRoot = tk.Tk()
MainCanvas = tk.Canvas(GuiRoot, width=500, height=400, relief="raised")
MainCanvas.pack()
DesignText1 = tk.Label(GuiRoot, text="Calculate the Square Root")
DesignText1.config(font=("halvetica", 14))
MainCanvas.create_window(250, 25, window=DesignText1)
DesignText2 = tk.Label(GuiRoot, text="Type your number")
DesignText2.config(font=("halvetica", 10))
MainCanvas.create_window(250, 100, window=DesignText2)
UserEntryBox = tk.Entry(GuiRoot)
MainCanvas.create_window(250, 200, window=UserEntryBox)
def GetSquareRoot():
x = UserEntryBox.get()
DesignText3 = tk.Label(GuiRoot, text="The Square Root of " + x + ' is:', font=("halvetica", 10))
MainCanvas.create_window(250, 260, window=DesignText3)
CalculationOutput = tk.Label(GuiRoot, text=float(x)**0.5, font=("halvetica", 10, "bold"))
MainCanvas.create_window(250, 280, window=CalculationOutput)
CalculationButton = tk.Button(text="Get the Square Root", command=GetSquareRoot, bg="brown", fg='white', font=('halvetica', 9, 'bold'))
MainCanvas.create_window(250, 230, window=CalculationButton)
def ClearButtonFunc():
global compression
compression = ""
CalculationOutput.set("")
ClearButton = tk.Button(GuiRoot, text="Clear Text", command=ClearButtonFunc)
MainCanvas.create_window(250, 320, window=ClearButton)
GuiRoot.mainloop()

Printing tkinter label in new line

First of all, sorry for that vague title. I am making a python application that shows time, fetches weather and News. Now, when i print news through tkinter label, it prints the titles of news on a separate line but in the center. If I try to specify the .pack(side=LEFT) geometry, it goes to the left but all the headlines print in a string and not in a newline. I have tried adding new line by '\n' and even carriage return '\n' but in vain. Please help me out with this issue. Attaching the code below.
P.s i could not get it the news to work with the For loop so i manually printed arrays.
from tkinter import *
import datetime
from PIL import Image, ImageTk
import requests
class Clock(Frame):
def __init__(self, parent):
Frame.__init__(self,parent, bg='black')
self.now = datetime.datetime.today()
self.time = str(self.now.hour) + ":" + str(self.now.minute)
self.timelb = Label(self, text=self.time, font=("Helvetica 50"), bg='black', fg='white')
self.timelb.pack(anchor=NE,padx=60,pady=0)
self.date = str(self.now.day) + '.' + str(self.now.month) + '.' + str(self.now.year)
self.day = self.now.strftime('%A')
self.daylb = Label(self, text=self.day, font="Helvetica 20", bg='black', fg='white')
self.daylb.pack(anchor=NE,padx=60)
self.datelb = Label(self, text=self.date, font="Helvetica 25", bg = 'black', fg='white')
self.datelb.pack(anchor=NE, padx=60)
class Weather(Frame):
def __init__(self, parent):
Frame.__init__(self,parent,bg='black')
url = 'http://api.openweathermap.org/data/2.5/weather?appid=c73d9cdb31fd6a386bee66158b116cd0&q=Karachi&units=metric'
json = requests.get(url).json()
temperature = json['main']['temp']
description = json['weather'][0]['description']
icon_id = json['weather'][0]['icon']
city = 'Karachi'
icon_url = ('http://openweathermap.org/img/wn/{icon}#2x.png'.format(icon=icon_id))
self.im = Image.open(requests.get(icon_url, stream=True).raw)
self.ph = ImageTk.PhotoImage(self.im)
degree = u'\N{DEGREE SIGN}' + 'C'
self.pic_label = Label(self,image=self.ph,bg='black')
self.pic_label.pack()
self.lab= Label(self,text=(str(temperature) + degree),font=("Helvetica 40"), bg='black', fg='white')
self.lab.pack()
self.description_label=Label(self, text=description, font='Helvetica 20',bg='black', fg='white')
self.description_label.pack()
self.city_label=Label(self, text=city, font = 'Helvetica 10', bg='black', fg='white')
self.city_label.pack()
class News(Frame):
def __init__(self, parent):
super(News, self).__init__(bg='black')
url = " https://newsapi.org/v1/articles?source=bbc-news&sortBy=top&apiKey=caa7f97ce8f2400a9785cbe704afc345"
json = requests.get(url).json()
self.title = 'Headlines'
self.title_lb = Label(self, text=self.title, font='Helvetica 25',bg='black', fg='white')
self.title_lb.pack(side=TOP, anchor=N)
im = Image.open('Newspaper_reduced.png')
self.pho = ImageTk.PhotoImage(im)
news1 = json['articles'][0]['title']
news2 = json['articles'][1]['title']
news3 = json['articles'][2]['title']
news4 = json['articles'][3]['title']
news5 = json['articles'][4]['title']
self.img = Label(self,image=self.pho,bg='black')
self.img.pack(side=LEFT)
self.headline1_lb = Label(self, text=news1, font = 'Helvetica 15' ,bg='black', fg='white')
self.headline1_lb.pack(side=LEFT)
self.img2 = Label(self,image=self.pho,bg='black')
self.img2.pack(side=LEFT)
self.headline2_lb = Label(self, text = news2, font='Helvetica 15',bg='black', fg='white')
self.headline2_lb.pack(side=LEFT)
self.img3 = Label(self,image=self.pho,bg='black')
self.img3.pack(side=LEFT)
self.headlines3_lb = Label(self, text=news3, font='Helvetica 15',bg='black', fg='white')
self.headlines3_lb.pack(side=LEFT)
self.img4 = Label(self,image=self.pho,bg='black')
self.img4.pack(side=LEFT)
self.headlines4_lb = Label(self, text=news4, font='Helvetica 15',bg='black', fg='white')
self.headlines4_lb.pack(side=LEFT)
self.img5 = Label(self,image=self.pho,bg='black')
self.img5.pack(side=LEFT)
self.headlines5_lb = Label(self, text=news5, font='Helvetica 15',bg='black', fg='white')
self.headlines5_lb.pack(side=LEFT)
class Fullscreen:
def __init__(self):
self.tk = Tk()
self.tk.configure(bg='black')
self.tk.title('smartmirror')
self.topFrame = Frame(self.tk , bg='black')
self.topFrame.pack(side=TOP, fill=BOTH, expand=YES)
self.bottomFrame = Frame(self.tk, bg='black')
self.bottomFrame.pack(side=BOTTOM, fill=BOTH, expand=YES)
self.clock = Clock(self.topFrame)
self.clock.pack(side=RIGHT, anchor=NE, padx=50, pady=60)
self.weather = Weather(self.topFrame)
self.weather.pack(side=LEFT, anchor=NW, padx=50, pady=70)
self.news = News(self.bottomFrame)
self.news.pack(side=BOTTOM, anchor=S)
if __name__ == '__main__':
w = Fullscreen()
w.tk.mainloop
First: I removed images in code because I don't have them and I want to waste time to search images which I could use as replacement.
If you set different color for labels then you see then have different width - they use width of text.
If you use
self.headline1_lb.pack(fill='x')
then they will use the same width but text still is in center.
If you use
Label(..., anchor='w')
then it will move text to left side.
If you will put in Label text with many lines then you may need also
Label(..., anchor='w', justify='left')
If you want use full width of window for text then you have to use fill='x'
self.news.pack(side=BOTTOM, anchor='s', fill='x')
After that you can again set black background.

tkinter, Image does not show up unless some function added

I have written a code for a basic game but the image and shape don't show up unless I add something like item.pack() or win.mainloop() [which doesn't really make sense] but then the lines below it don't run.
When I don't have anything, the buttons show up but the image doesn't show up.
import tkinter as tk
import random
from tkinter import messagebox
win = tk.Tk()
my_label = tk.Label(win, text="Color of the Baloon Game")
my_label.pack()
my_canvas = tk.Canvas(win, width=400, height=600)
my_canvas.pack()
background_image=tk.PhotoImage(file = "CS_Game_menu.png")
background_label = tk.Label(my_canvas, image=background_image)
background_label.photo = background_image
background_label.grid(row = 0, rowspan = 10, column = 0, columnspan = 10)
def drawCircle():
color = "green"
x1 = 265
y1 = 80
diameter = 90
my_canvas.destroy()
circle_button.destroy()
quit_button.destroy()
my_label.destroy()
my_label1 = tk.Label(win, text="What is the Color of the Baloon?", font="Purisa")
my_label1.pack()
my_canvas1 = tk.Canvas(win, width=400, height=600)
my_canvas1.pack()
image1 = r"CS_Game_baloon.png"
photo1 = tk.PhotoImage(file=image1)
item = my_canvas1.create_image(200, 350, image=photo1)
shape = my_canvas1.create_oval(x1, y1, x1 + diameter, y1 + diameter+20, fill=color)
item.pack()
game1_button = tk.Button(my_canvas1, text = "Green")
game1_button.grid(row= 8, column = 3)
game1_button["command"] = lambda: messagebox.showinfo("Congratulations!", "Correct Answer!")
game2_button = tk.Button(my_canvas1, text = "Blue")
game2_button.grid(row= 8, column = 5)
game2_button["command"] = lambda: messagebox.showinfo("Sorry!", "Incorrect Answer!")
game3_button = tk.Button(my_canvas1, text = "Red")
game3_button.grid(row= 8, column = 7)
game3_button["command"] = lambda: messagebox.showinfo("Sorry", "Incorrect Answer!")
circle_button = tk.Button(win, text="New Game")
circle_button.pack()
circle_button["command"] = drawCircle
quit_button = tk.Button(win, text="Quit")
quit_button.pack()
quit_button['command'] = win.destroy
You are using both the create_... methods and grid methods on your canvas object. It won't behave as you expected.
To achieve what you want, you can create a Frame, put your buttons in it, and then use create_window method on your canvas:
def drawCircle():
...
shape = my_canvas1.create_oval(x1, y1, x1 + diameter, y1 + diameter+20, fill=color)
frame = tk.Frame(my_canvas1)
game1_button = tk.Button(frame, text = "Green")
game1_button.grid(row= 8, column = 3)
game1_button["command"] = lambda: messagebox.showinfo("Congratulations!", "Correct Answer!")
game2_button = tk.Button(frame, text = "Blue")
game2_button.grid(row= 8, column = 5)
game2_button["command"] = lambda: messagebox.showinfo("Sorry!", "Incorrect Answer!")
game3_button = tk.Button(frame, text = "Red")
game3_button.grid(row= 8, column = 7)
game3_button["command"] = lambda: messagebox.showinfo("Sorry", "Incorrect Answer!")
my_canvas1.create_window(200,500,window=frame)
And of course, add win.mainloop() to the bottom of your program if you haven't already.

How do I add label widget over my canvas in tkinter?

So I have this code which extracts new values from the database and keeps on updating on the application. The problem with it is that I need to display these values in some attractive way for which I need canvas and I'm unable to do so.
Canvas isn't working. It is not making any shapes on application. I'm sure I've made a mistake but I don't know what. Help me thanks.
Code:
import Tkinter as tk
import sqlite3
import string
import time
import sys
from constants import DELAY,DB_PATH
def update_data_for_cod_bod():
conn = sqlite3.connect('ubiqx_db.db')
c = conn.cursor()
execute_query = c.execute('''select cod,bod,tss from front_end_data
where slave_id=1''')
result_set = c.fetchall()
data_for_cod = 0
data_for_bod = 0
data_for_tss = 0
for row in result_set:
data_for_cod = row[0]
data_for_bod = row[1]
data_for_tss = row[2]
lbl_cod_data["text"] = "COD "+str(data_for_cod)
lbl_bod_data["text"] = "BOD " + str(data_for_bod)
lbl_tss_data["text"] = "TSS " + str(data_for_tss)
root.after(DELAY, update_data_for_cod_bod) # Call this function again
after DELAY ms.
def exit(event):
root.quit()
root = tk.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (h, w))
root.title("COD_BOD")
root.configure(background='black')
root.bind("<Escape>", exit)
canvas = tk.Canvas(root, width=h, height=w, highlightthickness=0)
canvas.grid(row=0,column=0)
blackline = canvas.create_line(100, 100, 800, 100, fill="yellow")
lbl_cod_data = tk.Label(canvas, text="", font=("Times New Roman", 50,
"bold"), bg="black", fg="white")
lbl_cod_data.grid(row=0,column=0)
lbl_bod_data = tk.Label(canvas, text="", font=("Times New Roman", 50,
"bold"), bg="black", fg="white")
lbl_bod_data.grid(row=1,column=0)
lbl_tss_data = tk.Label(canvas, text="", font=("Times New Roman", 50,
"bold"), bg="black", fg="white")
lbl_tss_data.grid(row=2,column=0)
update_data_for_cod_bod() # Starts periodic calling of itself.
root.mainloop()
Actually your code is working but the canvas is covered on top by the lbl_cod_data and so you cannot see it. Try changing all .grid(...) to .place(...) like below:
canvas.place(x=0, y=0)
lbl_cod_data.place(x=50, y=100)
lbl_bod_data.place(x=50, y=200)
lbl_tss_data.place(x=50, y=300)
Then you can see the labels and the canvas together.
However, using label widgets over canvas is not a good design (for example the label widgets cannot have transparent background).
Suggest to use canvas text instead. Below is a modified code based on yours as an example:
import Tkinter as tk
import sqlite3
from constants import DELAY,DB_PATH
def update_data_for_cod_bod():
conn = sqlite3.connect('ubiqx_db.db')
c = conn.cursor()
execute_query = c.execute('''select cod,bod,tss from front_end_data where slave_id=1''')
result_set = c.fetchall()
data_for_cod = 0
data_for_bod = 0
data_for_tss = 0
for row in result_set:
data_for_cod = row[0] # do you actually want += instead?
data_for_bod = row[1]
data_for_tss = row[2]
# use itemconfig() to modify the labels text
canvas.itemconfig(lbl_cod_data, text="COD "+str(data_for_cod))
canvas.itemconfig(lbl_bod_data, text="BOD "+str(data_for_bod))
canvas.itemconfig(lbl_tss_data, text="TSS "+str(data_for_tss))
root.after(DELAY, update_data_for_cod_bod) # Call this function again after DELAY ms.
root = tk.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h)) # (h, w) in your original code
root.title("COD_BOD")
root.configure(background='black')
root.bind("<Escape>", lambda e: root.quit())
# width=h and height=w in your original code
canvas = tk.Canvas(root, width=w, height=h, highlightthickness=0, bg="dark blue")
canvas.pack()
blackline = canvas.create_line(100, 100, 800, 100, fill="yellow")
lbl_font = ("Times New Roman", 50, "bold")
lbl_cod_data = canvas.create_text(100, 100, text="COD", font=lbl_font, anchor='nw', fill="white")
lbl_bod_data = canvas.create_text(100, 180, text="BOD", font=lbl_font, anchor='nw', fill="green")
lbl_tss_data = canvas.create_text(100, 260, text="TSS", font=lbl_font, anchor='nw', fill="yellow")
update_data_for_cod_bod() # Starts periodic calling of itself.
root.mainloop()

Using validation on text entry box

I am trying to set up validation on text entry boxes. Three of the boxes need to only accept integers and one text as a postcode. I am not sure whether to do this in a function previously defined or when the entry boxes are created. Also how would i make the values from the text entry boxes be accessable in the function QuoteCreation. All my code is below.
from tkinter import *
class quote():
def __init__(self, master):
self.master=master
self.master.title("Quote Screen")
self.master.geometry("2100x1400")
self.master.configure(background = "white")
self.Borras = PhotoImage(file = "Borras.Logo.2.gif") #sets up image
self.Borras.image = self.Borras
self.BorrasLabel = Label(self.master, image = self.Borras, bg = "white")#puts image onto label
self.BorrasLabel.place(anchor=NW)
self.Title = Label(self.master, text = "New Quote", font = ("calibri", 20), bg = "White")
self.Title.place(x=650, y = 10)
self.SubmitButton = PhotoImage(file = "Submit.Button.gif") #sets up image
self.SubmitButton.image = self.SubmitButton
self.SubmitButtonLabel = Button(self.master, image = self.SubmitButton, bg = "white", command= self.QuoteCreation)#puts image onto a button
self.SubmitButtonLabel.place(x=900, y=290)
PostCodeVar = StringVar()
PostCodeEntry = Entry(master,width=50, font=20, textvariable=PostCodeVar)
PostCodeEntry.place(x = 20, y = 150)
PostCodeVar.set("Please enter the Post Code")
PostCodeValue = PostCodeVar.get()
HeightVar = StringVar()
HeightEntry = Entry(master, width=50, font=20, textvariable=HeightVar)
HeightEntry.place(x = 20, y = 220)
HeightVar.set("Please enter the Height")
HeightValue = HeightVar.get()
LengthVar = StringVar()
LengthEntry = Entry(master, width=50, font=20, textvariable=LengthVar)
LengthEntry.place(x = 20, y = 290)
LengthVar.set("Please enter the Length")
LengthValue = LengthVar.get()
PitchVar = StringVar()
PitchEntry = Entry(master, width=50, font=20, textvariable=PitchVar)
PitchEntry.place(x = 20, y = 360)
PitchVar.set("Please enter the Pitch")
PitchValue = PitchVar.get()
RiseVar = StringVar()
RiseEntry = Entry(master, width=50, font=20, textvariable=RiseVar)
RiseEntry.place(x = 20, y = 430)
RiseVar.set("Please enter the Rise")
RiseValue = RiseVar.get()
self.SubmitButton = PhotoImage(file = "Submit.Button.gif")
self.SubmitButton.image = self.SubmitButton
self.SubmitButtonLabel = Button(self.master, image = self.SubmitButton, bg = "white", command= self.QuoteCreation)#puts image onto a button
self.SubmitButtonLabel.place(x=900, y=290)
def on_button(self):
print(self.entry.get())
def QuoteCreation(self):
print(' ')
def quitWindow(self):
self.master.destroy()
def backToWelcome(self):
self.master.destroy()
You would set up separate functions to deal with the validation, when the submit button is pressed.
So, as an example, your submit button may look a bit like this:
submitButton = Button(master, text="Submit", command=validation)
The validation, in your case would then want to carry out these checks:
def validation():
postcode = PostCodeVar.get()
length = LengthVar.get()
pitch = PitchVar.get()
rise = RiseVar.get()
if postcodeCheck(postcode) == True and length.isdigit() == True and pitch.isdigit() == True and rise.isdigit() == True:
#carry out chosen process
In your case, you can try setting the postcode, length, pitch and height variables before calling the function, and setting them as global. The postcode should be created, and if it is okay, the function should then:
return True
...so it matches the outcome of the if statement.
I hope this is what you were looking for, and can adapt the example to your specific problem!

Categories