String with number on each line to list of floats - python

I am building a Python code that should read a text file using askopenfile in tkinter in Python. The text file is just a column of numbers:
300.0
250.0
250.0
250.0
250.0
270.61032473
289.91197172
290.23398559
275.90792547
263.86956625
264.8385967
My code is attached below:
from tkinter import *
from tkinter.ttk import *
import numpy as np
from tkinter.filedialog import askopenfile
root = Tk()
t=12
p=np.empty(t)
def open_file():
file = askopenfile(mode ='r', filetypes =[('all files', '*.*')])
if file is not None:
global x
x = file.read()
print(x)
global p
global count
#x=x.split('\n')
#count=0
#for row in x:
# i=float(row[0])#change from string to float type
# p[count]=i #updates x array
# count +=1 # increment of 1 to get the number of total values
#p=p.reshape(t,1)
#print(p)
return x
#print(p)
btn = Button(root, text ='Open', command = lambda:open_file())
btn.pack(side = TOP, pady = 10)
mainloop()
When I print x from the command window, the result is the following:
'300.0 \n300.0 \n250.0 \n250.0\n250.0\n250.0 \n270.61032473 \n289.91197172 \n290.23398559 \n275.90792547\n263.86956625 \n264.8385967'
Hence when I print x[0] for instance, the results is only: 3.
I actually want x[0] to be 300.0, x[1] to be 250.0, etc.
In addition to that, I want to convert them to numerical numbers not strings.

To parse the string x
x = '300.0 \n300.0 \n250.0 \n250.0\n250.0\n250.0 \n270.61032473 \n289.91197172 \n290.23398559 \n275.90792547\n263.86956625 \n264.8385967'
into a list of numbers, you could do:
x_as_list_of_numbers = [float(xx.strip()) for xx in x.split('\n')]

Related

I am trying to populate a Tkinter grid from a JSON and limit the number of rows to 5, so when it reaches the fifth it'd continue into another column

What I am trying to achieve is something like this:
But instead, what I am getting is this:
This is the structure:
The file that's getting the JSON data, called bitmex.py
import requests
def get_contracts():
response_object = requests.get('https://www.bitmex.com/api/v1/instrument/active')
contracts = []
for contract in response_object.json():
contracts.append(contract['symbol'])
return contracts
print(get_contracts())
And this is the main.py that is populating the data into a Grid:
import tkinter as tk
from bitmex import get_contracts
if __name__ == '__main__':
bitmex_contracts = get_contracts()
root = tk.Tk()
root.title("Bitmex Contracts")
x = 0
y = 0
for contract in bitmex_contracts:
label_widget = tk.Label(root, text=contract, borderwidth=1, relief=tk.SOLID, width=13).grid(row=x, column=y, sticky='ew')
if x >= 4:
y += 1
x = 0
else:
x += 1
root.geometry('800x600')
root.mainloop()
As you'll see the problem I am facing is that the data is getting one underneath each other but not on a grid but superimposed instead.
The version of Python I am using is v.3.9.7 and
Tkinter v.8.6

Is there a way of getting data from entries by rows from a table of entries in Tkinter?

