The following example uses a uniquely named exception to indicate
that the user wishes to quit rather than supply input. We'll define our
own exception, and define function which rewrites a built-in exception
to be our own exception.
We'll define a function, ckyorn
, which does a
“Check for Y or N”. This function has two parameters,
prompt
and help
, that are used to
prompt the user and print help if the user requests it. In this case,
the return value is always a "Y" or "N". A request for help ("?") is
handled automatically. A request to quit is treated as an exception, and
leaves the normal execution flow. This function will accept "Q" or
end-of-file (usually Control-
D
, but
also Control-
Z
on Windows) as the
quit signal.
Example 17.4. interaction.py
class UserQuit( Exception ): pass
def ckyorn( prompt, help="" ):
ok= 0
while not ok:
try:
a=raw_input( prompt + " [y,n,q,?]: " )
except EOFError:
raise UserQuit
if a.upper() in [ 'Y', 'N', 'YES', 'NO' ]: ok= 1
if a.upper() in [ 'Q', 'QUIT' ]:
raise UserQuit
if a.upper() in [ '?' ]:
print help
return a.upper()[0]
We can use this function as shown in the following example.
import interaction
answer= interaction.ckyorn(
help= "Enter Y if finished entering data",
prompt= "All done?")
This function transforms an
EOFError
into a
UserQuit
exception, and also transforms a
user entry of "Q" or "q" into this same exception. In a longer program,
this exception permits a short-circuit of all further processing,
omitting some potentially complex
if
statements.
Details of the ckyorn
Function. Our function uses a loop that will terminate when we have
successfully interpreted an answer from the user. We may get a request
for help or perhaps some uninterpretable input from the user. We will
continue our loop until we get something meaningful. The post
condition will be that the variable ok
is set to
True and the answer, a
is one of ("Y",
"y", "N", "n")
.
Within the loop, we surround our raw_input
function with a
try
suite,. This allows us to process
any kind of input, including user inputs that raise exceptions. The most
common example is the user entering the end-of-file character on their
keyboard. For Linux it is control-
D
;
for Windows it is control-
Z
.
We handle EOFError
by raising our
UserQuit
exception. This separates
end-of-file on ordinary disk files elsewhere in the program from this
end-of-file generated from the user's keyboard. When we get end-of-file
from the user, we need to tidy up and exit the program promptly. When we
get end-of-file from an ordinary disk file, this will require different
processing.
If no exception was raised, we examine the input character to see
if we can interpret it. Note that if the user enters 'Q' or 'QUIT', we
treat this exactly like as an end-of-file; we raise the
UserQuit
exception so that the program
can tidy up and exit quickly.
We return a single-character result only for ordinary, valid user
inputs. A user request to quit is considered extraordinary, and we raise
an exception for that.