\documentclass[noanswers,addpoints,11pt]{exam}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage[most]{tcolorbox}
\usepackage{datetime}
\usepackage{enumerate}
\usepackage{xltxtra}
\usepackage{listings}

\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{makecell}
\usepackage{multicol}
\usepackage{multirow}

\usepackage{tabularx}
\usepackage{textcomp}
\usepackage{tikz}
\usetikzlibrary{arrows,automata,decorations.pathmorphing,backgrounds,positioning,fit}
\usepackage{pgf-umlcd}

\lstset{
  basicstyle=\ttfamily,
  language=java,
}

\newcommand{\checkpoint}{{\Large $\checkmark$} }

% classname
\newcommand\assignmentTitle{A Reusable \lstinline{Menu} Class}
\newcommand\semester{Fall 2023}
\newcommand\className{Computer Science III}
\newcommand\classNumber{CIS~205}
\newcommand\classFullName{\classNumber~\className}
\renewcommand{\dateseparator}{-}
\yyyymmdddate

% /classname

\pagestyle{headandfoot}
\firstpageheader{\classNumber\\\semester}{\assignmentTitle\\~}{\today\\~}
\runningheader{\assignmentTitle}{}{\today}

\newenvironment{showExample}[1]{
  \begingroup
  \renewcommand{\solutiontitle}{\noindent\textbf{Example:}\enspace}
  \printanswers
  \begin{solution}[#1]
  }{
  \end{solution}
  \endgroup
}

\definecolor{outputgray}{gray}{0.95}


\begin{document}
\pointsinrightmargin{}

\section*{Learning Outcomes}
Upon completing this assignment, students should be able to

\begin{itemize}
  \item Write a \emph{reusable} class that can easily be put into
    future projects.
  \item Implement an object, \lstinline{Menu}, that maintains a
    collection (list) of a \emph{hidden} \textbf{inner} object,
    \lstinline{MenuItem}. \textbf{(This is review.)}
  \item Read a \emph{file} with an arbitrary number of text
    descriptions of objects of a single type and insert them into a
    \lstinline{List}. \textbf{(This is review.)}
  \item Document a thorough test plan for a reusable object.
\end{itemize}

\section*{Introduction}
It would be nice to have a standard user interface (UI) for
interacting with our programs this semester. To that end, this first
assignment is to implement a \lstinline{Menu} class. The items in the
menu will be loaded at runtime rather than part of the program.

If this class is going to be used, over and over again, you need to
have confidence that it is not adding bugs to your later
programs. This requires testing that it works, which means
understanding what it \emph{should} do. And testing that it does just that.

\section*{Method}

\subsection*{Getting Started}

There will be three files in this program: \lstinline{Menu.java},
\lstinline{RunMenu.java}, and \lstinline{TestMenu.java}. Both
\lstinline{RunMenu} and \lstinline{TestMenu} will have
\lstinline{main} methods, one to run the actual program (which, in
this case, is not much more than doing really simple arithmetic) and
the other to do its best to automate some testing of \lstinline{Menu}.

\subsubsection*{\lstinline{Menu}}
The \lstinline{Menu} class is a wrapper around a \lstinline{List} (you
will use the \lstinline{ArrayList} implementation in the Java standard
library) of \lstinline{MenuItem} objects. The \lstinline{MenuItem}
class is an inner class of \lstinline{Menu} and should not leak to
other classes.

The primary constructor for \lstinline{Menu} should take a
\lstinline{Scanner} and read lines from it, using groups of lines to
create \lstinline{MenuEntry} objects. There should be a secondary
constructor that takes an \lstinline{InputStream} and wraps it in a
\lstinline{Scanner} before calling the primary constructor, something
like this:

\begin{lstlisting}
public Menu(InputStream in) {
  this(new Scanner(in));
}
\end{lstlisting}

(Remember that \lstinline{this}, treated as a function, as the
\emph{first} line of a constructor, calls another constructor. So, the
one taking an \lstinline{InputStream} does no work except make a
\lstinline{Scanner} for the primary constructor.)

The primary constructor will read triples of lines from the
\lstinline{Scanner}: the \lstinline{name} of the item, its
\lstinline{displayText} and its \lstinline{helpText}. When it gets a
pair, it should construct a new \lstinline{MenuItem} with those two
values and add it to its collection of \lstinline{items}.

\lstinline{Menu} has two public methods: \lstinline{match} and
\lstinline{help}.


\lstinline{String match(String prompt)} does the following:

\begin{lstlisting}[language={}]
display all items
prompt user for an item ->user_name
while (user_name is not the name of any item in the menu)
  print an error message
  prompt user for an item -> user_name

return user_name
\end{lstlisting}

Displaying an item is to print the name, a dash, and the display
text. Notice that \lstinline{match} will not return until the user
enters a valid name of one of the items. If there is more than one
item with a given name, that is not your problem.

\lstinline{void help()} will print each item (that is name, dash,
display text) and then, on the next line, indent the corresponding
help text four spaces.



\subsection*{Input/Output}
\subsubsection*{File Formats}

\lstinline{RunMenu} should initialize the menu with a text file that
looks like the following:

\begin{lstlisting}[language={}]
+
add
prompts for a number and adds it to the total so far
-
minus
prompts for a number and subtracts it from the total so far
0
zero
resets the total so far to zero
h
help
display this help screen
q
quit
quit the program
\end{lstlisting}

\subsubsection*{User Interface}
If \lstinline{match("Action? ")} is called on this menu, then the
following could be the user's interaction with it:

\begin{verbatim}
+ - add
- - minus
0 - zero
h - help
q - quit
Action? wombat
"wombat" fails to match.
Action? 2
"2" fails to match.
Action? 0
\end{verbatim}

And the call would return the string \lstinline{"0"}.

A call to \lstinline{help()} would produce something like

\begin{lstlisting}[language={}]
+ - add
    prompts for a number and adds it to the total so far
- - minus
    prompts for a number and subtracts it from the total so far
0 - zero
    resets the total so far to zero
h - help
    display this help screen
q - quit
    quit the program
\end{lstlisting}


\subsection*{Design Considerations}
Obviously \lstinline{RunMenu} should perform the action described in
the menu. So it should have an \lstinline{int} total value (initialize
it to zero) and update it as mentioned. For two of the choices you
will prompt the user for an \lstinline{int} and use that to change the
total.

\subsubsection*{Testing}
For the moment, you will supply some menu files for
\lstinline{TestMenu} to load and then prompt the actual user, making
notes (in \lstinline{README}) as to what to answer and what response
to expect.

Make sure the right thing happens when the input file is empty, has
one item, and has multiple items (these are constructor tests). Should
you ever call \lstinline{match} on an empty menu?

You should type out what should be seen for the calls to
\lstinline{match} and \lstinline{help} for your test menus.

We will work on \emph{automating} these tests soon.

\subsection*{Documentation}

\subsubsection*{\lstinline{README}}
Must document how you tested. How do you know that it is right?

Must include instructions on how to \textbf{compile} and how to
\textbf{run} the program as submitted.

\subsection*{Deliverables}
\textbf{Submission medium}: \lstinline{git} to Gitea at
\lstinline{cs-devel.potsdam.edu}.
\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
