5
Making decisions in programs

A graphical representation shows a man with apron standing inside the kitchen and speaking over the phone. A cat is seated behind him.

What you will learn

I’ve described a computer as a sausage machine that accepts an input, does something with it, and then produces an output. This is a great way to start thinking about computers, but a computer does a lot more than that. Unlike a real-life sausage machine, which simply tries to create sausage from anything you put in it, a computer can respond to different inputs in different ways. In this chapter, you’ll learn how to make your programs respond to different inputs. You’ll also learn about the responsibility that comes with making the computer work in this way because you must be sure that the decisions your programs make are sensible.

Boolean thinking

The if construction

Use decisions to make an application

Improve the ride selector

What you have learned

Boolean thinking

In Chapter 4, you learned that programs use variables to represent different types of data. I like to think that you will forever associate the number of hairs on your head with whole numbers (integers) and the average length of your hair with real numbers (floating-point values). Now it’s time to meet another way of looking at data values: Boolean. Data that is Boolean can only have one of two values: true and false. You could use a Boolean value to represent whether a given person has any hair.

Boolean values in JavaScript

A program can create variables that can hold Boolean values. As with other JavaScript data types, JavaScript will deduce the type of a variable from the context in which it is used.

var itIsTimeToGetUp = true;

The above statement creates a variable called itIsTimeToGetUp and sets its value to true. In my world, it seems that it is always time to get up. In the highly unlikely event of me ever being allowed to stay in bed, we can change the assignment to set the value to false:

var itIsTimeToGetUp = false;

The words true and false are keywords. These are words that are “built in” to JavaScript. There are 63 different keywords. You’ve already seen a few of them. For example, function is a keyword. When JavaScript sees the keywords true or false, it thinks in terms of Boolean values.

JavaScript regards values that are numbers or text as being either “truthy” or “falsy.” Values are regarded as “truthy” unless they are zero, an empty string, Not a Number (NAN), or undefined—in which case, they are “falsy.”

CODE ANALYSIS

Boolean values

Boolean values are a new type of data that a program can manipulate. But of course, we have questions about them.

Question: What do you think would happen if you displayed the contents of a Boolean value?

alert(itIsTimeToGetUp);

Answer: When you display any value, JavaScript will try to convert that value into something sensible for us to look at. In the case of Boolean values, it will display true or false.

A screenshot shows the result in boolean value. The text that reads This page says, True is displayed. The 'ok' button is displayed on the bottom right.

Question: Is there a JavaScript function called Boolean that will convert things into Boolean values, just like there is a Number function that will convert things into a number?

Answer: Indeed, there is. The Boolean function applies the rules of “truthy” and “falsy” to the value supplied to it.

> Boolean(1);
<- true
> Boolean(0);
<- false

Applying Boolean to 0 gives the result false. Any other numeric value would be regarded as true.

Question: Are negative numbers regarded as false?

Answer: No. It is best to regard “truthy” as meaning “the presence of a value” rather than something that is positive or negative. Applying Boolean to a negative number will produce a result of true.

> Boolean(-1);
<- true

Question: Is the string false regarded as true?

Answer: Yes. If you understand this, you can call yourself a “truthy ninja.” Any string other than an empty string is regarded as true.

> Boolean("false");
<- true
> Boolean("");
<- false

Question: Is the value infinity regarded as true or false?

Answer: In our first encounter with JavaScript in Chapter 1, we tried dividing 1 by zero to see what happened. We discovered that this type of invalid calculation produces a value of infinity as a result. The best way to discover whether infinity is true or false is to ask JavaScript:

> Boolean(1/0);
<- true

The calculation 1/0 generates a result of infinity, which is regarded by the Boolean function as true.

Question: We know that if we ask JavaScript to perform a silly calculation, such as dividing a number by a string, the result is a special value called Not a number (NaN). Is NaN regarded as true or false?

Answer: JavaScript regards NaN as false. Dividing the number 1 by the string Rob produces NaN as a result. If we feed this into the Boolean function, it decides this value is false.

> Boolean(1/"Rob");
<- false

Question: What happens if a program combines Boolean values with other values?

Answer: In Chapter 4, in the section “Working with strings and numbers,” we discovered that when we combine numbers with strings, the numeric value is automatically “promoted” to a string. Something similar happens when logical values are combined with values of other types. A value that is true equates to the number 1 and the true string. A value of false equates to 0 and false.

> 1 + true;
<- 2
> "hello" + true;
<- "hellotrue"

