LEARN TO PROGRAM WITH SMALL BASIC: An Introduction to Programming with Games, Art, Science, and Math (2016)

8. MAKING DECISIONS WITH IF STATEMENTS

Which shirt should I wear? What should I have for dinner? Where should I go? Should I wear my pants so low that my underwear shows? You ask yourself questions like these and answer them every day. Just as you make decisions, your programs can too! Of course, they won’t do this on their own. Your programs only make the comparisons you want them to make, and then they either run some statements or skip them. In this chapter, you’ll write programs that can make decisions.

The programs you’ve written so far followed a simple path where the statements execute from top to bottom. But sometimes you might need to run some statements if a condition’s true or other statements if a condition’s false. This is similar to how you make decisions in your life. For example, you might say, “If there’s snow, then I’ll go skiing” or “If I finish my work before 4:00 PM, I’ll go to the movies; otherwise, I’ll just go to Steve’s house.” In both cases, the action you take depends on a condition.

Small Basic uses a few different ways to control which statements run in a program: selection statements (If, If/Else, If/ElseIf), jump statements (Goto), and iteration or loop statements (For and While). In this chapter and the next, we’ll explain selection and jump statements, and we’ll explain loops in Chapters 13 and 14. In this chapter, you’ll learn about relational operators, Boolean expressions, and how you can use If/Else statements to write some interesting programs.

The If Statement

Suppose your mom calls and tells you, “On your way home, stop at Captain Snarf’s Pizza. If it’s open, get us a large pizza.” Her instructions don’t say what to do if the pizza place is closed; you assume that you’ll just go home empty-handed. Listing 8-1 represents this situation in code.

' SnarfPizza.sb
2 TextWindow.WriteLine("Is Snarf's Pizza open?")
3 TextWindow.Write("Enter 1 (for open) or 2 (for closed): ")
4 status = TextWindow.ReadNumber()
5
If (status = 1) Then
7   TextWindow.WriteLine("You bought a delicious pizza!")
EndIf
9 TextWindow.WriteLine("Time to go home!")

Listing 8-1: Using If and EndIf keywords

Run this program and enter 1 in response to the prompt (to indicate that Snarf’s is open). Because the condition on line 6 is true, the program displays the message on line 7, which is "You bought a delicious pizza!" The statement on line 9 (which comes after the EndIf keyword) runs whether you buy a pizza or not. Run this code again, but this time enter 2 in response to the prompt. What happens?

The statement on line 6 is an If statement. The part of the statement after the If keyword (status = 1) is the condition. The program checks to see whether the condition is true. In this case, it checks whether Captain Snarf’s Pizza is open. The code between the Then and the EndIfkeywords is the action—what the program does. The program does the action only if the condition’s true. Programmers usually use the term code block to refer to the statements between the If and the EndIf keywords (between lines 6 and 8).

NOTE

Small Basic doesn’t require you to place parentheses around conditional expressions, meaning you can write the statement on line 6 like this: If status = 1 Then. But parentheses make the statement easier to read, so we’ll use them in this book.

Small Basic automatically indents If statements as you type the code. This makes the program easier to read and clearly shows when statements are part of code blocks. If your code ever gets unindented, right-click in the Editor and select Format Program from the pop-up menu to indent all your code. Awesome!

The If statement is the basis of all decision making in Small Basic. Check out the illustration in Figure 8-1 to understand how it works.

The condition of an If statement is a logical expression (also called a Boolean expression or a conditional expression) that’s either true or false. If the condition is true, the program runs the statements between the If and EndIf keywords (which is called the body of the If statement). But if the condition is false, the statements in the block are skipped. The program runs the statement after the EndIf keyword whether the condition is true or not.

image

Figure 8-1: The flowchart of the If/Then/EndIf block

TIP

You can think of an If statement as a detour in the flow of a program. It’s like an optional roller coaster loop.

BOOLEANS IN THE REAL WORLD

The word Boolean is used in honor of George Boole, a 19th-century British mathematician who invented a system of logic based on just two values: 1 and 0 (or true and false). Boolean algebra eventually became the basis for modern-day computer science.

In real life, we use Boolean expressions all the time to make decisions. Computers also use them to determine which branch of a program to follow. A remote server may grant or deny access when you swipe your credit card at a department store based on whether your card was valid (true) or invalid (false). A computer in a vehicle will automatically deploy the airbags when it decides that a collision has occurred (collision = true). Your cell phone may display a warning icon when the battery is low (batteryLow = true) and remove the icon when the battery’s charge is acceptable (batteryLow = false).

