Why I continue getting the error :
missing 1 required positional argument: 'category_id'
when the argument is already passed within query function in Backend class? I also don't understand the error of unfilled self or missing positional argument self:
missing 1 required positional argument: 'self'
I tried passing self to display_account_types() in Frontend class but it doesn't reflect. Do I need to pass self within the inner nested functions within a class?
import tkinter
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
import sqlite3
root =Tk()
root.title('Simple Application')
root.config(bg='SlateGrey')
root.geometry("")
# BackEnd
class Backend():
def __init__(self):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
self.conn.execute("""CREATE TABLE IF NOT EXISTS account_type(
id INTEGER PRIMARY KEY,
category_type INTEGER NOT NULL,
category_id TEXT NOT NULL
)"""),
self.conn.commit()
self.conn.close()
def insert_account_type(self, category_type, category_id):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
self.cur.execute("""INSERT INTO account_type(category_id, category_type) VALUES(?,?);""",
(self,category_type, category_id,))
self.conn.commit()
self.conn.close()
def view_account_type(self):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
self.cur.execute("SELECT * FROM account_type")
self.rows = self.cur.fetchall()
self.conn.close()
return self.rows
# calling the class
tb = Backend()
# Front End
class Frontend():
def __init__(self, master):
# Frames
self.top_frame = LabelFrame(master,bg ='SlateGrey', relief=SUNKEN)
self.top_frame.pack()
self.bottom_frame = LabelFrame(master, bg = 'SlateGrey', relief=SUNKEN)
self.bottom_frame.pack()
self.right_frame = LabelFrame(self.top_frame, bg = 'SlateGrey', relief = FLAT,
text = 'Details Entry',fg = 'maroon')
self.right_frame.pack(side = RIGHT, anchor = NE)
self.side_frame = LabelFrame(self.top_frame,bg ='SlateGrey',relief=SUNKEN,text = 'Menu Buttons',fg = 'maroon')
self.side_frame.pack(side = LEFT,anchor = NW)
self.bot_frame = LabelFrame(self.bottom_frame, bg='Grey',relief = SUNKEN,text = 'Field View',fg = 'maroon')
self.bot_frame.pack(side = BOTTOM,anchor = SW)
# Side Buttons
self.btn1 = Button(self.side_frame,
text='Main Account Types',
bg='SteelBlue4',
font=('cambria', 11),
anchor=W,
fg='white',
width=18,height=2,
command=lambda :[self.main_account()])
self.btn1.grid(row=0, column=0, pady=0, sticky=W)
def main_account(self):
# variables
self.category_type = StringVar()
self.category_id = StringVar()
# functions
def add_main_accounts():
if self.category_type.get() == "" or self.category_id.get() == "":
tkinter.messagebox.showinfo('All fields are required')
else:
Backend.insert_account_type(
self.category_type.get(),
self.category_id.get(),) # category type unfilled
tkinter.messagebox.showinfo('Entry successful')
def display_account_types(self):
self.trv.delete(*self.trv.get_children())
for self.rows in Backend.view_account_type(self):
self.trv.insert("", END, values=self.rows)
def get_account_type(e):
self.selected_row = self.trv.focus()
self.data = self.trv.item(self.selected_row)
global row
row = self.data["values"]
"""Grab items and send them to entry fields"""
self.category_id.set(row[1])
self.category_type.set(row[2])
"""=================TreeView==============="""
# Scrollbars
ttk.Style().configure("Treeview", background = "SlateGrey", foreground = "white", fieldbackground = "grey")
scroll_x = Scrollbar(self.bot_frame, orient = HORIZONTAL)
scroll_x.pack(side = BOTTOM, fill = X)
scroll_y = Scrollbar(self.bot_frame, orient = VERTICAL)
scroll_y.pack(side = RIGHT, fill = Y)
# Treeview columns & setting scrollbars
self.trv = ttk.Treeview(self.bot_frame, height=3, columns=
('id', 'category_id', 'category_type'), xscrollcommand = scroll_x.set, yscrollcommand = scroll_y.set)
# Treeview style configuration
ttk.Style().configure("Treeview", background = "SlateGrey", foreground = "white", fieldbackground = "grey")
# Configure vertical and Horizontal scroll
scroll_x.config(command = self.trv.xview)
scroll_y.config(command = self.trv.yview)
# Treeview Headings/columns
self.trv.heading('id', text = "No.")
self.trv.heading('category_id', text = 'Category ID')
self.trv.heading('category_type', text = 'Category Type')
self.trv['show'] = 'headings'
# Treeview columns width
self.trv.column('id', width = 23)
self.trv.column('category_id', width = 70)
self.trv.column('category_type', width = 100)
self.trv.pack(fill = BOTH, expand = YES)
# Binding Treeview with data
self.trv.bind('<ButtonRelease-1>',get_account_type)
# Account Types Labels
self.lbl1 = Label(self.right_frame,text = 'Category ID',anchor = W,
width=10,font = ('cambria',11,),bg = 'SlateGrey')
self.lbl1.grid(row = 0,column = 0,pady = 5)
self.lbl2 = Label(self.right_frame, text = 'Category Type', anchor = W,
width = 10,font = ('cambria',11,),bg = 'SlateGrey')
self.lbl2.grid(row = 1, column = 0,pady = 5,padx=5)
self.blank_label = Label(self.right_frame, bg='SlateGrey')
self.blank_label.grid(row=2, columnspan=2, pady=10)
# Account Type Entries
self.entry1 = Entry(self.right_frame,textvariable = self.category_id,
font = ('cambria',11,),bg = 'Grey',width=14)
self.entry1.grid(row = 0,column=1,sticky = W,padx = 5)
self.entry2 = Entry(self.right_frame, textvariable = self.category_type,
font = ('cambria', 11,), bg = 'Grey',width = 14)
self.entry2.grid(row = 1, column = 1, sticky = W,pady = 5,padx = 5)
# Buttons
self.btn_1 = Button(self.right_frame,text = 'Add',font = ('cambria',12,'bold'),bg = 'SlateGrey',
activebackground='green', fg = 'white',width=12,height = 2,relief=RIDGE,
command = lambda :[add_main_accounts()])
self.btn_1.grid(row = 3,column = 0,pady = 15)
self.btn_2 = Button(self.right_frame, text = 'View', font = ('cambria', 12, 'bold'),
bg = 'SlateGrey',command=lambda :[display_account_types()],
activebackground='green', fg ='white', width=12, height = 2, relief = RIDGE)
self.btn_2.grid(row = 3, column = 1)
# calling the class
app = Frontend(root)
root.mainloop()
I got and answer to this question,
I just passed in the 'self' argument to the inner nested functions of the class as below and it worked.
# functions
def add_main_accounts(self):
if self.category_id.get() == "" or self.category_type.get() == "":
tkinter.messagebox.showinfo('All fields are required')
else:
Backend.insert_account_type(self,
self.category_id.get(),
self.category_type.get()) # category type unfilled
tkinter.messagebox.showinfo('Entry successful')
def display_account_types(self):
self.trv.delete(*self.trv.get_children())
for rows in Backend.view_account_type(self):
self.trv.insert("", END, values = rows)
return
def get_account_type(e):
self.selected_row = self.trv.focus()
self.data = self.trv.item(self.selected_row)
global row
self.row = self.data["values"]
"""Grab items and send them to entry fields"""
self.category_id.set(row[1])
self.category_type.set(row[2])
I think you should remove the self in display_account_types function like you did to the previous one.
I needed some special charecters to be printed on cmd with Keyboard.h, but i dont have a English layout keyboard,ive got a Estoninan layout because im from Estonia. Lets get to the point!
Ive triend every special key but i havent got the \ key yet, anyone knows how can i get it?
Board used: Arduino Pro Micro
Currently got special charecters:
! = !
~ = ~~
" = Ä
# = #
¤ = +15708
% = %
& = /
/ = -
( = )
) = =
= = ´´
? = _
Õ = +15467
Ü = +15460
Ä = +15484
Ö = +15466
* = (
_ = ?
: = Ö
; = ö
> = :
# = "
£ = +15709
$ = ¤
€ = +32084
{ = Ü
[ = ü
] = õ
} = Õ
\ = '
§ = +15705
½ = +15683
ž = +14914
| = *
< = ;
š = +14943
ˇ = +13433
´ = +15692
+ = `
` = ˇ
ˇ = +13433
' = ä
ü = +15428
õ = +15435
ö = +15434
ä = +15452
- = +
. = .
, = ,
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press('_');
to get Backslash
Hi Can anyone know how to troubleshoot this.
url = "https://www.zillow.com/walnut-ca/?searchQueryState=%7B%22pagination%22%3A%7B%7D%2C%22usersSearchTerm%22%3A%22Walnut%2C%20CA%22%2C%22mapBounds%22%3A%7B%22west%22%3A-117.93482729053105%2C%22east%22%3A-117.75286623096073%2C%22south%22%3A33.93783156520187%2C%22north%22%3A34.06392018234896%7D%2C%22isMapVisible%22%3Atrue%2C%22mapZoom%22%3A12%2C%22filterState%22%3A%7B%22price%22%3A%7B%22min%22%3A400000%2C%22max%22%3A700000%7D%2C%22mp%22%3A%7B%22min%22%3A1448%2C%22max%22%3A2535%7D%2C%22sort%22%3A%7B%22value%22%3A%22globalrelevanceex%22%7D%7D%2C%22isListVisible%22%3Atrue%7D"
d = {'key':'value'}
print(d)
d['new key'] = 'new value'
print(d)
query_houses = {}
house_no = 0
while True:
response = requests.get(url)
data = response.text
soup = BeautifulSoup(data,'html.parser')
houses = soup.find_all('article',{'class':'list-card list-card-short list-card_not-saved'})
for house in houses:
location = house.find('address',{'class': 'list-card-addr'})
value = house.find('div',{'class': 'list-card-price'})
detail = house.find('ul', {'class':'list-card-details'})
seller = house.find('div',{'class':'list-card-truncate'})
link = house.find('a', {'class': 'list-card-link'}).get('href')
house_response = requests.get(link)
house_data = house_response.text
house_soup = BeautifulSoup(house_data, 'html.parser')
square = house_soup.find('span',{'class':'ds-bed-bath-living-area'})
year_build = house_soup.find('span',{'class':'ds-body ds-home-fact-value'})
estimated_sales_range = house_soup.find('div',{'class':'Spacer-sc-17suqs2-0 pfWXf'})
house_no+=1
query_houses[house_no] = [location, value, detail, seller, link, square, year_build, estimated_sales_range]
url_tag = soup.find('a',{'title':'Next-page'})
if url_tag.get('href'):
url= 'https://zillow.com' + url_tag.get('href')
print(url)
else:
break
My program is for a hangman game and I can't get the window to refresh once the button is clicked. At least i think that is the problem Here is my code for the window and the function linked to the button, let me know if you need more code:
def game(self, num):
self.game_window = tkinter.Tk()
self.game_window.title('Hangman')
self.game_window.geometry('200x150')
self.f1 = tkinter.Frame(self.game_window)
self.f2 = tkinter.Frame(self.game_window)
self.f3 = tkinter.Frame(self.game_window)
self.f4 = tkinter.Frame(self.game_window)
self.f5 = tkinter.Frame(self.game_window)
self.f6 = tkinter.Frame(self.game_window)
self.f7 = tkinter.Frame(self.game_window)
self.f8 = tkinter.Frame(self.game_window)
self.f9 = tkinter.Frame(self.game_window)
self.num = num
word_list = ['PYTHON','SOMETHING','COMPLETELY','DIFFERENT',
'LIST','STRING','SYNTAX','OBJECT','ERROR',
'EXCEPTION','OBJECT','CLASS','PERFORMANCE','VISUAL',
'JAVASCRIPT','JAVA','PROGRAMMING','TUPLE','ASSIGN',
'FUNCTION','OPERATOR','OPERANDS','PRECEDENCE',
'LOOPS','SENTENCE','TABLE','NUMBERS','DICTIONARY',
'GAME','SOFTWARE','NETWORK','SOCIAL','EDUCATION',
'MONITOR','COMPUTER']
shuffle = random.shuffle(word_list)
rand = random.choice(word_list)
self.word = rand.lower()
self.current = len(self.word)*'*'
self.letters = []
#self.start_lives = tkinter.Label(self.f1, text = 'You\'ve started the '
#'game with %s lives.\n'%(self.num))
#self.start_lives.pack(side = 'left')
self.lives_rem = tkinter.Label(self.f2,
text = 'Lives remaining: '+str(self.lives_left()))
self.lives_rem.pack(side = 'left')
self.guess_letter = tkinter.Label(self.f3, text = 'Guess a letter: ')
self.guess_entry = tkinter.Entry(self.f3, width = 10)
self.guess_letter.pack(side = 'left')
self.guess_entry.pack(side = 'left')
#self.f1.pack()
self.f2.pack()
self.f3.pack()
self.guess_button = tkinter.Button(self.f6,
text = 'Guess!',
command = self.update(self.guess_entry.get()))
self.guess_button.pack(side = 'left')
self.quit_game = tkinter.Button(self.f6,
text = 'Quit Game',
command = self.game_window.destroy)
self.quit_game.pack(side = 'left')
self.f6.pack()
def update(self, letter):
if letter in self.word and letter not in self.letters:
pos = self.word.index(letter)
self.current1 = list(self.current)
self.current1[pos] = letter.upper()
self.current2 = ''.join(self.current1)
self.letters.append(letter)
elif letter in self.letters:
self.already_guessed = tkinter.messagebox.showinfo('Error!',
'This letter has already '
'been guessed')
#letter is not in the word
elif letter not in self.word:
self.sorry = tkinter.Label(self.f5,
text = 'Sorry, guess again!')
self.sorry.pack(side = 'left')
self.letters.append(letter)
self.num -= 1
self.incorrect_word = tkinter.Label(self.f4,
text = 'Word: '+self.current)
self.incorrect_word.pack(side='left')
self.f5.pack()
self.f4.pack()
return self.current
These are two methods in a Hangman class.
The line that defines the guess button:
self.guess_button = tkinter.Button(self.f6, text = 'Guess!', command = self.update(self.guess_entry.get()))
requires modification. the command argument for the Button class should be a function, but this line is calling that function (which sends the output of the function as the value for the command argument). As you may see on the quit_game button definition, the self.game_window.destroy function is provided as the command, but is not called right now.
I suggest changing this line like this:
self.guess_button = tkinter.Button(self.f6, text = 'Guess!', command = self._on_guess_button_click)
and then add a new method to your class like this:
def _on_guess_button_click (self):
self.update(self.guess_entry.get())
I'm trying to get postfix to deliver mail to gmail. I've followed this article on configuring it, but I still gives me an error:
relay=smtp.gmail.com[173.194.66.108]:587, delay=0.46, delays=0.05/0/0.37/0.04,
dsn=5.5.1, status=bounced (host smtp.gmail.com[173.194.66.108] said: 530-5.5.1
Authentication Required.
http://mhawthorne.net/posts/postfix-configuring-gmail-as-relay.html
What am I missing?
Here's my postfix config:
alias_maps = hash:/etc/aliases
biff = no
canonical_maps = hash:/etc/postfix/canonical
command_directory = /usr/sbin
config_directory = /etc/postfix
content_filter =
daemon_directory = /usr/lib/postfix
data_directory = /var/lib/postfix
debug_peer_level = 3
debug_peer_list = smtp.gmail.com
debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin $daemon_directory/$process_name $process_id & sleep 5
defer_transports =
delay_warning_time = 1h
disable_dns_lookups = no
disable_mime_output_conversion = no
html_directory = /usr/share/doc/packages/postfix-doc/html
inet_interfaces = localhost
inet_protocols = all
mail_owner = postfix
mail_spool_directory = /var/mail
mailbox_command =
mailbox_size_limit = 0
mailbox_transport =
mailq_path = /usr/bin/mailq
manpage_directory = /usr/share/man
masquerade_classes = envelope_sender, header_sender, header_recipient
masquerade_domains =
masquerade_exceptions = root
message_size_limit = 0
message_strip_characters = \0
mydestination = $myhostname, localhost.$mydomain
myhostname = suse.home
mynetworks_style = subnet
newaliases_path = /usr/bin/newaliases
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/packages/postfix-doc/README_FILES
relay_clientcerts =
relayhost = [smtp.gmail.com]:587
relocated_maps = hash:/etc/postfix/relocated
sample_directory = /usr/share/doc/packages/postfix-doc/samples
sender_canonical_maps = hash:/etc/postfix/sender_canonical
sendmail_path = /usr/sbin/sendmail
setgid_group = maildrop
smtp_enforce_tls = no
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile =
smtp_tls_CApath = /etc/postfix/ssl/cacerts
smtp_tls_cert_file =
smtp_tls_key_file =
smtp_tls_session_cache_database = btree:/var/lib/postfix/smtpd_tls_session_cache
smtp_use_tls = yes
smtpd_client_restrictions =
smtpd_helo_required = no
smtpd_helo_restrictions =
smtpd_recipient_restrictions = permit_mynetworks,reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sender_restrictions = hash:/etc/postfix/access
smtpd_tls_CAfile =
smtpd_tls_CApath =
smtpd_tls_ask_ccert = no
smtpd_tls_cert_file =
smtpd_tls_key_file =
smtpd_tls_received_header = no
smtpd_use_tls = no
strict_8bitmime = no
strict_rfc821_envelopes = no
transport_maps = hash:/etc/postfix/transport
unknown_local_recipient_reject_code = 550
virtual_alias_domains = hash:/etc/postfix/virtual
virtual_alias_maps = hash:/etc/postfix/virtual
You most likely need to go to Google's unlock page, as the new IP address trying to send the mail is raising security concerns.
Once you have unlocked via the browser, the script will be able to send.