-
Notifications
You must be signed in to change notification settings - Fork 0
/
menu.py
108 lines (95 loc) · 2.94 KB
/
menu.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
class Menu():
"""
Dict-based Menu class
Attributes
----------
title: str
Menu title
_menu: dict
A dictionary structured as following:
{
idx1: {
'label': label1,
'action': action1
},
idx2: {
'label': label2,
'action': action2
},
...
}
It can be initialized by a list of (idx, label, action) tuples
"""
def __init__(self, title:str = '', entries: list[tuple[str|int, str, callable]] = None):
self.title = title
self._menu = {}
if entries:
for idx, label, action in entries:
self.add_action(idx, label, action)
def add_action(self, idx: str|int, label: str, action: callable) -> None:
"""
Parameters
----------
idx: str|int
The short name of the menu entry (i.g. '1', 1, 'A', 'X', ...)
label: str
The menu entry description (i.g. 'Back to the Main Menu')
action: callable
the function-like object that must be called by its idx
"""
self._menu[idx] = {'label' : label,
'action': action}
def execute(self, idx: str|int, *args) -> bool:
"""
Parameters
----------
idx: str|int
short name of the menu entry
*args
parameters which must be passed to the executed function
Returns
-------
bool
True if it actually executes the action
associated with the menu entry labelled idx,
else False
"""
if self._menu.get(idx):
self._menu.get(idx)['action'](*args)
return True
return False
def __str__(self) -> str:
string = f"\n{self.title}\nActions:\n"
for key, value in self._menu.items():
string += f" {key} - {value['label']}\n"
return string
def print(self) -> None:
print(self)
def __getitem__(self, idx):
return self._menu.get(idx) # no index error will be raised
def __iter__(self):
for dictitem in self._menu:
yield dictitem
# test library
if __name__ == '__main__':
def fun1():
print('fun1 works!')
def fun2():
print('fun2 works!')
def fun3():
print('fun3 works!')
def quit():
pass
actions = [('1', 'function 1', fun1),
('2', 'function 2', fun2),
('3', 'function 3', fun3),
('X', 'quit', quit)]
menu = Menu('MAIN MENU', actions)
menu.print()
choice = ''
while(choice != 'X'):
choice = input('Choose option: ').upper()
if choice == 'X':
break
menu.execute()
menu.print()