These are just few examples of how computers cause different actions to be taken by checking the results of Boolean conditions.

You can test all sorts of conditions using relational operators, which we’ll discuss next.

Relational Operators

The condition (status = 1) in Listing 8-1 tests whether the variable status is equal to 1. We call the equal sign here a relational operator (or a comparison operator) because it tests the relationship between two values (or expressions). Small Basic supports five other relational operators that you can use in conditions. Table 8-1 shows you these relational operators.

Table 8-1: Relational Operators in Small Basic

Operator

Meaning

Mathematical symbol

=

Equal to

=

Less than

<=

Less than or equal to

Greater than

>=

Greater than or equal to

<> 

Not equal to

Let’s look at a couple of short examples to see how these operators work. A lot of people want to be on Dancing with the Stars. You are hired to write an application form that potential dancers will fill out. One of the requirements is that the applicant must be at least 18 years old. How would you check this condition in your program?

Well, that’s easy. You can write something like this:

TextWindow.Write("How old are you? ")
age = TextWindow.ReadNumber()

If (age < 18) Then
  TextWindow.WriteLine("Sorry! You're not old enough!")
EndIf

The If condition checks whether age is less than 18. If it is, the applicant isn’t old enough, and their dream to dance with the stars is over. Nice try, tiny dancer!

Another way to check the applicant’s age is like this:

If (age >= 18) Then
  TextWindow.WriteLine("So far so good. You may have a chance!")
EndIf

The If condition checks whether age is greater than or equal to 18. If it’s true, the applicant passes this condition and still has a chance to dance with the stars.

But what if the applicant also needs to have exactly 9 years of dancing experience? (Don’t ask why!) You can write something like this:

TextWindow.Write("How many years of dancing experience do you have? ")
experience = TextWindow.ReadNumber()
If (experience <> 9) Then
  TextWindow.WriteLine("Sorry! You don't have the required experience.")
EndIf

Note that the If condition uses the not equal (<>) operator. If an applicant enters any number other than 9, it’s game over for that dancer!

TRY IT OUT 8-1

Santa wants to deliver presents more efficiently. Instead of crawling down chimneys, he’ll drop the presents down the chimneys from his sleigh. He needs a program that inputs the sleigh’s current height (in meters) and then computes the time it takes (in seconds) for a present to fall to the chimney. Here is the formula:

image

The program must check that the height Santa enters is a positive number before computing the time. Run the following program two times. Enter a positive height in the first run and a negative height in the second. Explain what happens in each case.

TextWindow.Write("Please enter the height (meters): ")
height = TextWindow.ReadNumber()
If (height > 0) Then
  time = Math.SquareRoot(10 * height / 49)
  time = Math.Round(time * 100) / 100 ' Rounds to 2 decimal places
  TextWindow.WriteLine("Fall time = " + time + " sec. ")
EndIf

Complex If Conditions

Like arithmetic operators, relational operators also need two operands, one on each side. These operands can be simple, using variables and constants, or they can be complicated math expressions. For example, if you want to check that you have enough money to buy two large pizzas and pay a $5 tip, enter this:

If (myMoney >= (2 * pizzaPrice + 5)) Then

Small Basic first finds the value of 2 * pizzaPrice + 5 (using the current value of pizzaPrice). It then compares the result with the current value of myMoney to see whether the If condition is true or false.

You can also use any method that returns a value inside the If condition. For example, if you create a pizza delivery video game and want to give the player an extra life when their score gets to 100, 200, 300, and so on, you can enter this:

If (Math.Remainder(score, 100) = 0) Then

This condition checks the remainder of the current score, score, divided by 100. If the remainder is 0, the If condition is true and the player gets the extra life they earned.

TRY IT OUT 8-2

Translate each of the following statements into a logical expression, and then check whether the condition is true or false. Assume x = 4 and y = 5.

1.    The sum of x and 3 is less than 8.

2.    The remainder of x divided by 3 is 2.

3.    The sum of x2 and y2 is greater than or equal to 40.

4.    x is evenly divisible by 2.

5.    The minimum of x and y is less than or equal to 10.

Comparing Strings

We just showed you how to use relational operators to compare numbers, but in some applications you’ll need to compare strings. For example, you might need to check if a user entered the correct password for your program or if they guessed the right word in a word-guessing game.