Note that, as with numbers, this conversion does not work the other way. Just as we had to use the Number function to convert a string into a number, we have to use the Boolean function to convert values of other types into values that obey the “truthy” and “falsy” rules.

In Chapter 3, we created a ticking clock that displayed the time. The program in Chapter 3 used the Date object that JavaScript provides to get the current date and time:

var currentDate = new Date();
var hours = currentDate.getHours();
var mins = currentDate.getMinutes();
var secs = currentDate.getSeconds();

The statements above get the hours, mins, and secs values for the current time. We could use these values to write some JavaScript that would decide whether I should get up. Note that the hours value is supplied as a 24-hour clock value, meaning it goes from 0 to 23 over the day.

Boolean expressions

We’ve said that JavaScript expressions are made up of operators (which identify the operation) and operands (which identify the items being processed). Figure 5-1 shows our first expression, which worked out the calculation 2+2.

The figure shows an expression with arithmetic operator. The expression 2 (operand) plus (operator) 2 (operand) is displayed.

Figure 5-1 An arithmetic operator

An expression can contain a comparison operator, as shown in Figure 5-2.

The figure shows an expression with comparision operator. The expression hours (operand) greater than (operator) 6 (operand) is displayed.

Figure 5-2 A comparison operator

An expression containing a comparison operator evaluates to a result that is either true or false. The > operator in this expression means “greater than.” If you read the expression aloud, you say “hour greater than six.” In other words, this expression is true if the hour value is greater than 6. I need to get up after 7, so this is what I need for my alarm clock. Expressions that return either true or false are called logical expressions.

Comparison operators

These are the comparison operators that you can use in JavaScript programs.

Operator

Name

Effect

>

Greater than

True if the value on the left is greater than the value on the right

<

Less than

True if the value on the left is less than the value on the right

>=

Greater than or equals

True if the value on the left is greater than or equal to the value on the right

<=

Less than or equals

True if the value on the left is less than or equal to the value on the right

==

Equality

True if the value on the left and the value on the right can be promoted to values that are equal

===

Identity

True if the values on the left and the value on the right are the same type and hold the same value

!=

Not equals

True if the value on the left and the value on the right cannot be promoted to values that are equal

!==

Not identical

True if the values on the left and the value on the right are not the same type or do not hold the same value

A program can use comparison operators in an expression to set a Boolean value.

itIsTimeToGetUp = hours > 6;

This statement will set the variable itIsTimeToGetUp to the value true if the value in hours is greater than 6 and false if the value in hours is not greater than 6. Remember that an operator that is a single equals character performs an assignment, not a test. If this seems hard to understand, try reading the statement and listen to how it sounds. The statement “itIsTimeToGetUp equals hour greater than six” is a good explanation of the action of this statement.

CODE ANALYSIS

Examining comparison operators

Question: How does the equality operator work?

Answer: The equality operator evaluates to true if the two operands hold the same value.

> 1==1;
<- true

The equality operator (==) can be used to compare strings and Boolean values, too.

> "Rob"=="Rob";
<- true
> true == true;
<- true

We’ve seen that JavaScript “promotes” values when they are used in expression. This happens with the equality operator, too. The logical value true is promoted to the value 1 when it is used in an expression with the equality operator.

> 1 == true;
<- true

JavaScript returned true because the value true was promoted to 1 before the comparison was performed. Note that comparing true for equality with any other value would return false, because true is always promoted to 1.

> 2 == true;
<- false

Question: What is the difference between equality and identity?

Answer: We’ve just seen how the == (equality) operator above promotes values before comparing them. This means that the operator can compare values of different types.

> true == 1;
<- true

In the example above, the statement compares a logical value with a number. This generates a true result because the true value is “promoted” to the integer value 1 before being compared.

The identity comparison === does not perform any promotion before comparing two values. If we use the identity comparison to compare the logical value of true with 1, a result of false is produced.

> true === 1;
<- false

JavaScript returned false because once side of the identity operator holds a logical value (true), and the other holds a number (1). If, like me, you are the kind of programmer who thinks that programs should never compare numbers and logical values for equality and get a result of true (because comparing numbers and logical values directly is not a meaningful thing to do), then you can use the === comparison operator to make sure of this.

Question: How do I remember which relational operator is which?

Answer: When I was learning to program, I associated the < in the <= operator with the letter L, which reminded me that <= means “less than or equal to.”

Question: Can we apply relational operators between other types of expressions?

