Home

Data Reading and Formatting

 

Value Reading and Writing in F#

 

Reading a Value or String

Value reading consist of getting an input value from the user. To support this, the Microsoft.FSharp.Core namespace provides an operator named stdin. Its signature is:

stdin<'T> : TextReader

As you can see, stdin is in fact a shortcut for an abstract class named TextReader. The TextReader class is defined in the System.IO namespace of the .NET Framework. To support the ability to get a value from the user, the stdin operator, that is the TextReader class is equipped with a method named ReadLine. Its syntax is:

abstract ReadLine : unit -> string  
override ReadLine : unit -> string

As you can see, this method doesn't take any argument and produces a string. You can get that string and use it as you see fit, such as displaying it to the user. Here is an example:

let mutable bookTitle = "";

printf "Enter the book title: ";
bookTitle <- stdin.ReadLine();

printfn "Book Title: %s" bookTitle;

Here is an example of running the program:

Enter the book title: F# Language Fundamentals
Book Title: F# Language Fundamentals
Press any key to continue . . .

In the above example, we first declared a variable. As an alternative, you can declare the variable where needed. Here is an example:

printf "Enter the book title: ";
let bookTitle = stdin.ReadLine();

printfn "Book Title: %s" bookTitle;

Reading Any Type of Value

Normally, the stdin.ReadLine() method produces a string. If you want to request another type of value, you can first get a string, then convert it to that value. The conversion can be done through the appropriate conversion function. Here is an example:

let mutable bookTitle = "";
let mutable unitPrice = 0.00;

printf "Enter the book title: ";
bookTitle <- stdin.ReadLine();

printf "Book Price: "
let strNumber = stdin.ReadLine();
unitPrice <- float strNumber;

printfn "-------------------------";
printfn "Book Title: %s" bookTitle;
printfn "Unit Price: %.02f" unitPrice;

Here is an example of running the program:

Enter the book title: F# Language Fundamentals
Book Price: 44.95
-------------------------
Book Title: F# Language Fundamentals
Unit Price: 44.95
Press any key to continue . . .

Once again, you don't have to first declare a mutable variable. Here is an example where the variable is declared only when the value is requested:

printf "Enter the book title: ";
let bookTitle = stdin.ReadLine();

printf "Book Price: "
let strNumber = stdin.ReadLine()
let unitPrice = float strNumber

printfn "-------------------------";
printfn "Book Title: %s" bookTitle;
printfn "Unit Price: %.02f" unitPrice;

In the same way, if you are requesting a value other than a string, you can declare the variable and convert the requested value where it is needed. Here is an example:

printf "Enter the book title: ";
let bookTitle = stdin.ReadLine();

printf "Book Price: "
let unitPrice = float (stdin.ReadLine());

printfn "-------------------------";
printfn "Book Title: %s" bookTitle;
printfn "Unit Price: %.02f" unitPrice;

Writing a Value

To support the ability to write a value, the Microsoft.FSharp.Core namespace provides an operator named stdout. Its signature is:

stdout<'T> : TextWriter

The stdout operator is a shortcut for the TextWriter class defined in the System.IO namespace. The stdout operator, that is the TextWriter class is equipped with a method named Write and another named WriteLine. Each of these methods takes a value or variable as argument. The method displays that value to the console screen. Actually, there is a version for each data type. Therefore, pass the desired value or its variable to the method.

When it has displayed its value, the TextWriter.Write() method keeps the caret on the same line. For the same operation, the TextWriter.WriteLine() method moves the caret to the next line.

Here are examples:

let mutable bookTitle = "";
let mutable unitPrice = 0.00;

stdout.Write "Enter the book title: ";
bookTitle <- stdin.ReadLine();

stdout.Write "Book Price: ";
let strNumber = stdin.ReadLine();
unitPrice <- float strNumber;

stdout.WriteLine "-------------------------";
stdout.Write "Book Title: ";
stdout.WriteLine(bookTitle);
stdout.Write "Unit Price: "
stdout.WriteLine(unitPrice);

Fundamentals of the Console

 

