Menu: Difference between revisions

From Rosetta Code
Content added Content deleted
(added ocaml)
(→‎Tcl: Added implementation)
Line 93: Line 93:
Which is from the three pigs: 3
Which is from the three pigs: 3
You chose: tick tock</pre>
You chose: tick tock</pre>

=={{header|Tcl}}==
<lang tcl>proc select {prompt choices} {
set nc [llength $choices]
if {!$nc} {
return ""
}
set numWidth [string length $nc]
while true {
for {set i 0} {$i<$nc} {} {
set s [lindex $choices $i]
incr i
puts [format " %-*d: %s" $numWidth $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>% 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>

Revision as of 20:35, 3 June 2009

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 out-of-range indices 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].

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 {

for {set i 0} {$i<$nc} {} { set s [lindex $choices $i] incr i puts [format "  %-*d: %s" $numWidth $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>% 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>