Many threads in daniweb's python forum deal with menu based programs which run in a terminal. This snippet defines a handy class, MenuCrawler, to help writing such programs. Subclassing from this base classes and adding methods corresponding to a given set of menus allows one to build the menu-based application. See the example code included in the snippets for details.
A class for menu based terminal applications.
# module menucrawler.py
# (C) 2008 Gribouillis at www.daniweb.com
"""This module implements a base class MenuCrawler for menu based
applications in a terminal.
Note: uses module cbprint from the snippet
http://www.daniweb.com/code/snippet1031.html
"""
import re
from cbprint import Print
menu_pattern = re.compile("^\s*MENU\s+(\w+)")
class MenuCrawler(object):
"""A base class for menu based applications in a terminal.
A MenuCrawler is initialized with a string containing several menus
separated by lines of the form "MENU name".
It can then be started by it's "run" method and it then displays
a menu and prompt the user for an answer.
Answers are handled by methods having the same names as the menus.
These methods can be typically be implemented by subclassing MenuCrawler.
See the example use in this module's source code.
"""
def __init__(self, menus):
self.menu = None
self.menus = {}
if menus is not None:
self.parse_menus(menus)
def parse_menus(self, menus):
lines = menus.split("\n")
name = ""
for line in lines:
match = menu_pattern.match(line)
if match is None:
if name:
self.menus[name].append(line)
else:
if name:
self.menus[name] = "\n".join(self.menus[name]).strip()
name = match.group(1)
self.menus[name] = []
if name:
self.menus[name] = "\n".join(self.menus[name]).strip()
def run(self, menu_name, prompt = "[choice] "):
self.menu = menu_name
while self.menu is not None:
Print(self.menus[self.menu])
choice = raw_input(prompt)
if hasattr(self, self.menu):
getattr(self, self.menu)(choice)
#### Example use ###
if __name__ == "__main__":
my_menus = """
MENU start
Chose one of these
[1] Fight a monster
[2] Sleep under a tree
[3] Eat the apple
MENU fight
Chose a monster
[1] Unicorn
[2] Dragon
[3] Ork
MENU sleep
You slept for an hour, but you were awaken by a strange noise overthere.
What will you do
[1] Run away
[2] Go see what caused the noise
[3] Resume your sleep
MENU apple
The apple is poisoined. You're dying.
[1] Call the charming prince
[2] Eat the other apple
[3] Pronounce the magic words
MENU magic
What is the magic formula ?
MENU quit
Do you want to play again ?
"""
class Game(MenuCrawler):
def __init__(self):
MenuCrawler.__init__(self, my_menus)
print self.menus
def start(self, choice):
if choice == "1":
self.menu = "fight"
elif choice == "2":
self.menu = "sleep"
elif choice == "3":
self.menu = "apple"
elif choice == "quit":
self.menu = "quit"
def do_quit(self):
Print("Thank you for playing")
raise SystemExit
def fight(self, choice):
if choice in ("1", "2", "3"):
Print("Fights are not yet implemented")
self.menu = "quit"
elif choice == "quit":
self.menu = "quit"
def quit(self, choice):
if choice in ("y", "yes", "ok"):
self.menu = "start"
else:
self.do_quit()
def sleep(self, choice):
Print("This feature is not yet implemented")
self.menu = "quit"
def apple(self, choice):
if choice == "3":
self.menu = "magic"
elif choice == "quit":
self.menu = "quit"
else:
Print("This feature is not yet implemented")
def magic(self, choice):
if choice == "abracadabra":
Print("The magic words save your life!")
self.menu = "start"
elif choice == "quit":
self.menu = "quit"
else:
Print("These are not the magic words ! You're dead.")
self.menu = "quit"
G = Game()
G.run("start")
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.