Menu

From Rosetta Code
Revision as of 21:28, 7 June 2009 by 67.142.130.21 (talk)
Task
Menu
You are encouraged to solve this task according to the task description, using any language you may know.

Given a list containing a number of strings of which one is to be selected and a prompt string, create a function that:

  • Print a textual menu formatted as an index value followed by its corresponding string for each item in the list.
  • Prompt the user to enter a number.
  • return the string corresponding to the index number.

The function should reject input that is not an integer or is an out of range integer index by recreating the whole menu before asking again for a number. The function should return an empty string if called with an empty list.

For test purposes use the four phrases: 'fee fie', 'huff and puff', 'mirror mirror' and 'tick tock' in a list.

Note: This task is fashioned after the action of the Bash select statement.

AutoHotkey

<lang autohotkey>GoSub, CreateGUI return

Submit: Gui, Submit, NoHide If Input =

GuiControl,,Output

Else If Input not between 1 and 4 {

Gui, Destroy
Sleep, 500
GoSub, CreateGUI

} Else {

GuiControlGet, string,,Text%Input%
GuiControl,,Output,% SubStr(string,4)

} return

CreateGUI: list = fee fie,huff and puff,mirror mirror,tick tock Loop, Parse, list, `,

Gui, Add, Text, vText%A_Index%, %A_Index%: %A_LoopField%

Gui, Add, Text, ym, Which is from the three pigs? Gui, Add, Edit, vInput gSubmit Gui, Add, Edit, vOutput Gui, Show return

GuiClose: ExitApp</lang>

BASIC

Works with: QuickBasic version 4.5

<lang qbasic> function sel$(choices$(), prompt$)

  if ubound(choices$) - lbound(choices$) = 0 then sel$ = ""
  ret$ = ""
  do
     for i = lbound(choices$) to ubound(choices$)
        print i; ": "; choices$(i)
     next i
     input ;prompt$, index
     if index <= ubound(choices$) and index >= lbound(choices$) then ret$ = choices$(index)
  while ret$ = ""
  sel$ = ret$

end function</lang>

Java

<lang java5>public static String select(List<String> list, String prompt){

   if(list.size() == 0) return "";
   Scanner sc = new Scanner(System.in);
   String ret = null;
   do{
       for(int i=0;i<list.size();i++){
           System.out.println(i + ": "+list.get(i));
       }
       System.out.print(prompt);
       int index = sc.nextInt();
       if(index >= 0 && index < list.size()){
           ret = list.get(index);
       }
   }while(ret == null);
   return ret;

}</lang>

OCaml

<lang ocaml>let rec select choices prompt = (* "choices" is an array of strings *)

 if Array.length choices = 0 then invalid_arg "no choices";
 Array.iteri (Printf.printf "%d: %s\n") choices;
 print_string prompt;
 let index = read_int () in
   if index >= 0 && index < Array.length choices then
     choices.(index)
   else
     select choices prompt</lang>

Python

<lang python>def _menu(items):

   for indexitem in enumerate(items):
       print ("  %2i) %s" % indexitem)

def _ok(reply, itemcount):

   try:
       n = int(reply)
       return 0 <= n < itemcount
   except:
       return False
   

def selector(items, prompt):

   'Prompt to select an item from the items'
   if not items: return 
   reply = -1
   itemcount = len(items)
   while not _ok(reply, itemcount):
       _menu(items)
       # Use input instead of raw_input for Python 3.x
       reply = raw_input(prompt).strip()
   return items[int(reply)]

if __name__ == '__main__':

   items = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']
   item = selector(items, 'Which is from the three pigs: ')
   print ("You chose: " + item)

</lang>

Sample runs:

   0) fee fie
   1) huff and puff
   2) mirror mirror
   3) tick tock
Which is from the three pigs:  -1
   0) fee fie
   1) huff and puff
   2) mirror mirror
   3) tick tock
Which is from the three pigs:      0
You chose: fee fie
>>> ================================ RESTART ================================
>>> 
   0) fee fie
   1) huff and puff
   2) mirror mirror
   3) tick tock
Which is from the three pigs: 4
   0) fee fie
   1) huff and puff
   2) mirror mirror
   3) tick tock
Which is from the three pigs: 3
You chose: tick tock

Tcl

<lang tcl>proc select {prompt choices} {

   set nc [llength $choices]
   if {!$nc} {

return ""

   }
   set numWidth [string length $nc]
   while true {

set i 0 foreach s $choices { puts [format "  %-*d: %s" $numWidth [incr i] $s] } puts -nonewline "$prompt: " flush stdout gets stdin num if {[string is int -strict $num] && $num >= 1 && $num <= $nc} { incr num -1 return [lindex $choices $num] }

   }

}</lang> Testing it out interactively... <lang tcl>% puts >[select test {}]< >< % puts >[select "Which is from the three pigs" {

   "fee fie" "huff and puff" "mirror mirror" "tick tock"

}]<

 1: fee fie
 2: huff and puff
 3: mirror mirror
 4: tick tock

Which is from the three pigs: 0

 1: fee fie
 2: huff and puff
 3: mirror mirror
 4: tick tock

Which is from the three pigs: skdfjhgz

 1: fee fie
 2: huff and puff
 3: mirror mirror
 4: tick tock

Which is from the three pigs:

 1: fee fie
 2: huff and puff
 3: mirror mirror
 4: tick tock

Which is from the three pigs: 5

 1: fee fie
 2: huff and puff
 3: mirror mirror
 4: tick tock

Which is from the three pigs: 2 >huff and puff<</lang>