So far I have a portion of code for a function that works fine as is for generating a table off of user input and then getting data from the table generated to be used in a line graph. However, the solution as it stands creates one massive list by iterating through every entry's data and is then graphed as one massive line graph. I intended for the function to create lists from each row of the table which is then inserted into a master list for pyplot to then graph as multiple lines on the same graph. Is there a way to achieve this? This is the code I am using:
import tkinter as tk
import matplotlib.pyplot as plt
graphinput = tk.Tk()
def opentable():
global total_rows
global total_columns
total_rows = int(yaxis.get())
total_columns = int(xaxis.get())
table = tk.Toplevel(graphinput)
table.resizable(0,0)
table.title("Table")
def tcompile():
masterlines = []
for cell in my_entries:
print(cell.get())
masterlines.append(int(cell.get()))
plt.plot(masterlines)
plt.show()
my_entries = []
for i in range(total_rows):
for j in range(total_columns):
cell = tk.Entry(table,width=20,font=('Agency FB',15))
cell.grid(row=i,column=j)
my_entries.append(cell)
tblframe = tk.Frame(table,bd=4)
tblframe.grid(row=i+1,column=j)
compbtn = tk.Button(tblframe,font=("Agency FB",20),text="Compile",command=tcompile)
compbtn.grid(row=0,column=0)
tablegrid = tk.Frame(graphinput,bd=4)
tablegrid.pack()
xlabel = tk.Label(tablegrid,text="Column Entry")
xlabel.grid(row=0,column=0)
ylabel = tk.Label(tablegrid,text="Row Entry")
ylabel.grid(row=0,column=1)
xaxis = tk.Entry(tablegrid)
xaxis.grid(row=1,column=0)
yaxis = tk.Entry(tablegrid)
yaxis.grid(row=1,column=1)
framebtn = tk.Button(tablegrid,text="Create",command=opentable)
framebtn.grid(row=3,column=0)
graphinput.mainloop()
Try something like this:
import tkinter as tk
def tcompile():
masterlines = []
for i in range(total_rows):
row = []
for j in range(total_columns):
data = my_entries[i*total_columns+j].get()
# data = int(data) # Removed for testing purposes
row.append(data)
masterlines.append(row)
print(masterlines)
root = tk.Tk()
total_rows = 3
total_columns = 4
my_entries = []
for i in range(total_rows):
for j in range(total_columns):
cell = tk.Entry(root)
cell.grid(row=i, column=j)
my_entries.append(cell)
# Add a button for testing purposes
button = tk.Button(root, text="Click me", command=tcompile)
button.grid(row=1000, columnspan=total_columns)
root.mainloop()
The key is to use my_entries[i*total_columns+j] to get the entry in row i and column j.
Note: I didn't add the matplotlib stuff because I don't really know how it works.

Turning StringVar value to list

