Posts: 42
Threads: 22
Joined: Oct 2021
Dec-17-2021, 03:13 PM
(This post was last modified: Dec-17-2021, 03:13 PM by 3lnyn0.)
Hello! I have a problem with the code below.
If I remove the 2 lines below from the code, the code enters the loop.
If I leave it when I use option 1 for products and enter the products menu it also shows me the main menu (I marked with ---> the outp that I want to disappear)
products = ['product_id', 'name', 'producer','category','price', 'stock']
clients = ['cnp', 'last_name', 'first_name', 'age']
def menu():
print("[1] Products")
print("[2] Clients")
print("[3] Display")
print('[4] Report')
print("[0] Exit the program.")
def products():
#Adăugarea/ Ștergerea/ Actualizarea unui nou produs
print("[1] Add new product")
print("[2] Product update")
print("[3] Delete product")
print('[4] Go back to main page')
print("[0] Exit the program.")
def clients():
#Adăugarea/ Ștergerea/ Actualizarea unui nou client
print("[1] Add new client")
print("[2] Client update")
print("[3] Delete client")
print('[4] Go back to main page')
print("[0] Exit the program.")
def display():
#Afișarea listei de produse/ clienți
#Afișarea unui client/ produs specific
print("[1] Search list of: ")
print("[2] Search a: ")
print('[4] Go back to main page')
print("[0] Exit the program.")
def reports():
#Media de varsta a clientilor
#Prețul mediu al produselor
print("[1] Average age of clients: ")
print("[2] The average price of the products ")
print('[4] Return to the main menu')
print("[0] Exit the program.")
def option3():
print("Optiunea 3!")
menu()
option = int(input("Enter your option: "))
while option != 0:
if option == 1:
products()
elif option == 2:
clients()
elif option == 3:
display()
elif option == 4:
reports()
else:
print("Invalid option.")
menu() -------->>>> this 2 line
option = int(input("Enter your option: "))
# sa nu intre in bucla
print("E gata!") Output: [1] Products
[2] Clients
[3] Display
[4] Report
[0] Exit the program.
Enter your option: 1
[1] Add new product
[2] Product update
[3] Delete product
[4] Go back to main page
[0] Exit the program.
[1] Products --->>> this output
[2] Clients
[3] Display
[4] Report
[0] Exit the program. ---> until here
Enter your option:
Posts: 379
Threads: 2
Joined: Jan 2021
Dec-17-2021, 07:03 PM
(This post was last modified: Dec-17-2021, 07:03 PM by BashBedlam.)
You're headed for trouble. If you keep going like that you will have to create a different if/elif list for every menu. Let's organize a little differently. In this code we have one operate_menu function that accepts a tuple of two lists. One list is the options to display for the menu and the other is a list of the command associated with those options. You can change the command that any menu item calls by changing the command in the command list. I've included a dummy_function as a place holder for the commands that you will be using.
Please let me know if you need any further help with this.
products = ['product_id', 'name', 'producer','category','price', 'stock']
clients = ['cnp', 'last_name', 'first_name', 'age']
def operate_menu (menu_tuple) :
acceptable_options = {'1': 0, '2': 1, '3': 2, '4': 3, '0': 4}
display_list = menu_tuple [0]
command_list = menu_tuple [1]
while True :
print ('\n----------------------')
for item in display_list :
print (item)
option = input ('Enter your option: ')
if option in acceptable_options :
exec (command_list [acceptable_options [option]])
else :
print (f'\n{option} is not an acceptable option.')
def exit_the_program () :
print("\n\nFinished!")
exit ()
def dummy_function () :
print ('\nThis is just a place holder function.\n')
products_menu = ((
"[1] Add new product",
"[2] Product update",
"[3] Delete product",
'[4] Go back to main page',
"[0] Exit the program."),
('dummy_function ()',
'dummy_function ()',
'dummy_function ()',
'operate_menu (main_menu)',
'exit_the_program ()'))
clients_menu = ((
"[1] Add new client",
"[2] Client update",
"[3] Delete client",
'[4] Go back to main page',
"[0] Exit the program."),
('dummy_function ()',
'dummy_function ()',
'dummy_function ()',
'operate_menu (main_menu)',
'exit_the_program ()'))
display_menu = ((
"[1] Search list of: ",
"[2] Search a: ",
"[3] No operation.",
'[4] Go back to main page',
"[0] Exit the program."),
('dummy_function ()',
'dummy_function ()',
'dummy_function ()',
'operate_menu (main_menu)',
'exit_the_program ()'))
reports_menu = ((
"[1] Average age of clients: ",
"[2] The average price of the products ",
"[3] No operation.",
'[4] Return to the main menu',
"[0] Exit the program."),
('dummy_function ()',
'dummy_function ()',
'dummy_function ()',
'operate_menu (main_menu)',
'exit_the_program ()'))
main_menu = ((
"[1] Products",
"[2] Clients",
"[3] Display",
'[4] Report',
"[0] Exit the program."),
('operate_menu (products_menu)',
'operate_menu (clients_menu)',
'operate_menu (display_menu)',
'operate_menu (report_menu)',
'exit_the_program ()'))
operate_menu (main_menu)
Posts: 1,094
Threads: 143
Joined: Jul 2017
Dec-18-2021, 03:56 AM
(This post was last modified: Dec-18-2021, 03:56 AM by Pedroski55.)
It is not a good idea to reinvent the wheel!
Seems to me, you need a database. I would use MySQL for this.
Python can interact with MySQL via the module pymysql.
json files are mini databases. They are a way of saving and passing on data, if MySQL seems difficult.
The code below will make a json file of all your products and product details.
You can change it to make a json file for your clients.
Then all you need is to read up on how to selectively display json file data.
Personally, I think you need a class for your products and clients.
I never use classes for my simple stuff, so I don't know much about them.
There is a guy here, deanhystad, he seems to be quite an expert on classes.
Maybe he can show you how to do this with classes.
def myApp():
# Step 1
# get the module
import json
# collect data
# this is a list of things we need to know about each product
# need some kind of check to keep 'product_id' unique
collect_data = ['product_id', 'name', 'producer','category','price', 'stock']
# save the information we collect in the list: product_data
product_data = []
# a function to collect our data
# this function returns a dictionary with product data
# this dictionary is saved in the list: product_data
def get_product_data():
product_dict = {}
for info in collect_data:
product_dict[info] = input(f'Please enter the {info}: ')
return product_dict
replies = ['yes', 'no']
reply = 'X'
# still need a way to keep the product ids unique!!
while not reply in replies:
print('Do you want to enter a product?')
reply = input('Enter yes to continue, enter no to stop ')
if reply == 'yes':
answers = get_product_data()
product_data.append(answers)
reply = 'maybe'
elif reply == 'no':
break
# Step 2
# use a DICTIONARY COMPREHENSION to make the list: product_data into a dictionary
product_data_dict = {i:product_data[i] for i in range(len(product_data))}
# look at product_data_dict
for item in product_data_dict.items():
print(json.dumps(item, indent = 4, sort_keys=True))
# Step 3
# save user_data_dict as a .json file
# USE YOUR PATH
mypath = '/home/pedro/temp/product_data_json.json'
# open 'a' in case the file already exists
with open(mypath, 'a') as json_file:
json.dump(product_data_dict, json_file)
# Step 4
# open the file you just saved in mypath
# USE YOUR PATH
with open(mypath) as f:
data = json.load(f)
print('data is ' + str(len(data)) + ' entries long')
# look at the content of '/home/pedro/winter2020/20PY/json/user_data_json.json'
for item in data.items():
print(json.dumps(item, indent = 4, sort_keys=True))
"""
You can open and append to this json file any time
Make another json file for clients
Then read up on how to display the contents of a json file
"""
Posts: 7,319
Threads: 123
Joined: Sep 2016
Dec-18-2021, 10:59 AM
(This post was last modified: Dec-18-2021, 10:59 AM by snippsat.)
If write menu function like this it will make more sense,this is how i usually do it when using menu with functions,can also call a class.
Now always fall back to the menu(loop) where can do other task or Quit out.
def solve_1():
answer = int(input('What is 2 + 2? '))
if answer == 4:
print('Correct')
else:
print('Wrong,try again')
def prod(data):
for item in data[0]:
print(item)
input('Press enter to retun to menu\n')
def func_data():
products = ['product_id', 'name', 'producer','category','price', 'stock']
clients = ['cnp', 'last_name', 'first_name', 'age']
return products, clients
def menu():
while True:
print('(1) Solve something')
print('(2) Show products list')
print('(Q) Quit')
choice = input('Enter your choice: ').lower()
if choice == '1':
solve_1()
elif choice == '2':
data = func_data()
prod(data)
elif choice == 'q':
return
else:
print(f'Not a correct choice: <{choice}>,try again')
if __name__ == '__main__':
menu()
Posts: 4,790
Threads: 76
Joined: Jan 2018
I suggest to insert the various menus in a collection (here a dictionary named 'menus'). This allows to refer to them more easily, add more of them etc.
Another useful feature is a registering system to register actions to do when the user makes a choice. Try to play with the following extensible code outline to see if you like it
import re
class Menu:
def __init__(self, name, value):
self.name = name
self.value = value
self.options = [s[1:-1] for s in re.findall(r'\[[^\]]*\]', value)]
def __str__(self):
return(self.value)
menus = {}
menus['main'] = Menu('main', """\
[1] Products
[2] Clients
[3] Display
[4] Report
[0] Exit the program.""")
menus['products'] = Menu('products', """\
[1] Add new product
[2] Product update
[3] Delete product
[4] Go back to main page
[0] Exit the program.""")
menus['clients'] = Menu('clients', """\
[1] Add new client
[2] Client update
[3] Delete client
[4] Go back to main page
[0] Exit the program.""")
menus['display'] = Menu('display', """\
[1] Search list of:
[2] Search a:
[4] Go back to main page
[0] Exit the program.""")
menus['reports'] = Menu('reports', """\
[1] Average age of clients:
[2] The average price of the products
[4] Return to the main menu
[0] Exit the program.""")
def ask_option(menu):
while True:
print(menu)
opt = input('Please select an option: ')
if opt in menu.options:
try:
return int(opt)
except ValueError:
return opt
else:
print(f'Invalid option, please choose one of {menu.options}')
registered = {}
def register(name, opt):
def decorator(func):
registered[(name, opt)] = func
return func
return decorator
@register('main', 1)
def main_choose_products(menu, opt):
return menus['products']
@register('main', 2)
def main_choose_clients(menu, opt):
return menus['clients']
@register('main', 3)
def main_choose_display(menu, opt):
return menus['display']
@register('main', 4)
def main_choose_reports(menu, opt):
return menus['reports']
@register('main', 0)
@register('products', 0)
@register('clients', 0)
@register('display', 0)
@register('reports', 0)
def all_choose_exit(menu, opt):
return None
if __name__ == '__main__':
menu = menus['main']
while menu:
opt = ask_option(menu)
func = registered.get((menu.name, opt), None)
if func:
menu = func(menu, opt)
else:
menu = menus['main']
Posts: 379
Threads: 2
Joined: Jan 2021
Here is another version using a class and a dictionary. I personally like this one best.
def dummy_function () :
print ('\nThe dummy function has run.')
def say_goodbye () :
print ('\nBye for now.')
exit ()
class Menu_Tree :
def __init__ (self) :
self.all_menus = {
'main_menu' : {
"[1] Products": 'products_menu',
"[2] Clients": 'clients_menu',
"[3] Display": 'display_menu',
'[4] Report': 'report_menu',
"[0] Exit the program.": say_goodbye},
'products_menu' : {
"[1] Add new product": dummy_function,
"[2] Product update": dummy_function,
"[3] Delete product": dummy_function,
'[4] Go back to main page': 'main_menu',
"[0] Exit the program.": say_goodbye},
'clients_menu' : {
"[1] Add new client": dummy_function,
"[2] Client update": dummy_function,
"[3] Delete client": dummy_function,
'[4] Go back to main page': 'main_menu',
"[0] Exit the program.": say_goodbye},
'display_menu' : {
"[1] Search list of: ": dummy_function,
"[2] Search a: ": dummy_function,
'[4] Go back to main page': 'main_menu',
"[0] Exit the program.": say_goodbye},
'report_menu' : {
"[1] Average age of clients: ": dummy_function,
"[2] The average price of the products ": dummy_function,
'[4] Return to the main menu': 'main_menu',
"[0] Exit the program.": say_goodbye}}
self.run_menus (self.all_menus ['main_menu'])
def run_menus (self, menu) :
look_up_table = {label [1: 2]: label for label in menu}
print ('\n==============================')
for label in menu :
print (' ', label)
while True :
menu_choice = input ('Enter your selection: ')
if menu_choice != '' and menu_choice in look_up_table :
command = menu [look_up_table [menu_choice]]
if type (command) == str :
self.run_menus (self.all_menus [command])
else :
command ()
self.run_menus (self.all_menus ['main_menu'])
else :
print (f' "{menu_choice}" is not a valid entry.')
Menu_Tree ()
Gribouillis likes this post
Posts: 4,790
Threads: 76
Joined: Jan 2018
Dec-20-2021, 07:09 AM
(This post was last modified: Dec-20-2021, 07:09 AM by Gribouillis.)
@ BashBedlam With very little work, you could make Menu_Tree.run_menus() non recursive. Also add the possibility that after command() , the menu to run is not the main_menu .
BashBedlam likes this post
Posts: 379
Threads: 2
Joined: Jan 2021
Dec-20-2021, 09:32 PM
(This post was last modified: Dec-20-2021, 09:32 PM by BashBedlam.)
(Dec-20-2021, 07:09 AM)Gribouillis Wrote: @BashBedlam With very little work, you could make Menu_Tree.run_menus() non recursive. Also add the possibility that after command() , the menu to run is not the main_menu . This would be my best shot at that
def dummy_function () :
print ('\n The dummy function has finished running.')
def say_goodbye () :
print ('\nBye for now.')
exit ()
class Menu_Tree :
def __init__ (self) :
self.all_menus = {
'main_menu' : {
"[1] Products": 'products_menu',
"[2] Clients": 'clients_menu',
"[3] Display": 'display_menu',
'[4] Report': 'report_menu',
"[0] Exit the program.": say_goodbye},
'products_menu' : {
"[1] Add new product": dummy_function,
"[2] Product update": dummy_function,
"[3] Delete product": dummy_function,
'[4] Go back to main page': 'main_menu',
"[0] Exit the program.": say_goodbye},
'clients_menu' : {
"[1] Add new client": dummy_function,
"[2] Client update": dummy_function,
"[3] Delete client": dummy_function,
'[4] Go back to main page': 'main_menu',
"[0] Exit the program.": say_goodbye},
'display_menu' : {
"[1] Search list of: ": dummy_function,
"[2] Search a: ": dummy_function,
'[4] Go back to main page': 'main_menu',
"[0] Exit the program.": say_goodbye},
'report_menu' : {
"[1] Average age of clients: ": dummy_function,
"[2] The average price of the products ": dummy_function,
'[4] Return to the main menu': 'main_menu',
"[0] Exit the program.": say_goodbye}}
self.run_the_current_command ('main_menu')
def run_the_current_command (self, command) :
if type (command) == str :
self.current_menu = command
command = self.run_the_menus (self.all_menus [command])
else :
command ()
self.run_the_menus (self.all_menus [self.current_menu])
def run_the_menus (self, menu) :
look_up_table = {label [1: 2]: label for label in menu}
print ('\n ==============================')
for label in menu :
print (' ', label)
still_selecting = True
while still_selecting :
menu_choice = input (' Enter your selection: ')
if menu_choice != '' and menu_choice in look_up_table :
still_selecting = False
command = menu [look_up_table [menu_choice]]
else :
print (f' "{menu_choice}" is not a valid entry.')
self.run_the_current_command (command)
if __name__ == '__main__' :
Menu_Tree ()
Posts: 42
Threads: 22
Joined: Oct 2021
Dec-21-2021, 07:17 PM
(This post was last modified: Dec-21-2021, 08:20 PM by 3lnyn0.)
(Dec-18-2021, 03:56 AM)Pedroski55 Wrote: It is not a good idea to reinvent the wheel!
Seems to me, you need a database. I would use MySQL for this.
Python can interact with MySQL via the module pymysql.
json files are mini databases. They are a way of saving and passing on data, if MySQL seems difficult.
The code below will make a json file of all your products and product details.
You can change it to make a json file for your clients.
Then all you need is to read up on how to selectively display json file data.
Personally, I think you need a class for your products and clients.
I never use classes for my simple stuff, so I don't know much about them.
There is a guy here, deanhystad, he seems to be quite an expert on classes.
Maybe he can show you how to do this with classes.
def myApp():
# Step 1
# get the module
import json
# collect data
# this is a list of things we need to know about each product
# need some kind of check to keep 'product_id' unique
collect_data = ['product_id', 'name', 'producer','category','price', 'stock']
# save the information we collect in the list: product_data
product_data = []
# a function to collect our data
# this function returns a dictionary with product data
# this dictionary is saved in the list: product_data
def get_product_data():
product_dict = {}
for info in collect_data:
product_dict[info] = input(f'Please enter the {info}: ')
return product_dict
replies = ['yes', 'no']
reply = 'X'
# still need a way to keep the product ids unique!!
while not reply in replies:
print('Do you want to enter a product?')
reply = input('Enter yes to continue, enter no to stop ')
if reply == 'yes':
answers = get_product_data()
product_data.append(answers)
reply = 'maybe'
elif reply == 'no':
break
# Step 2
# use a DICTIONARY COMPREHENSION to make the list: product_data into a dictionary
product_data_dict = {i:product_data[i] for i in range(len(product_data))}
# look at product_data_dict
for item in product_data_dict.items():
print(json.dumps(item, indent = 4, sort_keys=True))
# Step 3
# save user_data_dict as a .json file
# USE YOUR PATH
mypath = '/home/pedro/temp/product_data_json.json'
# open 'a' in case the file already exists
with open(mypath, 'a') as json_file:
json.dump(product_data_dict, json_file)
# Step 4
# open the file you just saved in mypath
# USE YOUR PATH
with open(mypath) as f:
data = json.load(f)
print('data is ' + str(len(data)) + ' entries long')
# look at the content of '/home/pedro/winter2020/20PY/json/user_data_json.json'
for item in data.items():
print(json.dumps(item, indent = 4, sort_keys=True))
"""
You can open and append to this json file any time
Make another json file for clients
Then read up on how to display the contents of a json file
"""
I try to save the dictionary in a json file in the folder called project but I automatically create another file in the main folder and add the information there. I tried 3 methods and the same thing happens with everything
if name == 'products':
m = 'D:\python visio\proiect\clients.json'
#m = 'D:\python visio\proiect\clients.json'
#m = 'proiect\products.json
with open(m, 'w') as f:
json.dump(answer, f)
FIXED
Posts: 1,583
Threads: 3
Joined: Mar 2020
Sorry, I don't know what you mean by "same thing happens". For the code snippet above, can you tell us what the computer does (output or error) and what you expect to happen instead?
Is the folder in the middle supposed to be named "proiect" instead of "project"?
|