Introduction

 

To allow you to display things on the monitor's screen, the .NET Framework provides a class named Console. 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.

The Console class is static. This means means that you never have to declare a variable from it in order to use it.

Writing to the Console

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 of the parentheses, type the value you want to display. Here is an example:

open System;

System.Console.Write("Welcome to the Wonderful World of F# Programming!!!")

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

Writing With a New Line

After displaying a value on the screen, the Write() method keeps the caret on the same 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

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.

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:

VariableName = 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.

Read() 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 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 class is equipped with a member named KeyChar. 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 class is equipped with a member named Key. 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:

Title

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"

Title

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:

static member Clear : unit -> unit

Data Reading

 

String Value Request 

In most assignments of your programs, you will not know the value of a string when writing your application. For example, you may want the user to provide such a string. To request a string (or any of the variables we will see in this lesson), you can call the Console.Read() or the Console.ReadLine() function and assign it to the name of the variable whose value you want to retrieve. Here is an example:

open System

let mutable firstName : string = ""

Console.Write("Enter First Name: ")
firstName <- Console.ReadLine()

Number Request

In C#, everything the user types is a string and the compiler would hardly analyze it without your explicit asking it to do so. Therefore, if you want to get a number from the user, first request a string. Here is an example:

open System

let mutable strNumber : string = "";

strNumber <- Console.ReadLine();

After getting the string, you must convert it to a number. To perform this conversion, each data type of the .NET Framework provides a method called Parse. When calling the Parse() method, type the data type, followed by a period, followed by Parse, and followed by parentheses. In the parentheses of Parse, type the string that you requested from the user. Here is an example:

open System

let mutable strNumber : string = "";

strNumber <- Console.ReadLine();

let number = Int32.Parse(strNumber);

An advanced but faster way to do this is to type Console.ReadLine() in the parentheses of Parse. This has the same effect. Here is an example:

open System

let number = Int32.Parse(Console.ReadLine());

Requesting Dates and Times

As done with the regular numbers, you can request a date value from the user. This is also done by requesting a string from the user. Here is an example:

open System

let mutable strDateHired = "";

strDateHired <- Console.ReadLine();

After the user has entered the string you can then convert it to a DateTime value. Just like any value you request from the user, a date or time value that the user types must be valid, otherwise, the program would produce an error. Because dates and times follow some rules for their formats, you should strive to let the user know how you expect the value to be entered.

By default, if you request only a date from the user and the user enters a valid date, the compiler would add the midnight value to the date. If you request only the time from the user and the user enters a valid time, the compiler would add the current date to the value. Later on, we will learn how to isolate either only the date or only the time.

 
   
 

Formatting Data Display in the Console

 

Introduction

Instead of using two Write() 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:

  1. The first part of the string provided to Write() or WriteLine() is the complete string that would display to the user. This first string itself can be made of different sections:
    1. One section is a string in any way you want it to display
    2. Another section is a number included between an opening curly bracket "{" and a closing curly bracket "}". This combination of "{" and "}" is referred to as a placeholder

      You can put the placeholder anywhere inside of the string. The first placeholder must have number 0. The second must have number 1, etc. With this technique, you can create the string anyway you like and use the placeholders anywhere inside of the string
  2. The second part of the string provided to Write() or WriteLine() is the value that you want to display. It can be one value if you used only one placeholder with 0 in the first string. If you used different placeholders, you can then provide a different value for each one of them in this second part, separating the values 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.

Conversion To String

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().

Number Formatting

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 placer 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());

This would produce:

Full Name:        Anselme Bogos
Age:            15
Distance: 22.74

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.

Data and Time Formatting

As mentioned earlier, when the user enters a date value for a DateTime variable, the compiler adds a time part to the value. Fortunately, if you want to consider only the date or only the time part, you can specify this to the compiler. To support this, the DateTime data type provides a series of letters you can use to format how its value should be displayed to the user. The character is entered in the placeholder of the DateTime variable after the 0 or the incremental numeric value.

 
 
   
 

Previous Copyright © 2008-2015 FunctionX Next