Answer: Yes, we can. If a relational operator is applied between two string operands, it uses an alphabetic comparison to determine the order.

> "Alice" < "Brian";
<- true

JavaScript returned true because the name Alice appears alphabetically before Brian.

WHAT COULD GO WRONG

Equality and floating-point values

In Chapter 4, we saw that a floating-point number is sometimes only an approximation of the real number value our program is using. In other words, some numbers are not stored precisely.

This approximation of real number values can lead to serious problems when we write programs that test to see whether two variables hold the same floating-point values. Consider the following statements, which I’ve typed into the Developer View in the Edge browser:

> var x = 0.3;
> var y = 0.1 + 0.2;

These statements create two variables, x and y, which should both hold the value 0.3. The variable x has the value 0.3 directly assigned, whereas the second variable, y, gets the value 0.3 as the result of a calculation that works out the result of 0.1 + 0.2. What do you think we will see if we test the two variables for equality?

> x == y;
<- false

This expression uses the equality operator (==), which will produce a result of true if its two operands hold the same value. However, JavaScript decides that x and y are different because the variable x holds the value 0.3, and the variable y holds the value 0.30000000000000004. This illustrates a problem with program code that compares floating-point values to determine whether they are equal. The tiny floating-point errors mean values we think are the same do not always evaluate that way.

If a program needs to compare two floating-point values for equality, the best approach is to decide they are equal if they differ by only a very small amount. If you don’t do this, you might find that your programs don’t behave as you might expect.

The date and time values returned from the JavaScript Date object are supplied as integers so you can test these for equality without problems.

Logical operators

At the moment, my test to determine whether it is time to get up is only controlled by the hour value of the time.

itIsTimeToGetUp = hours > 6;

The above statement sets the value of itIsTimeToGetUp to true if the hour is greater than 6 (meaning from 7 and onward) but we might want to get up at 7:30. To be able to do this, we need a way of testing for a time when the hour is greater than 6 and the minute is greater than 29. JavaScript provides three logical operators we can use to work with logical values. Perhaps they can help solve this problem.

Operator

Effect

!

Evaluates to True if the operand it is working on is False

Evaluates to False if the operand it is working on is True

&&

Evaluates to True if the left-hand value and the right-hand value are both True

||

Evaluates to True if the left-hand value and the right-hand value are both True

The && (and) operator is applied between two Boolean values and returns true if both values are true. There is also an || (or) operator, which is applied between two Boolean values and returns true if one of the values is true. The third operator is the operator ! (not), which can be used to invert a Boolean value.

CODE ANALYSIS

Logical operators

We can investigate the behavior of logical operators by using the Developer View in the Edge browser. We can just type in expressions and see how they evaluate. Please don’t be confused by the way that the < and > characters are used in the devleoper console samples below.

Question: What does the following expression evaluate to?

<- !true;

Answer: The effect of ! is to invert a Boolean value, turning the true into a false.

> !true;
<- false

Question: What does this expression evaluate to?

> true && true;

Answer: The operands on each side of the && are true, so the result evaluates to true.

> true && true;
<- true

Question: What does this expression evaluate to?

> true && false;

Answer: Because both sides (operands) of the && (and) operator need to be true for the result to be true, you shouldn’t be surprised to see a result of false here.

> true && false;
<- false

Question: What does this expression evaluate to?

> true || false;

Answer: Because only one side of an || (or) operator needs to be true for the result to be true, the expression evaluates to true.

> true || false;
<- true

Question: So far, the examples have used only Boolean values. What happens when we start to combine Boolean and numeric values?

> true && 1;

Answer: It turns out that JavaScript is quite happy to use and combine logical and numeric values. The above combination would not return true, however. Instead, it will return 1.

> true && 1;
<- 1

This looks a bit confusing, but it gives us an insight into how JavaScript evaluates our logical expression. JavaScript will start at the beginning of a logical expression and then work along the expression until it finds the first value it can use to determine the result of the expression. It will then return that value.

In the above expression, when JavaScript sees the left-hand operand is true, it says to itself “Aha. The value of the && (and) expression is now determined by the right-hand value. If the right-hand value is true, the result is true. If the right-hand value is false, the result is false.” So the expression simply returns the right-hand operand. We can test this behavior by reversing the order of the operands:

> 1 && true;
<- true

We know that any value other than 0 is true, so JavaScript will return the right-hand operand, which in this case is True. We can see this behavior with the || (or) operation, too. JavaScript only looks at the operands of a logical operator until it can determine whether the result is true or false.

