W1161 Basic Input

From Coder Merlin
Revision as of 18:16, 24 September 2022 by Jeff-strong (talk | contribs) (Editorial review and minor corrections)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder
IBM 1402 Card Punch Input

Prerequisites[edit]

Introduction[edit]

The programs that we've written so far have not involved input provided by humans. Either the data were hard-coded before the program was executed or they were established immediately before execution by  Merlin Mission Manager . Hard-coded data means that the data in question is embedded in the program as "code" and consequently cannot be changed without altering the program itself. While there are some circumstances in which this is sufficient (consider physical constants such as the gravitational constant G or speed of light c), in most cases this results in a program of very limited usefulness. (Consider a calculator without any buttons that only adds the predetermined numbers 123 and 456.) Input, perhaps provided by a keyboard or mouse, or both, empower programs with the ability to calculate answers to specific problems that a human is encountering. Nearly all programs with which you interact involve input provided by humans.

ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 1
  1. List three programs that you commonly use for which you provide input.
  2. List one program that you commonly use for which you provide no input.
  3. List three input devices, excluding a mouse and keyboard, that you commonly use to interact with electronic devices.

Keyboard[edit]

Teletype

A teletype machine (or teleprinter) is an electromechanical device that can be used to send and received typed messages over a distance. It was one of the first devices that enabled the layman, not trained in Morse Code, to communicate easily with another. It included a keyboard for use by a human operator. In addition to the expected alphabetic and numeric characters, it contained a series of non-printable characters to control the conversation.
The most common of these are:

END OF TRANSMISSION/FILE
A control character (ASCII code 0x04) used to indicate the end of transmission or end of file. Abbreviated EOT or EOF.
TAB
A control character (ASCII code 0x09) used to move a device's position to the next horizontal tab stop.
LINE FEED
A control character (ASCII code 0x0A) used to move a device's position to the next line. Abbreviated as LF.
CARRIAGE RETURN
A control character (ASCII code 0x0D) used to reset a device's position to the beginning of a line of text. Abbreviated as CR.
ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 2
  1. Which button(s) is/are used on a calculator to indicate that you've completed an expression and want the calculator to evaluate the expression and provide an answer?
  2. Which button(s) is/are used on a calculator to indicate that you've completed a number?


In a similar manner to the way the print function advances the cursor when printing, reading from a stream of data advances a pointer from one character to the next.

Reading a Single Line of Text[edit]

The readLine() function enables us to (unsurprisingly) read a single line of text from the console. The signature is:

func readLine() -> String?

All the characters entered up to (but by default excluding) the newLine character will be returned. For example, given the code:

let line = readLine()

If we typed A B C D ENTER, line would contain "ABCD". If instead we typed 1 2 3 ENTER, line would contain "123". And if instead we typed only Enter, line would contain "", an empty string.

But note that the return type from readLine() is String?, an optional string. Under what circumstances would the return value be nil? readLine() will return nil if (and only if) the end-of-file marker is encountered when beginning a readLine().

ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 3
  1. Which control character is used to indicate end-of-file?

As a consequence, we'll need to ensure that the result of a readLine() is not nil before we access the value. By now, this should be a familiar paradigm:

let line = readLine()
if line != nil {
    print("You typed '\(line!)'")
}

Single-Line Syntactic Sugar[edit]

Let's take a closer look at this code:

let line = readLine()
if line != nil {
    print("You typed '\(line!)'")
}

We're taking four distinct actions with regard to readLine():

  1. On line 1, we evaluate the R-value of the expression readLine()
  2. Again on line 1, we assign the R-value to a constant
  3. On line 2, we check to see if this value is non-nil
  4. On line 3, we unwrap the value to obtain a String

We can add some syntactic sugar to accomplish all these actions in one line, using a construct called if-let:

if let line = readLine() {
    print("You typed '\(line)'")
}

In the above code, line 1 performs the following:

  1. Evaluate the R-value of the expression readLine()
  2. Check the value of the expression to see if is non-nil. If (and only if) the expression is non-nil:
  3. Unwrap the value to obtain a string
  4. Assign the value to a constant

Note that in this case, on line 2, there is no need to unwrap (bang) the variable because it is already of type String, having been unwrapped in line 1.

Reading Multiple Lines of Text[edit]

To read multiple lines of text, we need to have some way of detecting when we're done. We previously discussed the EOF marker and we've seen that in the case of readLine() the function will return nil when EOF is encountered. Using this information we can read multiple lines of text as follows:

var line : String?
repeat {
    line = readLine()
    if line != nil {
        print("You typed: '\(line!)'")
    }
} while line != nil

The above loop continues until the user types CONTROL-D.

Be Kind, Use a Prompt[edit]

It's generally considered to be rather rude to simply pause a program's output without informing the user that the program is waiting for them to do something. So, be kind, and let the user know what it is that they're being asked to do. The message that is displayed to the user in this case is called a prompt. Rewriting the above with a prompt:

var line : String?
repeat {
    print("Enter the name of a vegetable, or ^D to quit: ", terminator:"")
    line = readLine()
    if line != nil {
        print("You typed: '\(line!)'")
    }
} while line != nil

Multi-Line Syntactic Sugar[edit]

In a manner very similar to using the if-let construct to simplify single-line input, we can use a while-let construct to simplify multi-line input:

print("Enter the name of a vegetable, or ^D to quit: ", terminator:"")
while let line = readLine() {
    print("You typed: '\(line)'\nAnother or ^D: ", terminator:"")
}
ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 4
  1. What four actions does a while-let construct perform?

Standard Input Stream[edit]

Standard Streams

By default, a user's console input from a keyboard is fed to a program through the standard input stream. This stream of data is established by the operating system and connected to the running program automatically.

Key Concepts[edit]

Key ConceptsKeyConceptsIcon.png
  • Hard-coded data means that the data in question is embedded in a program as "code" and consequently cannot be changed without altering the program itself
  • Common, non-printable characters include:
    • End of transmission/file, ASCII code 0x04
    • Tab, ASCII code 0x09
    • Line feed, ASCII code 0x0A
    • Carriage return, ASCII code 0x0D
  • The readLine() function enables us to read a single line of text
    • readLine() returns an optional string, i.e., String?
    • readLine() will return nil if (and only if) the end-of-file marker is encountered when beginning a readLine()
  • The if-let construct:
    • Evaluates the R-value of an expression that can return nil
    • Checks the value of the expression to see if is non-nil. If (and only if) the result is non-nil:
      • Unwraps the value to obtain the underlying type
      • Assigns the value to a constant
  • The while-let construct is very similar to the if-let, but it functions as part of a while loop rather than a conditional

Exercises[edit]

ExercisesExercisesIcon.png
  1.  J1161  Create a journal and answer all questions in this experience. Be sure to include all sections of the journal, properly formatted.
  2.  M1161-10  Complete  Merlin Mission Manager  Mission M1161-10

References[edit]