ypranite
ypranite

Reputation: 103

How to efficiently make a text-based menu?

I am currently making a program with a text based menu, and I was wondering if there was anyway to avoid an excessive amount of if-statements while keeping it object oriented. I thought of something like this:

class Options:
    def displayOptions():
        #display user options
    def option1():
        #do option 1
    def option2():
        #do option 2 
    def option3():
        #do option 3 and so on

class Menu(Options):
    options = {1: option1(), 2: option2(), 3: option3()} #and so on 
    def promptUser():
        #prompts user to make a choice
    def printHeader():
        #prints header
    def handleInput():
        #checks if input is valid
    def begin():
        #initialize menu

Would something like this be convoluted? Is the Options class pointless? I'm pretty new to OOP and I was wondering how this would most efficiently be done.

Upvotes: 0

Views: 1679

Answers (2)

Aidan N.
Aidan N.

Reputation: 1

!Py3 code!

    b=input('>')

    if b == '1':
    print("")

    if b == '2':

        print("")

     if b == '2':
        print("")

       if b == '3':
        print("")

      else
        Print('please select a valid option. thanks!')
       b=input('>')

     if b == '1':
         print("")

      if b == '2':
         print("")

     if b == '3':
        print("")

    if b == '3':
         print("")

       else
        print('please select a valid option. thanks!')
      b=input('>')

    if b == '1':
       print("")

    if b == '2':
       print("")

    if b == '3':
        print("")

This is python. What it does is it starts, and u have 3 options 1 ... 2 ... 3 ... If you don't select a valid option, u have 2 more chances. Use

    Print('*')

to show another text. *: what u want it to say

To add 1 option, use

    If b == '*1':
     Print('*2')

*1: the option numeral/word u want *2: the word(s) u want it to say when it is selected.

Upvotes: -3

Daniel Walker
Daniel Walker

Reputation: 6760

This is a bit hacky but it gets the job done.

class Options:
    def doOption(self, opt):
        option = f'option{opt}'
        func = type(self).__dict__.get(option)
        if hasattr(func, '__call__'):
            return func(self)

        raise ValueError(f'Unsupported option: {opt}')

class Menu(Options):
    def option1(self):
        print('Foo!')

    def option2(self):
        print('Bar!')

    def optionbang(self):
        print('Bang!')

menu = Menu()
menu.doOption(1) # Foo!
menu.doOption(2) # Bar!
menu.doOption('bang') # Bang!

What this does is look through the the class' properties and try to find a function (i.e., hasattr(func, '__call__')) with the right name. The nice thing is that the logic doesn't even require opt to be an integer.

That being said, if this is your only use case, then I agree with @GradyPlayer in the comments that the abstraction probably isn't worth it.

Upvotes: 1

Related Questions