You can use the = (equal) or <> (not equal) operators to test whether two strings are identical. Listing 8-2 asks the user to guess the secret passcode.

' SecretCode.sb
2 TextWindow.Write("Guess the secret code! ")
3 guess = TextWindow.Read()
If (guess = "Pizza rules!") Then
5   TextWindow.WriteLine("You're right!")
EndIf
7 TextWindow.WriteLine("Goodbye!")

Listing 8-2: Comparing strings in Small Basic

Run this program several times, and try a few different guesses. For example, try entering pizza rules! (using a lowercase p). What happens? Run the program again, but this time enter Pizza rules! (with an uppercase P). Did it work this time? Yep! The reason is that when you compare strings, they must be an exact match. All the capitalization, spacing, and punctuation must match.

Note that the other relational operators (<, <=, >, and >=) can’t be used with strings. If you use any of these operators with non-numeric strings, the result will always be false.

The If/Else Statement

Your mom calls you back again and gives you more instructions: “One more thing! If Captain Snarf’s is closed, please stop by LongLine Grocery and get a frozen pizza.” Now you can use If/Else statements in Small Basic to help you!

The If/Else statement (also called the two-way If statement) lets you take one action when the condition’s true and another action when the condition’s false. Figure 8-2 illustrates how this statement works.

image

Figure 8-2: The flowchart of the If/Else statement

If the condition is true, Small Basic runs the statements in the If block (between the If and Else keywords). If the condition is false, Small Basic runs the Else block (between the Else and EndIf keywords). So Small Basic runs the statements in only one of the two blocks (either the Ifblock or the Else block).

You can write your mom’s new instructions, as shown in Listing 8-3.

 1 ' SnarfPizza2.sb
 2 TextWindow.WriteLine("Is Snarf's Pizza open?")
 3 TextWindow.Write("Enter 1 (for open) or 2 (for closed): ")
 4 status = TextWindow.ReadNumber()
 5
 6 If (status = 1) Then
 7   TextWindow.WriteLine("You bought a delicious pizza!")
 8 Else
 9   TextWindow.WriteLine("You got a frozen pizza!")
10 EndIf
11 TextWindow.WriteLine("Time to go home!")

Listing 8-3: Demonstrating the If/Else statement

If status = 1, meaning that Captain Snarf’s is open, you’ll buy a delicious pizza and go home. But if status is not 1 (Captain Snarf’s is not open), you’ll buy a frozen pizza from LongLine Grocery and go home.

Your mom’s instructions assume that LongLine is always open and that you’ll find what you’re looking for. But what if the grocery store has run out of frozen pizzas? Stay tuned; you might receive another call from your mom to give you new instructions!

TRY IT OUT 8-3

Complete the following program to create a brainteaser quiz. This program will surprise you with its answers. Be sure to get creative with the way you present the correct answers!

' Asks first question
TextWindow.Write("If you take 2 apples from 3 apples, how many apples do you have? ")
ans = TextWindow.ReadNumber()
If (ans = 2) Then
  TextWindow.Write("Correct. ")
Else
  TextWindow.Write("Nope. ")
EndIf
TextWindow.WriteLine("If you take 2 apples, then you have 2 apples!")
TextWindow.WriteLine("")

' Ask more fun questions here

Here are some suggestions for the questions you can add:

1.    How many inches of soil are in a hole 1-foot deep and 1-foot wide?

(Answer: 0. Display: There is no soil in a hole!)

2.    Is a ton of gold heavier than a ton of feathers? (Yes or No)

(Answer: No. Display: A ton of anything weighs a ton!)

3.    How many 4-cent stamps are in a dozen?

(Answer: 12. Display: There are always 12 in a dozen!)

Nested If and If/Else Statements

The statements you write in the body of an If (or Else) block can be any kind of Small Basic statement, including another If or If/Else statement. Writing an If (or If/Else) statement inside another one creates a nested If statement (see Figure 8-3). The inner If statement can also include other If or If/Else statements, and the nesting can continue to any level you want. But be careful not to nest down too many levels, or you’ll get lost in all the levels and might feel like Super Mario falling down an endless pit!

You can use nested If statements when you need to perform multiple checks on the same variable or when you need to test multiple conditions. Let’s look at an example that uses a nested If/Else block to test multiple conditions.

image

Figure 8-3: Illustrating nested If and If/Else statements