I have been working on a Tkinter project. I have set the listbox as StringVar and I would like to call a list of items inside the right listbox by setting a function 'process'.
enter image description here
After I press the button process in the gui, I am supposed to return a list ['A'] in the above case.
However, it return ['(', "'", 'A', "'", ')']
If I just print app.list_var2.get() it return ('A',)
import tkinter as tk
import pandas as pd
app=tk.Tk()
app.geometry('640x480')
app.resizable(width=True, height=True)
app.title('Simulator')
# list variables
app.list_var1 = tk.StringVar()
app.list_var2 = tk.StringVar()
app.list_var1.set(value=['A','B','C'])
app.list_var2.set(value=[])
# label frame
app.label_frame= tk.Frame(app)
app.label1 = tk.Label(app.label_frame,text='PDC',justify='left')
app.label1.pack(ipadx=10,ipady=10,side='left', anchor='w')
app.label2 = tk.Label(app.label_frame,text='SDC')
app.label2.pack(ipadx=20,ipady=10, side='left',anchor='e')
# main frame
app.main_frame = tk.Frame(app)
app.listbox1 = tk.Listbox(app.main_frame, listvariable=app.list_var1, selectmode='single')
app.listbox2 = tk.Listbox(app.main_frame, listvariable=app.list_var2, selectmode='single')
def init_default_values():
app.list_var1.set(value=['A','B','C'])
app.list_var2.set(value=[])
def move_to_right(only_one_item=False):
if app.listbox1.curselection() == ():
return
# get tuple of selected indices
if only_one_item:
selection = (app.listbox1.curselection()[0],)
else:
selection = app.listbox1.curselection()
# left all/selected values
left_value_list = [line.strip(' \'') for line in app.list_var1.get()[1:-1].split(',')]
left_selected_list = [left_value_list[index] for index in selection]
# values from right side
right_value_list = [line.strip(' \'') for line in app.list_var2.get()[1:-1].split(',')]
# merge w/o duplicates
result_list = sorted(list(set(right_value_list + left_selected_list)))
for x in left_value_list:
if x in result_list:
left_value_list.remove(x)
while("" in left_value_list) :
left_value_list.remove("")
while("" in result_list) :
result_list.remove("")
app.list_var2.set(value=result_list)
app.list_var1.set(value=left_value_list)
def move_to_left(only_one_item=False):
if app.listbox2.curselection() == ():
return
# get tuple of selected indices
if only_one_item:
selection = (app.listbox2.curselection()[0],)
else:
selection = app.listbox2.curselection()
# right all/selected values
right_value_list = [line.strip(' \'') for line in app.list_var2.get()[1:-1].split(',')]
right_selected_list = [right_value_list[index] for index in selection]
# values from left side
left_value_list = [line.strip(' \'') for line in app.list_var1.get()[1:-1].split(',')]
# merge w/o duplicates
result_list = sorted(list(set(left_value_list + right_selected_list)))
for x in right_value_list:
if x in result_list:
right_value_list.remove(x)
while("" in right_value_list) :
right_value_list.remove("")
while("" in result_list) :
result_list.remove("")
app.list_var1.set(value=result_list)
app.list_var2.set(value=right_value_list)
def reset():
init_default_values()
def process():
#if len(app.list_var2.get()) == 1:
lst=app.list_var2.get()
print(len(lst))
lst = str(app.list_var2.get()).replace(',','')
lst=list(lst)
print(type(lst))
print(len(lst))
print(lst)
# little button frame
app.button_frame = tk.Frame(app.main_frame)
app.one_to_right_button = tk.Button(app.button_frame, text='>', command=lambda: move_to_right(True))
app.one_to_left_button = tk.Button(app.button_frame, text='<', command=lambda: move_to_left(True))
app.reset_button = tk.Button(app.button_frame,text='Reset',command=reset)
app.process = tk.Button(app.button_frame,text='Process',command=process)
# packing
app.one_to_right_button.pack()
app.one_to_left_button.pack()
app.reset_button.pack()
app.process.pack()
app.listbox1.pack(side='left', anchor='w')
app.button_frame.pack(side='left')
app.listbox2.pack(side='right', anchor='e')
app.label_frame.pack()
app.main_frame.pack(padx=20,pady=20)
# insert default values
init_default_values()
app.mainloop()
Since app.list_var2 is a StringVar, so app.list_var2.get() will always return a string.
Better use app.listbox2.get(0, "end") to get all the items (a tuple) in the listbox:
def process():
lst = list(app.listbox2.get(0, 'end'))
print(lst, type(lst))
Note that you can use eval() to convert the string returned by app.list_var2.get() to tuple but it is not recommended:
def process():
lst = list(eval(app.list_var2.get()))
print(lst, type(lst))

How to insert special characters in tkinter

