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.
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:
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.
link:{source-dir}/readFromFile.nim[role=include]
-
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. -
To split a multiline string into a sequence of strings (each string contains all the contents of a single line) we use
splitLines
from thestrutils
module.
Alice A.
Bob B.
Carol C.
(1)
@["Alice A.", "Bob B.", "Carol C.", ""] (2)
-
There was a final new line (empty last line) in the original file, which is also present here.
-
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.
link:{source-dir}/readFromFile2.nim[role=include]
-
Using
strip
provides the expected results.
Alice A.
Bob B.
Carol C.
@["Alice A.", "Bob B.", "Carol C."]
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.
link:{source-dir}/interaction1.nim[role=include]
-
The type of
name
is inferred to be a string.
Please enter your name:
(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.
|
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.
link:{source-dir}/interaction2.nim[role=include]
-
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
orninety-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:
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:
link:{source-dir}/interaction3.nim[role=include]
-
We import multiple modules.
strutils
gives usstrip
andsplitLines
,sequtils
givesmap
, andmath
givessum
. -
We strip the final new line, and split lines to create a sequence of strings.
-
map
works by applying a procedure (in this caseparseFloat
) to each member of a container. In other words, we convert each string to a float, returning a new sequence of floats. -
Using
sum
frommath
module to give us the sum of all elements in a sequence. -
We need to convert the length of a sequence to float, because
sumNums
is a float.
226.15
45.23
-
Ask a user for their height and weight. Calculate their BMI. Report them the BMI value and the category.
-
Repeat Collatz conjecture exercise so your program asks a user for a starting number. Print the resulting sequence.
-
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 returngnal-miN
. (Hint: use indexing andcountdown
)