I was trying to create a stock managing program as follows:
import mysql.connector as mc
from tkinter import*
import time
from datetime import date
mycon=mc.connect(host="localhost",user="root",passwd="1234",database="stock_manager")
cursor=mycon.cursor()
global stock_name
global stock_unit_price
global stocks_bought
def add():
global stock_name
global stock_unit_price
global stocks_bought
stock_name_label=Label(root,text="Enter Stock Name")
stock_name_entry=Entry(root,width=50)
stock_unit_price_label=Label(root,text="Enter unit price of stock")
stock_unit_price_entry=Entry(root,width=50)
stocks_bought_label=Label(root,text="Enter number of stocks bought: ")
stocks_bought_entry=Entry(root,width=50)
stock_name=stock_name_entry.get()
stock_unit_price=int(float(stock_unit_price_entry.get()))
stocks_bought=int(stocks_bought_entry.get())
stock_name_label.grid(row=2,column=0)
stock_name_entry.grid(row=3,column=0)
stock_unit_price_label.grid(row=4,column=0)
stock_unit_price_entry.grid(row=5,column=0)
stocks_bought_label.grid(row=6,column=0)
stocks_bought_entry.grid(row=7,column=0)
submit_stock_button=Button(root,text="Submit",command=submit)
submit_stock_button.grid(row=8,column=1)
def submit():
global stock_name
global stock_unit_price
global stocks_bought
submitted_label=Label(root,text="Submitted!")
total_investment=(stock_unit_price)*(stocks_bought)
date=date.today()
cursor.execute("insert into
all_stocks values(%s,%s,%s,%s,%s)"%(stock_name,stock_unit_price,stocks_bought,total_investment,date))
submitted_label.grid(row=9,column=1)
root=Tk()
title_label=Label(root,text="All Investments")
add_stock_button=Button(root,text="Add Stock",command=add)
title_label.grid(row=0,column=1)
add_stock_button.grid(row=1,column=0)
root.mainloop()
So what this program is supposed to do is let the user add a stock by clicking the button "add stock". It then reveals the entry fields as given in the add() function defined at the top. After inputting all the information, the user clicks submit. The program then sends a query to update a mysql database with the given information.
My problem is that I need "stock_unit_price" as float and "stocks_bought" as int so that the query is successful. But it appears that the entry field is giving a string value.
I tried converting the string into int like:
int('5.0')
And even tried like:
int(float('5.0'))
But nothing works. Pls help
You are using it wrongly .You cant get and assign at same time. I will suggest you to use StringVar . Please check the snippet
import tkinter as tk
root=tk.Tk()
root.geometry("300x100")
sk=tk.StringVar()
sb=tk.StringVar()
def Add():
stock_entry=int(stock_unit_price_entry.get())
stock_bought=int(stocks_bought_entry.get())
print(stock_entry+stock_bought)
sk.set("")
sb.set("")
stock_name_label = tk.Label(root,text = 'Enter unit price of stock')
stock_unit_price_entry = tk.Entry(root,textvariable = sk)
stocks_bought_label = tk.Label(root,text = 'Enter number of stocks bought:', )
stocks_bought_entry=tk.Entry(root, textvariable = sb)
submit_stock_button=tk.Button(root,text = 'Submit', command = Add)
stock_name_label.grid(row=0,column=0)
stock_unit_price_entry.grid(row=0,column=1)
stocks_bought_label.grid(row=1,column=0)
stocks_bought_entry.grid(row=1,column=1)
submit_stock_button.grid(row=2,column=1)
root.mainloop()
You will get integer as output
Or if you want to go by your method, you have to store your get value which is converted into integer in another variable and then you can use it.
stock_unit_price_entry=Entry(root,width=50)
stocks_bought_entry=Entry(root,width=50)
stock_unit=int(stock_unit_price_entry.get())
stock_bought=int(stocks_bought_entry.get())
print(stock_unit)
print(stock_bought)
This will also produce same integer output
Related
I have a hard time doing something simple enough. Sorry if I dwell a little in the explanation, but I do it to make the question clear even if it is a simple thing. I would like to update the selected and displayed values in the database by means of a combobox.
I present an executable code. I have a combobox from which I select an element which searches for values in the combobox (using WHERE Choice =?) And displays them in the textboxes. The values are selected through two simple rows of a table in which in the lines there is the word selected in the combobox which is Choice 1 and Choice 2. For example, if in the combobox I select "Choice 1", the values of a row of the database are printed which contains the text "Choice 1". This works correctly, no problem.
I have difficulty in creating and creating the save function to modify the values (modifying them inside the textbox) and saving them (or better to say update them). The difficulty is that the values shown in the textboxes vary automatically depending on the choice in the combobx. So I should write something to make Python understand which table row to modify and save depending on the combobox choice.
For example, in the example of the screenshot, selecting "Choice 1" from the combobox, I display the data 1 and 2 in the textboxes (because in row 1 of the database I have the WHERE Choice =?). I would like to be able to modify the numbers in the textoboxes and save them (or better say "update" them) in the same row 1 of the database. Same thing for Choise 2 and row 2 of the database.
Can anyone help me with the save function? Thank you
Executable code:
import sqlite3
from tkinter import ttk
import tkinter as tk
from tkinter import *
from tkinter import ttk
import tkinter as tk
root = tk.Tk()
root.geometry('300x200')
root.config(bg="gray")
root.state("normal")
conn = sqlite3.connect('....')
cursor = conn.cursor()
#VIEW COMBOBOX'S ELEMENT
def combo():
cursor.execute('SELECT choise FROM table')
values = [row[0] for row in cursor]
return values
combo_choice=ttk.Combobox(root, width = 21)
combo_choice.place(x=10, y=10)
combo_choice.set("Select")
combo_choice['value'] = combo()
a = Entry(root,width = 4)
a.place(x=10, y=70)
b = Entry(root,width = 4)
b.place(x=60, y=70)
#RETRIEVE AND PRINT
def get_values(event):
selected_value = combo_choice.get()
cursor.execute('SELECT number1, number2 FROM table WHERE choice=?', (selected_value,))
value = cursor.fetchone()
if value:
#clean
a.delete("0", tk.END)
b.delete("0", tk.END)
#insert
a.insert(tk.END, value[0])
b.insert(tk.END, value[1])
time.bind("<<ComboboxSelected>>", get_values)
#SAVE THE CHANGES
def save():
pass
button = Button(root, text="Save", command= save)
button.place(x=10, y=150)
The database is simply:
CREATE TABLE "table" (
"id" INTEGER,
"number1" INTEGER,
"number2" INTEGER,
"choice" TEXT,
PRIMARY KEY("id")
);
Use an UPDATE statement similar to the SELECT statement that you use to display the current values.
def save():
selected_value = combo_choice.get()
number1 = a.get()
number2 = b.get()
cursor.execute("UPDATE table SET number1 = ?, number2 = ? WHERE choice = ?", (number1, number2, selected_value))
conn.commit()
pass
I am trying to call a function from another Python file after a button is click. I have imported the file and used the FileName.fuctionName() to run the function. The problem is my exception keeps catching. I am guessing that the data from the function being called is not being grabbed.What I am trying to do is have a user fill out a Tkinter gui then click a button. Once the button is click the user will then be asked to scan their tag (rfid) and that data will then be sent to a firebase real time database which will store the user's inputted info along with the card_id and user_id that was created when the tag was scanned.
Im kinda at a loss because other than the exception catching I am not getting any other errors, any thoughts? I have posted the code below along with comments.
error : local variable 'user_id' referenced before assignment
from tkinter import *
#Second File
import Write
from tkcalendar import DateEntry
from firebase import firebase
data = {}
global user_id
# Firebase
firebase= firebase.FirebaseApplication("https://xxxxxxx.firebaseio.com/",None)
# button click
def sub ():
global user_id
#setting Variables from user input
name = entry_1.get()
last = entry_2.get()
number = phone.get()
try:
#Calling Function from other file
Write.scan()
if Write.scan():
#getting the New User Id
user_id= new_id
#User Info being sent to the Database
data = {
'Name #': name,
'Last': last,
'Number': number,
'Card #':user_id
}
results = firebase.post('xxxxxxxx/User',data)
except Exception as e:
print(e)
# setting main frame
root = Tk()
root.geometry('850x750')
root.title("Registration Form")
label_0 = Label(root, text="Registration form",width=20,font=("bold", 20))
label_0.place(x=280,y=10)
label_1 = Label(root, text="First Name",width=20,font=("bold", 10))
label_1.place(x=80,y=65)
entry_1 = Entry(root)
entry_1.place(x=240,y=65)
label_2 = Label(root, text="Last Name",width=20,font=("bold", 10))
label_2.place(x=68,y=95)
entry_2 = Entry(root)
entry_2.place(x=240,y=95)
phoneLabel = Label(root, text="Contact Number : ",width=20,font=("bold", 10))
phoneLabel.place(x=400,y=65)
phone = Entry(root)
phone.place(x=550,y=65)
Button(root, text='Submit',command = sub,width=20,bg='brown',fg='white').place(x=180,y=600)
root.mainloop()
Write.py file being Imported
import string
from random import*
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()
#Function being called
def scan():
try:
#Creating user hash
c = string.digits + string.ascii_letters
new_id = "".join(choice(c) for x in range(randint(25,25)))
print("Please Scan tag")
#Writing to tag
reader.write(new_id)
if reader.write(new_id):
print("Tag Scanned")
else:
print("Scan Tag First")
print("Scanning Complete")
finally:
GPIO.cleanup()
I see that the value new_id in one file isn't going to influence the value with the same name in the other file, for a similar reason as for the first problem. In both places it appears, new_id is a local variable that only exists in the enclosing function.
Another issue I see is that you're calling Write.scan() twice in a row. Do you mean to be calling it twice? I expect not.
Also, you're testing the return value of Write.scan(), but that function doesn't return a value. So I think that the code in the if block in the first file will never run.
Globals are a bad idea in general, as they're easy to get wrong and they tend to obscure what the code is really doing. "Never say never", but I'll say that I very rarely find the need for a global variable in Python. In your case, I think it would be much better to have Write.scan() return the value of the new user id instead of passing it back as a global. Since you're testing the value of Write.scan(), maybe this is what you were thinking of doing already. Here are the changes I'd make to address these three issues and hopefully get your code working the way you want...
...
def sub ():
...
try:
#Calling Function from other file
new_id = Write.scan()
if new_id:
#getting the New User Id
user_id= new_id
...
...
def scan():
try:
...
new_id = "".join(choice(c) for x in range(randint(25,25)))
...
return new_id
finally:
GPIO.cleanup()
It's impossible to tell what your problem is, because there is no place in your code that references user_id and hence the error message you cite can't come from the code you provide. However, I see a pretty common mistake that your code appears to be making that could very well account for why you expect user_id to be defined somewhere in your code and yet it is not...
In your first block of code, the global user_id is not being set by the sub function. Rather, when the sub function calls user_id=new_id, it is creating and setting a variable that is local to that function. When that function ends, the result of that call is lost and the global user_id is still undefined.
What you want is to define user_id as being global inside of the sub() function. Just add global user_id anywhere near the top of the function definition.
Here's an example of what I'm talking about:
global x
def sub():
x = 3
sub()
print(x)
result:
Traceback (most recent call last):
File "t", line 7, in <module>
print(x)
NameError: global name 'x' is not defined
whereas:
global x
def sub():
global x
x = 3
sub()
print(x)
result:
3
I have a dataframe with 3 columns: Date, attribute_one, attribute_two. The date column is blank but the other two columns are filled with some data. how can I use tkinter package to build a GUI which would prompt the user to enter date which will then be eventually stored in the dataframe.
Using the tkinter Entry class, and using a list, you can easily accomplish so.
from tkinter import *
tk = Tk()
def add_data():
o = i.get()
code = o
print(code)
i = Entry(tk)
i.pack()
code = str()
btn = Button(tk, command = add_data, text='Add')
i.pack()
btn.pack()
You can then add it to the column. If you want to ask them in the console, use this instead:
import sys
print('Please enter the date.')
i = str(sys.stdin.readline())
print(i)
Then just add the variable i to your dataframe.
I am serializing my GUI to save the information.But the problem is that it is only saving the last value entered not all of them.
So now the problem is that when I click on the + button, the row gets incremented but only the last name entered is saved. I want to save all of them
def increment(self):
current_row=1
MoreButton=Button(self.listFrame,text="+",command=entry_1(self))
MoreButton.grid(column=1,row=0)
def entry_1(self):
self.entryName=Entry(self.listFrame)
self.entryName.grid(column=1,row=current_row,sticky="EW")
self.entryName.get()
nameLabel=Label(self.listFrame,text="NAME")
nameLabel.grid(column=0,row=current_row)
save_button=Button(self.listFrame,text="save",command=save_data(self))
save_button.grid(column=2,row=0)
current_row=current_row+1
def save_data(self):
data={
"Name":self.entryName.get(),
}
with open("test.json","wb") as f:
dill.dump(data,f)
def load_data(self):
with open("test.json","rb") as f:
data=dill.load(f)
Sorry for the past incorrect answer. I think the problem is that your entry_1 function creates entry boxes with the same name. This means when you try getting the text in it, it gets the text of the last one only. Here is the full code I created that creates entry's with different names. It is in a class but I don't know how you want them set out.
from Tkinter import *
import dill
import sys
boxes=[]
no_of_boxes=0
root=Tk()
current_row=1
current_box=0
data={}
class Main(object):
#this is used every time a new entry is created
def save_data(self):
global current_box
global current_row
global no_of_boxes
###this it the key. It creates the entries
###in a list so that we can access them
###without the name
boxes.append(Entry(root))
boxes[-1].grid(column=1, row=current_row)
###
try:
data["Name"+str(current_box)]=boxes[-2].get()
except:
data["Name"+str(current_box)]=boxes[-1].get()
current_row+=1
current_box+=1
no_of_boxes+=1
print no_of_boxes
print boxes
print data
with open("test.json","wb") as f:
dill.dump(data,f)
#to save when closing
def save_close(self):
global current_box
global current_row
boxes.append(Entry(root))
boxes[-1].grid(column=1, row=current_row)
data["Name"+str(current_box)]=boxes[-2].get()
with open("test.json","wb") as f:
dill.dump(data,f)
print no_of_boxes
print boxes
print data
sys.exit()
def load_data(self):
with open("test.json","rb") as f:
data=dill.load(f)
def entry_1(self):
global current_row
global no_of_boxes
nameLabel=Label(root,text="NAME")
nameLabel.grid(column=0,row=current_row)
self.save_data()
app=Main()
MoreButton=Button(root,text="+",command=app.entry_1)
MoreButton.grid(column=1,row=0)
CloseButton=Button(root, text="Close and save", command=app.save_close)
CloseButton.grid(column=2, row=0)
root.mainloop()
The saved data is saved as "Name" plus current_box in data so to get it go data["Name1"] for entry box 1 and so on.
I hope this is a better answer than my last one!
P.S if you still have problems with other parts of this code, feel free to contact me on my website.
I am attempting to create a database management system with the ability to delete accounts. I can get the drop down menu to display the current list of users, but I don't understand how to make it show the new list of users. The code for the dropdown menu is as follows:
import tkinter
from tkinter import *
tkwindow = Tk()
tkwindow.title
users = ['user1','user2','user3']
def callback(*args):
name = var.get()
print ('%s' % name)
users.remove(name)
print (users)
option.setitems(*users)
var = StringVar(tkwindow)
var.trace("w", callback)
option = OptionMenu(tkwindow, var, *users)
option.pack()
Thanks in advance.
Try using the Menu option of the OptionMenu. For example if you get the index of the name string, you can delete that from the OptionMenu using the code below.
def callback(*args):
name = var.get()
print ('%s' % name)
users.remove(name)
print (users)
menu = option['menu']
menu.delete(menu.index(name))