Skip to content

Latest commit

 

History

History
155 lines (109 loc) · 4.8 KB

09-user-input.adoc

File metadata and controls

155 lines (109 loc) · 4.8 KB

Interacting with user input

Using the stuff we’ve introduced so far (basic data types and containers, control flow, loops) allows us to make quite a few simple programs. To make our programs more interactive, we need an option to read data from a file, or ask a user for an input.

Reading from a file

Let’s say we have a text file called people.txt in the same directory as our Nim code. The contents of that file looks like this:

people.txt
link:{source-dir}/people.txt[role=include]

We want to use the contents of that file in our program, as a list (sequence) of names.

readFromFile.nim
link:{source-dir}/readFromFile.nim[role=include]
  1. To read contents of a file, we use the readFile procedure, and we provide a path to the file from which to read (if the file is in the same directory as our Nim program, providing a filename is enough). The result is a multiline string.

  2. To split a multiline string into a sequence of strings (each string contains all the contents of a single line) we use splitLines from the strutils module.

Alice A.
Bob B.
Carol C.
            (1)
@["Alice A.", "Bob B.", "Carol C.", ""] (2)
  1. There was a final new line (empty last line) in the original file, which is also present here.

  2. Because of the final new line, our sequence is longer than we expected/wanted.

To solve the problem of a final new line, we can use the strip procedure from strutils after we have read from a file. All this does is remove any so-called whitespace from the start and end of our string. Whitespace is simply any character that makes some space, new-lines, spaces, tabs, etc.

readFromFile2.nim
link:{source-dir}/readFromFile2.nim[role=include]
  1. Using strip provides the expected results.

Alice A.
Bob B.
Carol C.
@["Alice A.", "Bob B.", "Carol C."]

Reading user input

If we want to interact with a user, we must be able to ask them for an input, and then process it and use it. We need to read from standard input (stdin) by passing stdin to the readLine procedure.

interaction1.nim
link:{source-dir}/interaction1.nim[role=include]
  1. The type of name is inferred to be a string.

Please enter your name:
        (1)
  1. Waiting for user input. After we write our name and press Enter, the program will continue.

Please enter your name:
Alice
Hello Alice, nice to meet you!
Note
VS Code users cannot run this the usual way (using Ctrl+Alt+N) because output window doesn’t allow user inputs. This needs to be run in the terminal.

Dealing with numbers

Reading from a file or from a user input always gives a string as a result. If we would like to use numbers, we need to convert strings to numbers: we again use the strutils module and use parseInt to convert to integers or parseFloat to convert into a float.

interaction2.nim
link:{source-dir}/interaction2.nim[role=include]
  1. Convert a string to an integer. When written like this, we trust our user to give a valid integer. What would happen if a user inputs '79 or ninety-three? Try it yourself.

Please enter your year of birth:
1934
You are 84 years old.

 

If we have file numbers.txt in the same directory as our Nim code, with the following content:

numbers.txt
link:{source-dir}/numbers.txt[role=include]

and we want to read that file and find the sum and average of the numbers provided, we can do something like this:

interaction3.nim
link:{source-dir}/interaction3.nim[role=include]
  1. We import multiple modules. strutils gives us strip and splitLines, sequtils gives map, and math gives sum.

  2. We strip the final new line, and split lines to create a sequence of strings.

  3. map works by applying a procedure (in this case parseFloat) to each member of a container. In other words, we convert each string to a float, returning a new sequence of floats.

  4. Using sum from math module to give us the sum of all elements in a sequence.

  5. We need to convert the length of a sequence to float, because sumNums is a float.

226.15
45.23

Exercises

  1. Ask a user for their height and weight. Calculate their BMI. Report them the BMI value and the category.

  2. Repeat Collatz conjecture exercise so your program asks a user for a starting number. Print the resulting sequence.

  3. Ask a user for a string they want to have reversed. Create a procedure which takes a string and returns a reversed version. For example, if user types Nim-lang, the procedure should return gnal-miN. (Hint: use indexing and countdown)