I am trying to create the below tkinter program:
- Select an option from each of the 4 optionmenus.
- Click Submit
- Value from a dictionary where I have set up the keys to match the combination of the options prints next to Submit.
E.g. User selects '18-29, dry, acne, yes' from the options. I have a dictionary in a separate python file with 200 pairs. One of pairs is: '18-29, dry, acne, yes': 'Cetaphil'
The value printed should be Cetaphil. However, nothing is printing. What am I doing wrong?
import tkinter as tk
from rp import recommendedproducts
age_menu = [
"18-29",
"30-49",
"50-81",
]
skintype_menu = [
"dry",
"combination",
"normal",
"oily",
"sensitive"
]
mainskinconcern_menu = [
"acne",
"anti-ageing",
"dehydration",
"pigmentation",
"sensitivity/redness"
]
cleanbeauty_menu = [
"Yes",
"No"
]
# root window
root = tk.Tk()
root.geometry("600x580")
root.title("SAVE MY SKIN")
root.configure(bg = "#32402f")
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
greeting = tk.Label(root, text = "Hello!", fg = "#faf2e9", bg = "#32402f",
font = ("Courier",20,"bold"),
anchor = "w",
padx = 30,
pady = 10)
greeting.grid(row = 0, column = 0, sticky = tk.W)
instructions = tk.Label(root, text = "Fill in your details to get a list of "
"product recommendations perfect for your specific "
"skincare needs!",
fg = "#faf2e9",
bg = "#32402f",
wraplength = 400,
justify = "left",
font = ("Courier",20),
anchor = "w",
width = 60,
padx = 30,
pady = 10)
instructions.grid(row = 1, column = 0, sticky = tk.W)
disclaimer = tk.Label(root,text = "This is not intended as a subsititute "
"for professional medical advice and should not be "
"relied on as health or personal advice. Always seek "
"the guidance of your doctor or other qualified health "
"professional with any questions you may have "
"regarding your health or a medical condition.",
fg = "#faf2e9",
bg = "#32402f",
wraplength = 500,
justify = "left",
font = ("Helvetica Neue",10),
anchor = "w",
width = 100,
padx = 30,
pady = 20)
disclaimer.grid(row = 10, column = 0, sticky = tk.W)
ageclicked = tk.StringVar()
ageclicked.set("age")
agedropdown = tk.OptionMenu(root,ageclicked,*age_menu)
agedropdown.config(fg = "#faf2e9",
bg = "#32402f",
font = ("helvetica neue",20),
anchor = "e",
width = 27)
agedropdown.grid(row = 2, column = 0, padx = 25, pady = 10, sticky = tk.W)
stclicked = tk.StringVar()
stclicked.set("skin type")
stdropdown = tk.OptionMenu(root,stclicked,*skintype_menu)
stdropdown.config(fg = "#faf2e9",
bg = "#32402f",
font = ("helvetica neue",20),
anchor = "e",
width = 27)
stdropdown.grid(row = 4, column = 0, padx = 25, pady = 10, sticky = tk.W)
mscclicked = tk.StringVar()
mscclicked.set("main skin concern")
mscdropdown = tk.OptionMenu(root,mscclicked,*mainskinconcern_menu)
mscdropdown.config(fg = "#faf2e9",
bg = "#32402f",
font = ("helvetica neue",20),
anchor = "e",
width = 27)
mscdropdown.grid(row = 6, column = 0, padx = 25, pady = 10, sticky = tk.W)
cbclicked = tk.StringVar()
cbclicked.set("clean beauty")
cbdropdown = tk.OptionMenu(root,cbclicked,*cleanbeauty_menu)
cbdropdown.config(fg = "#faf2e9",
bg = "#32402f",
font = ("Helvetica Neue",20),
anchor = "e",
width = 27)
cbdropdown.grid(row = 7, column = 0, padx = 25, pady = 10, sticky = tk.W)
def helptext():
print("Contact [email protected] for more information.")
def userresult():
userage = ageclicked.get()
userst = stclicked.get()
usermsc = mscclicked.get()
usercb = cbclicked.get()
print(userage,",", userst,",",usermsc,",",usercb)
def userrp():
if userresult in recommendedproducts:
print(recommendedproducts[userresult])
def show():
result = tk.Label(root, text = userrp()).grid(row = 8, column = 1, sticky = tk.W)
helpButton = tk.Button(
text = "HELP",
width = 27,
highlightbackground = "#32402f",
fg = "#faf2e9",
font = ("avenir next condensed", 20, "bold"),
command = helptext
)
helpButton.grid(row = 9, column = 0, padx = 25, pady = 10, sticky = tk.W)
submitButton = tk.Button(
text = "SUBMIT",
width = 27,
highlightbackground = "#32402f",
fg = "#faf2e9",
font = ("avenir next condensed", 20, "bold"),
command = show
)
submitButton.grid(row = 8, column = 0, padx = 25, pady = 10, sticky = tk.W)
root.mainloop()
Dictionary
recommendedproducts = {
'18-29, dry, acne, Yes': 'Cetaphil',
'18-29, dry, acne, No': 'Cetaphil',
'18-29, dry, anti-ageing, Yes': 'Cetaphil',
'18-29, dry, anti-ageing, No': 'Cetaphil',
'18-29, dry, dehydration, Yes': 'Cetaphil',
'18-29, dry, dehydration, No': 'Cetaphil',
'18-29, dry, pigmentation, Yes': 'Cetaphil',
'18-29, dry, pigmentation, No': 'Cetaphil',
'18-29, dry, sensitivity/redness, Yes': 'Cetaphil',
'18-29, dry, sensitivity/redness, No': 'Cetaphil',
'18-29, combination, acne, Yes': 'Cetaphil',
'18-29, combination, acne, No': 'Cetaphil',
'18-29, combination, anti-ageing, Yes': 'Cetaphil',
'18-29, combination, anti-ageing, No': 'Cetaphil',
'18-29, combination, dehydration, Yes': 'Cetaphil',
'18-29, combination, dehydration, No': 'Cetaphil',
'18-29, combination, pigmentation, Yes': 'Cetaphil',
'18-29, combination, pigmentation, No': 'Cetaphil',
'18-29, combination, sensitivity/redness, Yes': 'Cetaphil',
'18-29, combination, sensitivity/redness, No': 'Cetaphil',
'18-29, normal, acne, Yes': 'Cetaphil',
'18-29, normal, acne, No': 'Cetaphil',
'18-29, normal, anti-ageing, Yes': 'Cetaphil',
'18-29, normal, anti-ageing, No': 'Cetaphil',
'18-29, normal, dehydration, Yes': 'Cetaphil',
'18-29, normal, dehydration, No': 'Cetaphil',
'18-29, normal, pigmentation, Yes': 'Cetaphil',
'18-29, normal, pigmentation, No': 'Cetaphil',
'18-29, normal, sensitivity/redness, Yes': 'Cetaphil',
'18-29, normal, sensitivity/redness, No': 'Cetaphil',
'18-29, oily, acne, Yes': 'Cetaphil',
'18-29, oily, acne, No': 'Cetaphil',
'18-29, oily, anti-ageing, Yes': 'Cetaphil',
'18-29, oily, anti-ageing, No': 'Cetaphil',
'18-29, oily, dehydration, Yes': 'Cetaphil',
'18-29, oily, dehydration, No': 'Cetaphil',
'18-29, oily, pigmentation, Yes': 'Cetaphil',
'18-29, oily, pigmentation, No': 'Cetaphil',
'18-29, oily, sensitivity/redness, Yes': 'Cetaphil',
'18-29, oily, sensitivity/redness, No': 'Cetaphil',
'18-29, sensitive, acne, Yes': 'Cetaphil',
'18-29, sensitive, acne, No': 'Cetaphil',
'18-29, sensitive, anti-ageing, Yes': 'Cetaphil',
'18-29, sensitive, anti-ageing, No': 'Cetaphil',
'18-29, sensitive, dehydration, Yes': 'Cetaphil',
'18-29, sensitive, dehydration, No': 'Cetaphil',
'18-29, sensitive, pigmentation, Yes': 'Cetaphil',
'18-29, sensitive, pigmentation, No': 'Cetaphil',
'18-29, sensitive, sensitivity/redness, Yes': 'Cetaphil',
'18-29, sensitive, sensitivity/redness, No': 'Cetaphil',
'30-49, dry, acne, Yes': 'Cetaphil',
'30-49, dry, acne, No': 'Cetaphil',
'30-49, dry, anti-ageing, Yes': 'Cetaphil',
'30-49, dry, anti-ageing, No': 'Cetaphil', '30-49, dry, dehydration, Yes': 'Cetaphil', '30-49, dry, dehydration, No': 'Cetaphil', '30-49, dry, pigmentation, Yes': 'Cetaphil', '30-49, dry, pigmentation, No': 'Cetaphil', '30-49, dry, sensitivity/redness, Yes': 'Cetaphil', '30-49, dry, sensitivity/redness, No': 'Cetaphil', '30-49, combination, acne, Yes': 'Cetaphil', '30-49, combination, acne, No': 'Cetaphil', '30-49, combination, anti-ageing, Yes': 'Cetaphil', '30-49, combination, anti-ageing, No': 'Cetaphil', '30-49, combination, dehydration, Yes': 'Cetaphil', '30-49, combination, dehydration, No': 'Cetaphil', '30-49, combination, pigmentation, Yes': 'Cetaphil', '30-49, combination, pigmentation, No': 'Cetaphil', '30-49, combination, sensitivity/redness, Yes': 'Cetaphil', '30-49, combination, sensitivity/redness, No': 'Cetaphil', '30-49, normal, acne, Yes': 'Cetaphil', '30-49, normal, acne, No': 'Cetaphil', '30-49, normal, anti-ageing, Yes': 'Cetaphil', '30-49, normal, anti-ageing, No': 'Cetaphil', '30-49, normal, dehydration, Yes': 'Cetaphil', '30-49, normal, dehydration, No': 'Cetaphil', '30-49, normal, pigmentation, Yes': 'Cetaphil', '30-49, normal, pigmentation, No': 'Cetaphil', '30-49, normal, sensitivity/redness, Yes': 'Cetaphil', '30-49, normal, sensitivity/redness, No': 'Cetaphil', '30-49, oily, acne, Yes': 'Cetaphil', '30-49, oily, acne, No': 'Cetaphil', '30-49, oily, anti-ageing, Yes': 'Cetaphil', '30-49, oily, anti-ageing, No': 'Cetaphil', '30-49, oily, dehydration, Yes': 'Cetaphil', '30-49, oily, dehydration, No': 'Cetaphil', '30-49, oily, pigmentation, Yes': 'Cetaphil', '30-49, oily, pigmentation, No': 'Cetaphil', '30-49, oily, sensitivity/redness, Yes': 'Cetaphil', '30-49, oily, sensitivity/redness, No': 'Cetaphil', '30-49, sensitive, acne, Yes': 'Cetaphil', '30-49, sensitive, acne, No': 'Cetaphil', '30-49, sensitive, anti-ageing, Yes': 'Cetaphil', '30-49, sensitive, anti-ageing, No': 'Cetaphil', '30-49, sensitive, dehydration, Yes': 'Cetaphil', '30-49, sensitive, dehydration, No': 'Cetaphil', '30-49, sensitive, pigmentation, Yes': 'Cetaphil', '30-49, sensitive, pigmentation, No': 'Cetaphil', '30-49, sensitive, sensitivity/redness, Yes': 'Cetaphil', '30-49, sensitive, sensitivity/redness, No': 'Cetaphil', '50-81, dry, acne, Yes': 'Cetaphil', '50-81, dry, acne, No': 'Cetaphil', '50-81, dry, anti-ageing, Yes': 'Cetaphil', '50-81, dry, anti-ageing, No': 'Cetaphil', '50-81, dry, dehydration, Yes': 'Cetaphil', '50-81, dry, dehydration, No': 'Cetaphil', '50-81, dry, pigmentation, Yes': 'Cetaphil', '50-81, dry, pigmentation, No': 'Cetaphil', '50-81, dry, sensitivity/redness, Yes': 'Cetaphil', '50-81, dry, sensitivity/redness, No': 'Cetaphil', '50-81, combination, acne, Yes': 'Cetaphil', '50-81, combination, acne, No': 'Cetaphil', '50-81, combination, anti-ageing, Yes': 'Cetaphil', '50-81, combination, anti-ageing, No': 'Cetaphil', '50-81, combination, dehydration, Yes': 'Cetaphil', '50-81, combination, dehydration, No': 'Cetaphil', '50-81, combination, pigmentation, Yes': 'Cetaphil', '50-81, combination, pigmentation, No': 'Cetaphil', '50-81, combination, sensitivity/redness, Yes': 'Cetaphil', '50-81, combination, sensitivity/redness, No': 'Cetaphil', '50-81, normal, acne, Yes': 'Cetaphil', '50-81, normal, acne, No': 'Cetaphil', '50-81, normal, anti-ageing, Yes': 'Cetaphil', '50-81, normal, anti-ageing, No': 'Cetaphil', '50-81, normal, dehydration, Yes': 'Cetaphil', '50-81, normal, dehydration, No': 'Cetaphil', '50-81, normal, pigmentation, Yes': 'Cetaphil', '50-81, normal, pigmentation, No': 'Cetaphil', '50-81, normal, sensitivity/redness, Yes': 'Cetaphil', '50-81, normal, sensitivity/redness, No': 'Cetaphil', '50-81, oily, acne, Yes': 'Cetaphil', '50-81, oily, acne, No': 'Cetaphil', '50-81, oily, anti-ageing, Yes': 'Cetaphil', '50-81, oily, anti-ageing, No': 'Cetaphil', '50-81, oily, dehydration, Yes': 'Cetaphil', '50-81, oily, dehydration, No': 'Cetaphil', '50-81, oily, pigmentation, Yes': 'Cetaphil', '50-81, oily, pigmentation, No': 'Cetaphil', '50-81, oily, sensitivity/redness, Yes': 'Cetaphil', '50-81, oily, sensitivity/redness, No': 'Cetaphil', '50-81, sensitive, acne, Yes': 'Cetaphil', '50-81, sensitive, acne, No': 'Cetaphil', '50-81, sensitive, anti-ageing, Yes': 'Cetaphil', '50-81, sensitive, anti-ageing, No': 'Cetaphil', '50-81, sensitive, dehydration, Yes': 'Cetaphil', '50-81, sensitive, dehydration, No': 'Cetaphil', '50-81, sensitive, pigmentation, Yes': 'Cetaphil', '50-81, sensitive, pigmentation, No': 'Cetaphil', '50-81, sensitive, sensitivity/redness, Yes': 'Cetaphil', '50-81, sensitive, sensitivity/redness, No': 'Cetaphil'
}
edited function userrp() as:
def userrp():
userresult()
print(recommendedproducts[userresult])
resulted in error:
18-29, dry, acne, Yes
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 1892, in __call__
return self.func(*args)
File "/Users/xx/checki.py", line 153, in show
result = tk.Label(root, text = userrp(), bg = '#32402f', fg = '#faf2e9').grid(row = 8, column = 1, sticky = tk.E)
File "/Users/xx/checki.py", line 149, in userrp
print(recommendedproducts[userresult])
KeyError: <function userresult at 0x7ff01fd3c9d0>
CodePudding user response:
You forgot to do a function call for userresult()
.
if userresult in recommendedproducts
Here you are checking if the function object is a key in the dictionary recommendedproducts
. So what is happening can be compared to this:
def foo(): pass
dict1 = {"a": 1, foo: 2}
dict2 = {"a": 1, "b": foo}
print(foo in dict1) # True
print(foo in dict2) # False
Edit:
After taking a second look at the code, there are several things that occur that seem pretty obvious that the intended code is different from the one that is executing.
Let's begin with the structure, then work outwards.
Currently this is the flow of the nested function calls:
show()
-> userrp()
-> userresult()
def userresult():
userage = ageclicked.get()
userst = stclicked.get()
usermsc = mscclicked.get()
usercb = cbclicked.get()
print(userage,",", userst,",",usermsc,",",usercb)
userresult()
does not return anything, by default this function will then return None
if userresult()
would then be the same as
if None
In other words, this if condition will never return True
with the current code.
So let's fix that one:
def userresult():
userage = ageclicked.get()
userst = stclicked.get()
usermsc = mscclicked.get()
usercb = cbclicked.get()
# We must return this string, so it will be used whenever the function is called.
return f"{userage}, {userst}, {usermsc}, {usercb}"
Now we can use the return value for our if condition:
def userrp():
if userresult() in recommendedproducts:
# We want this function to return as well.
return recommendedproducts[userresult()]
This function should now work properly, or as intended.
def show():
result = tk.Label(root, text = userrp()).grid(row = 8, column = 1, sticky = tk.W)
I've made a code snippet in hopes to clarify how nested functions, print(built-in function) and return statements work.
def foo():
print("foo")
# This function does not return anything and will return a NoneType object
def bar():
return "bar"
foo() # Prints foo.
bar() # Prints nothing.
print(foo()) # Prints foo, then prints None
print(bar()) # Prints bar
x = foo() # x = None, and prints foo
y = bar() # y = "bar"
print(x) # Prints None
print(y) # Prints bar