After hanging up with you, your mom thought LongLine Grocery might be out of frozen pizzas. So she calls you again and says, “Listen, if Captain Snarf’s is closed and LongLine doesn’t have any frozen pizzas, then get a bag of frozen chicken wings.” Listing 8-4 shows how to turn these instructions into code.

 1 ' SnarfPizza3.sb
 2 TextWindow.WriteLine("Is Snarf's Pizza Open?")
 3 TextWindow.Write("Enter 1 (for open) or 2 (for closed): ")
 4 status = TextWindow.ReadNumber()
 5
 6 If (status = 1) Then ' Snarf's is open
 7   TextWindow.WriteLine("You bought a delicious pizza!")
 8 Else ' Snarf's is closed, so you'll go to LongLine
 9   TextWindow.WriteLine("Snarf's is closed. Try LongLine Grocery.")
10   hasPizza = Math.GetRandomNumber(2) ' Checks your luck
11   If (hasPizza = 1) Then
12     TextWindow.WriteLine("You got a frozen pizza!")
13   Else
14     TextWindow.WriteLine("You got a bag of frozen chicken wings!")
15   EndIf
16 EndIf
17 TextWindow.WriteLine("Time to go home!")

Listing 8-4: Demonstrating nested If conditions

There it is—a nested If/Else statement! If Captain Snarf’s is closed, you run a nested If/Else statement to decide what to buy from the grocery store. Line 10 sets the variable hasPizza randomly to either 1 or 2. A 1 means that LongLine still has frozen pizzas, and a 2 means the grocery store has run out. Run this program several times to see what you’ll pick up for dinner tonight.

But wait, your mom just realized that you might not have money, and she’s calling back: “Sorry, I forgot to tell you. If you don’t have enough money, just go to Steve’s house and have dinner there!” Now we have to add another level of nesting. Listing 8-5 shows you how to handle this situation.

 1 ' SnarfPizza4.sb
 2 TextWindow.Write("How many dollars do you have? ")
 3 myMoney = TextWindow.ReadNumber()
 4
 5 If (myMoney >= 25) Then ' I have enough money
 6   TextWindow.WriteLine("Is Snarf's Pizza Open?")
 7   TextWindow.Write("Enter 1 (for open) or 2 (for closed): ")
 8   status = TextWindow.ReadNumber()
 9
10   If (status = 1) Then ' Snarf's is open
11     TextWindow.WriteLine("You bought a delicious pizza!")
12   Else ' Snarf's is closed, so you'll go to LongLine
13     TextWindow.WriteLine("Snarf's is closed. Try LongLine Grocery.")
14     hasPizza = Math.GetRandomNumber(2) ' Checks your luck
15     If (hasPizza = 1) Then
16       TextWindow.WriteLine("You got a frozen pizza!")
17     Else
18       TextWindow.WriteLine("You got a bag of frozen chicken wings!")
19     EndIf
20   EndIf
21 Else ' I don't have enough money
22   TextWindow.Write("Go to Steve's house for dinner ")
23   TextWindow.WriteLine("(it's earthworm pizza night).")
24 EndIf
25 TextWindow.WriteLine("Time to go home!")

Listing 8-5: More levels of nesting

As you can see, you make decisions in a program in the same way that you make decisions in real life!

TRY IT OUT 8-4

Change the following program so that it starts by reading the values for x and y input by the user. Change the output messages to make the users laugh!

If (x > 5) Then
  If (y > 5) Then
    TextWindow.WriteLine("The skylight is falling!")
  Else
    TextWindow.WriteLine("Now it's time to play the piper!")
  EndIf
Else
  TextWindow.WriteLine("I'll huff, puff, and blow $5 on tacos!")
EndIf

The Goto Statement

The Goto statement also changes the flow of your program by letting you branch to a statement that appears earlier or later in your program. Look at Mark and Andy’s annoying conversation in Listing 8-6.

' GotoDemo.sb
2 Again:
3 TextWindow.Write("Mark: Pete and Repeat were in a boat. ")
4 TextWindow.WriteLine("Pete fell out, who was left?")
5 TextWindow.WriteLine("Andy: Repeat.")
6 TextWindow.WriteLine("")
7 Program.Delay(1000) ' Waits 1 sec to slow the program down
Goto Again

Listing 8-6: An endless Goto loop

The statement in line 2 is called a label; it’s used to identify a specific line of the program. Labels end with a colon, and you can place them anywhere in a program.

