creating an object doesn't work - python

class phonebook:
def __init__(self,first_name, last_name, street, postcode, city, number):
root = tk.Tk()
root.title('Book')
menubar = tk.Menu(root)
root.config(menu = menubar)
menubar.add_command(label = 'Anlegen', command = self.create)
menubar.add_command(label = 'Bearbeiten', command = self.change)
menubar.add_command(label = 'Löschen')
menubar.add_command(label = 'Sortieren')
menubar.add_command(label = 'Suche')
menubar.add_command(label = 'Hilfe')
root.mainloop()
def printing(self):
account = (self.first_name.get(), self.last_name.get(), self.street.get(), self.postcode.get(), self.city.get(), self.number.get())
accounts.append(account)
for i in accounts:
print(i)
def change(self):
account = accounts[0]
account.first_name = 'test'
self.printing
def create(self):
creation = tk.Toplevel()
tk.Label(creation, text = 'Vorname').grid(row = 1, column = 0)
tk.Label(creation, text = 'Nachname').grid(row = 2, column = 0)
tk.Label(creation, text = 'Stadt').grid(row = 3, column = 0)
tk.Label(creation, text = 'Postleitzahl').grid(row = 4, column = 0)
tk.Label(creation, text = 'Straße').grid(row = 5, column = 0)
tk.Label(creation, text = 'Telefonnummer').grid(row = 6, column = 0)
self.first_name = tk.Entry(creation)
self.last_name = tk.Entry(creation)
self.city = tk.Entry(creation)
self.postcode = tk.Entry(creation)
self.street = tk.Entry(creation)
self.number = tk.Entry(creation)
a = tk.Button(creation, text = 'end', command = self.printing)
self.first_name.grid(row = 1, column = 1)
self.last_name.grid(row = 2, column = 1)
self.city.grid(row = 3, column = 1)
self.postcode.grid(row = 4, column = 1)
self.street.grid(row = 5, column = 1)
self.number.grid(row = 6, column = 1)
a.grid(row = 7, column = 1)
phonebook()
As you can see in my code I'm trying to create and edit objects. The problem is that I cannot create a real object. When I want to create a object with class phonebook, I get this error:
TypeError: __init__() missing 6 required positional arguments: 'first_name', 'last_name', 'street', 'postcode', 'city', and 'number'
What do I have to do so that I don't get this error and so that I can edit the objects?

phonebook must be called with 6 arguments, not 0. You call phonebook(), which causes your code to break. Try calling with something like this:
phonebook("first_name", "last_name", "street", "post_code", "your_city", 123)
substitute in the appropriate values instead of the ones I've provided.
P.S. You won't get much help on this site with a username like that

Related

object in not callable in GUI temperature converter

I'm doing an assignment in Python for a converter between Celsius and Fahrenheit.
The GUI frame appears but the terminal says the FloatField object isn't callable. the error resides within the computeCelsius function within the line that says getNumber(). Trying to ind a solution please help.
from breezypythongui import EasyFrame
class TemperatureConverter(EasyFrame):
"""A termperature conversion program."""
def __init__(self):
"""Sets up the window and widgets."""
EasyFrame.__init__(self, width = 1000, title = "Temperature Converter")
self.addLabel(text = "Celsius", row = 0, column = 0)
self.addLabel(text = "Fahrenheit", row = 0, column = 1)
self.CelsiusField = self.addFloatField(value = 0.0, row = 1, column = 0)
self.FahrenheitField = self.addFloatField(value = 32.0, row = 1, column = 1)
self.grp1 = self.addButton(text = ">>>>", row = 2, column = 0, command = self.computeFahrenheit)
self.grp2 = self.addButton(text = "<<<<", row = 2, column = 1, command = self.computeCelsius)
def computeFahrenheit(self):
inputVal = self.CelsiusField().getNumber()
farh = 9.0/5.0 * inputVal + 32
self.getInputFahrenheit.setValue(farh)
def computeCelsius(self):
inputVal = self.FahrenheitField().getNumber()
cels = (farh - 32) * 5.0/9.0
self.getInputCelsius.setValue(cels)
def main():
"""Instantiate and pop up the window."""
TemperatureConverter().mainloop()
if __name__ == "__main__":
main()

Executing a function prevents tkinter window from appearing