> 1 || false;
<- 1
> 0 || True;
<- True

You might wish to experiment with other values to confirm that you understand what is happening.

We want to make some JavaScript that takes in hour and minute values and decides whether to sound the alarm. We could try to make an alarm that triggers after 7:30 by writing the following statement:

var itIsTimeToGetUp= hours>6 && minutes>29;

The && (and) operator is applied between the result of two Boolean expressions and returns true if both of the expressions evaluate to true. The above statement would set the variable itIsTimeToGetUp to true if the value in hours is greater than 6 and the value in minutes is greater than 29, which you might think is what we want. However, this statement is incorrect. We can discover the bug by designing some tests:

Hours

Minutes

Required Result

Observed Result

6

00

False

False

7

29

False

False

7

30

True

True

8

0

True

False

The table shows four times, along with the required result (what should happen), and the observed result (what does happen). One of the times has been observed to work incorrectly. When the time is 8:00, the value of itIsTimeToGetUp is set to false, which is wrong.

The condition we are using evaluates to true if the hours value is greater than 6 and the minutes value is greater than 29. This means that the condition evaluates to false for any minute value that is less than 29, meaning it is false at 8:00. To fix the problem, we need to develop a slightly more complex test:

var itIsTimeToGetUp= (hours>7) || (hours==7 && minutes>29);

I’ve added parentheses to show how the two tests are combined by the || (or) operator. If the value of hours is greater than 7, we don’t care what the value of minutes is. If the hours value is equal to 7, we need to test to see whether the minutes value is greater than 29. If you try the values in the table with the above statement, you will find that it works correctly. This illustrates an important point when designing code intended to perform logic like this. You need to design tests that you can use to ensure that the program will do what you want.

The if construction

Suppose I want to make a program that will display a message telling me whether it’s time to get out of bed. We can use the Boolean value we just created to control the execution of programs by using JavaScript’s if construction. Figure 5-3 shows how an if construction fits together.

The figure shows the syntax of if condition. The syntax of 'If condition' is as follows. If left parenthesis condition right parenthesis statement;.

Figure 5-3 If construction

The condition controls the execution of the statement. In other words, if the condition is “truthy,” the statement is performed; otherwise, it is not performed.

if (itIsTimeToGetUp) alert("It is time to get up!");

The statement above would display an alert if it were time to get up. You can see this in use in the example Ch05 Making Decisions in ProgramsCh05-01 Alarm Alert, which displays the alert if you visit the page after 07:30 in the morning.

A screenshot displays the source code forAlarm alert program.
A screenshot displays the closing sections of the source code for Alarm alert program.

This is the full text of the alarm alert page. Note that the statement that implements the “intelligence” of the program is only one tiny part of the code.

The behavior of the if construction is controlled by the condition. The condition does not have to be a variable; it can also be a logical expression:

if ((hours>7) || (hours==7 && minutes>29)) alert("It is time to get up!");

This statement removes the need for the itIsTimeToGetUp variable. However, I quite like using the variable because it helps the user understand what the program is doing.

Adding an else part

Many programs want to perform one action if a condition is true and another action if the condition is false. The if construction can have an else element added, which identifies a statement to be performed if the condition is false. See Figure 5-4.

The figure shows the syntax of if else condition. The structure of If else condition is as follows. If left parenthesis condition right parenthesis statement; else statement;.

Figure 5-4 If construction with else

The else part is added onto the end of a conditional statement. If comprises the keyword else followed by the statement to be performed if the condition is false. We could use it to make our alert program display a message when we can stay in bed.

if(itIsTimeToGetUp)
    alert("It is time to get up!");
else
    alert("You can stay in bed");

This program displays a different message depending on the time of day that the user runs the program. Note that although I’ve spread the statement over several lines, the content matches the structure in Figure 5-4.

CODE ANALYSIS

If constructions

Question: Must an if construction have an else part?

Answer: No. They are very useful sometimes, but it depends on the problem that the program is trying to solve.

Question: What happens if a condition is never true?

Answer: If a condition is never true, the statement controlled by the condition never gets to run.

Question: Why is the statement underneath the if condition in my example indented by a few spaces?

Answer: This statement doesn’t need to be indented. JavaScript would be able to understand what we want the program to do even if we put everything on one line. The indentation is there to make the program easier to understand. It shows that the statement underneath the if construction is being controlled by the condition above it. Indenting like this is such common practice that you will find the behavior “baked in” to the Visual Studio Code editor. In other words, if you start typing an if construction and press the Enter key at the end of the condition part, Visual Studio Code will automatically indent the next line.