I'm creating a GUI with tkinter, in this GUI there are some entry widgets that the user has to fill in, and the inputs will be stored in a file.
The issue that I'm facing is that the user can't insert special characters like emojis in these entry widgets.
I found some ways to display them...:
converting a special character to the equivalent surrogate pair:
this '\U0001f64f'(🙏) to this '\ud83d\ude4f'
Python: Find equivalent surrogate pair from non-BMP unicode char
converting a special character to the equivalen javascript format:
this 😊 to this '\uD83D\uDE05'
Displaying emojis/symbols in Python using tkinter lib
... but I didn't find anything about my problem.
I thought about solving it by displaying near the entries a table with the emojis and the relative code to insert it in the entry instead of inserting the emoji directly, so something like this...:
1:🙏 2:😊 3:🔥 4:😃
...and have the user insert 1, 2, 3 or 4 instead of the emoji, but I don't think that this is a good way to solve the problem.
From my research, I understood that the problem is in the tkinter module and I was wondering if there was a way to overcome it.
# -*- coding: utf-8 -*-
from tkinter import *
def sumbit():
print(var.get())
root = Tk()
root.tk.call('encoding', 'system', 'utf-8')
var = StringVar()
entry = Entry(root, textvariable=var)
entry.pack()
button = Button(root, text="sumbit", command=sumbit)
button.pack()
root.mainloop()
This is an example of the problem, I have a window with an Entry widget where the user can insert an emoji, but if the user inserts an emoji, the code raises the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/Users/mcara/PycharmProjects/1/python/1.py", line 5, in sumbit
print(var.get())
File "C:\Program Files\Python37-32\lib\tkinter\__init__.py", line 484, in get
value = self._tk.globalgetvar(self._name)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xed in position 0: invalid continuation byte
I'm working with Windows and Pyton 3.7
I have worked around this problem as this for now:
# -*- coding: utf-8 -*-
from tkinter import *
import tkinter.font as tkFont
# Dict with all the emojis
# it is made in this format --> EMOJI_NAME: EMOJI_SURROGATE_PAIR
emoji_dict = {
"GRINNING_FACE": '\ud83d\ude00',
"GRINNING_FACE_WITH_BIG_EYES": '\ud83d\ude03',
"GRINNING_FACE_WITH_SMILING_EYES": '\ud83d\ude04',
"BEAMING_FACE_WITH_SMILING_EYES": '\ud83d\ude01',
"GRINNING_SQUINTING_FACE": '\ud83d\ude06',
"GRINNING_FACE_WITH_SWEAT": '\ud83d\ude05',
"LAUGHING_ON_THE_FLOOR": '\ud83e\udd23',
"TEARS_OF_JOY": '\ud83d\ude02',
"SMILING_FACE_SLIGHTLY": '\ud83d\ude42',
"UPSIDE-DOWN_FACE": '\ud83d\ude43',
"WINKING_FACE": '\ud83d\ude09',
}
emoji_num_name = dict()
emoji_name_num = dict()
counter = 0
for key in emoji_dict:
emoji_num_name[counter] = key
emoji_name_num[key] = counter
counter += 1
def search(text):
for widget in emoji_frame.winfo_children():
if isinstance(widget, Button):
widget.destroy()
emoji_name_list = list(emoji_dict.keys())
emoji_name_list.sort()
if text == "" or text == " ":
creates_emojis()
else:
x = 10
y = 0
for emoji_name in emoji_name_list:
if emoji_name.startswith(text):
emoji_code = emoji_dict[emoji_name]
code_ = emoji_name_num[emoji_name]
emoji_button = Button(emoji_frame, text=emoji_code, borderwidth=0, font=customFont)
emoji_button.place(x=x, y=y)
emoji_button.bind("<Button-1>", lambda event, code=code_, var=sumbit_var: insert_emoji(var, ":-" + str(code) + "-:"))
if x <= 150:
x += 30
else:
x = 10
y += 30
emoji_frame.configure(widt=200, height=y+60)
def insert_emoji(var, code):
var.set(var.get() + code)
def creates_emojis():
x = 10
y = 0
for emoji_name in emoji_dict:
emoji_code = emoji_dict[emoji_name]
code_ = emoji_name_num[emoji_name]
emoji_button = Button(emoji_frame, text=emoji_code, borderwidth=0, font=customFont)
emoji_button.place(x=x, y=y)
emoji_button.bind("<Button-1>", lambda event, code=code_, var=sumbit_var: insert_emoji(var, ":-" + str(code) + "-:"))
if x <= 150:
x += 30
else:
x = 10
y += 30
emoji_frame.configure(widt=200, height=y+60)
def sumbit(text):
text = text.split(":-")
for index in range(len(text)):
word = text[index]
word = word.split("-:")
for index_ in range(len(word)):
little_word = word[index_]
if little_word.isdigit():
emoji_name = emoji_num_name[int(little_word)]
emoji = emoji_dict[emoji_name]
word[index_] = emoji
text[index] = "".join(word)
text = "".join(text)
text = text.encode('utf-16', 'surrogatepass').decode('utf-16')
print(text)
root = Tk()
root.tk.call('encoding', 'system', 'utf-8')
root.configure(width=500, height=500)
font = "Courier"
customFont = tkFont.Font(family=font, size=14)
emoji_frame = LabelFrame(text="emojis")
emoji_frame.place(x=10, y=60)
search_var = StringVar()
search_entry = Entry(root, textvariable=search_var)
search_entry.place(x=10, y=10)
search_button = Button(root, text="search", command=lambda: search(search_var.get().upper()))
search_button.place(x=10, y=30)
displat_all_button = Button(root, text="display all", command=lambda: creates_emojis())
displat_all_button.place(x=60, y=30)
sumbit_var = StringVar()
sumbit_entry = Entry(root, textvariable=sumbit_var)
sumbit_entry.place(x=200, y=10)
sumbit_button = Button(root, text="sumbit", command=lambda: sumbit(sumbit_var.get()))
sumbit_button.place(x=200, y=30)
creates_emojis()
root.mainloop()
This is a runnable example of what i made, I've created a kind of table where you can insert as many emojis as you want (by editing the emoji_dict and inserting the emoji that you want) and return an output in utf-8.
For find the emoji surrogate pair i've used the code
import re
_nonbmp = re.compile(r'[\U00010000-\U0010FFFF]')
def _surrogatepair(match):
char = match.group()
assert ord(char) > 0xffff
encoded = char.encode('utf-16-le')
return (
chr(int.from_bytes(encoded[:2], 'little')) +
chr(int.from_bytes(encoded[2:], 'little')))
def with_surrogates(text):
return _nonbmp.sub(_surrogatepair, text)
emoji_dict = {
"Grinning_Face": u'\ud83d\ude00',
"Grinning_Face_With_Big_Eyes": u'\ud83d\ude03',
"Grinning_Face_With_Smiling_Eyes": u'\ud83d\ude04',
"Beaming_Face_With_Smiling_Eyes": u'\ud83d\ude01',
"Grinning_Squinting_Face": u'\ud83d\ude06',
"Grinning_Face_With_Sweat": u'\ud83d\ude05',
"Laughing_on_the_Floor": u'\ud83e\udd23',
"Tears_of_Joy": u'\ud83d\ude02',
"Smiling_Face_Slightly": u'\ud83d\ude42',
"Upside-Down_Face": u'\ud83d\ude43',
"Winking_Face": u'\ud83d\ude09',
}
emoji_list =[ "😀", "😃", "😄", "😁", "😆", "😅", "🤣", "😂", "🙂", "🙃", "😉", ]
for emoji in emoji_list:
print(repr(_nonbmp.sub(_surrogatepair, emoji)))
you can found it at this question
Python: Find equivalent surrogate pair from non-BMP unicode char