I have a function that is going to be the main area of this program, but when I add in a new function that needs to be executed by a button, it prevents the window from appearing, or gives out an error. The function I am trying to get to appear after a button press is new_function.
def bowler():
global bowler_win
global batsmen
bowler_win = Toplevel(master)
batsmen_win_2.withdraw()
variable = StringVar(bowler_win)
variable.set(fielding_team[0])
title = Label(bowler_win, text = "Please choose the bowler").grid(row = 0, column = 1)
w = OptionMenu(bowler_win, variable, *fielding_team)
w.grid(row = 1, column = 1)
def ok2():
current_bowler = variable.get()
for players in batting_team:
if players == current_bowler:
fielding_team.remove(current_bowler)
main_play()
button = Button(bowler_win, text="OK", command=ok2).grid(row = 2, column = 1)
#####CODE ABOVE IS ONLY TO SHOW WHERE THE FUNCTION BELOW IS EXECUTED FROM
def main_play():
while innings != 3:
facing_length = len(batsmen)
while over != over_amount or out_full == True or facing_length <= 1:
main_win = Toplevel(master)
bowler_win.withdraw()
ws = Label(main_win, text = " ").grid(row = 1, column = 1)
title = Label(main_win, text = "Current Game").grid(row = 0, column = 1)
score = Label(main_win, text = "Current Score:").grid(row = 2, column = 1)
line = Label(main_win, text = "--------------").grid(row = 1, column = 1)
score = Label(main_win, text = str(runs) + "/" + str(out)).grid(row = 3, column = 1)
line = Label(main_win, text="--------------").grid(row=4, column=1)
cur_bat = Label(main_win, text = "Facing Batsmen: " + batsmen[0]).grid(row = 5, column = 1)
other_bat = Label(main_win, text = "Other Batsmen: " + batsmen[1]).grid(row = 6, column = 1)
current_patner = Label(main_win, text = "Patnership: " + str(partnership_runs)).grid(row = 7, column = 1)
button = Button(main_win, text = "Next Play", command = new_function).grid(row = 8, column = 1) ###THIS IS WHERE THE NEW FUNCTION IS EXECUTED
If I call the function new_function after the button, the main_win window does not appear, this is the same for if I call new_function above the main_play function, the same error occurs.
If I try to nest new_function below the button, I get the error
UnboundLocalError: local variable 'new_func' referenced before assignment
Even though its a function(and I don't have a variable named that)
If anyone can help, that would be amazing

Error with parameters in Python with SQLite3 TypeError: unsupported operand type(s) for +: 'sqlite3.Cursor' and 'str'

I am a beginner in coding and this new community.I need your help to understand why it is not possible to get this solution. I would like to get a number from an entry and then sum up with the last record of the same item, so I can aggregate it.
Here is my code:
def add_stock(self):
time = datetime.now().strftime("%B %d, %Y")
hour = datetime.now().strftime("%I:%M%p")
query = 'SELECT totalstock FROM stocks WHERE name = ? AND MovementID = ( SELECT max( MovementID ) FROM stocks)'
parameters = (self.name.get(),)
lastrecord = self.run_query(query, parameters)
total = lastrecord + self.quantity.get()
if self.validation():
query = 'INSERT INTO stocks VALUES(NULL, ?, ?, ?, ?, ?)'
parameters = (self.name.get(), self.quantity.get(), total, time, hour)
self.run_query(query, parameters)
self.message['text'] = 'Movement {} added succesfully'.format(self.name.get())
self.name.delete(0, END)
self.quantity.delete(0, END)
else:
self.message['text'] = 'Name and Quantity required'
self.get_product()
But there is something wrong with it, can anybody help me out?
This is the entire code:
from tkinter import *
from tkinter import ttk
from datetime import datetime
import sqlite3
class Main:
db_name = 'materiales.db'
def __init__(self,window):
self.wind = window
self.wind.title('Stock App')
#create frame
frame = LabelFrame(self.wind, text = 'Add stock')
frame.grid(row = 0, column = 0, columnspan = 3, pady = 20)
# Name Input
Label(frame, text = 'Name: ').grid(row = 1, column = 0)
self.name = Entry(frame)
self.name.focus()
self.name.grid(row = 1, column = 1)
# Quantity Input
Label(frame, text = 'Quantity: ').grid(row = 2, column = 0)
self.quantity = Entry(frame)
self.quantity.grid(row = 2, column = 1)
# Button Add Stock
ttk.Button(frame, text = 'Add Stock', command = self.add_stock).grid(row = 3, columnspan = 2, sticky = W + E)
#Log Message
self.message = Label(text = '', fg = 'red')
self.message.grid(row = 3, column = 0, columnspan = 2, sticky = W + E)
# Table
self.tree = ttk.Treeview(height = 10, columns = 2)
self.tree.grid(row = 4, column = 0, columnspan = 2)
self.tree.heading('#0', text = 'Name', anchor = CENTER)
self.tree.heading('#1', text = 'Stock', anchor = CENTER)
#Buttons
ttk.Button(text = 'DELETE', command = self.delete_product).grid(row = 5, column = 0, sticky = W + E)
ttk.Button(text = 'MODIFY', command = self.modify_product).grid(row = 5, column = 1, sticky = W + E)
self.get_product()
def run_query(self, query, parameters = ()):
with sqlite3.connect(self.db_name) as conn:
cursor = conn.cursor()
result = cursor.execute(query, parameters)
conn.commit()
return result
def get_product(self):
records = self.tree.get_children()
for element in records:
self.tree.delete(element)
query = 'SELECT * FROM product ORDER BY name DESC'
db_rows = self.run_query(query)
for row in db_rows:
self.tree.insert('', 0, text = row[1], values = row[2])
def validation(self):
return len(self.name.get()) != 0 and len(self.quantity.get()) !=0
def add_stock(self):
time = datetime.now().strftime("%B %d, %Y")
hour = datetime.now().strftime("%I:%M%p")
query = 'SELECT totalstock FROM stocks WHERE name = ? AND MovementID = ( SELECT max( MovementID ) FROM stocks)'
parameters = (self.name.get(),)
lastrecord = self.run_query(query, parameters)
total = lastrecord + self.quantity.get()
if self.validation():
query = 'INSERT INTO stocks VALUES(NULL, ?, ?, ?, ?, ?)'
parameters = (self.name.get(), self.quantity.get(), total, time, hour)
self.run_query(query, parameters)
self.message['text'] = 'Movement {} added succesfully'.format(self.name.get())
self.name.delete(0, END)
self.quantity.delete(0, END)
else:
self.message['text'] = 'Name and Quantity required'
self.get_product()
def delete_product(self):
try:
self.tree.item(self.tree.selection())['text'][0]
except IndexError as e:
self.message['text'] = 'Please Select a Record'
return
name = self.tree.item(self.tree.selection())['text']
query = 'DELETE FROM product WHERE name = ?'
self.run_query(query,(name,))
self.message['text'] = 'Product {} deleted succesfully'.format(name)
self.get_product()
def modify_product(self):
try:
self.tree.item(self.tree.selection())['text'][0]
except IndexError as e:
self.message['text'] = 'Please Select a Record'
return
name = self.tree.item(self.tree.selection())['text']
old_price = self.tree.item(self.tree.selection())['values'][0]
self.edit_wind = Toplevel()
self.edit_wind.title = 'Edit Product'
#Old Name
Label(self.edit_wind, text = 'Old Name: ').grid(row = 0, column = 1)
Entry(self.edit_wind, textvariable = StringVar(self.edit_wind, value = name), state = 'readonly').grid(row = 0, column = 2)
#New Name
Label(self.edit_wind, text = 'New Name: ').grid(row = 1, column = 1)
new_name = Entry(self.edit_wind)
new_name.grid(row = 1, column = 2)
#Old Price
Label(self.edit_wind, text = 'Old Price: ').grid(row = 2, column = 1)
Entry(self.edit_wind, textvariable = StringVar(self.edit_wind, value = old_price), state = 'readonly').grid(row = 2, column = 2)
#New Price
Label(self.edit_wind, text = 'New Price: ').grid(row = 3, column = 1)
new_price = Entry(self.edit_wind)
new_price.grid(row = 3, column = 2)
Button(self.edit_wind, text = 'Update', command = lambda: self.edit_records(new_name.get(), name, new_price.get(), old_price)).grid(row = 4, column = 2, sticky = W)
def edit_records(self, new_name, name, new_price, old_price):
query = 'UPDATE product SET name = ?, precio = ? WHERE name = ? AND precio = ?'
parameters = (new_name, new_price, name, old_price)
self.run_query(query, parameters)
self.edit_wind.destroy()
self.message['text'] = 'Record {} updated successfully'.format(name)
self.get_product()
if __name__ == '__main__':
window = Tk()
application = Main(window)
window.mainloop()
Thanks in advance and kind regards.
The exception is raised on line 72 of your code. The code attempts to add a string object to a sqlite.Cursor object, which fails because these types are incompatible for that operation.
Instead you need to extract the data held in the returned Cursor object which can be done like this:
total = lastrecord.fetchone()[0]
fetchone() returns the first row of the data which is of type tuple. The first item in the tuple is the queried value, which is assumed to be an integer in this case. You can't add the string returned by self.quantity.get(), so you need to convert that to an integer (assuming that it is an integer.. it could be another numeric type) to calculate the new total:
total += int(self.quantity.get())

Trying to get the validate command to work with multiple inputs

I'm not at all familiar with Tkinter's validatecommands, but I have done some research and would like to implement it in a widget that creates a tree graph from a bunch of entries. I want to restrict each entry so that the user can create lists of numbers from 0 to the highest row, not including the same row. So, for example, Row 0 entry can't have 0 in it or 12. So far I have only attempted to restrict the input from being the same value as the row, but I haven't been able to get that to work. I must be implementing the validate command incorrectly.
Any help would be much appreciated.
import tkinter as tk
class widget:
def __init__(self,master):
# vcmd = (master.register(self.validate),
# '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.master = master
self.entryNumbers = tk.Entry(master,justify = tk.CENTER)
self.entryNumbers.insert(0, "5")
self.entryNumbers.grid(row = 0,column = 0,columnspan =2,sticky="EW")
self.createEntriesButton = tk.Button(master,text = "Create Entries",command = self.createEntries)
self.createEntriesButton.grid(row = 1, column = 0,columnspan = 2,sticky="EW")
def createEntries(self):
self.entryNumbers.grid_forget()
self.createEntriesButton.grid_forget()
self.entries = []
self.entryLabels = []
vcmd = self.master.register(self.validateEntry)
for i in range(int(self.entryNumbers.get())):
self.entryLabels.append(tk.Label(self.master,text = "Row {}".format(i)))
self.entryLabels[-1].grid(row = i,column = 0)
self.entries.append(tk.Entry(self.master, validatecommand=(vcmd,'%P',i)))
self.entries[-1].grid(row = i,column = 1)
self.addEntriesButton = tk.Button(self.master,text = "Add Entries",command = self.addEntry)
self.addEntriesButton.grid(row = i+1, column = 0,columnspan = 2,sticky="EW")
def addEntry(self):
count = len(self.entries)
vcmd = self.master.register(self.validateEntry)
self.entryLabels.append(tk.Label(self.master,text = "Row {}".format(count)))
self.entryLabels[-1].grid(row = count+1,column = 0)
self.entries.append(tk.Entry(self.master, validatecommand=(vcmd,'%P',count)))
self.entries[-1].grid(row = count+1,column = 1)
self.addEntriesButton.grid(row = count+2, column = 0,columnspan = 2,sticky="EW")
def validateEntry(self,P,row):
if P != row:
return True
else:
return False
root1=tk.Tk()
widget(root1)
root1.mainloop()
Also, can vcmd be a member variable? I would like to only initialize it once?
I figured it out using a lambda function:
vcmd = lambda row:(self.master.register(self.validateEntry),'%P',row)
for i in range(int(self.entryNumbers.get())):
self.entryLabels.append(tk.Label(self.master,text = "Row {}".format(i)))
self.entryLabels[-1].grid(row = i,column = 0)
self.entries.append(tk.Entry(self.master, validate = "all", validatecommand=vcmd(i)))

Python timetable pass start and finish time that pressed button relevant to position

For my coursework i am making a booking system and i have been messing around trying to make a page which shows current week lessons and when the button is clicked it comes up with that students details on a separate page.But i don't know how to go about passing that time into my open page sub(which writes a txt file which is going to be used for SQL to get the students details). The current way i have done it just passes the max times into the sub.
from tkinter import *
import datetime
class Application(Frame):
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
self.grid()
self.timetable_button_gen_weekdays()
self.timetable_button_gen_weekends()
def timetable_button_gen_weekdays(self):
c = datetime.datetime(100,1,1,16,00,00)
self.Monday_lbl = Label(self, text = "Monday")
self.Monday_lbl.grid(row = 1, column = 0)
self.Tuesday_lbl = Label(self, text = "Tuesday")
self.Tuesday_lbl.grid(row = 2, column = 0)
self.Wednesday_lbl = Label(self, text = "Wednesday")
self.Wednesday_lbl.grid(row = 3, column = 0)
self.Thursday_lbl = Label(self, text = "Thursday")
self.Thursday_lbl.grid(row = 4, column = 0)
self.Friday_lbl = Label(self, text = "Friday")
self.Friday_lbl.grid(row = 5, column = 0)
for k in range(8):
b = c + datetime.timedelta(minutes = (30 * k))
d = b + datetime.timedelta(minutes = (30))
self.i_time_weekdays_lbl = Label(self, text = b.time().strftime('%H:%M')+" to "+d.time().strftime('%H:%M'))
self.i_time_weekdays_lbl.grid(row = 0, column = k + 1)
for i in range(5):
for a in range(8):
b = c + datetime.timedelta(minutes = (30 * a))
d = b + datetime.timedelta(minutes = (30))
bttn_i_a = Button(self, text = "available",command = lambda: self.OpenPage(b.time().strftime('%H:%M'),d.time().strftime('%H:%M')))
bttn_i_a.grid(row = i + 1, column = a + 1)
bttn_i_a.config(height = 2, width = 10)
def timetable_button_gen_weekends(self):
c = datetime.datetime(100,1,1,10,00,00)
self.Saturday_lbl = Label(self, text = "Saturday")
self.Saturday_lbl.grid(row = 8, column = 0)
self.Sunday_lbl = Label(self, text = "Sunday")
self.Sunday_lbl.grid(row = 9, column = 0)
self.weekend_lbl = Label(self, text = "Weekend")
self.weekend_lbl.grid(row = 6, column = 1, sticky = W)
for k in range(10):
b = c + datetime.timedelta(minutes = (30 * k))
d = b + datetime.timedelta(minutes = (30))
self.i_time_weekdays_lbl = Label(self, text = b.time().strftime('%H:%M')+" to "+d.time().strftime('%H:%M'))
self.i_time_weekdays_lbl.grid(row = 7, column = k + 1)
for i in range(2):
for a in range(10):
b = c + datetime.timedelta(minutes = (30 * a))
d = b + datetime.timedelta(minutes = (30))
bttn_i_a = Button(self, text = "available",command = lambda: self.OpenPage(b.time().strftime('%H:%M'),d.time().strftime('%H:%M')))
bttn_i_a.grid(row = i + 8, column = a + 1)
bttn_i_a.config(height = 2, width = 10)
def OpenPage(self,startime,finishtime):
file = open("PassTimes.txt","w")
file.write(startime)
file.write("\n")
file.write(finishtime)
print(startime)
print(finishtime)
filepath = "PresentStudent.py"
global_namespace = {"__file__": filepath, "__name__": "__main__"}
with open(filepath, 'rb') as file:
exec(compile(file.read(), filepath, 'exec'), global_namespace)
root = Tk()
root.title("test")
root.geometry("2000x2000")
app = Application(root)
root.mainloop()
Welcome to SO.
General
IMHO, running the main routine of "PresentStudent.py" does not look that clean.
It works, but a main routine is built for when the script is called directly, not when it is imported and used in some other script.
Are you aware of the modules functionality in python?
I would recommend creating a function in PresentStudent.py that does what you are doing inside your main routine. Give the function parameters to pass the .txt-Filename.
e.g.
def presentStudentCall(inputFile):
and use it inside your script like:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# here we import PresentStudent.py, as we import it __main__ will not run
import PresentStudent
#[...]
def OpenPage(self, stime, etime):
#[...]
# Instead of executing a file we call the function from the module
PresentStudent.presentStudentCall(file)
If you want to display the data inside a second frame, you could also declare a class in PresentStudent.py and use it like:
def OpenPage(self, stime, etime):
#[...]
student=PresentStudent.Student() # assuming to name the class "Student"
student.presentStudentCall(file)
Your question itself
using the lambda does not need to be the best way. In matters of scope and garbage collecting your code only passes the last generated "b"s and "c"s to the definition.
What you could do to make it work is calculating the sender item in OpenPage:
To achieve that, I recommend having arrays for your time spans storing starting times.
Like
c = datetime.datetime(100,1,1,16,00,00)
self.weektimes = ["%s"%(c+datetime.timedelta(minutes=30*k)) for k in range(8)]
self.weekendtimes = ["%s"%((c+datetime.timedelta(minutes=30*k)) for k in range(10)]
First you need to bind the click event to the widget(in that case your button)
bttn_i_a.bind("<Button-1>", self.OnPage)
Your OpenPage could then look like this:
def OpenPage(self, event):
import time
# With that, we get the row and column where we clicked in
grid_info=event.widget.grid_info()
# week or weekend?
if grid_info["row"] > 5: #may depend on amount of headers
_timearray=self.weekendtimes
else:
_timearray=self.weektimes
# get the column
col=grid_info["column"]
# get the startTime
stime=_timearray[col]
# end time is +30 minutes
etime="%s"%(time.strptime("%s"%stime, "%H:%M")+time.struct_time(tm_min=30))
# now call the handler...

Categories

Resources