Creating blocks of statements

The if condition controls the execution of a single statement. However, sometimes you might want to perform multiple statements if a condition is true. For example, we might what to play an alarm sound as well as displaying an alert message when it is time to get up. To do this, a program needs to control multiple statements from a single condition. You write code for a task like this by creating a block of statements.

A block of statements is a sequence of JavaScript statements enclosed in a pair of curly braces—the { and } characters. You have already seen blocks of statements in the programs we’ve examined and written. In those programs, the statements in all the functions are enclosed in a block. You can create a block anywhere in a program, and it is equivalent to a single statement.

if (itIsTimeToGetUp) {
    alarmAudio.play();
    outputElement.textContent = "It is time to get up!";
}else {
    outputElement.textContent = "You can stay in bed";
}

The code above displays a message and plays an alarm sound. You can find the working program in the example Ch05 Making Decisions in ProgramsCh05-03 Alarm Alert with sound block. This uses the “everything sound” as an alarm, which some might feel a bit harsh, but it certainly wakes me up. Note that in the above code, I’ve used curly braces to enclose the statements for both the if and else parts of the condition, even though there is no need to do this for the else part as it only contains one statement. I do this to make it clear what is going on. It also means that it is easier to add extra statements controlled by the else part because I can just put them inside the block.

Use decisions to make an application

Now that you know how to make decisions in your programs, you can start to make more useful software. Let’s say your next-door neighbor is the owner of a theme park and has a job for you. Some rides at the theme park are restricted to people by age, and he wants to install some computers around his theme park so that people can find out which rides they may go on. He needs some software for the computers, and he’s offering a season pass to the park if you can come up with the goods, which is a very tempting proposition. He provides you with the following information about the rides at his park:

Ride Name

Mininum Age Requirement

Scenic River Cruise

None

Carnival Carousel

At least 3 years old

Jungle Adventure Water Splash

At least 6 years old

Downhill Mountain Run

At least 12 years old

The Regurgitator (a super scary roller coaster)

Must be at least 12 years old and less than 90

You discuss with him the design of the program user interface. The user interface is what people see when they use the program and the steps that they go through when they are using it. In this application, users will specify the ride they want to go on and enter their age. They then click a button and are told whether they can go on that ride (see Figure 5-5).

A screenshot displays a page with a title that reads crazy adventure wonderfunland.

Figure 5-5 Theme park rides

Build the user interface

The first thing we need to do is create the HTML web page and the style sheet for the application. In Chapter 3, we decided that it was a good idea to separate the style sheet file, which holds the style of the page elements, from the page layout. It is also a good idea to separate the JavaScript program code from the HTML layout. We do this by putting the JavaScript into a file with the language extension “.js.” We can then add an element in the head of the HTML file that specifies this file name:

<script src="themepark.js" ></script>

The HTML above is added to the <head> part of an HTML document and includes the contents of the JavaScript file themepark.js in an HTML page. You can see it in use in the HTML below.

A screenshot displays the source code for theme park ride selector program.
A screenshot displays the closing sections of the source code of theme park program.

This is the HTML file for the Theme Park Ride Selector application. It uses some features of HTML that we’ve not seen before. We can create an ordered list of items by using the <ol> tag to enclose some <li> list elements. The browser will automatically number the elements for us. Each element on the page is assigned a class that has a specific style. The settings for each of the styles are in a separate CSS style sheet file called styles.css. A part of this file is given below:

A screenshot displays a part of the source code for theme park ride selector program.

The menuHeading class is in the HTML used to format the heading. It uses the Impact font and adds two shadows to the text. The first shadow is blue and close to the text, which provides a 3D effect for each character. The second shadow is more diffuse and darker blue so that it makes the characters appear to stand out from the page. You can see the effect in Figure 5-5. Each shadow is defined by a color value preceded by three values. The first two values give the x and y offsets of the shadow from the text. The third value determines how “diffuse” the shadow is. The first shadow is not diffused at all, whereas the second has a diffusion size of 10px, leading to the text shown earlier in Figure 5-5.

The style sheet also applies some shared settings to all the menu input classes. This means that the font is set once for all those classes, making it easy to change the font if required. It is a good idea to group classes in this way if they all have a set of common characteristics. Remember that classes accumulate setting values, which are then used on the HTML elements that are assigned to that class. So, for example, the menuYes class will bring together the following settings—some from those shared by other menu settings, and some specific to that class:

font-family:Arial, Helvetica, sans-serif;
font-size: 2em;

color: green;

Add the code

Now that we have the user interface complete, we need to add the JavaScript that implements the behavior that the application needs. When the user presses the button to check their age, the doCheckAge function runs. This function gets values for the number of the selected ride and the age of the person wishing to use it. The function then tests these values to see whether the combination is valid. The first part of this function works in the same way as the adding machine that we created earlier. It fetches text from the input elements in the HTML and uses the Number function to convert the text into a number.

The screenshot shows two variables from two different program.

When these statements have completed, the variables rideNo and ageNo contain the number of the ride and the age of the guest. The next thing the function does is get a reference to the paragraph that will be used to display the result. If you look at the HTML for the user interface, you’ll see that this paragraph has the ID menuAnswerPar:

var resultElement = document.getElementById("menuAnswerPar");

Now that the program has the input data and somewhere to put the output, it can make decisions about the use of the rides. If the user has selected ride number 1, there are no age restrictions for the Scenic River Cruise, so this code is a single test for a ride number of 1. If the user has selected this ride, we set the style class for the result element to the menuYes class. This has the effect of changing the style of that element so that the text is now green. Then the inner text for the paragraph is set to You can go on the Scenic River Cruise so that this is displayed for the user.

if(rideNo==1) {
    // This is the Scenic River Cruise
    // There are no age limits for this ride
    resultElement.className="menuYes";
    resultElement.innerText = "You can go on the Scenic River Cruise";
}

If the user has not selected ride number 1, the program must test to see whether ride number 2 has been picked.

if(rideNo==2) {
    // This is the Carnival Carousel
    // riders must be 3 or over
    if(ageNo<3) {
        resultElement.className="menuNo";
        resultElement.innerText = "You are too young for the Carnival Carousel";
    }
    else {
        resultElement.className="menuYes";
        resultElement.innerText = "You can go on the Carnival Carousel";
    }
}

The code above shows how this works. The program works by nesting one conditional statement inside another. Note how I’ve used the layout of the program to make it clear which statements are controlled by which condition.

Now that you have code that works for the Carnival Carousel, you can use it as the basis for the code that handles some of the other rides. To make the program work correctly for the Jungle Adventure Water Splash, you need to check for a different ride number and confirm or reject the user based on a different age value. Remember that for this ride, a visitor must be at least six years old.

if(rideNo==3) {
    // This is the Jungle Adventure Water Splash
    if(ageNo<6) {
        resultElement.className="menuNo";
        resultElement.innerText =
           "You are too young for Jungle Adventure Water Splash";
    }
    else {
        resultElement.className="menuYes";
        resultElement.innerText = "You can go on Jungle Adventure Water Splash";
    }
}

You can implement the Downhill Mountain Run very easily by using the same pattern as for the previous two rides. But the final ride, the Regurgitator, is the most difficult. The ride is so extreme that the owner of the theme park is concerned for the health of older people who ride it and has added a maximum age restriction as well as a minimum age. The program must test for users who are older than 90 as well as those who are younger than 12. We must design a sequence of conditions to deal with this situation.

The code that deals with the Regurgitator is the most complex piece of the program that we’ve had to write so far. To make sense of how it needs to work, you need to know more about the way that if constructions are used in programs. Consider the following code:

