Menu: Difference between revisions
Content added Content deleted
(Updated to work with Nim 1.4: added missing parameter types.) |
Drkameleon (talk | contribs) (Replaced content with "=={{header|Arturo}}== <lang rebol>menu: function [items][ selection: neg 1 while [not? in? selection 1..size items][ loop.with:'i items 'item -> print ~"|i...") |
||
Line 1: | Line 1: | ||
=={{header|Arturo}}== |
|||
{{task|Text processing}} |
|||
<lang rebol>menu: function [items][ |
|||
selection: neg 1 |
|||
;Task: |
|||
while [not? in? selection 1..size items][ |
|||
Given a prompt and a list containing a number of strings of which one is to be selected, create a function that: |
|||
loop.with:'i items 'item -> print ~"|i+1|. |item|" |
|||
inp: input "Enter a number: " |
|||
* prints a textual menu formatted as an index value followed by its corresponding string for each item in the list; |
|||
if numeric? inp -> |
|||
* prompts the user to enter a number; |
|||
selection: to :integer inp |
|||
* returns the string corresponding to the selected index number. |
|||
] |
|||
print items \ selection-1 |
|||
<br> |
|||
The function should reject input that is not an integer or is out of range by redisplaying 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 following four phrases in a list: |
|||
fee fie |
|||
huff and puff |
|||
mirror mirror |
|||
tick tock |
|||
;Note: |
|||
This task is fashioned after the action of the [http://www.softpanorama.org/Scripting/Shellorama/Control_structures/select_statements.shtml Bash select statement]. |
|||
=={{header|11l}}== |
|||
<lang 11l>V items = [‘fee fie’, ‘huff and puff’, ‘mirror mirror’, ‘tick tock’] |
|||
L |
|||
L(item) items |
|||
print(‘#2. #.’.format(L.index + 1, item)) |
|||
V reply = input(‘Which is from the three pigs: ’).trim(‘ ’) |
|||
I !reply.is_digit() |
|||
L.continue |
|||
I Int(reply) C 1..items.len |
|||
print(‘You chose: ’items[Int(reply) - 1]) |
|||
L.break</lang> |
|||
{{out}} |
|||
<pre> |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Which is from the three pigs: a |
|||
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: 2 |
|||
You chose: huff and puff |
|||
</pre> |
|||
=={{header|Ada|}}== |
|||
<lang Ada>with ada.text_io,Ada.Strings.Unbounded; use ada.text_io, Ada.Strings.Unbounded; |
|||
procedure menu is |
|||
type menu_strings is array (positive range <>) of Unbounded_String ; |
|||
function "+" (s : string) return Unbounded_String is (To_Unbounded_String (s)); |
|||
function choice (m : menu_strings; prompt : string) return string is |
|||
begin |
|||
if m'length > 0 then |
|||
loop |
|||
put_line (prompt); |
|||
for i in m'range loop |
|||
put_line (i'img &") " & To_String (m(i))); |
|||
end loop; |
|||
begin |
|||
return To_String (m(positive'value (get_line))); |
|||
exception when others => put_line ("Try again !"); |
|||
end; |
|||
end loop; |
|||
end if; |
|||
return ""; |
|||
end choice; |
|||
begin |
|||
put_line ("You chose " & |
|||
choice ((+"fee fie",+"huff and puff",+"mirror mirror",+"tick tock"),"Enter your choice ")); |
|||
end menu;</lang> |
|||
=={{header|ALGOL 68}}== |
|||
{{trans|C}} |
|||
{{works with|ALGOL 68|Revision 1 - no extensions to language used}} |
|||
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}} |
|||
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''}} |
|||
<lang algol68>PROC menu select := (FLEX[]STRING items, UNION(STRING, VOID) prompt)STRING: |
|||
( |
|||
INT choice; |
|||
IF LWB items <= UPB items THEN |
|||
WHILE |
|||
FOR i FROM LWB items TO UPB items DO |
|||
printf(($g(0)") "gl$, i, items[i])) |
|||
OD; |
|||
CASE prompt IN |
|||
(STRING prompt):printf(($g" "$, prompt)), |
|||
(VOID):printf($"Choice ? "$) |
|||
ESAC; |
|||
read((choice, new line)); |
|||
# WHILE # 1 > choice OR choice > UPB items |
|||
DO SKIP OD; |
|||
items[choice] |
|||
ELSE |
|||
"" |
|||
FI |
|||
); |
|||
test:( |
|||
FLEX[0]STRING items := ("fee fie", "huff and puff", "mirror mirror", "tick tock"); |
|||
STRING prompt := "Which is from the three pigs : "; |
|||
printf(($"You chose "g"."l$, menu select(items, prompt))) |
|||
)</lang> |
|||
Output: |
|||
<pre> |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Which is from the three pigs : 2 |
|||
You chose huff and puff. |
|||
</pre> |
|||
=={{header|AutoHotkey}}== |
|||
<lang AutoHotkey>Menu(list:=""){ |
|||
if !list ; if called with an empty list |
|||
return ; return an empty string |
|||
for i, v in x := StrSplit(list, "`n", "`r") |
|||
string .= (string?"`n":"") i "- " v |
|||
, len := StrLen(v) > len ? StrLen(v) : len |
|||
while !x[Choice] |
|||
InputBox , Choice, Please Select From Menu, % string ,, % 200<len*7 ? 200 ? len*7 , % 120 + x.count()*20 |
|||
return x[Choice] |
|||
}</lang> |
|||
Examples:<lang AutoHotkey>list = |
|||
( |
|||
fee fie |
|||
huff and puff |
|||
mirror mirror |
|||
tick tock |
|||
) |
|||
MsgBox % Menu(list) ; call menu with list |
|||
MsgBox % Menu() ; call menu with empty list |
|||
return</lang> |
|||
=={{header|AWK}}== |
|||
<lang AWK> |
|||
# syntax: GAWK -f MENU.AWK |
|||
BEGIN { |
|||
print("you picked:",menu("")) |
|||
print("you picked:",menu("fee fie:huff and puff:mirror mirror:tick tock")) |
|||
exit(0) |
|||
} |
|||
function menu(str, ans,arr,i,n) { |
|||
if (str == "") { |
|||
return |
|||
} |
|||
n = split(str,arr,":") |
|||
while (1) { |
|||
print("") |
|||
for (i=1; i<=n; i++) { |
|||
printf("%d - %s\n",i,arr[i]) |
|||
} |
|||
printf("? ") |
|||
getline ans |
|||
if (ans in arr) { |
|||
return(arr[ans]) |
|||
} |
|||
print("invalid choice") |
|||
} |
|||
} |
|||
</lang> |
|||
=={{header|Axe}}== |
|||
{{incorrect|Axe|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
In Axe, static data (such as strings) is laid out sequentially in memory. So the H in "HUFF" is the byte after the null terminator for "FIE". However, null terminators are only added to strings when they are stored with the store symbol →. strGet returns a pointer to the start of the nth null-terminated string in the data, which is why the strings must be laid out in memory correctly. |
|||
<lang axe>"FEE FIE"→Str1 |
|||
"HUFF AND PUFF"→Str2 |
|||
"MIRROR MIRROR"→Str3 |
|||
"TICK TOCK"→Str4 |
|||
For(I,1,4) |
|||
Disp I▶Hex+3,":",strGet(Str1,I-1),i |
|||
End |
|||
Disp "NUMBER? " |
|||
input→A |
|||
{A}-'0'→N |
|||
If N<1 or N>4 |
|||
Disp "BAD NUMBER",i |
|||
Return |
|||
End |
|||
Disp strGet(Str1,N-1),i</lang> |
|||
=={{header|BASIC}}== |
|||
{{works with|QuickBasic|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> |
|||
=={{header|Batch File}}== |
|||
Example 1 |
|||
<lang dos>@echo off & setlocal enabledelayedexpansion |
|||
set "menuChoices="fee fie","huff and puff","mirror mirror","tick tock"" |
|||
call :menu |
|||
pause>nul & exit |
|||
:menu |
|||
if defined menuChoices ( |
|||
set "counter=0" & for %%a in (%menuChoices%) do ( |
|||
set /a "counter+=1" |
|||
set "currentMenuChoice=%%a" |
|||
set option[!counter!]=!currentMenuChoice:"=! |
|||
) |
|||
) |
|||
:tryagain |
|||
cls&echo. |
|||
for /l %%a in (1,1,%counter%) do echo %%a^) !option[%%a]! |
|||
echo. |
|||
set /p "input=Choice 1-%counter%: " |
|||
echo. |
|||
for /l %%a in (1,1,%counter%) do ( |
|||
if !input! equ %%a echo You chose [ %%a^) !option[%%a]! ] & goto :EOF |
|||
) |
|||
echo. |
|||
echo.Invalid Input. Please try again... |
|||
pause |
|||
goto :tryagain</lang> |
|||
Example 2 |
|||
<lang dos> |
|||
@echo off |
|||
call:menu "fee fie" "huff and puff" "mirror mirror" "tick tock" |
|||
pause>nul |
|||
exit /b |
|||
:menu |
|||
cls |
|||
setlocal enabledelayedexpansion |
|||
set count=0 |
|||
set reset=endlocal ^& goto menu |
|||
:menuloop |
|||
for %%i in (%*) do ( |
|||
set /a count+=1 |
|||
set string[!count!]=%%~i |
|||
echo string[!count!] = %%~i |
|||
) |
|||
echo. |
|||
set /p choice=^> |
|||
if "%choice%"=="" %reset% |
|||
set "isNum=" |
|||
for /f "delims=0123456789" %%i in ("%choice%") do set isNum=%%i |
|||
if defined isNum %reset% |
|||
if %choice% gtr %count% %reset% |
|||
echo.!string[%choice%]! |
|||
goto:eof |
|||
</lang> |
|||
=={{header|BBC BASIC}}== |
|||
<lang bbcbasic> DIM list$(4) |
|||
list$() = "fee fie", "huff and puff", "mirror mirror", "tick tock" |
|||
selected$ = FNmenu(list$(), "Please make a selection: ") |
|||
PRINT selected$ |
|||
END |
|||
DEF FNmenu(list$(), prompt$) |
|||
LOCAL index%, select$ |
|||
IF SUM(list$()) = "" THEN = "" |
|||
REPEAT |
|||
CLS |
|||
FOR index% = 0 TO DIM(list$() ,1) |
|||
IF list$(index%)<>"" PRINT ; index% ":", list$(index%) |
|||
NEXT |
|||
PRINT prompt$ ; |
|||
INPUT "" select$ |
|||
index% = VAL(select$) |
|||
IF select$<>STR$(index%) index% = -1 |
|||
IF index%>=0 IF index%<=DIM(list$() ,1) IF list$(index%)="" index% = -1 |
|||
UNTIL index%>=0 AND index%<=DIM(list$(), 1) |
|||
= list$(index%)</lang> |
|||
Empty entries in the list are not offered as options, nor accepted as a selection. |
|||
=={{header|Brat}}== |
|||
<lang brat>menu = { prompt, choices | |
|||
true? choices.empty? |
|||
{ "" } |
|||
{ |
|||
choices.each_with_index { c, i | |
|||
p "#{i}. #{c}" |
|||
} |
|||
selection = ask prompt |
|||
true? selection.numeric? |
|||
{ selection = selection.to_i |
|||
true? selection < 0 || { selection >= choices.length } |
|||
{ p "Selection is out of range"; menu prompt, choices } |
|||
{ choices[selection] } |
|||
} |
|||
{ p "Selection must be a number"; menu prompt, choices } |
|||
} |
|||
} |
|||
p menu "Selection: " ["fee fie" "huff and puff" "mirror mirror" "tick tock"]</lang> |
|||
=={{header|C}}== |
|||
<lang c>#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
const char *menu_select(const char *const *items, const char *prompt); |
|||
int |
|||
main(void) |
|||
{ |
|||
const char *items[] = {"fee fie", "huff and puff", "mirror mirror", "tick tock", NULL}; |
|||
const char *prompt = "Which is from the three pigs?"; |
|||
printf("You chose %s.\n", menu_select(items, prompt)); |
|||
return EXIT_SUCCESS; |
|||
} |
|||
const char * |
|||
menu_select(const char *const *items, const char *prompt) |
|||
{ |
|||
char buf[BUFSIZ]; |
|||
int i; |
|||
int choice; |
|||
int choice_max; |
|||
if (items == NULL) |
|||
return NULL; |
|||
do { |
|||
for (i = 0; items[i] != NULL; i++) { |
|||
printf("%d) %s\n", i + 1, items[i]); |
|||
} |
|||
choice_max = i; |
|||
if (prompt != NULL) |
|||
printf("%s ", prompt); |
|||
else |
|||
printf("Choice? "); |
|||
if (fgets(buf, sizeof(buf), stdin) != NULL) { |
|||
choice = atoi(buf); |
|||
} |
|||
} while (1 > choice || choice > choice_max); |
|||
return items[choice - 1]; |
|||
}</lang> |
|||
=={{header|C sharp}}== |
|||
<lang csharp> |
|||
using System; |
|||
using System.Collections.Generic; |
|||
public class Menu |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
List<string> menu_items = new List<string>() { "fee fie", "huff and puff", "mirror mirror", "tick tock" }; |
|||
//List<string> menu_items = new List<string>(); |
|||
Console.WriteLine(PrintMenu(menu_items)); |
|||
Console.ReadLine(); |
|||
} |
|||
private static string PrintMenu(List<string> items) |
|||
{ |
|||
if (items.Count == 0) |
|||
return ""; |
|||
string input = ""; |
|||
int i = -1; |
|||
do |
|||
{ |
|||
for (int j = 0; j < items.Count; j++) |
|||
Console.WriteLine("{0}) {1}", j, items[j]); |
|||
Console.WriteLine("What number?"); |
|||
input = Console.ReadLine(); |
|||
} while (!int.TryParse(input, out i) || i >= items.Count || i < 0); |
|||
return items[i]; |
|||
} |
|||
} |
|||
</lang> |
|||
=={{header|C++}}== |
|||
<lang cpp>#include <iostream> |
|||
#include <string> |
|||
#include <vector> |
|||
void print_menu(const std::vector<std::string>& terms) |
|||
{ |
|||
for (size_t i = 0; i < terms.size(); i++) { |
|||
std::cout << i + 1 << ") " << terms[i] << '\n'; |
|||
} |
|||
} |
|||
int parse_entry(const std::string& entry, int max_number) |
|||
{ |
|||
int number = std::stoi(entry); |
|||
if (number < 1 || number > max_number) { |
|||
throw std::invalid_argument(""); |
|||
} |
|||
return number; |
|||
} |
|||
std::string data_entry(const std::string& prompt, const std::vector<std::string>& terms) |
|||
{ |
|||
if (terms.empty()) { |
|||
return ""; |
|||
} |
|||
int choice; |
|||
while (true) { |
|||
print_menu(terms); |
|||
std::cout << prompt; |
|||
std::string entry; |
|||
std::cin >> entry; |
|||
try { |
|||
choice = parse_entry(entry, terms.size()); |
|||
return terms[choice - 1]; |
|||
} catch (std::invalid_argument&) { |
|||
// std::cout << "Not a valid menu entry!" << std::endl; |
|||
} |
|||
} |
|||
} |
|||
int main() |
|||
{ |
|||
std::vector<std::string> terms = {"fee fie", "huff and puff", "mirror mirror", "tick tock"}; |
|||
std::cout << "You chose: " << data_entry("> ", terms) << std::endl; |
|||
} |
|||
</lang> |
|||
=={{header|Ceylon}}== |
|||
<lang ceylon>"Run the module `menu`." |
|||
shared void run() { |
|||
value selection = menu("fee fie", "huff And puff", "mirror mirror", "tick tock"); |
|||
print(selection); |
|||
} |
|||
String menu(String* strings) { |
|||
if(strings.empty) { |
|||
return ""; |
|||
} |
|||
value entries = map(zipEntries(1..strings.size, strings)); |
|||
while(true) { |
|||
for(index->string in entries) { |
|||
print("``index``) ``string``"); |
|||
} |
|||
process.write("> "); |
|||
value input = process.readLine(); |
|||
if(exists input, exists int = parseInteger(input), exists string = entries[int]) { |
|||
return string; |
|||
} |
|||
} |
|||
} |
|||
</lang> |
|||
=={{header|Clojure}}== |
|||
<lang clojure>(defn menu [prompt choices] |
|||
(if (empty? choices) |
|||
"" |
|||
(let [menutxt (apply str (interleave |
|||
(iterate inc 1) |
|||
(map #(str \space % \newline) choices)))] |
|||
(println menutxt) |
|||
(print prompt) |
|||
(flush) |
|||
(let [index (read-string (read-line))] |
|||
; verify |
|||
(if (or (not (integer? index)) |
|||
(> index (count choices)) |
|||
(< index 1)) |
|||
; try again |
|||
(recur prompt choices) |
|||
; ok |
|||
(nth choices (dec index))))))) |
|||
(println "You chose: " |
|||
(menu "Which is from the three pigs: " |
|||
["fee fie" "huff and puff" "mirror mirror" "tick tock"]))</lang> |
|||
=={{header|COBOL}}== |
|||
<lang cobol> IDENTIFICATION DIVISION. |
|||
PROGRAM-ID. Test-Prompt-Menu. |
|||
DATA DIVISION. |
|||
WORKING-STORAGE SECTION. |
|||
01 Num-Options USAGE UNSIGNED-INT VALUE 4. |
|||
01 Example-Menu. |
|||
03 Example-Options-Data. |
|||
05 FILLER PIC X(30) VALUE "fee fie". |
|||
05 FILLER PIC X(30) VALUE "huff and puff". |
|||
05 FILLER PIC X(30) VALUE "mirror mirror". |
|||
05 FILLER PIC X(30) VALUE "tick tock". |
|||
03 Example-Options-Values REDEFINES Example-Options-Data. |
|||
05 Example-Options PIC X(30) OCCURS 4 TIMES. |
|||
01 Chosen-Option PIC X(30). |
|||
PROCEDURE DIVISION. |
|||
CALL "Prompt-Menu" USING BY CONTENT Num-Options |
|||
BY CONTENT Example-Menu |
|||
BY REFERENCE Chosen-Option |
|||
DISPLAY "You chose: " Chosen-Option |
|||
GOBACK |
|||
. |
|||
END PROGRAM Test-Prompt-Menu. |
|||
IDENTIFICATION DIVISION. |
|||
PROGRAM-ID. Prompt-Menu. |
|||
DATA DIVISION. |
|||
LOCAL-STORAGE SECTION. |
|||
01 User-Input USAGE UNSIGNED-INT. |
|||
01 Input-Flag PIC X. |
|||
88 Valid-Input VALUE "Y". |
|||
01 Options-Index USAGE UNSIGNED-INT. |
|||
01 Index-Display PIC Z(10). |
|||
LINKAGE SECTION. |
|||
01 Num-Options USAGE UNSIGNED-INT. |
|||
01 Menu-Options. |
|||
03 Options-Table PIC X(30) OCCURS 0 TO 10000000 TIMES |
|||
DEPENDING ON Num-Options. |
|||
01 Chosen-Option PIC X(30). |
|||
PROCEDURE DIVISION USING Num-Options Menu-Options Chosen-Option. |
|||
Main. |
|||
IF Num-Options = 0 |
|||
MOVE SPACES TO Chosen-Option |
|||
GOBACK |
|||
END-IF |
|||
PERFORM UNTIL Valid-Input |
|||
PERFORM Display-Menu-Options |
|||
DISPLAY "Choose an option: " WITH NO ADVANCING |
|||
ACCEPT User-Input |
|||
PERFORM Validate-Input |
|||
END-PERFORM |
|||
MOVE Options-Table (User-Input) TO Chosen-Option |
|||
GOBACK |
|||
. |
|||
Display-Menu-Options. |
|||
PERFORM VARYING Options-Index FROM 1 BY 1 |
|||
UNTIL Num-Options < Options-Index |
|||
MOVE Options-Index TO Index-Display |
|||
DISPLAY |
|||
Index-Display ". " Options-Table (Options-Index) |
|||
END-DISPLAY |
|||
END-PERFORM |
|||
. |
|||
Validate-Input. |
|||
IF User-Input = 0 OR > Num-Options |
|||
DISPLAY "Invalid input." |
|||
ELSE |
|||
SET Valid-Input TO TRUE |
|||
END-IF |
|||
. |
|||
END PROGRAM Prompt-Menu.</lang> |
|||
=={{header|Common Lisp}}== |
|||
<lang lisp>(defun select (prompt choices) |
|||
(if (null choices) |
|||
"" |
|||
(do (n) |
|||
((and n (<= 0 n (1- (length choices)))) |
|||
(nth n choices)) |
|||
(format t "~&~a~%" prompt) |
|||
(loop for n from 0 |
|||
for c in choices |
|||
do (format t " ~d) ~a~%" n c)) |
|||
(force-output) |
|||
(setf n (parse-integer (read-line *standard-input* nil) |
|||
:junk-allowed t)))))</lang> |
|||
=={{header|D}}== |
|||
<lang d>import std.stdio, std.conv, std.string, std.array, std.typecons; |
|||
string menuSelect(in string[] entries) { |
|||
static Nullable!(int, -1) validChoice(in string input, |
|||
in int nEntries) |
|||
pure nothrow { |
|||
try { |
|||
immutable n = input.to!int; |
|||
return typeof(return)((n >= 0 && n <= nEntries) ? n : -1); |
|||
} catch (Exception e) // Very generic |
|||
return typeof(return)(-1); // Not valid. |
|||
} |
|||
if (entries.empty) |
|||
return ""; |
|||
while (true) { |
|||
"Choose one:".writeln; |
|||
foreach (immutable i, const entry; entries) |
|||
writefln(" %d) %s", i, entry); |
|||
"> ".write; |
|||
immutable input = readln.chomp; |
|||
immutable choice = validChoice(input, entries.length - 1); |
|||
if (choice.isNull) |
|||
"Wrong choice.".writeln; |
|||
else |
|||
return entries[choice]; // We have a valid choice. |
|||
} |
|||
} |
|||
void main() { |
|||
immutable items = ["fee fie", "huff and puff", |
|||
"mirror mirror", "tick tock"]; |
|||
writeln("You chose '", items.menuSelect, "'."); |
|||
}</lang> |
|||
{{out}} |
|||
<pre>Choose one: |
|||
0) fee fie |
|||
1) huff and puff |
|||
2) mirror mirror |
|||
3) tick tock |
|||
> 2 |
|||
You chose 'mirror mirror'.</pre> |
|||
=={{header|Elixir}}== |
|||
<lang elixir>defmodule Menu do |
|||
def select(_, []), do: "" |
|||
def select(prompt, items) do |
|||
IO.puts "" |
|||
Enum.with_index(items) |> Enum.each(fn {item,i} -> IO.puts " #{i}. #{item}" end) |
|||
answer = IO.gets("#{prompt}: ") |> String.strip |
|||
case Integer.parse(answer) do |
|||
{num, ""} when num in 0..length(items)-1 -> Enum.at(items, num) |
|||
_ -> select(prompt, items) |
|||
end |
|||
end |
|||
end |
|||
# test empty list |
|||
response = Menu.select("Which is empty", []) |
|||
IO.puts "empty list returns: #{inspect response}" |
|||
# "real" test |
|||
items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"] |
|||
response = Menu.select("Which is from the three pigs", items) |
|||
IO.puts "you chose: #{inspect response}"</lang> |
|||
{{out}} |
|||
<pre> |
|||
empty list returns: "" |
|||
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" |
|||
</pre> |
|||
=={{header|ERRE}}== |
|||
<lang ERRE> |
|||
PROCEDURE Selection(choices$[],prompt$->sel$) |
|||
IF UBOUND(choices$,1)-LBOUND(choices$,1)=0 THEN |
|||
sel$="" |
|||
EXIT PROCEDURE |
|||
END IF |
|||
ret$="" |
|||
REPEAT |
|||
FOR i=LBOUND(choices$,1) TO UBOUND(choices$,1) DO |
|||
PRINT(i;": ";choices$[i]) |
|||
END FOR |
|||
PRINT(prompt$;) |
|||
INPUT(index) |
|||
IF index<=UBOUND(choices$,1) AND index>=LBOUND(choices$,1) THEN ret$=choices$[index] END IF |
|||
UNTIL ret$<>"" |
|||
sel$=ret$ |
|||
END PROCEDURE |
|||
</lang> |
|||
=={{header|Euphoria}}== |
|||
<lang euphoria>include get.e |
|||
function menu_select(sequence items, object prompt) |
|||
if length(items) = 0 then |
|||
return "" |
|||
else |
|||
for i = 1 to length(items) do |
|||
printf(1,"%d) %s\n",{i,items[i]}) |
|||
end for |
|||
if atom(prompt) then |
|||
prompt = "Choice?" |
|||
end if |
|||
return items[prompt_number(prompt,{1,length(items)})] |
|||
end if |
|||
end function |
|||
constant items = {"fee fie", "huff and puff", "mirror mirror", "tick tock"} |
|||
constant prompt = "Which is from the three pigs? " |
|||
printf(1,"You chose %s.\n",{menu_select(items,prompt)})</lang> |
|||
=={{header|F Sharp|F#}}== |
|||
<lang fsharp>open System |
|||
let rec menuChoice (options : string list) prompt = |
|||
if options = [] then "" |
|||
else |
|||
for i = 0 to options.Length - 1 do |
|||
printfn "%d. %s" (i + 1) options.[i] |
|||
printf "%s" prompt |
|||
let input = Int32.TryParse(Console.ReadLine()) |
|||
match input with |
|||
| true, x when 1 <= x && x <= options.Length -> options.[x - 1] |
|||
| _, _ -> menuChoice options prompt |
|||
[<EntryPoint>] |
|||
let main _ = |
|||
let menuOptions = ["fee fie"; "huff and puff"; "mirror mirror"; "tick tock"] |
|||
let choice = menuChoice menuOptions "Choose one: " |
|||
printfn "You chose: %s" choice |
|||
0</lang> |
|||
=={{header|Factor}}== |
|||
<lang factor>USING: formatting io kernel math math.parser sequences ; |
|||
: print-menu ( seq -- ) |
|||
[ 1 + swap "%d - %s\n" printf ] each-index |
|||
"Your choice? " write flush ; |
|||
: (select) ( seq -- result ) |
|||
dup print-menu readln string>number dup integer? [ |
|||
drop 1 - swap 2dup bounds-check? |
|||
[ nth ] [ nip (select) ] if |
|||
] [ drop (select) ] if* ; |
|||
: select ( seq -- result ) [ "" ] [ (select) ] if-empty ;</lang> |
|||
Example usage: |
|||
<pre>( scratchpad ) { "fee fie" "huff and puff" "mirror mirror" "tick tock" } select |
|||
1 - fee fie |
|||
2 - huff and puff |
|||
3 - mirror mirror |
|||
4 - tick tock |
|||
Your choice? 1 |
|||
--- Data stack: |
|||
"fee fie"</pre> |
|||
=={{header|Fantom}}== |
|||
{{incorrect|Fantom|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
<lang fantom>class Main |
|||
{ |
|||
static Void displayList (Str[] items) |
|||
{ |
|||
items.each |Str item, Int index| |
|||
{ |
|||
echo ("$index: $item") |
|||
} |
|||
} |
|||
public static Str getChoice (Str[] items) |
|||
{ |
|||
selection := -1 |
|||
while (selection == -1) |
|||
{ |
|||
displayList (items) |
|||
Env.cur.out.print ("Select: ").flush |
|||
input := Int.fromStr(Env.cur.in.readLine, 10, false) |
|||
if (input != null) |
|||
{ |
|||
if (input >= 0 && input < items.size) |
|||
{ |
|||
selection = input |
|||
} |
|||
} |
|||
echo ("Try again") |
|||
} |
|||
return items[selection] |
|||
} |
|||
public static Void main () |
|||
{ |
|||
choice := getChoice (["fee fie", "huff and puff", "mirror mirror", "tick tock"]) |
|||
echo ("You chose: $choice") |
|||
} |
|||
}</lang> |
|||
=={{header|Forth}}== |
|||
===Idiomatic Forth=== |
|||
Out of the box Forth does not have lists. This version uses strings and a vector table, which arguably is more how one would do this task in Forth. It returns a nil string if a nil string is given otherwise the input string becomes the title of the menu. |
|||
<lang Forth>\ Rosetta Code Menu Idiomatic Forth |
|||
\ vector table compiler |
|||
: CASE: ( -- ) CREATE ; |
|||
: | ( -- <text>) ' , ; IMMEDIATE |
|||
: ;CASE ( -- ) DOES> SWAP CELLS + @ EXECUTE ; |
|||
: NIL ( -- addr len) S" " ; |
|||
: FEE ( -- addr len) S" fee fie" ; |
|||
: HUFF ( -- addr len) S" huff and puff" ; |
|||
: MIRROR ( -- addr len) S" mirror mirror" ; |
|||
: TICKTOCK ( -- addr len) S" tick tock" ; |
|||
CASE: SELECT ( n -- addr len) |
|||
| NIL | FEE | HUFF | MIRROR | TICKTOCK |
|||
;CASE |
|||
CHAR 1 CONSTANT '1' |
|||
CHAR 4 CONSTANT '4' |
|||
: BETWEEN ( n low hi -- ?) 1+ WITHIN ; |
|||
: MENU ( addr len -- addr len ) |
|||
DUP 0= |
|||
IF |
|||
2DROP NIL EXIT |
|||
ELSE |
|||
BEGIN |
|||
CR |
|||
CR 2DUP 3 SPACES TYPE |
|||
CR ." 1 " 1 SELECT TYPE |
|||
CR ." 2 " 2 SELECT TYPE |
|||
CR ." 3 " 3 SELECT TYPE |
|||
CR ." 4 " 4 SELECT TYPE |
|||
CR ." Choice: " KEY DUP EMIT |
|||
DUP '1' '4' BETWEEN 0= |
|||
WHILE |
|||
DROP |
|||
REPEAT |
|||
-ROT 2DROP \ drop input string |
|||
CR [CHAR] 0 - SELECT |
|||
THEN |
|||
;</lang> |
|||
===If there must be lists=== |
|||
Here we extend Forth to support simple lists and complete the task using the language extensions. |
|||
<lang forth>\ Rosetta Menu task with Simple lists in Forth |
|||
: STRING, ( caddr len -- ) HERE OVER CHAR+ ALLOT PLACE ; |
|||
: " ( -- ) [CHAR] " PARSE STRING, ; |
|||
: { ( -- ) ALIGN 0 C, ; |
|||
: } ( -- ) { ; |
|||
: {NEXT} ( str -- next_str) COUNT + ; |
|||
: {NTH} ( n array_addr -- str) SWAP 0 DO {NEXT} LOOP ; |
|||
: {LEN} ( array_addr -- ) \ count strings in a list |
|||
0 >R \ Counter on Rstack |
|||
{NEXT} \ skip 1st empty string |
|||
BEGIN |
|||
{NEXT} DUP C@ \ Fetch length byte |
|||
WHILE \ While true |
|||
R> 1+ >R \ Inc. counter |
|||
REPEAT |
|||
DROP |
|||
R> ; \ return counter to data stack |
|||
: {TYPE} ( $ -- ) COUNT TYPE ; |
|||
: '"' ( -- ) [CHAR] " EMIT ; |
|||
: {""} ( $ -- ) '"' SPACE {TYPE} '"' SPACE ; |
|||
: }PRINT ( n array -- ) {NTH} {TYPE} ; |
|||
\ ===== TASK BEGINS ===== |
|||
CREATE GOODLIST |
|||
{ " fee fie" |
|||
" huff and puff" |
|||
" mirror mirror" |
|||
" tick tock" } |
|||
CREATE NIL { } |
|||
CHAR 1 CONSTANT '1' |
|||
CHAR 4 CONSTANT '4' |
|||
CHAR 0 CONSTANT '0' |
|||
: BETWEEN ( n low hi -- ?) 1+ WITHIN ; |
|||
: .MENULN ( n -- n) DUP '0' + EMIT SPACE OVER }PRINT ; |
|||
: MENU ( list -- string ) |
|||
DUP {LEN} 0= |
|||
IF |
|||
DROP NIL |
|||
ELSE |
|||
BEGIN |
|||
CR |
|||
CR 1 .MENULN |
|||
CR 2 .MENULN |
|||
CR 3 .MENULN |
|||
CR 4 .MENULN |
|||
CR ." Choice: " KEY DUP EMIT |
|||
DUP '1' '4' BETWEEN |
|||
0= WHILE |
|||
DROP |
|||
REPEAT |
|||
[CHAR] 0 - |
|||
CR SWAP {NTH} |
|||
THEN |
|||
;</lang> |
|||
Test at the gForth console |
|||
<PRE>GOODLIST MENU |
|||
1 fee fie |
|||
2 huff and puff |
|||
3 mirror mirror |
|||
4 tick tock |
|||
Choice: 0 |
|||
1 fee fie |
|||
2 huff and puff |
|||
3 mirror mirror |
|||
4 tick tock |
|||
Choice: Q |
|||
1 fee fie |
|||
2 huff and puff |
|||
3 mirror mirror |
|||
4 tick tock |
|||
Choice: 2 |
|||
ok |
|||
{TYPE} huff and puff ok |
|||
ok |
|||
NIL MENU ok |
|||
{TYPE} ok</PRE> |
|||
=={{header|Fortran}}== |
|||
Please find the build instructions in the comments at the start of the FORTRAN 2008 source. Compiler: gfortran from the GNU compiler collection. Command interpreter: bash. |
|||
<lang FORTRAN> |
|||
!a=./f && make $a && OMP_NUM_THREADS=2 $a |
|||
!gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none f.f08 -o f |
|||
module menu |
|||
public :: selector |
|||
contains |
|||
function selector(title,options) result(choice) |
|||
character(len=*),intent(in) :: title |
|||
character(len=*),dimension(:),intent(in) :: options |
|||
character(len=len(options)) :: choice |
|||
integer :: i,ichoose,ios,n |
|||
choice = "" |
|||
n = size(options) |
|||
if (n > 0) then |
|||
do |
|||
print "(a)",title |
|||
print "(i8,"", "",a)",(i,options(i),i=1,n) |
|||
read (*,fmt="(i8)",iostat=ios) ichoose |
|||
if (ios == -1) exit ! EOF error |
|||
if (ios /= 0) cycle ! other error |
|||
if (ichoose < 1) cycle |
|||
if (ichoose > n) cycle ! out-of-bounds |
|||
choice = options(ichoose) |
|||
exit |
|||
end do |
|||
end if |
|||
end function selector |
|||
end module menu |
|||
program menu_demo |
|||
use menu |
|||
character(len=14),dimension(:),allocatable :: zero_items,fairytale |
|||
character(len=len(zero_items)) :: s |
|||
!! empty list demo |
|||
allocate(zero_items(0)) |
|||
print "(a)","input items:",zero_items |
|||
s = selector('Choose from the empty list',zero_items) |
|||
print "(a)","returned:",s |
|||
if (s == "") print "(a)","(an empty string)" |
|||
!! Fairy tale demo |
|||
allocate(fairytale(4)) |
|||
fairytale = (/'fee fie ','huff and puff ', & |
|||
'mirror mirror ','tick tock '/) |
|||
print "(a)","input items:",fairytale |
|||
s = selector('Choose a fairy tale',fairytale) |
|||
print "(a)","returned: ",s |
|||
if (s == "") print "(a)","(an empty string)" |
|||
end program menu_demo |
|||
</lang> |
|||
=={{header|Gambas}}== |
|||
<lang gambas> |
|||
Public Sub Main() |
|||
Dim asMenu As String[] = ["fee fie", "huff And puff", "mirror mirror", "tick tock"] |
|||
Dim sValuePrompt As String = "Please select one of the above numbers> " |
|||
Dim sChoice As String |
|||
Dim sFeedbackFormat As String = "You have chosen '&1'\r\n" |
|||
sChoice = Menu(asMenu, sValuePrompt) |
|||
If sChoice = "" Then |
|||
Print "menu returned an empty string" |
|||
Else |
|||
Print Subst(sFeedbackFormat, sChoice) |
|||
Endif |
|||
End |
|||
Private Function Menu(asChoices As String[], sPrompt As String) As String |
|||
Dim sReturnValue As String = "" |
|||
Dim sMenuLineFormat As String = "&1) &2" |
|||
Dim sAnswer As String |
|||
Dim iAnswer As Integer |
|||
Dim iIndex As Integer = 0 |
|||
Dim sMenuItem As String |
|||
If Not IsNull(asChoices) Then |
|||
If asChoices.Count > 0 Then |
|||
Do |
|||
For iIndex = 0 To asChoices.Max |
|||
sMenuItem = asChoices[iIndex] |
|||
Print Subst(sMenuLineFormat, iIndex, sMenuItem) |
|||
Next |
|||
Print sPrompt |
|||
Input sAnswer |
|||
If IsNumber(sAnswer) Then |
|||
iAnswer = sAnswer |
|||
If (0 <= iAnswer) And (iAnswer <= asChoices.Max) Then |
|||
sReturnValue = asChoices[iAnswer] |
|||
Break |
|||
Endif |
|||
Endif |
|||
Loop |
|||
Endif |
|||
Endif |
|||
Return sReturnValue |
|||
End |
|||
</lang> |
|||
=={{header|Go}}== |
|||
<lang go>package main |
|||
import "fmt" |
|||
func menu(choices []string, prompt string) string { |
|||
if len(choices) == 0 { |
|||
return "" |
|||
} |
|||
var c int |
|||
for { |
|||
fmt.Println("") |
|||
for i, s := range choices { |
|||
fmt.Printf("%d. %s\n", i+1, s) |
|||
} |
|||
fmt.Print(prompt) |
|||
_, err := fmt.Scanln(&c) |
|||
if err == nil && c > 0 && c <= len(choices) { |
|||
break |
|||
} |
|||
} |
|||
return choices[c-1] |
|||
} |
|||
func main() { |
|||
pick := menu(nil, "No prompt") |
|||
fmt.Printf("No choices, result = %q\n", pick) |
|||
choices := []string{ |
|||
"fee fie", |
|||
"huff and puff", |
|||
"mirror mirror", |
|||
"tick tock", |
|||
} |
|||
pick = menu(choices, "Enter number: ") |
|||
fmt.Printf("You picked %q\n", pick) |
|||
}</lang> |
|||
Output: |
|||
<pre> |
|||
No choices, result = "" |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Enter number: 2 |
|||
You picked "huff and puff" |
|||
</pre> |
|||
=={{header|Haskell}}== |
|||
<lang Haskell>module RosettaSelect where |
|||
import Data.Maybe (listToMaybe) |
|||
import Control.Monad (guard) |
|||
select :: [String] -> IO String |
|||
select [] = return "" |
|||
select menu = do |
|||
putStr $ showMenu menu |
|||
putStr "Choose an item: " |
|||
choice <- getLine |
|||
maybe (select menu) return $ choose menu choice |
|||
showMenu :: [String] -> String |
|||
showMenu menu = unlines [show n ++ ") " ++ item | (n, item) <- zip [1..] menu] |
|||
choose :: [String] -> String -> Maybe String |
|||
choose menu choice = do |
|||
n <- maybeRead choice |
|||
guard $ n > 0 |
|||
listToMaybe $ drop (n-1) menu |
|||
maybeRead :: Read a => String -> Maybe a |
|||
maybeRead = fmap fst . listToMaybe . filter (null . snd) . reads</lang> |
|||
Example usage, at the GHCI prompt: |
|||
<lang Haskell>*RosettaSelect> select ["fee fie", "huff and puff", "mirror mirror", "tick tock"] |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Choose an item: 3 |
|||
"mirror mirror" |
|||
*RosettaSelect></lang> |
|||
=={{header|HicEst}}== |
|||
{{incorrect|HicEst|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
<lang HicEst>CHARACTER list = "fee fie,huff and puff,mirror mirror,tick tock,", answer*20 |
|||
POP(Menu=list, SelTxt=answer) |
|||
SUBROUTINE list ! callback procedure must have same name as menu argument |
|||
! Subroutine with no arguments: all objects are global |
|||
! The global variable $$ returns the selected list index |
|||
WRITE(Messagebox, Name) answer, $$ |
|||
END</lang> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
{{incorrect|Icon|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}{{incorrect|Unicon|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine].}} |
|||
<lang Icon>procedure main() |
|||
L := ["fee fie", "huff and puff", "mirror mirror", "tick tock"] |
|||
every i := 1 to *L do |
|||
write(i,") ",L[i]) |
|||
repeat { |
|||
writes("Choose a number from the menu above: ") |
|||
a := read() |
|||
if 1 <= integer(a) <= i then break |
|||
} |
|||
write("You selected ",a," ==> ",L[a]) |
|||
end</lang> |
|||
=={{header|J}}== |
|||
'''Solution:''' |
|||
<lang j> |
|||
CHOICES =: ];._2 'fee fie;huff and puff;mirror mirror;tick tock;' |
|||
PROMPT =: 'Which is from the three pigs? ' |
|||
showMenu =: smoutput@:(,"1~ (' ' ,.~ 3 ": i.@:(1 ,~ #))) |
|||
read_stdin =: 1!:1@:1: |
|||
menu =: '? '&$: :(4 : 0) |
|||
NB. use: [prompt] menu choice_array |
|||
CHOICES =. y |
|||
if. 0 = # CHOICES do. return. end. |
|||
PROMPT =. x |
|||
whilst. RESULT -.@:e. i. # CHOICES do. |
|||
showMenu CHOICES |
|||
smoutput PROMPT |
|||
RESULT =. _1 ". read_stdin'' |
|||
end. |
|||
RESULT {:: CHOICES |
|||
) |
|||
</lang> |
|||
See [[Talk:Select#J_implementation|Talk page]] for explanation. |
|||
=={{header|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> |
|||
=={{header|JavaScript}}== |
|||
{{works with|Node.js}} |
|||
<lang javascript>const readline = require('readline'); |
|||
async function menuSelect(question, choices) { |
|||
if (choices.length === 0) return ''; |
|||
const prompt = choices.reduce((promptPart, choice, i) => { |
|||
return promptPart += `${i + 1}. ${choice}\n`; |
|||
}, ''); |
|||
let inputChoice = -1; |
|||
while (inputChoice < 1 || inputChoice > choices.length) { |
|||
inputChoice = await getSelection(`\n${prompt}${question}: `); |
|||
} |
|||
return choices[inputChoice - 1]; |
|||
} |
|||
function getSelection(prompt) { |
|||
return new Promise((resolve) => { |
|||
const lr = readline.createInterface({ |
|||
input: process.stdin, |
|||
output: process.stdout |
|||
}); |
|||
lr.question(prompt, (response) => { |
|||
lr.close(); |
|||
resolve(parseInt(response) || -1); |
|||
}); |
|||
}); |
|||
} |
|||
const choices = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']; |
|||
const question = 'Which is from the three pigs?'; |
|||
menuSelect(question, choices).then((answer) => { |
|||
console.log(`\nYou chose ${answer}`); |
|||
});</lang> |
|||
=={{header|jq}}== |
|||
{{works with|jq|1.5}} |
|||
This version uses jq 1.5's 'input' builtin to read programmatically from STDIN. |
|||
<lang jq>def choice: |
|||
def read(prompt; max): |
|||
def __read__: |
|||
prompt, |
|||
( input as $input |
|||
| if ($input|type) == "number" and 0 < $input and $input <= max then $input |
|||
else __read__ |
|||
end); |
|||
__read__; |
|||
if length == 0 then "" |
|||
else |
|||
. as $in |
|||
| ("Enter your choice:\n" + |
|||
(reduce range(0; length) as $i (""; . + "\($i + 1): \($in[$i])\n")) ) as $prompt |
|||
| read($prompt; length) as $read |
|||
| if ($read|type) == "string" then $read |
|||
else "Thank you for selecting \($in[$read-1])" end |
|||
end ;</lang> |
|||
'''Example:''' |
|||
<lang jq>["fee fie", "huff and puff", "mirror mirror", "tick tock"] | choice</lang> |
|||
<lang sh> |
|||
$ jq -n -r -f Menu.jq |
|||
Enter your choice: |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
5 |
|||
Enter your choice: |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
1 |
|||
Thank you for selecting fee fie</lang> |
|||
=={{header|Julia}}== |
|||
{{trans|Python}} |
|||
<lang julia>using Printf |
|||
function _menu(items) |
|||
for (ind, item) in enumerate(items) |
|||
@printf " %2i) %s\n" ind item |
|||
end |
|||
end |
|||
_ok(::Any,::Any) = false |
|||
function _ok(reply::AbstractString, itemcount) |
|||
n = tryparse(Int, reply) |
|||
return isnull(n) || 0 ≤ get(n) ≤ itemcount |
|||
end |
|||
"Prompt to select an item from the items" |
|||
function _selector(items, prompt::AbstractString) |
|||
isempty(items) && return "" |
|||
reply = -1 |
|||
itemcount = length(items) |
|||
while !_ok(reply, itemcount) |
|||
_menu(items) |
|||
print(prompt) |
|||
reply = strip(readline(STDIN)) |
|||
end |
|||
return items[parse(Int, reply)] |
|||
end |
|||
items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"] |
|||
item = _selector(items, "Which is from the three pigs: ") |
|||
println("You chose: ", item)</lang> |
|||
=={{header|Kotlin}}== |
|||
<lang scala>// version 1.1.2 |
|||
fun menu(list: List<String>): String { |
|||
if (list.isEmpty()) return "" |
|||
val n = list.size |
|||
while (true) { |
|||
println("\n M E N U\n") |
|||
for (i in 0 until n) println("${i + 1}: ${list[i]}") |
|||
print("\nEnter your choice 1 - $n : ") |
|||
val index = readLine()!!.toIntOrNull() |
|||
if (index == null || index !in 1..n) continue |
|||
return list[index - 1] |
|||
} |
|||
} |
|||
fun main(args: Array<String>) { |
|||
val list = listOf( |
|||
"fee fie", |
|||
"huff and puff", |
|||
"mirror mirror", |
|||
"tick tock" |
|||
) |
|||
val choice = menu(list) |
|||
println("\nYou chose : $choice") |
|||
}</lang> |
|||
Sample session: |
|||
{{out}} |
|||
<pre> |
|||
M E N U |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Enter your choice 1 - 4 : 0 |
|||
M E N U |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Enter your choice 1 - 4 : asdf |
|||
M E N U |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Enter your choice 1 - 4 : 2 |
|||
You chose : huff and puff |
|||
</pre> |
|||
=={{header|langur}}== |
|||
{{works with|langur|0.7.1}} |
|||
<lang langur>val .select = f(.entries) { |
|||
if not isArray(.entries): throw "invalid args" |
|||
if len(.entries) == 0: return ZLS |
|||
# print the menu |
|||
writeln join "\n", map(f $"\.i:2;: \.e;", .entries, 1..len .entries) |
|||
val .idx = toNumber read( |
|||
"Select entry #: ", |
|||
f(.x) { |
|||
if not matching(RE/^[0-9]+$/, .x): return false |
|||
val .y = toNumber .x |
|||
.y > 0 and .y <= len(.entries) |
|||
}, |
|||
"invalid selection\n", -1, |
|||
) |
|||
.entries[.idx] |
|||
} |
|||
writeln .select(["fee fie", "eat pi", "huff and puff", "tick tock"])</lang> |
|||
{{out}} |
|||
<pre> 1: fee fie |
|||
2: eat pi |
|||
3: huff and puff |
|||
4: tick tock |
|||
Select entry #: 7 |
|||
invalid selection |
|||
Select entry #: 2 |
|||
eat pi</pre> |
|||
=={{header|Logo}}== |
|||
{{incorrect|Logo|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
{{works with|UCB Logo}} |
|||
<lang logo>to select :prompt [:options] |
|||
foreach :options [(print # ?)] |
|||
forever [ |
|||
type :prompt type "| | |
|||
make "n readword |
|||
if (and [number? :n] [:n >= 1] [:n <= count :options]) [output item :n :options] |
|||
print sentence [Must enter a number between 1 and] count :options |
|||
] |
|||
end |
|||
print equal? [huff and puff] (select |
|||
[Which is from the three pigs?] |
|||
[fee fie] [huff and puff] [mirror mirror] [tick tock]) |
|||
</lang> |
|||
=={{header|Lua}}== |
|||
<lang lua>function select (list) |
|||
if not list or #list == 0 then |
|||
return "" |
|||
end |
|||
local last, sel = #list |
|||
repeat |
|||
for i,option in ipairs(list) do |
|||
io.write(i, ". ", option, "\n") |
|||
end |
|||
io.write("Choose an item (1-", tostring(last), "): ") |
|||
sel = tonumber(string.match(io.read("*l"), "^%d+$")) |
|||
until type(sel) == "number" and sel >= 1 and sel <= last |
|||
return list[math.floor(sel)] |
|||
end |
|||
print("Nothing:", select {}) |
|||
print() |
|||
print("You chose:", select {"fee fie", "huff and puff", "mirror mirror", "tick tock"})</lang> |
|||
{{out}} |
|||
<pre> |
|||
Nothing: |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Choose an item (1-4): 0 |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Choose an item (1-4): a |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Choose an item (1-4): 1.7 |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Choose an item (1-4): 10 |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Choose an item (1-4): 3 |
|||
You chose: mirror mirror |
|||
</pre> |
|||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
|||
'''Interpreter:''' Wolfram Desktop and Wolfram Desktop Kernel |
|||
{{works with|Wolfram Language|12}} |
|||
Redisplays the list of choices on every invalid input as per the task description. In the notebook interface (of Wolfram Desktop, at least), Print[] would most pragmatically be located outside of the loop because Input[] uses a dialog box. |
|||
<lang Mathematica>textMenu[data_List] := Module[{choice}, |
|||
If[Length@data == 0, Return@""]; |
|||
While[!(IntegerQ@choice && Length@data >= choice > 0), |
|||
MapIndexed[Print[#2[[1]], ") ", #1]&, data]; |
|||
choice = Input["Enter selection..."] |
|||
]; |
|||
data[[choice]] |
|||
]</lang> |
|||
{{out|Kernel (REPL) output|note=function definition omitted}} |
|||
<pre>Wolfram Desktop Kernel (using Wolfram Language 12.0.0) for Microsoft Windows (64-bit) |
|||
Copyright 1988-2019 Wolfram Research, Inc. |
|||
In[1]:= (*! ELIDED !*) |
|||
In[2]:= textMenu[{}] |
|||
Out[2]= |
|||
In[3]:= textMenu[{"fee fie", "huff and puff", "mirror mirror", "tick tock"}] |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Enter selection...0 |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Enter selection...5 |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Enter selection...-1 |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Enter selection...fee fie |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Enter selection...3 |
|||
Out[3]= mirror mirror</pre> |
|||
=={{header|MATLAB}}== |
|||
<lang MATLAB>function sucess = menu(list) |
|||
if numel(list) == 0 |
|||
sucess = ''; |
|||
return |
|||
end |
|||
while(true) |
|||
disp('Please select one of these options:'); |
|||
for i = (1:numel(list)) |
|||
disp([num2str(i) ') ' list{i}]); |
|||
end |
|||
disp([num2str(numel(list)+1) ') exit']); |
|||
try |
|||
key = input(':: '); |
|||
if key == numel(list)+1 |
|||
break |
|||
elseif (key > numel(list)) || (key < 0) |
|||
continue |
|||
else |
|||
disp(['-> ' list{key}]); |
|||
end |
|||
catch |
|||
continue |
|||
end |
|||
end |
|||
sucess = true; |
|||
end |
|||
</lang> |
|||
=={{header|min}}== |
|||
{{works with|min|0.19.3}} |
|||
min has an operator <code>choose</code> that nearly conforms to this task. The input list is altered so that the choice can be returned, and the empty list case is handled. |
|||
<lang min>( |
|||
:prompt =list |
|||
(list bool) |
|||
(list (' dup append) map prompt choose) |
|||
("") if |
|||
) :menu |
|||
("fee fie" "huff and puff" "mirror mirror" "tick tock") |
|||
"Enter an option" menu |
|||
"You chose: " print! puts!</lang> |
|||
{{out}} |
|||
<pre> |
|||
Enter an option |
|||
1 - fee fie |
|||
2 - huff and puff |
|||
3 - mirror mirror |
|||
4 - tick tock |
|||
Enter your choice (1 - 4): 5 |
|||
Invalid choice. |
|||
1 - fee fie |
|||
2 - huff and puff |
|||
3 - mirror mirror |
|||
4 - tick tock |
|||
Enter your choice (1 - 4): 1 |
|||
You chose: fee fie |
|||
</pre> |
|||
=={{header|Modula-2}}== |
|||
{{incorrect|Modula-2|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
<lang modula2>MODULE Menu; |
|||
FROM InOut IMPORT WriteString, WriteCard, WriteLn, ReadCard; |
|||
CONST StringLength = 100; |
|||
MenuSize = 4; |
|||
TYPE String = ARRAY[0..StringLength-1] OF CHAR; |
|||
VAR menu : ARRAY[0..MenuSize] OF String; |
|||
selection, index : CARDINAL; |
|||
BEGIN |
|||
menu[1] := "fee fie"; |
|||
menu[2] := "huff and puff"; |
|||
menu[3] := "mirror mirror"; |
|||
menu[4] := "tick tock"; |
|||
FOR index := 1 TO HIGH(menu) DO |
|||
WriteString("["); |
|||
WriteCard( index,1); |
|||
WriteString( "] "); |
|||
WriteString( menu[index]); |
|||
WriteLn; |
|||
END;(*of FOR*) |
|||
WriteString("Choose what you want : "); |
|||
ReadCard(selection); |
|||
IF (selection <= HIGH(menu)) AND (selection > 0) THEN |
|||
WriteString("You have chosen: "); |
|||
WriteString( menu[selection]); |
|||
WriteLn; |
|||
ELSE |
|||
WriteString("Selection is out of range!"); |
|||
WriteLn; |
|||
END (*of IF*) |
|||
END Menu.</lang> |
|||
=={{header|MUMPS}}== |
|||
<lang MUMPS>MENU(STRINGS,SEP) |
|||
;http://rosettacode.org/wiki/Menu |
|||
NEW I,A,MAX |
|||
;I is a loop variable |
|||
;A is the string read in from the user |
|||
;MAX is the number of substrings in the STRINGS list |
|||
;SET STRINGS="fee fie^huff and puff^mirror mirror^tick tock" |
|||
SET MAX=$LENGTH(STRINGS,SEP) |
|||
QUIT:MAX=0 "" |
|||
WRITEMENU |
|||
FOR I=1:1:MAX WRITE I,": ",$PIECE(STRINGS,SEP,I),! |
|||
READ:30 !,"Choose a string by its index: ",A,! |
|||
IF (A<1)!(A>MAX)!(A\1'=A) GOTO WRITEMENU |
|||
KILL I,MAX |
|||
QUIT $PIECE(STRINGS,SEP,A)</lang> |
|||
Usage:<pre> |
|||
USER>W !,$$MENU^ROSETTA("fee fie^huff and puff^mirror mirror^tick tock","^") |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Choose a string by its index: 3 |
|||
mirror mirror |
|||
USER>W !,$$MENU^ROSETTA("fee fie^huff and puff^mirror mirror^tick tock","^") |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Choose a string by its index: 5 |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Choose a string by its index: A |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Choose a string by its index: 0 |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Choose a string by its index: 1 |
|||
fee fie |
|||
</pre> |
|||
=={{header|Nanoquery}}== |
|||
{{trans|Ursa}} |
|||
<lang Nanoquery>def _menu($items) |
|||
for ($i = 0) ($i < len($items)) ($i = $i + 1) |
|||
println " " + $i + ") " + $items[$i] |
|||
end |
|||
end |
|||
def _ok($reply, $itemcount) |
|||
try |
|||
$n = int($reply) |
|||
return (($n >= 0) && ($n < $itemcount)) |
|||
catch |
|||
return $false |
|||
end |
|||
end |
|||
def selector($items, $pmt) |
|||
// Prompt to select an item from the items |
|||
if (len($items) = 0) |
|||
return "" |
|||
end |
|||
$reply = -1 |
|||
$itemcount = len($items) |
|||
while !_ok($reply, $itemcount) |
|||
_menu($items) |
|||
println $pmt |
|||
$reply = int(input()) |
|||
end |
|||
return $items[$reply] |
|||
end |
|||
$items = list() |
|||
append $items "fee fie" "huff and puff" "mirror mirror" "tick tock" |
|||
$item = selector($items, "Which is from the three pigs: ") |
|||
println "You chose: " + $item</lang> |
|||
=={{header|Nim}}== |
|||
{{trans|Python}} |
|||
<lang nim>import strutils, rdstdin |
|||
proc menu(xs: openArray[string]) = |
|||
for i, x in xs: echo " ", i, ") ", x |
|||
proc ok(reply: string; count: Positive): bool = |
|||
try: |
|||
let n = parseInt(reply) |
|||
return 0 <= n and n < count |
|||
except: return false |
|||
proc selector(xs: openArray[string]; prompt: string): string = |
|||
if xs.len == 0: return "" |
|||
var reply = "-1" |
|||
while not ok(reply, xs.len): |
|||
menu(xs) |
|||
reply = readLineFromStdin(prompt).strip() |
|||
return xs[parseInt(reply)] |
|||
const xs = ["fee fie", "huff and puff", "mirror mirror", "tick tock"] |
|||
let item = selector(xs, "Which is from the three pigs: ") |
|||
echo "You chose: ", item</lang> |
|||
{{out}} |
|||
<pre> 0) fee fie |
|||
1) huff and puff |
|||
2) mirror mirror |
|||
3) tick tock |
|||
Which is from the three pigs: foo |
|||
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: 2 |
|||
You chose: mirror mirror</pre> |
|||
=={{header|OCaml}}== |
|||
<lang ocaml> |
|||
let select ?(prompt="Choice? ") = function |
|||
| [] -> "" |
|||
| choices -> |
|||
let rec menu () = |
|||
List.iteri (Printf.printf "%d: %s\n") choices; |
|||
print_string prompt; |
|||
try List.nth choices (read_int ()) |
|||
with _ -> menu () |
|||
in menu () |
|||
</lang> |
|||
Example use in the REPL: |
|||
<lang ocaml> |
|||
# select ["fee fie"; "huff and puff"; "mirror mirror"; "tick tock"];; |
|||
0: fee fie |
|||
1: huff and puff |
|||
2: mirror mirror |
|||
3: tick tock |
|||
Choice? 2 |
|||
- : string = "mirror mirror" |
|||
</lang> |
|||
=={{header|OpenEdge/Progress}}== |
|||
<lang progress>FUNCTION bashMenu RETURNS CHAR( |
|||
i_c AS CHAR |
|||
): |
|||
DEF VAR ii AS INT. |
|||
DEF VAR hfr AS HANDLE. |
|||
DEF VAR hmenu AS HANDLE EXTENT. |
|||
DEF VAR ikey AS INT. |
|||
DEF VAR ireturn AS INT INITIAL ?. |
|||
EXTENT( hmenu ) = NUM-ENTRIES( i_c ). |
|||
CREATE FRAME hfr ASSIGN |
|||
WIDTH = 80 |
|||
HEIGHT = NUM-ENTRIES( i_c ) |
|||
PARENT = CURRENT-WINDOW |
|||
VISIBLE = TRUE |
|||
. |
|||
DO ii = 1 TO NUM-ENTRIES( i_c ): |
|||
CREATE TEXT hmenu ASSIGN |
|||
FRAME = hfr |
|||
FORMAT = "x(79)" |
|||
SCREEN-VALUE = SUBSTITUTE( "&1. &2", ii, ENTRY( ii, i_c ) ) |
|||
ROW = ii |
|||
VISIBLE = TRUE |
|||
. |
|||
END. |
|||
IF i_c = "" THEN |
|||
ireturn = 1. |
|||
DO WHILE ireturn = ?: |
|||
READKEY. |
|||
ikey = INTEGER( CHR( LASTKEY ) ) NO-ERROR. |
|||
IF ikey >= 1 AND ikey <= NUM-ENTRIES( i_c ) THEN |
|||
ireturn = ikey. |
|||
END. |
|||
RETURN ENTRY( ireturn, i_c ). |
|||
END FUNCTION. |
|||
MESSAGE |
|||
bashMenu( "fee fie,huff and puff,mirror mirror,tick tock" ) |
|||
VIEW-AS ALERT-BOX.</lang> |
|||
=={{header|Oz}}== |
|||
<lang oz>declare |
|||
fun {Select Prompt Items} |
|||
case Items of nil then "" |
|||
else |
|||
for |
|||
Item in Items |
|||
Index in 1..{Length Items} |
|||
do |
|||
{System.showInfo Index#") "#Item} |
|||
end |
|||
{System.printInfo Prompt} |
|||
try |
|||
{Nth Items {ReadInt}} |
|||
catch _ then |
|||
{Select Prompt Items} |
|||
end |
|||
end |
|||
end |
|||
fun {ReadInt} |
|||
class TextFile from Open.file Open.text end |
|||
StdIo = {New TextFile init(name:stdin)} |
|||
in |
|||
{String.toInt {StdIo getS($)}} |
|||
end |
|||
Item = {Select "Which is from the three pigs: " |
|||
["fee fie" "huff and puff" "mirror mirror" "tick tock"]} |
|||
in |
|||
{System.showInfo "You chose: "#Item}</lang> |
|||
=={{header|PARI/GP}}== |
|||
{{incorrect|PARI/GP|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
<lang parigp>choose(v)=my(n);for(i=1,#v,print(i". "v[i]));while(type(n=input())!="t_INT"|n>#v|n<1,);v[n] |
|||
choose(["fee fie","huff and puff","mirror mirror","tick tock"])</lang> |
|||
=={{header|Pascal}}== |
|||
{{works with|Free_Pascal}} |
|||
Tested with Free Pascal 2.6.4 (arm). |
|||
<lang pascal>program Menu; |
|||
{$ASSERTIONS ON} |
|||
uses |
|||
objects; |
|||
var |
|||
MenuItems :PUnSortedStrCollection; |
|||
selected :string; |
|||
Function SelectMenuItem(MenuItems :PUnSortedStrCollection):string; |
|||
var |
|||
i, idx :integer; |
|||
code :word; |
|||
choice :string; |
|||
begin |
|||
// Return empty string if the collection is empty. |
|||
if MenuItems^.Count = 0 then |
|||
begin |
|||
SelectMenuItem := ''; |
|||
Exit; |
|||
end; |
|||
repeat |
|||
for i:=0 to MenuItems^.Count-1 do |
|||
begin |
|||
writeln(i+1:2, ') ', PString(MenuItems^.At(i))^); |
|||
end; |
|||
write('Make your choice: '); |
|||
readln(choice); |
|||
// Try to convert choice to an integer. |
|||
// Code contains 0 if this was successful. |
|||
val(choice, idx, code) |
|||
until (code=0) and (idx>0) and (idx<=MenuItems^.Count); |
|||
// Return the selected element. |
|||
SelectMenuItem := PString(MenuItems^.At(idx-1))^; |
|||
end; |
|||
begin |
|||
// Create an unsorted string collection for the menu items. |
|||
MenuItems := new(PUnSortedStrCollection, Init(10, 10)); |
|||
// Add some menu items to the collection. |
|||
MenuItems^.Insert(NewStr('fee fie')); |
|||
MenuItems^.Insert(NewStr('huff and puff')); |
|||
MenuItems^.Insert(NewStr('mirror mirror')); |
|||
MenuItems^.Insert(NewStr('tick tock')); |
|||
// Display the menu and get user input. |
|||
selected := SelectMenuItem(MenuItems); |
|||
writeln('You chose: ', selected); |
|||
dispose(MenuItems, Done); |
|||
// Test function with an empty collection. |
|||
MenuItems := new(PUnSortedStrCollection, Init(10, 10)); |
|||
selected := SelectMenuItem(MenuItems); |
|||
// Assert that the function returns an empty string. |
|||
assert(selected = '', 'Assertion failed: the function did not return an empty string.'); |
|||
dispose(MenuItems, Done); |
|||
end.</lang> |
|||
{{out}} |
|||
<pre> |
|||
$ bin/menu |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Make your choice: abc |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Make your choice: 99 |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Make your choice: 3 |
|||
You chose: mirror mirror |
|||
</pre> |
|||
=={{header|Perl}}== |
|||
<lang perl>sub menu |
|||
{ |
|||
my ($prompt,@array) = @_; |
|||
return '' unless @array; |
|||
print " $_: $array[$_]\n" for(0..$#array); |
|||
print $prompt; |
|||
$n = <>; |
|||
return $array[$n] if $n =~ /^\d+$/ and defined $array[$n]; |
|||
return &menu($prompt,@array); |
|||
} |
|||
@a = ('fee fie', 'huff and puff', 'mirror mirror', 'tick tock'); |
|||
$prompt = 'Which is from the three pigs: '; |
|||
$a = &menu($prompt,@a); |
|||
print "You chose: $a\n";</lang> |
|||
=={{header|Phix}}== |
|||
<lang Phix>function menu_select(sequence items, object prompt) |
|||
sequence res = "" |
|||
items = remove_all("",items) |
|||
if length(items)!=0 then |
|||
while 1 do |
|||
for i=1 to length(items) do |
|||
printf(1,"%d) %s\n",{i,items[i]}) |
|||
end for |
|||
puts(1,iff(atom(prompt)?"Choice?":prompt)) |
|||
res = scanf(trim(gets(0)),"%d") |
|||
puts(1,"\n") |
|||
if length(res)=1 then |
|||
integer nres = res[1][1] |
|||
if nres>0 and nres<=length(items) then |
|||
res = items[nres] |
|||
exit |
|||
end if |
|||
end if |
|||
end while |
|||
end if |
|||
return res |
|||
end function |
|||
constant items = {"fee fie", "huff and puff", "mirror mirror", "tick tock"} |
|||
constant prompt = "Which is from the three pigs? " |
|||
string res = menu_select(items,prompt) |
|||
printf(1,"You chose %s.\n",{res})</lang> |
|||
=={{header|PHP}}== |
|||
<lang php><?php |
|||
$stdin = fopen("php://stdin", "r"); |
|||
$allowed = array(1 => 'fee fie', 'huff and puff', 'mirror mirror', 'tick tock'); |
|||
for(;;) { |
|||
foreach ($allowed as $id => $name) { |
|||
echo " $id: $name\n"; |
|||
} |
|||
echo "Which is from the four pigs: "; |
|||
$stdin_string = fgets($stdin, 4096); |
|||
if (isset($allowed[(int) $stdin_string])) { |
|||
echo "You chose: {$allowed[(int) $stdin_string]}\n"; |
|||
break; |
|||
} |
|||
}</lang> |
|||
=={{header|PicoLisp}}== |
|||
<lang PicoLisp>(de choose (Prompt Items) |
|||
(use N |
|||
(loop |
|||
(for (I . Item) Items |
|||
(prinl I ": " Item) ) |
|||
(prin Prompt " ") |
|||
(flush) |
|||
(NIL (setq N (in NIL (read)))) |
|||
(T (>= (length Items) N 1) (prinl (get Items N))) ) ) ) |
|||
(choose "Which is from the three pigs?" |
|||
'("fee fie" "huff and puff" "mirror mirror" "tick tock") )</lang> |
|||
{{out}} |
|||
<pre> |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Which is from the three pigs? q |
|||
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 |
|||
</pre> |
|||
=={{header|PL/I}}== |
|||
{{incorrect|PL/I|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
<lang PL/I> |
|||
test: proc options (main); |
|||
declare menu(4) character(100) varying static initial ( |
|||
'fee fie', 'huff and puff', 'mirror mirror', 'tick tock'); |
|||
declare (i, k) fixed binary; |
|||
do i = lbound(menu,1) to hbound(menu,1); |
|||
put skip edit (trim(i), ': ', menu(i) ) (a); |
|||
end; |
|||
put skip list ('please choose an item number'); |
|||
get list (k); |
|||
if k >= lbound(menu,1) & k <= hbound(menu,1) then |
|||
put skip edit ('you chose ', menu(k)) (a); |
|||
else |
|||
put skip list ('Could not find your phrase'); |
|||
end test; |
|||
</lang> |
|||
=={{header|PowerShell}}== |
|||
<lang PowerShell> |
|||
function Select-TextItem |
|||
{ |
|||
<# |
|||
.SYNOPSIS |
|||
Prints a textual menu formatted as an index value followed by its corresponding string for each object in the list. |
|||
.DESCRIPTION |
|||
Prints a textual menu formatted as an index value followed by its corresponding string for each object in the list; |
|||
Prompts the user to enter a number; |
|||
Returns an object corresponding to the selected index number. |
|||
.PARAMETER InputObject |
|||
An array of objects. |
|||
.PARAMETER Prompt |
|||
The menu prompt string. |
|||
.EXAMPLE |
|||
“fee fie”, “huff and puff”, “mirror mirror”, “tick tock” | Select-TextItem |
|||
.EXAMPLE |
|||
“huff and puff”, “fee fie”, “tick tock”, “mirror mirror” | Sort-Object | Select-TextItem -Prompt "Select a string" |
|||
.EXAMPLE |
|||
Select-TextItem -InputObject (Get-Process) |
|||
.EXAMPLE |
|||
(Get-Process | Where-Object {$_.Name -match "notepad"}) | Select-TextItem -Prompt "Select a Process" | Stop-Process -ErrorAction SilentlyContinue |
|||
#> |
|||
[CmdletBinding()] |
|||
Param |
|||
( |
|||
[Parameter(Mandatory=$true, |
|||
ValueFromPipeline=$true)] |
|||
$InputObject, |
|||
[Parameter(Mandatory=$false)] |
|||
[string] |
|||
$Prompt = "Enter Selection" |
|||
) |
|||
Begin |
|||
{ |
|||
$menuOptions = @() |
|||
} |
|||
Process |
|||
{ |
|||
$menuOptions += $InputObject |
|||
} |
|||
End |
|||
{ |
|||
if(!$inputObject){ |
|||
return "" |
|||
} |
|||
do |
|||
{ |
|||
[int]$optionNumber = 1 |
|||
foreach ($option in $menuOptions) |
|||
{ |
|||
Write-Host ("{0,3}: {1}" -f $optionNumber,$option) |
|||
$optionNumber++ |
|||
} |
|||
Write-Host ("{0,3}: {1}" -f 0,"To cancel") |
|||
$choice = Read-Host $Prompt |
|||
$selectedValue = "" |
|||
if ($choice -gt 0 -and $choice -le $menuOptions.Count) |
|||
{ |
|||
$selectedValue = $menuOptions[$choice - 1] |
|||
} |
|||
} |
|||
until ($choice -match "^[0-9]+$" -and ($choice -eq 0 -or $choice -le $menuOptions.Count)) |
|||
return $selectedValue |
|||
} |
|||
} |
|||
“fee fie”, “huff and puff”, “mirror mirror”, “tick tock” | Select-TextItem -Prompt "Select a string" |
|||
</lang> |
|||
{{Out}} |
|||
<pre> |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
0: To cancel |
|||
Select a string: 3 |
|||
mirror mirror |
|||
</pre> |
|||
=={{header|ProDOS}}== |
|||
{{incorrect|ProDOS|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
<lang> |
|||
:a |
|||
printline ==========MENU========== |
|||
printline 1. Fee Fie |
|||
printline 2. Huff Puff |
|||
printline 3. Mirror, Mirror |
|||
printline 4. Tick, Tock |
|||
editvar /newvar /value=a /userinput=1 /title=What page do you want to go to? |
|||
if -a- /hasvalue 1 printline You chose a line from the book Jack and the Beanstalk. & exitcurrentprogram 1 |
|||
if -a- /hasvalue 2 printline You chose a line from the book The Three Little Pigs. & exitcurrentprogram 1 |
|||
if -a- /hasvalue 3 printline You chose a line from the book Snow White. & exitcurrentprogram 1 |
|||
if -a- /hasvalue 4 printline You chose a line from the book Beauty and the Beast. & exitcurrentprogram 1 |
|||
printline You either chose an invalid choice or didn't chose. |
|||
editvar /newvar /value=goback /userinput=1 /title=Do you want to chose something else? |
|||
if -goback- /hasvalue y goto :a else exitcurrentprogram 1 </lang> |
|||
=={{header|Prolog}}== |
|||
{{works with|SWI-Prolog|6}} |
|||
<lang prolog> |
|||
rosetta_menu([], "") :- !. %% Incase of an empty list. |
|||
rosetta_menu(Items, SelectedItem) :- |
|||
repeat, %% Repeat until everything that follows is true. |
|||
display_menu(Items), %% IO |
|||
get_choice(Choice), %% IO |
|||
number(Choice), %% True if Choice is a number. |
|||
nth1(Choice, Items, SelectedItem), %% True if SelectedItem is the 1-based nth member of Items, (fails if Choice is out of range) |
|||
!. |
|||
display_menu(Items) :- |
|||
nl, |
|||
foreach( nth1(Index, Items, Item), |
|||
format('~w) ~s~n', [Index, Item]) ). |
|||
get_choice(Choice) :- |
|||
prompt1('Select a menu item by number:'), |
|||
read(Choice). |
|||
</lang> |
|||
Example run: |
|||
<lang prolog> |
|||
?- rosetta_menu(["fee fie", "huff and puff", "mirror mirror", "tick tock"], String). |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Select a menu item by number:a. |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Select a menu item by number:10. |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Select a menu item by number:3. |
|||
String = "mirror mirror". |
|||
</lang> |
|||
=={{header|PureBasic}}== |
|||
<lang PureBasic>If OpenConsole() |
|||
Define i, txt$, choice |
|||
Dim txts.s(4) |
|||
EnableGraphicalConsole(1) ;- Enable graphical mode in the console |
|||
Repeat |
|||
ClearConsole() |
|||
Restore TheStrings ; Set reads address |
|||
For i=1 To 4 |
|||
Read.s txt$ |
|||
txts(i)=txt$ |
|||
ConsoleLocate(3,i): Print(Str(i)+": "+txt$) |
|||
Next |
|||
ConsoleLocate(3,6): Print("Your choice? ") |
|||
choice=Val(Input()) |
|||
Until choice>=1 And choice<=4 |
|||
ClearConsole() |
|||
ConsoleLocate(3,2): Print("You chose: "+txts(choice)) |
|||
; |
|||
;-Now, wait for the user before ending to allow a nice presentation |
|||
ConsoleLocate(3,5): Print("Press ENTER to quit"): Input() |
|||
EndIf |
|||
End |
|||
DataSection |
|||
TheStrings: |
|||
Data.s "fee fie", "huff And puff", "mirror mirror", "tick tock" |
|||
EndDataSection</lang> |
|||
=={{header|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: |
|||
<pre> 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</pre> |
|||
=={{header|R}}== |
|||
Uses [http://www.stat.ucl.ac.be/ISdidactique/Rhelp/library/base/html/menu.html menu]. |
|||
<lang R>showmenu <- function(choices = NULL) |
|||
{ |
|||
if (is.null(choices)) return("") |
|||
ans <- menu(choices) |
|||
if(ans==0) "" else choices[ans] |
|||
} |
|||
str <- showmenu(c("fee fie", "huff and puff", "mirror mirror", "tick tock")) |
|||
str <- showmenu() |
|||
</lang> |
|||
=={{header|Racket}}== |
|||
<lang Racket> |
|||
#lang racket |
|||
(define (menu choices) |
|||
(cond [(null? choices) ""] |
|||
[else (for ([c choices] [i (in-naturals 1)]) (printf "~a. ~a\n" i c)) |
|||
(printf "Enter a number: ") |
|||
(define n (string->number (read-line))) |
|||
(or (and (exact-integer? n) |
|||
(<= 1 n (length choices)) |
|||
(list-ref choices (sub1 n))) |
|||
(menu choices))])) |
|||
(menu '("fee fie" "huff and puff" "mirror mirror" "tick tock")) |
|||
</lang> |
|||
Sample Run: |
|||
<pre> |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Enter a number: three |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Enter a number: help |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Enter a number: 3!! |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Enter a number: 3 |
|||
"mirror mirror" |
|||
</pre> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<lang perl6>sub menu ( $prompt, @items ) { |
|||
return '' unless @items.elems; |
|||
repeat until my $selection ~~ /^ \d+ $/ && @items[--$selection] { |
|||
my $i = 1; |
|||
say " {$i++}) $_" for @items; |
|||
$selection = prompt $prompt; |
|||
} |
|||
return @items[$selection]; |
|||
} |
|||
my @choices = 'fee fie', 'huff and puff', 'mirror mirror', 'tick tock'; |
|||
my $prompt = 'Enter the number corresponding to your selection: '; |
|||
my $answer = menu( $prompt, [] ); |
|||
say "You chose: $answer" if $answer.chars; |
|||
$answer = menu( $prompt, @choices ); |
|||
say "You chose: $answer" if $answer.chars;</lang> |
|||
=={{header|REBOL}}== |
|||
{{incorrect|REBOL|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
<lang REBOL>REBOL [ |
|||
Title: "Text Menu" |
|||
URL: http://rosettacode.org/wiki/Select |
|||
] |
] |
||
menu ["fee fie" "huff and puff" "mirror mirror" "tick tock"]</lang> |
|||
choice: "" |
|||
valid?: func [ |
|||
choices [block! list! series!] |
|||
choice |
|||
][ |
|||
if error? try [choice: to-integer choice] [return false] |
|||
all [0 < choice choice <= length? choices] |
|||
] |
|||
while [not valid? choices choice][ |
|||
repeat i length? choices [print [" " i ":" choices/:i]] |
|||
choice: ask "Which is from the three pigs? " |
|||
] |
|||
print ["You chose:" pick choices to-integer choice]</lang> |
|||
Output: |
|||
<pre> 1 : fee fie |
|||
2 : huff and puff |
|||
3 : mirror mirror |
|||
4 : tick tock |
|||
Which is from the three pigs? klf |
|||
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 |
|||
You chose: huff and puff</pre> |
|||
=={{header|Red}}== |
|||
<lang Red>Red ["text menu"] |
|||
menu: function [items][ |
|||
print either empty? items [""] [until [ |
|||
repeat n length? items [print [n ":" items/:n]] |
|||
attempt [pick items to-integer ask "Your choice: "] |
|||
]] |
|||
]</lang> |
|||
{{out}} |
|||
<pre>>> menu ["fee fie" "huff and puff" "mirror mirror" "tick tock"] |
|||
1 : fee fie |
|||
2 : huff and puff |
|||
3 : mirror mirror |
|||
4 : tick tock |
|||
Your choice: azerty |
|||
1 : fee fie |
|||
2 : huff and puff |
|||
3 : mirror mirror |
|||
4 : tick tock |
|||
Your choice: 7 |
|||
1 : fee fie |
|||
2 : huff and puff |
|||
3 : mirror mirror |
|||
4 : tick tock |
|||
Your choice: 3 |
|||
mirror mirror |
|||
>> menu [] |
|||
>> </pre> |
|||
=={{header|REXX}}== |
|||
<lang rexx>/*REXX program displays a list, then prompts the user for a selection number (integer).*/ |
|||
do forever /*keep prompting until response is OK. */ |
|||
call list_create /*create the list from scratch. */ |
|||
call list_show /*display (show) the list to the user.*/ |
|||
if #==0 then return '' /*if list is empty, then return null.*/ |
|||
say right(' choose an item by entering a number from 1 ───►' #, 70, '═') |
|||
parse pull x /*get the user's choice (if any). */ |
|||
select |
|||
when x='' then call sayErr "a choice wasn't entered" |
|||
when words(x)\==1 then call sayErr 'too many choices entered:' |
|||
when \datatype(x,'N') then call sayErr "the choice isn't numeric:" |
|||
when \datatype(x,'W') then call sayErr "the choice isn't an integer:" |
|||
when x<1 | x># then call sayErr "the choice isn't within range:" |
|||
otherwise leave /*this leaves the DO FOREVER loop.*/ |
|||
end /*select*/ |
|||
end /*forever*/ |
|||
/*user might've entered 2. or 003 */ |
|||
x=x/1 /*normalize the number (maybe). */ |
|||
say; say 'you chose item' x": " #.x |
|||
return #.x /*stick a fork in it, we're all done. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
list_create: #.1= 'fee fie' /*this is one method for list-building.*/ |
|||
#.2= 'huff and puff' |
|||
#.3= 'mirror mirror' |
|||
#.4= 'tick tock' |
|||
#=4 /*store the number of choices in # */ |
|||
return /*(above) is just one convention. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
list_show: say /*display a blank line. */ |
|||
do j=1 for # /*display the list of choices. */ |
|||
say '[item' j"] " #.j /*display item number with its choice. */ |
|||
end /*j*/ |
|||
say /*display another blank line. */ |
|||
return |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
sayErr: say; say '***error***' arg(1) x; say; return</lang> |
|||
{{out|output|text= (which includes what the user entered):}} |
|||
<pre> |
|||
[item 1] fee fie |
|||
[item 2] huff and puff |
|||
[item 3] mirror mirror |
|||
[item 4] tick tock |
|||
════════════════════ choose an item by entering a number from 1 ───► 4 |
|||
2 ◄■■■■■■■■■■■■■■■■■■■■■■ what the user entered at the terminal. |
|||
you chose item 2: huff and puff |
|||
</pre> |
|||
=={{header|Ring}}== |
|||
<lang ring> |
|||
aList = ["fee fie", "huff and puff", "mirror mirror", "tick tock"] |
|||
selected = menu(aList, "please make a selection: ") |
|||
see "" + selected + nl |
|||
func menu aList, prompt |
|||
ndex = 1 |
|||
while index>0 and index<=len(aList) |
|||
for index = 1 to len(aList) |
|||
if aList[index]!="" see "" + index + " : " + aList[index] + " " ok |
|||
next |
|||
see nl |
|||
see prompt |
|||
give select |
|||
index = number(select) |
|||
see "" + aList[index] + nl |
|||
if select!=string(index) index = -1 ok |
|||
if index>=0 if index<=len(aList) if aList[index]="" index = -1 ok ok ok |
|||
end |
|||
return aList[index] |
|||
</lang> |
|||
Output: |
|||
<pre> |
|||
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock |
|||
please make a selection: 2 |
|||
huff and puff |
|||
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock |
|||
please make a selection: 1 |
|||
fee fie |
|||
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock |
|||
please make a selection: 4 |
|||
tick tock |
|||
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock |
|||
please make a selection: 3 |
|||
mirror mirror |
|||
</pre> |
|||
=={{header|Ruby}}== |
|||
<lang ruby> |
|||
def select(prompt, items = []) |
|||
if items.empty? |
|||
'' |
|||
else |
|||
answer = -1 |
|||
until (0...items.length).cover?(answer) |
|||
items.each_with_index {|i,j| puts "#{j}. #{i}"} |
|||
print "#{prompt}: " |
|||
begin |
|||
answer = Integer(gets) |
|||
rescue ArgumentError |
|||
redo |
|||
end |
|||
end |
|||
items[answer] |
|||
end |
|||
end |
|||
# test empty list |
|||
response = select('Which is empty') |
|||
puts "empty list returns: >#{response}<\n" |
|||
# "real" test |
|||
items = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock'] |
|||
response = select('Which is from the three pigs', items) |
|||
puts "you chose: >#{response}<" |
|||
</lang> |
|||
=={{header|Run BASIC}}== |
|||
<lang runbasic>dim choose$(5) |
|||
choose$(1) = "1 Fee Fie" |
|||
choose$(2) = "2 Huff Puff" |
|||
choose$(3) = "3 Mirror, Mirror" |
|||
choose$(4) = "4 Tick, Tock" |
|||
choose$(5) = "Exit" |
|||
[start] |
|||
print "Menu Selection" |
|||
listbox #lb,choose$(),5 |
|||
button #sel, "Accept",[select] |
|||
wait |
|||
[select] |
|||
selected$=#lb selection$() |
|||
print " " |
|||
if selected$<>"" then |
|||
print "You selected ";selected$ |
|||
else |
|||
print "No selection made" |
|||
end if |
|||
button #con, "Continue",[go2] |
|||
wait |
|||
[go2] |
|||
if selected$<>"Exit" then |
|||
cls |
|||
goto [start] |
|||
else |
|||
cls |
|||
end |
|||
end if</lang> |
|||
=={{header|Rust}}== |
|||
<lang rust> |
|||
fn menu_select<'a>(items: &'a [&'a str]) -> &'a str { |
|||
if items.len() == 0 { |
|||
return ""; |
|||
} |
|||
let stdin = std::io::stdin(); |
|||
let mut buffer = String::new(); |
|||
loop { |
|||
for (i, item) in items.iter().enumerate() { |
|||
println!("{}) {}", i + 1, item); |
|||
} |
|||
print!("Pick a number from 1 to {}: ", items.len()); |
|||
// Read the user input: |
|||
stdin.read_line(&mut buffer).unwrap(); |
|||
println!(); |
|||
if let Ok(selected_index) = buffer.trim().parse::<usize>() { |
|||
if 0 < selected_index { |
|||
if let Some(selected_item) = items.get(selected_index - 1) { |
|||
return selected_item; |
|||
} |
|||
} |
|||
} |
|||
// The buffer will contain the old input, so we need to clear it before we can reuse it. |
|||
buffer.clear(); |
|||
} |
|||
} |
|||
fn main() { |
|||
// Empty list: |
|||
let selection = menu_select(&[]); |
|||
println!("No choice: {:?}", selection); |
|||
// List with items: |
|||
let items = [ |
|||
"fee fie", |
|||
"huff and puff", |
|||
"mirror mirror", |
|||
"tick tock", |
|||
]; |
|||
let selection = menu_select(&items); |
|||
println!("You chose: {}", selection); |
|||
} |
|||
</lang> |
|||
=={{header|Scala}}== |
|||
===Scala idiom (Functional)=== |
|||
<lang>import scala.util.Try |
|||
object Menu extends App { |
|||
val choice = menu(list) |
|||
def menu(menuList: Seq[String]): String = { |
|||
if (menuList.isEmpty) "" else { |
|||
val n = menuList.size |
|||
def getChoice: Try[Int] = { |
|||
println("\n M E N U\n") |
|||
menuList.zipWithIndex.map { case (text, index) => s"${index + 1}: $text" }.foreach(println(_)) |
|||
print(s"\nEnter your choice 1 - $n : ") |
|||
Try { |
|||
io.StdIn.readInt() |
|||
} |
|||
} |
|||
menuList(Iterator.continually(getChoice) |
|||
.dropWhile(p => p.isFailure || !(1 to n).contains(p.get)) |
|||
.next.get - 1) |
|||
} |
|||
} |
|||
def list = Seq("fee fie", "huff and puff", "mirror mirror", "tick tock") |
|||
println(s"\nYou chose : $choice") |
|||
}</lang> |
|||
=={{header|Seed7}}== |
|||
<lang seed7>$ include "seed7_05.s7i"; |
|||
const func string: menuSelect (in array string: items, in string: prompt) is func |
|||
result |
|||
var string: selection is ""; |
|||
local |
|||
var string: item is ""; |
|||
var integer: index is 0; |
|||
var integer: num is 0; |
|||
begin |
|||
if length(items) <> 0 then |
|||
repeat |
|||
for item key index range items do |
|||
writeln(index <& ". " <& item); |
|||
end for; |
|||
write(prompt); |
|||
readln(num); |
|||
until num >= 1 and num <= length(items); |
|||
selection := items[num]; |
|||
end if |
|||
end func; |
|||
const array string: items is [] ("fee fie", "huff and puff", "mirror mirror", "tick tock"); |
|||
const string: prompt is "Which is from the three pigs? "; |
|||
const proc: main is func |
|||
begin |
|||
writeln("You chose " <& menuSelect(items, prompt)); |
|||
end func;</lang> |
|||
=={{header|Sidef}}== |
|||
<lang ruby>func menu (prompt, arr) { |
|||
arr.len > 0 || return '' |
|||
loop { |
|||
for i in ^arr { |
|||
say " #{i}: #{arr[i]}" |
|||
} |
|||
var n = Sys.scanln(prompt) \\ return() |
|||
n ~~ /^[0-9]+\z/ ? Num(n) : next |
|||
arr.exists(n) && return arr[n] |
|||
} |
|||
} |
|||
var list = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock'] |
|||
var prompt = 'Please choose an item number: ' |
|||
var answer = menu(prompt, list) |
|||
say "You choose: #{answer}"</lang> |
|||
=={{header|Swift}}== |
|||
<lang swift>func getMenuInput(selections: [String]) -> String { |
|||
guard !selections.isEmpty else { |
|||
return "" |
|||
} |
|||
func printMenu() { |
|||
for (i, str) in selections.enumerated() { |
|||
print("\(i + 1)) \(str)") |
|||
} |
|||
print("Selection: ", terminator: "") |
|||
} |
|||
while true { |
|||
printMenu() |
|||
guard let input = readLine(strippingNewline: true), !input.isEmpty else { |
|||
return "" |
|||
} |
|||
guard let n = Int(input), n > 0, n <= selections.count else { |
|||
continue |
|||
} |
|||
return selections[n - 1] |
|||
} |
|||
} |
|||
let selected = getMenuInput(selections: [ |
|||
"fee fie", |
|||
"huff and puff", |
|||
"mirror mirror", |
|||
"tick tock" |
|||
]) |
|||
print("You chose: \(selected)")</lang> |
|||
=={{header|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> |
|||
=={{header|TI-83 BASIC}}== |
|||
TI-83 BASIC does not support lists of strings, so this works by accepting a string containing an arbitrary number of items separated by colons. If you want to use a different delimiter, change the colons on lines 2, 3, 6 and 7 to your symbol of choice. |
|||
The calculator's screen isn't big enough to display more than 7 (9 on the new C Silver Edition and CE calcs) options at a time, so the display scrolls to accommodate options if necessary. You won't be able to see options that have scrolled off the top of the screen, but they're still accessible from the input. |
|||
Although TI-BASIC ''can'' handle empty strings, there's no way to give it one through the Input function, so it doesn't have to worry about being "called with an empty list." |
|||
Input "",Str1 //input as ITEM 1:ITEM 2:ITEM 3... |
|||
":"+Str1+":→Str1 |
|||
Σ(sub(Str1,X,1)=":",X,1,length(Str1→X |
|||
0→dim(L₁ |
|||
For(Z,2,length(Str1 |
|||
inString(Str1,":",Z-1 |
|||
1+Ans+.01inString(Str1,":",Ans+1→L₁(1+dim(L₁ |
|||
ᴇ2fPart(Ans→Z |
|||
End |
|||
seq(iPart(L₁(X))+.01(ᴇ2fPart(L₁(X))-iPart(L₁(X))),X,1,dim(L₁→L₁ |
|||
Repeat A>0 and A<X |
|||
ClrHome |
|||
For(Z,1,dim(L₁ |
|||
Disp " :"+sub(Str1,iPart(L₁(Z)),ᴇ2fPart(L₁(Z |
|||
Output(min(7,Z),1+(Z≤7),Z |
|||
End |
|||
Input A |
|||
End |
|||
Disp sub(Str1,iPart(L₁(A)),ᴇ2fPart(L₁(A |
|||
Output with <tt>FEE FIE:HUFF AND PUFF:MIRROR MIRROR:TICK TOCK</tt> |
|||
<lang> 1:FEE FIE |
|||
2:HUFF AND PUFF |
|||
3:MIRROR MIRROR |
|||
4:TICK TOCK |
|||
? [flashing cursor]</lang> |
|||
The language also has a Menu( command, but it doesn't really follow the requirements for the challenge (only up to 7 options allowed, no user input, option is selected using the arrow keys instead of by entering a number, etc) |
|||
"FEE FIE→Str0 |
|||
"HUFF AND PUFF→Str1 |
|||
"MIRROR MIRROR→Str2 |
|||
"TICK TOCK→Str3 |
|||
Menu("CHOOSE",Str0,A,Str1,B,Str2,C,Str3,D) |
|||
Lbl A |
|||
Disp Str0 |
|||
Return |
|||
Lbl B |
|||
Disp Str1 |
|||
Return |
|||
Lbl C |
|||
Disp Str2 |
|||
Return |
|||
Lbl D |
|||
Disp Str3 |
|||
=={{header|UNIX Shell}}== |
|||
This example uses the [http://www.softpanorama.org/Scripting/Shellorama/Control_structures/select_statements.shtml Bash select statement], but Bash did not invent this feature. The ''select'' loop comes originally from the [[Korn Shell]], and appears in some other shells. This loop always continues to read menu choices until the script breaks the loop, or the standard input reaches end of file (EOF). |
|||
* If the user enters a blank line, the ''select'' loop repeats the list of choices. This is the only way to print the list again. An invalid choice only repeats the prompt, not the list. |
|||
Our ''choose'' function wraps a ''select'' loop. This wrapper implements the task requirement to provide an empty string from an empty list of choices. It also breaks the ''select'' loop after the first good choice. |
|||
{{works with|bash}} |
|||
{{works with|ksh93}} |
|||
{{works with|pdksh}} |
|||
{{works with|zsh}} |
|||
<lang bash># choose 'choice 1' 'choice 2' ... |
|||
# Prints menu to standard error. Prompts with PS3. |
|||
# Reads REPLY from standard input. Sets CHOICE. |
|||
choose() { |
|||
CHOICE= # Default CHOICE is empty string. |
|||
[[ $# -gt 0 ]] || return # Return if "$@" is empty. |
|||
select CHOICE; do # Select from "$@". |
|||
if [[ -n $CHOICE ]]; then |
|||
break |
|||
else |
|||
echo Invalid choice. |
|||
fi |
|||
done |
|||
} |
|||
PS3='Which is from the three pigs: ' |
|||
choose 'fee fie' 'huff and puff' 'mirror mirror' 'tick tock' |
|||
[[ -n $CHOICE ]] && echo You chose: $CHOICE |
|||
[[ -z $CHOICE ]] && echo No input.</lang> |
|||
<pre>$ bash menu.sh |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Which is from the three pigs: 5 |
|||
Invalid choice. |
|||
Which is from the three pigs: 2 |
|||
You chose: huff and puff |
|||
$</pre> |
|||
<pre>$ zsh menu.sh |
|||
1) fee fie 2) huff and puff 3) mirror mirror 4) tick tock |
|||
Which is from the three pigs: 2 |
|||
You chose: huff and puff</pre> |
|||
==={{header|es}}=== |
|||
{{incorrect|es|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}} |
|||
There is no ''select'' loop, but this ''es'' script provides just enough code to mimic one. |
|||
* ''Deviation from task:'' When the list of choices is empty, this function returns an empty list, not an empty string. |
|||
<lang es># choose 'choice 1' 'choice 2' ... |
|||
# Prints menu to standard error. Prompts with $prompt. |
|||
# Returns choice. If no input, returns empty list. |
|||
fn choose args { |
|||
# If args are empty, return empty list. |
|||
~ $#args 0 && return |
|||
# Echo to standard error. |
|||
let (reply =; choice =; fn-menu =; fn-ch =) >[1=2] { |
|||
fn-menu = { |
|||
# Show menu. |
|||
let (i = 1) for (c = $args) { |
|||
echo $i') '$c |
|||
i = `{expr $i + 1} |
|||
} |
|||
} |
|||
fn-ch = { |
|||
# Set choice = $args($reply), but ignore error |
|||
# if $reply is not a valid index. |
|||
choice = <={catch @ e {result} { |
|||
result $args($reply) |
|||
}} |
|||
} |
|||
menu |
|||
forever { |
|||
# Show prompt, read reply. |
|||
echo -n $prompt |
|||
reply = <={%read} |
|||
# If no input, return empty list. |
|||
~ $#reply 0 && return |
|||
# Parse reply and return choice. |
|||
reply = <={%split \ \t\n $reply} |
|||
if {~ $#reply 0} { |
|||
# Empty reply: show menu again. |
|||
menu |
|||
} {~ $#reply 1 && ch; ~ $#choice 1} { |
|||
return $choice |
|||
} { |
|||
echo Invalid choice. |
|||
} |
|||
} |
|||
} |
|||
} |
|||
let (choice = <={ |
|||
local (prompt = 'Which is from the three pigs: ') |
|||
choose 'fee fie' 'huff and puff' 'mirror mirror' 'tick tock' |
|||
}) { |
|||
~ $#choice 1 && echo You chose: $choice |
|||
~ $#choice 0 && echo No input. |
|||
}</lang> |
|||
<pre>$ es menu.es |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Which is from the three pigs: 2 |
|||
You chose: huff and puff</pre> |
|||
=={{header|Ursa}}== |
|||
{{trans|Python}} |
|||
<lang ursa>def _menu (string<> items) |
|||
for (decl int i) (< i (size items)) (inc i) |
|||
out " " i ") " items<i> endl console |
|||
end for |
|||
end _menu |
|||
def _ok (string reply, int itemcount) |
|||
try |
|||
decl int n |
|||
set n (int reply) |
|||
return (and (or (> n 0) (= n 0)) (< n itemcount)) |
|||
catch |
|||
return false |
|||
end try |
|||
end _ok |
|||
def selector (string<> items, string prompt) |
|||
# Prompt to select an item from the items |
|||
if (= (size items) 0) |
|||
return "" |
|||
end if |
|||
decl int itemcount reply |
|||
set reply -1 |
|||
set itemcount (size items) |
|||
while (not (_ok reply itemcount)) |
|||
_menu items |
|||
out prompt console |
|||
set reply (in int console) |
|||
end while |
|||
return items<(int reply)> |
|||
end selector |
|||
decl string<> items |
|||
append "fee fie" "huff and puff" "mirror mirror" "tick tock" items |
|||
decl string item |
|||
set item (selector items "Which is from the three pigs: ") |
|||
out "You chose: " item endl console</lang> |
|||
=={{header|VBScript}}== |
|||
<lang vb>'The Function |
|||
Function Menu(ArrList, Prompt) |
|||
Select Case False 'Non-standard usage hahaha |
|||
Case IsArray(ArrList) |
|||
Menu = "" 'Empty output string for non-arrays |
|||
Exit Function |
|||
Case UBound(ArrList) >= LBound(ArrList) |
|||
Menu = "" 'Empty output string for empty arrays |
|||
Exit Function |
|||
End Select |
|||
'Display menu and prompt |
|||
Do While True |
|||
For i = LBound(ArrList) To UBound(ArrList) |
|||
WScript.StdOut.WriteLine((i + 1) & ". " & ArrList(i)) |
|||
Next |
|||
WScript.StdOut.Write(Prompt) |
|||
Choice = WScript.StdIn.ReadLine |
|||
'Check if input is valid |
|||
If IsNumeric(Choice) Then 'Check for numeric-ness |
|||
If CStr(CLng(Choice)) = Choice Then 'Check for integer-ness (no decimal part) |
|||
Index = Choice - 1 'Arrays are 0-based |
|||
'Check if Index is in array |
|||
If LBound(ArrList) <= Index And Index <= UBound(ArrList) Then |
|||
Exit Do |
|||
End If |
|||
End If |
|||
End If |
|||
WScript.StdOut.WriteLine("Invalid choice.") |
|||
Loop |
|||
Menu = ArrList(Index) |
|||
End Function |
|||
'The Main Thing |
|||
Sample = Array("fee fie", "huff and puff", "mirror mirror", "tick tock") |
|||
InputText = "Which is from the three pigs: " |
|||
WScript.StdOut.WriteLine("Output: " & Menu(Sample, InputText))</lang> |
|||
{{Out}} |
|||
<pre>C:\>cscript /nologo menu.vbs |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Which is from the three pigs: cdsfklfm |
|||
Invalid choice. |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Which is from the three pigs: -2 |
|||
Invalid choice. |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Which is from the three pigs: 3.14159 |
|||
Invalid choice. |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Which is from the three pigs: 45 |
|||
Invalid choice. |
|||
1. fee fie |
|||
2. huff and puff |
|||
3. mirror mirror |
|||
4. tick tock |
|||
Which is from the three pigs: 2 |
|||
Output: huff and puff</pre> |
|||
=={{header|XPL0}}== |
|||
<lang XPL0>string 0; |
|||
func Menu(List); |
|||
int List; |
|||
int Size, I, C; |
|||
[Size:= List(0); |
|||
if Size < 1 then return List(0); \if empty list, return pointer to 0 |
|||
for I:= 1 to Size-1 do |
|||
[IntOut(0, I); Text(0, ": "); |
|||
Text(0, List(I)); CrLf(0); |
|||
]; |
|||
CrLf(0); |
|||
Text(0, List(Size)); \display prompt |
|||
loop [C:= ChIn(0); \buffered keyboard requires Enter key |
|||
if C>=^1 & C<=Size-1+^0 then return List(C-^0); |
|||
Text(0, "Please enter 1 thru "); IntOut(0, Size-1); |
|||
Text(0, ": "); |
|||
]; |
|||
]; |
|||
Text(0, Menu([5, "fee fie", "huff and puff", "mirror mirror", "tick tock", |
|||
"Which phrase is from the Three Little Pigs? "]))</lang> |
|||
Example output: |
|||
<pre> |
|||
1: fee fie |
|||
2: huff and puff |
|||
3: mirror mirror |
|||
4: tick tock |
|||
Which phrase is from the Three Little Pigs? 5 |
|||
Please enter 1 thru 4: 2 |
|||
huff and puff |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
<lang zkl>fcn teleprompter(options){ |
|||
os:=T("exit").extend(vm.arglist); N:=os.len(); |
|||
if(N==1) return(""); |
|||
while(1){ |
|||
Utils.zipWith(fcn(n,o){"%d) %s".fmt(n,o).println()},[0..],os); |
|||
a:=ask("Your choice: "); |
|||
try{ n:=a.toInt(); if(0<=n<N) return(os[n]); } catch{} |
|||
println("Ack, not good"); |
|||
} |
|||
} |
|||
teleprompter("fee fie" , "huff and puff" , "mirror mirror" , "tick tock") |
|||
.println();</lang> |
|||
{{out}} |
|||
<pre> |
|||
0) exit |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Your choice: abc |
|||
Ack, not good |
|||
0) exit |
|||
1) fee fie |
|||
2) huff and puff |
|||
3) mirror mirror |
|||
4) tick tock |
|||
Your choice: 3 |
|||
mirror mirror |
|||
</pre> |
|||
{{omit from|GUISS}} |