Entries in Tkinter

I'd like to make a program which takes an integer from user and makes as many entries in a Tkinkter window. Then It'll make a graph base on them but for now I do not know how to make as many entries in my window. I tried something like this below but It does not work. Please help.. edit: oh and It's PyDev for Eclipse python 2.75
# -*- coding: utf-8 -*-
#import matplotlib.pyplot as mp
import Tkinter as T, sys
def end():
sys.exit()
def check():
z = e.get()
try:
z = int(z)
e.config(bg = 'green')
e.after(1000, lambda: e.config(bg = 'white'))
x = []
for i in (0,z):
x.append(e = T.Entry(main, justify = 'center'))
x[i].pack()
except:
e.config(bg = 'red')
e.after(1000, lambda: e.config(bg = 'white'))
z = 0
main = T.Tk()
main.title('something')
main.geometry('600x600')
main.config(bg = "#3366ff")
e = T.Entry(main,justify = 'center')
l = T.Label(main,text = 'Give me an N =',bg = '#3366ff')
b1 = T.Button(main, text = 'OK', command = check)
b = T.Button(main,text = 'Zakończ', command = end)
l.pack()
e.pack()
b1.pack()
b.pack()
main.mainloop()
Make youre for-loop look like this:
for i in range(0,z):
x.append( T.Entry(main, justify = 'center'))
x[i].pack()
you need to use range because when you dont it is only iterating through twice because it thinks its iterationg through a 2 item tuple instead of a list of numbers
also get rid of the e = so that it is just appending a new entry each time

Categories

Resources