Data Reading and Formatting
Data Reading and Formatting
Introduction to Console Input/Output
Introduction
Probably the primary purpose of an application is to create interaction between a user (a person, another application in the same computer, an application in a different computer, another machine, etc) and the machine. The simplest application is where a user simply reads text, views data, or plays streaming (music, video, etc). A common interaction is where a user is asked to submit values and the application must respond by processing, validating, etc the values. Most (but of course not all) compiter languages provides the means to create interactivity between their application (an application created with that language) and a user.
Performing Input/Output Operations
Stream input is the ability to enter or transmit data IN the computer. This transmission can be performed from an external device such as a keyboard, a mouse, a screen reader, etc INTO the computer. Stream output is the ability to retrieve or read data OUT of/from the computer. This transmission can be performed from a computer's internal devices such as the computer memory, a hard drive, a network drive, etc OUT of/from a computer to an exernal device such a a printer, a scanner, etc.
To support the primary stream operations, the .NET Framework provides a namespace named System.IO. This namespace is equipped with appropriate classes for all types of useful operations.
Introduction to the F# Core Library
Like most languages, F# has its own libraries that contain various namespaces. The primary namespace of the F# language is named Microsoft.FSharp.Core.
Introduction to the Console
To allow you to perform all types of operations on the console screen, the .NET Framework provides a class named Console:
C#: public static class Console
The Console class is static. This means that you never have to declare a variable from it in order to use it.
The Console class is defined in the System namespace. The System namespace is part of the mscorlib.dll library. When you create an F# application, the mscorlib.dll library is directly available; which means you don't have to import it.
Because the Console class is created in the System namespace, you have two options to use that class. You can type that name of the namespace, the period operator, and the name of the class, as in System.Console. You can then add a period and the name of the class member you want. As an alternative, in the top section of the document where you want to use the class, type open System. You can end the line with an optional semicolon. After writing that line, in the document, you can type the name of the class, a period, and the desired member of the class.
Writing to a Console
Introduction
Remember that the .NET Framework provides the static Console class for primary input/output operations.To provide the ability to display one or more values to the screen, the Console class is equipped with a mehod named Write. To use the Write() method, inside its parentheses, type the value you want to display.
To be able to handle any value of the data types we have used so far, the Write() method is overloaded with various versions, a version that takes an argument for each data type:
static member Write : value:bool -> unit static member Write : value:char -> unit static member Write : value:int -> unit static member Write : value:uint32 -> unit static member Write : value:string -> unit static member Write : value:int64 -> unit static member Write : value:uint32 -> unit static member Write : value:float32 -> unit static member Write : value:float -> unit static member Write : value:decimal -> unit static member Write : value:Object -> unit
Therefore, to display a string or a value of a primitive type, write that value in the parentheses of a Write() class. Here are a few examples:
open System; let semiColon = ';' let fName = "Paul Bertrand Yamaguchi" // Displaying a string directly in Write() Console.Write("Employee Name: ") // Displaying a string variable Console.Write(fName) // Displaying a character directly in Write() Console.Write(',') // Displaying a string directly in Write() Console.Write(" Full-Time? ") // Displaying a Boolean value directly in Write() Console.Write(true) // Displaying a character variable in Write() Console.Write(semiColon) // Displaying a string directly in Write() Console.Write(" Hourly Salary: ") // Displaying a number directly in Write() Console.Write(24.68) // Displaying a string directly in Write() Console.Write(", Estimated Weekly Salary: ") // Displaying an expression directly in Write() Console.Write(24.68 * 38.00)
This would produce:
Employee Name: Paul Bertrand Yamaguchi, Full-Time? True; Hourly Salary: 24.68, Estimated Weekly Salary: 937.84 Press any key to close this window . . .
Writing With a New Line
After displaying a value on the screen, the Console.Write() method keeps the caret on the same line. If you want to move the caret to the next line, you can include a New Line escape sequence when calling the Console.Write() method. Here are examples:
open System let nLine = '\n' let fName = "Paul Bertrand Yamaguchi" // Displaying a string directly in Write() Console.Write("Employee Record") // Displaying an escape sequence, a string, and an escape sequence in Write() Console.Write("\n---------------------------------------\n") // Displaying a string directly in Write() Console.Write("Employee Name: ") // Displaying a string variable Console.Write(fName) // Displaying an escape sequence character directly in Write() Console.Write('\n') // Displaying a string directly in Write() Console.Write("Full-Time? ") // Displaying a Boolean value directly in Write() Console.Write(true) // Displaying an escape sequence variable in Write() Console.Write(nLine) // Displaying a string directly in Write() Console.Write(" Hourly Salary: ") // Displaying a number directly in Write() Console.Write(24.68) // Displaying an escape sequence and a string in Write() Console.Write("\nEstimated Weekly Salary: ") // Displaying an expression directly in Write() Console.Write(24.68 * 38.00) // Displaying an escape sequence and a string in Write() Console.Write("\n=======================================")
This would produce:
Employee Record --------------------------------------- Employee Name: Paul Bertrand Yamaguchi Full-Time? True Hourly Salary: 24.68 Estimated Weekly Salary: 937.84 ======================================= Press any key to close this window . . .
Intead of making you include a New Line escape sequence in a Console.Write() call just to create a new line, to give you the ability to move the caret to the next line after displaying a value, the Console class is equipped with a method named WriteLine. Like Write(), the WriteLine() method has a version for each of the data types we have used so far:
static member WriteLine : value:bool -> unit static member WriteLine : value:char -> unit static member WriteLine : value:int -> unit static member WriteLine : value:uint32 -> unit static member WriteLine : value:string -> unit static member WriteLine : value:int64 -> unit static member WriteLine : value:uint32 -> unit static member WriteLine : value:float32 -> unit static member WriteLine : value:float -> unit static member WriteLine : value:decimal -> unit static member WriteLine : value:Object -> unit
You use the Console.WriteLine() method the same way you use the Console.Write(), except that, when the Console.WriteLine() method has been called, it automatically creates a new line. Here are examples:
open System; let fName = "Paul Bertrand Yamaguchi" // Displaying a string directly in WriteLine() Console.WriteLine("Employee Record") // Displaying a string in WriteLine() Console.WriteLine("---------------------------------------") // Displaying a string directly in Write() Console.Write("Employee Name: ") // Displaying a string variable in WriteLine() Console.WriteLine(fName) // Displaying a string directly in Write() Console.Write("Full-Time? ") // Displaying a Boolean value directly in WriteLine() Console.WriteLine(true) // Displaying a string directly in Write() Console.Write("Hourly Salary: ") // Displaying a number directly in WriteLine() Console.WriteLine(24.68) // Displaying an escape sequence and a string in Write() Console.Write("Estimated Weekly Salary: ") // Displaying an expression directly in WriteLine() Console.WriteLine(24.68 * 38.00) // Displaying an escape sequence and a string in WriteLine() Console.WriteLine("=======================================")
Besides these versions, the Write() and the WriteLine() methods have each a version that takes an unlimited number of arguments. Later on, we will learn how to use these versions to display a value, a series of values, and to specify how the value must be displayed.
Formatting Data Display in the Console
Introduction
Instead of using two Write() calls or a combination of Write() and WriteLine() to display data, you can convert a value to a string and display it directly. To do this, you can provide two strings to the Write() or WriteLine() and separate them with a comma:
Here are examples:
open System let fullName = "Anselme Bogos" let age = 15 let hSalary = 22.74 Console.WriteLine("Full Name: {0}", fullName) Console.WriteLine("Age: {0}", age) Console.WriteLine("Distance: {0}", hSalary)
This would produce:
Full Name: Anselme Bogos Age: 15 Distance: 22.74
As mentioned already, the numeric value typed in the curly brackets of the first part is an ordered number. If you want to display more than one value, provide each incremental value in its curly brackets. The syntax used is:
Write("To Display {0} {1} {2} {n}", First, Second, Third, nth);
You can use the sections between a closing curly bracket and an opening curly bracket to create a meaningful sentence.
We mentioned earlier that everything the user types using the keyboard is primarily a string and it's your job to convert it to the appropriate type. In reverse, if you have a value that is not a string, you can easily convert it to a string. To support this, each .NET Framework data type provides a mechanism called ToString. Normally, in C#, as we mentioned with boxing, and as we have done so far, this conversion is automatically or transparently done by the compiler. In some cases, you will need to perform the conversion yourself.
To convert a value of a primitive data type to a string, type the name of the variable, followed by a period, followed by ToString(). Here is an example:
open System let fullName = "Anselme Bogos"; let age = 15; let hSalary = 22.74; Console.WriteLine("Full Name: {0}", fullName); Console.WriteLine("Age: {0}", age.ToString()); Console.WriteLine("Distance: {0}", hSalary.ToString());
In some cases, you will type something in the parentheses of ToString().
To properly display data in a friendly and most familiar way, you can format it. Formatting tells the compiler what kind of data you are using and how you want the compiler to display it to the user. As it happens, you can display a natural number in a common value or, depending on the circumstance, you may prefer to show it as a hexadecimal value. When it comes to double-precision numbers, you may want to display a distance with three values on the right side of the decimal separator and in some cases, you may want to display a salary with only 2 decimal places.
The System namespace provides a specific letter that you can use in the Write() or WriteLine()'s placeholder for each category of data to display. To format a value, in the placeholder of the variable or value, after the number, type a colon and one of the appropriate letters from the following table. If you are using ToString(), then, in the parentheses of ToString(), you can include a specific letter or combination inside of double-quotes. The letters and their meanings are:
Character | Description | |
c | C | Currency values |
d | D | Decimal numbers |
e | E | Scientific numeric display such as 1.45e5 |
f | F | Fixed decimal numbers |
d | D | General and most common type of numbers |
n | N | Natural numbers |
r | R | Roundtrip formatting |
s | S | Hexadecimal formatting |
p | P | Percentages |
Here are examples:
open System let distance = 248.38782 let age = 15 let newColor = 3478 let hSalary = 22.74 let hoursWorked = 35.5018473 let weeklySalary = hSalary * hoursWorked Console.WriteLine("Distance: {0}", distance.ToString("E")) Console.WriteLine("Age: {0}", age.ToString()) Console.WriteLine("Color: {0}", newColor.ToString("X")) Console.WriteLine("Weekly Salary: {0} for {1} hours", weeklySalary.ToString("c"), hoursWorked.ToString("F"))
This would produce:
Distance: 2.483878E+002 Age: 15 Color: D96 Weekly Salary: $807.31 for 35.50 hours
As you may have noticed, if you leave the parentheses of ToString() empty, the compiler would use a default formatting to display the value.
As opposed to calling ToString(), you can use the above letters in the curly brackets of the first part of Write() or WriteLine(). In this case, after the number in the curly brackets, type the colon operator followed by the letter.
Line Formatting
In the above programs, to display a line of text, we easily used Write() or WriteLine(). To position text of different lengths one above the other, we had to "corrupt" a string by including extra-empty spaces. Such a technique is uncertain and less professional. Fortunately, you can highly format how a string or a line of text should display. The .NET Framework provides mechanisms to control the amount of space used to display a string of text and how to align that string on its line.
To specify the amount of space used to display a string, you can use its placeholder in Write() or WriteLine(). To do this, in the placeholder, type the 0 or the incrementing number of the place and its formatting character if necessary and if any. Then, type a comma followed by the number of characters equivalent to the desired width. Here are examples:
open System let fullName = "Anselme Bogos" let age = 15 let hSalary = 22.74 Console.WriteLine("Full Name: {0,20}", fullName) Console.WriteLine("Age:{0,14}", age.ToString()) Console.WriteLine("Distance: {0:C,8}", hSalary.ToString())
The sign you provide for the width is very important. If it is positive, the line of text is aligned to the right. This should be your preferred alignment for numeric values. If the number is negative, then the text is aligned to the left.
Writing Values to a Stream
Introduction to Writing Text
Text writing is the ability to print text on a document, the computer screen, etc. To give you the ability to write text to a document, the .NET Framework provides a class named TextWriter:
public abstract class TextWriter : MarshalByRefObject, IDisposable
Notice that this is an abstract class. As a result, to use this class, you need a class derived from it. One of the candidate classes is named StreamWriter:
public class StreamWriter : System.IO.TextWriter
As a result, when necessary, you can declare a variable and initialize it with this class. This can be done as follows:
open System.IO
let tr = new StreamWriter("C:\Exercises\Exercise1.txt")
Of course, to indicate that you are starting an operation for a TextWriter object, you can specify the data type of the variable. This can be done as follows:
open System.IO
let tr : TextWriter = new StreamWriter("C:\Exercises\Exercise1.txt")
One of the most used methods of the TextWriter class is named WriteLine. This method is provided in various versions that take one or more arguments. Based on this, as one way to display a value in a document, you can declare a TextWriter variable, and access its WriteLine() method.
Getting the Console Out
To prepare the .NET languages for text writing, the Console class is equipped with a property named Out. It is of type TextWriter:
C#: public static System.IO.TextWriter Out { get; }
To use this property, you can declare a variable and initialize it with this property. This can be done as follows:
open System.IO
let writeOut = Console.Out
As an option, you can specify the type of the variable as TextWriter. This can be done as follows:
open System.IO
let writeOut : TextWriter = Console.Out
After declaring and initializing the variable, you can use it to access the members of the TextWriter class.
Writing Out a Value
Probably the most common operation of text writing is to write text. To support this operation, the TextWriter class is equipped with a method named Write. This method is provided in many versions, just like a method of the same name in the Console class. As a result, to to display a value on a line, you can call the Write() method from a Console.Out variable and pass the desired value to its parentheses. As mentioned for the Console.Write() method, the TextWriter.Write() method writes a value on a line and keeps the caret on the same line. If you want to write a value and move the caret to the next line, you can pass a New Line escape sequence to the method. Here are examples:
open System open System.IO let out : TextWriter = Console.Out let nLine = '\n' let fName = "Paul Bertrand Yamaguchi" out.Write("Employee Record") out.Write("\n---------------------------------------\n") out.Write("Employee Name: ") out.Write(fName) out.Write('\n') out.Write("Full-Time? ") out.Write(true) out.Write(nLine) out.Write("Hourly Salary: ") out.Write(24.68) out.Write("\nEstimated Weekly Salary: ") out.Write(24.68 * 38.00) out.Write("\n=======================================")
When a value has been written, to provide the ability to move the caret to the next line, the TextWriter class is equipped with a method named WriteLine. Here are examples of calling this method:
open System open System.IO let out : TextWriter = Console.Out let fName = "Paul Bertrand Yamaguchi" out.WriteLine("Employee Record") out.WriteLine("---------------------------------------") out.Write("Employee Name: ") out.WriteLine(fName) out.Write("Full-Time? ") out.WriteLine(true) out.Write("Hourly Salary: ") out.WriteLine(24.68) out.Write("Estimated Weekly Salary: ") out.WriteLine(24.68 * 38.00) out.WriteLine("=======================================")
Standardizing an Output Operation
The goal of most programming languages is to make programmers life a little easy by reducing, as much as possible, the amount of code necessary to perform any operation. For example, instead of going through the various steps of referencing the System.IO namespace and declaring a Console.Out variable, the F# language provides a custom type definition of the Console.Out property.
To ease your output operations, the F# language provides a type definition of the Console.Out property in a name as stdout. This is done in the https://github.com/dotnet/fsharp/blob/main/src/FSharp.Core/prim-types.fs file as follows:
[<CompiledName("ConsoleOut")>]
let stdout<'T> = Console.Out
Based on this, to perform an output operation in a console window, type the stdout object followed by a period. Then type the name of the System.IO.TextWriter member you want to access. As mentioned already, the two most regular members to access are System.IO.TextWriter.Write() and System.IO.TextWriter.WriteLine() methods. Here are examples of calling those methods:
let fName = "Paul Bertrand Yamaguchi" stdout.WriteLine("Employee Record") stdout.WriteLine("---------------------------------------") stdout.Write("Employee Name: ") stdout.WriteLine(fName) stdout.Write("Full-Time? ") stdout.WriteLine(true) stdout.Write("Hourly Salary: ") stdout.WriteLine(24.68) stdout.Write("Estimated Weekly Salary: ") stdout.WriteLine(24.68 * 38.00) stdout.WriteLine("=======================================")
Printing Values to a Console
Introduction
To help you work a little faster especially when it comes to displaying values, the F# language provides its own library of functions, referred to as print functions. The functions are created in a module named Printf (https://github.com/dotnet/fsharp/blob/main/src/FSharp.Core/printf.fs). Some of the functions are mostly for internal use. Some of those functions are used internally by other functions.
Printing with a Function
To help you display values to a computer screen, the F# language provides a function named printf. This function takes one argument, which can be a string to display. When this function has displays the value, it keeps the caret on the same line it displayed the value.
Printing a Value to the Next Line
To help you display values to a computer screen and move the caret to the next line, the F# language provides a function named printfn.
Putting Values Into a Stream
Introduction to Reading Text
Text Reading is the ability to get text transmitted through a medium such as a keyboard or a mouse. The user can do this by typing text using a keyboard or selecting text with a mouse and copying/pasting it into a document or a Windows control. To support the ability to read text, the System.IO namespace provides a class named TextReader:
C#: public abstract class TextReader : MarshalByRefObject, IDisposable
Notice that System.IO.TextReader is an abstract class. This means that if you want to use it, you should use a class that is derived from it. An example of such a class is StreamReader. Here is an example of declaring a TextReader variable:
open System.IO let tr : TextReader = new StreamReader("C:\Exercises\Attention.txt")
Reading a String
To support the ability to read text from a computer device, the Console class is equipped with a property named In. It is of type TextReader:
C#: public static System.IO.TextReader In { get; }
To use this property, you can declare a variable and initialize it with this property. This can be done as follows:
open System
let readIn = Console.In
As an option, you can specify the type of the variable as TextReader. This can be done as follows:
open System
let readIn : TextReader = Console.In
After declaring and initializing the variable, you can use it to access the members of the TextReader class. Probably the most useful member of that class is a method named ReadLine. Its syntax is:
abstract ReadLine : unit -> string override ReadLine : unit -> string
You can call this method to read a value. Notice that this method returns a string. As a result, you can call this method and assign its call to a string variable. You can then display the resulting value of that variable using a printf() or a printfn() function. This can be done as follows:
open System open System.IO let readIn : TextReader = Console.In printf "Enter a unit of measure: " let unitOfMeasure = readIn.ReadLine() printfn "--------------------------------" printfn "Unit of Measure: %s" unitOfMeasure
Here is an example of running the program:
Enter a unit of measure: meter -------------------------------- Unit of Measure: meter Press any key to close this window . . .
Reading a Non-String Value
Because the TextReader.ReadLine() method returns a string, if you want it to produce a different type of value, you can cast that value to the appropriate type. Here are two examples of doing that (we have seen various examples in previous lessons):
open System let readIn = Console.In printfn "Enter the following pieces of information" printfn "----------------------------------------------" printf "Employee Name: " let fName = readIn.ReadLine() printf "Hourly Salary: " let strHourlySalary = readIn.ReadLine() printf "Weekly Time Worked: " let hSalary = float strHourlySalary let timeWorked = float(readIn.ReadLine()) printfn "=============================================" printfn "Employee Name: %s" fName printfn "Hourly Salary: %0.02f" hSalary printfn "Weekly Time Worked: %0.02f" timeWorked printfn "---------------------------------------------" printfn "Weekly Salary: %0.02f" (hSalary * timeWorked) printfn "============================================="
Here is an example of running the program:
Enter the following pieces of information ---------------------------------------------- Employee Name: Paul Bertrand Yamaguchi Hourly Salary: 22.48 Weekly Time Worked: 38.50 ============================================= Employee Name: Paul Bertrand Yamaguchi Hourly Salary: 22.48 Weekly Time Worked: 38.50 --------------------------------------------- Weekly Salary: 865.48 ============================================= Press any key to close this window . . .
Type-Defining a Text Reader
To support value reading, the F# language type-defines the Console.In property in its Microsoft.FSharp.Core namespace (https://github.com/dotnet/fsharp/blob/main/src/FSharp.Core/prim-types.fs). The type definition is named stdin:
[<CompiledName("ConsoleIn")>]
let stdin<'T> = Console.In
As a result, in an F# document, you can use the stdin name as representing the System.IO.TextReader abstract class. As seen so far, the most commonly used member of the TextReader class is its ReadLine() function. As a result, instead of declaring a System.IO.TextReader (or rather a System.IO.StreamReader) variable to access its ReadLine() method, instead of declaring a variable and assigning Console.In to it, as seen in previous lessons, you can directly use the stdin object and access the ReadLine() method from it. As a result, and as donne in previous lessons, the above program can be written as follows:
printfn "Enter the following pieces of information" printfn "----------------------------------------------" printf "Employee Name: " let fName = stdin.ReadLine() printf "Hourly Salary: " let strHourlySalary = stdin.ReadLine() printf "Weekly Time Worked: " let hSalary = float strHourlySalary let timeWorked = float(stdin.ReadLine()) printfn "=============================================" printfn "Employee Name: %s" fName printfn "Hourly Salary: %0.02f" hSalary printfn "Weekly Time Worked: %0.02f" timeWorked printfn "---------------------------------------------" printfn "Weekly Salary: %0.02f" (hSalary * timeWorked) printfn "============================================="
Reading from the Console
Introduction
We saw that the Console class allows using the Write() or the WriteLine() methods to display values on the screen. While the Console.Write() method is used to display something on the screen, the Console class provides the Read() method to get a value from the user:
variable-name = Console.Read()
This simply means that, when the user types something and presses Enter, what the user had typed would be given (the word is assigned) to the variable specified on the left side of the assignment operator.
The call to the Read() method doesn't always have to assign its value to a variable. For example, it can be used on its own line, which simply means that the user is expected to type something but the value typed by the user would not be used for any significant purpose. You can use the Read() function to wait for the user to press any key in order to close the DOS window.
Reading a Character
As you may know already, each letter of the alphabet is represented on the keyboard by a key. Other symbols, readable (such as #, @, or $) or not (such as Shift, Ctrl, or Enter) are also represented. To represent a character produced from one of those keys or a combination of those keys, the .NET Framework provides a structure named ConsoleKeyInfo:
[<System.Serializable>] type ConsoleKeyInfo = struct end
To get the letter or the action that those keys represent, the Console class is equipped with a method named ReadKey that is overloaded with two versions. One of the versions uses the following syntax:
static member ReadKey : unit -> ConsoleKeyInfo
This method takes no argument and produces a value of type ConsoleKeyInfo. To get the value returned by this method, you can declare a ConsoleKeyInfo variable and assign it to the calling of this method.
If the user presses a key for a letter or a readable symbol (such as #, !, /, or %), to recognize the key that was pressed, the ConsoleKeyInfo structure is equipped with a read-only property named KeyChar:
C#: public char KeyChar { get; }
Here is an example of getting the letter:
open System let mutable cki : ConsoleKeyInfo = new ConsoleKeyInfo() Console.Write("Press a key: ") cki <- System.Console.ReadKey() Console.WriteLine() Console.Write("You pressed: ") Console.WriteLine(cki.KeyChar)
If the key that the user pressed is not a readable symbol such as the Space Bar, a Ctrl key, or Enter key, to recognize it, the ConsoleKeyInfo structure is equipped with a read-only property named Key:
C#: public ConsoleKey Key { get; }
Here is an example of using it:
open System
let mutable cki : ConsoleKeyInfo = new ConsoleKeyInfo()
Console.Write("Press a key: ")
cki <- System.Console.ReadKey()
Console.WriteLine()
Console.Write("You pressed: ")
Console.WriteLine(cki.Key)
When it finishes reading its key, the Console.ReadKey() method stops and lets you decide what to do. If you want it to display the result, the Console class provides another version of the ReadKey() method. Its syntax is:
static member ReadKey : intercept:bool -> ConsoleKeyInfo
The Boolean argument specifies whether you want the method to display the value.
Reading With a New Line
Besides Read(), the Console class also provides the ReadLine() method. Like the WriteLine() method, after performing its assignment, the ReadLine() method sends the caret to the next line. Otherwise, it plays the same role as the Read() function.
Characteristics and Behaviors of a Console
The Title of a Console Screen
A console window is primarily a normal window with classic behaviors. It is equipped with a title bar that displays a title. By default, the title bar displays the path of the Command Prompt:
The Console class allows you to change the title of the console. To do this, assign a string to Console.Title. Here is an example:
using System Console.Title <- "Department Store"
Clearing the Console
If the console screen is filled with text you don't need anymore, you can empty it. To allow you to clear the screen, the Console class is equipped with a method named Clear. It syntax is:
C#: public static void Clear();
When this method is called, it removes all the text in the console screen.
|
|||
Previous | Copyright © 2008-2024, FunctionX | Monday 14 February 2022 | Next |
|