Reputation: 55
I am trying to create a Menu class for my python CLI application. When a user selects an option, the corresponding function is fired.
from collections import namedtuple
Option = namedtuple('Option', ['label', 'callback'])
class Menu:
SEPARATOR = '-'
_title = ''
_options = []
def __init__(self, title, options):
self._title = title
for option in options:
self._options.append(Option(option[0], option[1]))
def header(self, text):
line = self.SEPARATOR * (len(text) + 2)
return f"{line}\n {text}\n{line}\n"
def display(self):
string = self.header(self._title)
for i, option in enumerate(self._options):
string += f"{i + 1} {option.label}\n"
return string
def callback(self, i):
if i <= len(self._options):
return self._options[i - 1].callback
def getInput(self):
incorrect = True
while incorrect:
option = int(input('>> '))
if option < 1 or option > len(self._options):
print("Invalid Input")
else:
incorrect = False
return self.options[option-1].callback()
My first menu:
mainMenu = Menu.Menu(
"Main Menu - Please Select an Option", [
('Setup Attacker', setupAttacker),
('Setup Victim', setupVictim),
('Run Attack Simulation', runAttackSim),
('View Results', viewResults),
('Exit', quitProgram)])
Things were going well until I made my second menu.
setupVictimMenu = Menu.Menu(
"Setup Victim - Please Select an Option", [
('Download Server Software', installServerSoftware),
('Open a Port...', openPort),
('Send Malicious File', sendMaliciousFile)])
On running the program it gave me this output:
-------------------------------------
Main Menu - Please Select an Option
-------------------------------------
1 Download Server Software
2 Open a Port...
3 Send Malicious File
4 Setup Attacker
5 Setup Victim
6 Run Attack Simulation
7 View Results
8 Exit
Both menu options were combined! I think the issue has something to do with options variable in the Class Menu. It has taken both lists.
Do note that the second list is a submenu to the first, so I don't understand why the options are combined despite the fact that the submenu isn't instantiated at the point that the first menu is called.
Upvotes: 1
Views: 1542
Reputation: 9230
The _options
variable is a class variable. It's shared among instances of Menu
class.
Make it an instance variable to make it private to an instance.
class Menu:
SEPARATOR = "-"
_title = ""
# _options = []
def __init__(self, title, options):
self._title = title
self._options = [Option(*option) for option in options]
Upvotes: 1