if(rideNo==5) {
    // This is the Regurgitator

The condition is true when the user has selected ride number 3, and all the statements we add to the block of code controlled by this condition will run only if the selected ride is the Regurgitator. In other words, there is no need for any statement in that block to ask the question “Is the selected ride the Regurgitator?” because the statements are run only if this is the case. The decisions leading up to a statement in a program determine the context in which that statement will run. I like to add comments to clarify the context:

if(rideNo==5) {
    // This is the Regurgitator
    if(ageNo<12) {
        resultElement.className="menuNo";
        resultElement.innerText = "You are too young for the Regurgitator";
    }
    else {
        // get here if the age is 12 or above
        if(ageNo>90) {
            resultElement.className="menuNo";
            resultElement.innerText = "You are too old for the Regurgitator";
        }
        else {
            resultElement.className="menuYes";
            resultElement.innerText = "You can go on the Regurgitator";
        }
    }
}

These comments make the program slightly longer, but they also make it a lot clearer. This code is the complete construction that deals with the Regurgitator. The best way to work out what it does is to work through each statement in turn with a value for the user’s age. You can find all the sample code in the folder Ch05 Making Decisions in ProgramsCh05-04 Theme Park.

Using the switch construction

The program code for the ride selector is a sequence of if constructions controlled by the value of rideNo. This pattern appears frequently in programs, so JavaScript contains an additional construction to make it slightly easier. This is something we’ve not seen before. Up until now, everything we have learned is about making something possible. However, the switch construction is all about making something easier. Programs can use a switch to select different behaviors based on the value in a single control variable. Take a look at this code, which implements the Theme Park Ride Selector.

switch(rideNo)
{
    case 1:
    // This is the Scenic River Cruise
    // There are no age limits for this ride
    resultElement.className = "menuYes";
    resultElement.innerText = "You can go on the Scenic River Cruise";
    break;

    case 2:
    // This is the Carnival Carousel
    // .. statements for Carnival Carousel go here
    break;

    case 3:
    // This is the Jungle Adventure Water Splash
    // .. statements for Jungle Adventure Water Splash go here
    break;

    case 4:
    // This is the Downhill Mountain Run
    // .. statements for Downhill Mountain Run go here
    break;

    case 5:
    // This is the Regurgitator
    // .. statements for the Regurgitator go here
}

The code above shows how the switch would be used. The value in rideNo is used as the control value for the switch, and the program will select the case that matches the control value. You can put as many statements as you like in a particular case, but you must make sure that the last statement in the case is the break keyword, which ends the execution of the code for that case. You can find my switch-powered solution for the Theme Park ride selector in the Ch05 Making Decisions in ProgramsCh05-05 Switch Theme Park Ride Selector folder.

You can use the switch statement with strings and integer values, which can be a convenient way of selecting an option. A switch construction can have a default selector, which is obeyed if none of the cases match the control value. You can also use multiple case elements to select a particular behavior. The switch below is controlled by a variable called commandName. The commands Delete, Del, and Erase all result in the erase behavior being selected:

var commandName ;

switch(commandName)
{
    case "Delete":
    case "Del":
    case "Erase":
        // Erase behavior goes here
        break;

    case "Print":
    case "Pr":
    case "Output":
        // Print behavior goes here
        break;

    default:
        // Invalid command behavior goes here
        break;
}

WHAT COULD GO WRONG

Missing breaks in switches can cause mayhem

switch(rideNo)
{
    case 1:
    // This is the Scenic River Cruise
    // There are no age limits for this ride
    resultElement.className = "menuYes";
    resultElement.innerText = "You can go on the Scenic River Cruise";

    case 2:
    // This is the Carnival Carousel
    if (ageNo < 3) {
        resultElement.className = "menuNo";
        resultElement.innerText = "You are too young for the Carnival Carousel";
    }
    else {
        resultElement.className = "menuYes";
        resultElement.innerText = "You can go on the Carnival Carousel";
    }
    break;
}

The code above is part of my switch-controlled version of the Theme Park ride selector. It has a dangerous bug in it. The bug will not cause JavaScript to crash, but it will cause the program to do the wrong thing. The bug is caused by a missing break keyword between case 1 and case 2. When the user selects ride number 1, the program will perform the statements for case 1 and then go straight through and perform the statements for case 2. This means that if the user selects the Scenic River Cruise (option 1), the program will behave as if the Carnival Carousel (option 2) was selected. Bugs like this that cause a program to “mostly work” are particularly dangerous, and you should make sure to test for every input to make sure that you have no missing breaks in your switches.

MAKE SOMETHING HAPPEN

Improve the ride selector

You can use the application in Ch05 Making Decisions in ProgramsCh05-04 Theme Park as the starting point for a really good ride selector program—but it is not perfect. It would benefit from some testing of the input values to prevent the user from entering invalid ride numbers or age values. You could even design custom graphics for each ride and then display them when the ride is selected. You could even add suitable sound effects for each ride, too.

Fortune Teller

The Math.random function can be used in if constructions to make programs that perform in a way that appears random.

var resultString = "You will meet a ";

if(Math.random()>0.5)
  resultString = resultString+"tall ";
else
  resultString = resultString+"short ";

if(Math.random()>0.5)
  resultString = resultString+"blonde ";
else
  resultString = resultString+"dark ";

resultString = resultString + "stranger.";

The if constructions test the value produced by a call to the Math.random function. This produces a value in the range 0 to 1. If the value is less than 0.5, the program selects one option; otherwise, another option is picked. This is repeated to produce a random seeming program. You can build on this sequence of such conditions to make a fun fortune teller program. You could also create some graphical images to go along with the program predictions.

What you have learned

This chapter has introduced you to the use of Boolean values in programs and showed you how to make code that can take decisions. Here are the major points we have covered:

  • Boolean data has one of only two possible values—true or false. JavaScript contains the keywords true and false that can be used to represent these values in programs.

  • JavaScript can regard variables of other types in terms of their “truthy” or “falsy” nature. Any numeric value other than 0 is regarded as true. Any string other than an empty string is regarded as true. The value that represents Not a Number (NaN) is regarded as false, but the value that represents Inifinity is regarded as true.

  • The JavaScript function Boolean can be used to convert a variable of any type into the Boolean value true or false, according to the ways of “truthy” and “falsy.”

  • Programs can generate Boolean values by using comparison operators such as < (less than) between values of other types. Care should be exercised when comparing floating point values (numbers with a fractional part) for equality because they might not be held accurately.

  • JavaScript provides two ways to test if things are the same. The equality comparison operator (==) will promote values before comparing them. Comparing the values true and 1 for equality would give a true result because the logical value true would be promoted to 1 before the comparison. The identity comparison operator (===) will always return false when comparing values of different types, so comparing true and 1 for identity would return false.

  • JavaScript also provides Boolean operators such as && (and) that can be used between Boolean values.

  • The if construction is used in programs to select statements based on Boolean expression used as a condition. The if construction can have an else part, which specifies a statement to be performed if the condition is false. Conditional statements can be nested.

  • JavaScript statements can be enclosed in curly braces ({ and })to create blocks that can be controlled by a single condition in an if construction.

  • It is possible to store the JavaScript component of an application in a separate code file that is included in an HTML page.

  • The switch construction is an easier way to create code that selects a behavior based on the content of a single control variable.

Here are some questions that you might like to ponder about making decisions in programs:

Can a program test two boolean values to see if they are equal?

Yes, it can. The equality operator (==) will work between two values that are either true or false.

Why does JavaScript provide equality and identity logical operators?

The identity operator (===) can be said to be “stricter” than the equality operator (==) because attempts to compare values of different types (for example compare a number with a Boolean value) will always return false. This is why some programmers (including me) use identity (===) in preference to equality (==).

Can JavaScript regard any value in terms of “truthy” and “falsy”?

Yes. Essentially, if there is something there (a value other than zero or a non-empty string) then this will be regarded as true. Otherwise, it will be false.

Must every if construction have an else part?

No. If an else is present, it will “bind” to the nearest if construction in the program. If you write a program in which only some conditions have an else part, you need to make sure that an else binds to the correct if.

Is there a limit to how many if conditions you can nest inside each other?

No. JavaScript will be quite happy to let you put 100 if statements in a row (although you would have a problem editing them). If you find yourself doing this, you might want to step back from the problem a bit and see if there is a better way of attacking the problem.

How long can a block be?

A block of code can be very long indeed. You could control 1,000 lines of JavaScript with a single if condition. However, very long blocks can make code hard to understand. If you want to control a large amount of code with a condition, you should put the code into a function. We will learn about functions in Chapter 8.

Does the use of Boolean values mean that a program will always do the same thing given the same data inputs?

It is very important that, given the same inputs, the computer does the same thing each time. If the computer starts to behave inconsistently, this makes it much less useful. When we want random behavior from a computer (for example, when writing a fortune teller program), we have to obtain values that are explicitly random and make decisions based on those. Nobody wants a “moody” computer that changes its mind (although, of course, it might be fun to try to program one using random numbers).

Will the computer always do the right thing when we write programs that make decisions?

It would be great if we could guarantee that the computer will always do the right thing. However, the computer is only ever as good as the program it is running. If something happens that the program was not expecting, it might respond incorrectly. For example, if a program was working out cooking time for a bowl of soup, and the user entered 10 servings rather than 1, the program would set the cooking time to be far too long (and probably burn down the kitchen in the process).

In that situation, you can blame the user (because they input the wrong data), but there should probably also be a test in the program that checks to see if the value entered is sensible. If the cooker can’t hold more than 3 servings, it would seem sensible to perform a test that limits the input to 3.

This part of a program is called “input validation,” and it is a very important that programs do this. When you write a program, you need to “second guess” what the user might do and create decisions that make your program behave sensibly in each situation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.211.66