This program then runs lines 3–7. When it reaches line 8, it returns to line 2 (to the Again label), and Small Basic runs lines 3–7 again. A loop is when you run the same block of code more than once, and this loop goes on forever (like The Song That Never Ends and the Barney song). Run this program to see its output (and try to get those songs out of your head; mwahaha).

The Goto statement is an unconditional jump (or unconditional transfer) statement, because the program jumps unconditionally (without asking any questions) to the location given by the Goto’s label. The If/Then statement, on the other hand, is a conditional transfer statement, because the program changes its normal flow only when a certain condition is met.

Most programmers suggest that you don’t use Goto statements because they can turn a program into spaghetti code—code that is so tangled and complex that no one can follow it! But sometimes a Goto statement can be very useful, and it’s helpful to know when it might come in handy.

One common use of Goto is to check the data entered by a user to make sure it’s correct, as shown in Listing 8-7.

' VaildateWithGoto.sb
2 TryAgain:
3 TextWindow.Write("Enter a positive number: ")
4 num = TextWindow.ReadNumber()
If (num <= 0) Then
6   Goto TryAgain
EndIf
8 TextWindow.Write("You entered: " + num)

Listing 8-7: Using Goto to check the user’s input

This code asks the user to enter a positive number (line 3) and reads the input into the num variable (line 4). If the user’s input number isn’t positive (line 5), the Goto statement sends the program back to the TryAgain label and asks the user to reenter the number. If the input number’s positive, the program continues to the statement on line 8. You’ll learn another way to check users’ input using a While loop in Chapter 14.

TRY IT OUT 8-5

We (the authors of this book) plan to use the following program to measure our readers’ satisfaction. Do you think it’s fair? We do! Rewrite it and make it personal. Then have someone take your survey!

Again:
TextWindow.Write("How many stars do you give this book [1-5]? ")
ans = TextWindow.ReadNumber()
ans = Math.Floor(ans) ' In case the user typed a decimal
If (ans <> 5) Then
  TextWindow.Write("Invalid number! Please enter an integer. ")
  TextWindow.WriteLine("That's greater than 4 but less than 6.")
  Goto Again
EndIf
TextWindow.WriteLine("Wow! Thank you. You made our day!")

Programming Challenges

If you get stuck, check out http://nostarch.com/smallbasic/ for the solutions and for more resources and review questions for teachers and students.

1.    The following program creates a simple coin toss game by asking the user to toss a coin and enter either an h (for heads) or a t (for tails). Based on the user’s input, the program displays a different message. Do you think the computer’s playing a fair game? See if you can get a family member or friend to play this unfair coin toss game!

TextWindow.Write("Toss a coin. Heads(h) or Tails(t)? ")
ans = TextWindow.Read()
If (ans = "h") Then
  TextWindow.WriteLine("I won. I'm the champion!")
Else
  TextWindow.WriteLine("You lost. Cry home to Momma.")
EndIf

2.    Captain James P. Cork is piloting the Century Hawk enterprise-class starship. He has intercepted a message from the enemy Clingoffs and needs your help cracking the code! The message has millions of sets of three numbers; each set of numbers needs to be sorted and then reentered to understand the message. Build a program that reads three numbers from the user and then displays these numbers, sorted from smallest to biggest, to Captain Cork. We wrote the sorting logic for you, but you’ll need to write the user input part. Open the file CaptainCork_Incomplete.sbfrom this chapter’s folder, and follow the comments to complete this application and stop the vile Clingoffs!

3.    You’re starting a new business called Mud in a Can. You’ve got mud, and people want it, so why not put it in a can? Write a program that lets your customer enter the height and radius of the can. The program should then compute the can’s volume (to figure out how much mud to put in it). Have the program display an appropriate error message if the user enters a negative value for the height or the radius.

4.    As the fairytale goes, Rumpelstiltskin helps a woman spin straw into gold. In return, she promises to give her firstborn child to him. When the baby is born, the woman refuses to give up the baby. Rumpelstiltskin agrees to release his claim to the child if the woman can guess his name in three days. Write a program that prompts the woman to enter her guess and then checks whether her guess is correct. Here’s a sample run of the program:

What is my name? Paul
No! Your child will be mine! Mwahaha!
What is my name? Peter
No! Your child will be mine! Mwahaha!
What is my name? Rumpelstiltskin
Correct. You can keep the child. She's a brat anyway!