Module 2: Boolean Variables and Arrays


Objectives

 

By the end of this module, for simple programs with real numbers, you will be able to:

 

2.0 Audio:
 


2.0    Boolean variables

 

What is a Boolean variable?

  • An int variable takes integer values like: 12, 256, or -9.

  • A double variable takes on values like 3.141, -14.0, or 2.718.

  • A boolean variable takes on one of only two values: true or false.
 

An example:

  • boolean, true and false are reserved words.

  • Note: true and false are not in quotes.
 

Boolean operators:

  • Recall: an operator is something that "acts" on the values of variables (like multiply takes two values and does the familiar multiplication of those values).

  • Thus, a Boolean operator will "do things" with Boolean values like true and false.

  • Two binary operators: && and ||

  • One unary operator: !

  • An example:

  • To understand the && operator:

    Let's see what c could be based on all possible combinations of a and b values:
    a b c = a && b
    false false false
    false true false
    true true true
    true false false

  • In short, the result of an AND operation is true only when both operands are true.

  • Similarly, let's look at the || operator:

    Let's see what c could be based on all possible combinations of a and b values:
    a b c = a || b
    false false false
    false true true
    true true true
    true false true

  • In short, the result of an OR operation is false only when both operands are false.

  • The ! operator:
    a !a
    true false
    false true

  • In short, the NOT operator flips the value.

  • Note: the above table describes some of the "rules" for logic.
 

Let's do a few examples.

First, consider


public class BooleanExample2 {

    public static void main (String[] argv)
    {
	boolean a = true;
	boolean b = false;
	boolean c = true;
	boolean d = false;

	boolean w = a && b;
	System.out.println (w);

	boolean x = a && c;
	System.out.println (x);

	boolean y = a || b;
	System.out.println (y);
	
	boolean z = b || d;
	System.out.println (z);

	boolean u = !a;
	System.out.println (u);
    }

}
     
 

2.1 Exercise: Type up (in BooleanExamle2.java) and see what the above prints out.
 

Now let's explain:

  • First, look at:
    	boolean a = true;
    	boolean b = false;
    	boolean c = true;
    	boolean d = false;
         
    • Here, there are four boolean variables, each of which is assigned a (boolean) value.
    • Think of the variables as "boxes" in the usual way but as boxes that can hold only boolean values (true or false).

  • Next, look at
    	boolean w = a && b;
    	System.out.println (w);
         
    • We know that a has the value true in it, while b has the value false.
    • Thus, the && operator is applied to the values true and false.
    • You can picture this as: true && false.
    • What is the result?
    • Similar to applying the "rules of multiplication" to two numbers, we apply the rules of AND (that is, &&) to true and false.

    • The result is: false.
    • Thus, the value false is assigned to the variable w.
    • This is what's printed.

  • Similarly, with
    	boolean y = a || b;
    	System.out.println (y);
         
    the result is true

  • The unary operation ! is a bit different:
    	boolean u = ! a;
    	System.out.println (u);
         
    • Here, the value in a is copied and "flipped" to its opposite.
    • Thus, because the value in a is true the result is false

    • This is what gets assigned to the variable u.
 

2.2 Video:

 


2.1    Combining Boolean operators

 

Just as many int or double variables can be combined in an expression like (i*j) - a/(a+b) so can boolean variables:

  • Consider these examples:
    	boolean v = (a && b) || (a || d);
    	System.out.println (v);
    
    	boolean s = (!v) || (! (b && c));
    	System.out.println (s);
         

  • We can draw an expression tree to help us evaluate (by hand) the first expression:

    • The expression tree is just something we do on paper to understand the result.
    • What's interesting is that "under the hood", a similar tree is constructed by javac when the program is compiled.
 

2.3 Exercise: In module2.pdf, draw the expression tree for the second expression above and evaluate it.
 


2.2    Boolean operators and other types of variables

 

Boolean operators and values arise most frequently with working with numbers.

For example, consider this example:

	int age = IOTool.readIntFromTerminal ("Enter your age: ");
	if (age >= 100) {
	    System.out.println ("May everyone be so fortunate");
	}
     
  • Let's pay attention to the condition (age > 100).

  • This is really a Boolean result: it's either true or false.

  • Thus, we could have written:
    	int age = IOTool.readIntFromTerminal ("Enter your age: ");
            boolean isCentenarian = (age >= 100);
    	if (isCentenarian) {
    	    System.out.println ("May everyone be so fortunate");
    	}
         

  • Notice that the Boolean result of (age > 100). (which is either true or false will get assigned to the boolean variable isCentenarian.

  • Also, we can use Boolean variables directly as the expression for a conditional (if) statement.
 

It is even more common to combine multiple such comparisons into a single expression:


	int age = IOTool.readIntFromTerminal ("Enter your age: ");
	if (age >= 100) {
	    System.out.println ("May everyone be so fortunate");
	}
	else if ( (age >= 90) && (age < 100) ) {
	    System.out.println ("Hey, that's not so bad");
	}
     
  • Here, we've combined two Boolean expressions:
    1. The expression (age < 100)
    2. The expression (age >= 90)
    using the && (AND) operator.

  • Each part (often called a clause) evaluates to either true or false.

  • For example, suppose the age entered was 31.
    • The clause (Boolean expression) (age >= 90) evaluates to false.
    • The clause (age < 100) evaluates to true.
    • Then the large expression turns out to be (false) && (true) which evaluates to false.
    • Thus, one would not enter the else if block of code.
    • In the diagramming approach:

    • Lastly: did you notice how the parentheses were deployed to have the overall expression make sense?
 

Boolean expression can get as complex as desired, for example:

	int age = IOTool.readIntFromTerminal ("Enter your age: ");
	int hours = IOTool.readIntFromTerminal ("Hours of exercise/day: ");
	if ( ( (age >= 90) && (hours > 2) ) 
	     ||
	     ( (age < 10) && (hours > 3) ) ) {
	    System.out.println ("That may be too much exercise");
	}
     
 

2.4 Exercise: In module2.pdf, draw the expression tree for the expression above and evaluate it when age=5 and hours=3.
 

2.5 Exercise: Consider this code example:

	int k = 5;
	int m = 3;
	int n = 8;
	boolean a = true;
	boolean b = false;
	char ch = 'q';

	boolean first = (m < k) && (n > k);
	boolean second = ( (k+m == n) || (k-m < 10) );
	boolean third = first && (!second);
	boolean fourth = (first || a) && (b);
	boolean fifth = (ch >= 'a') && (ch <= 'z');
     
If one were to print the last five (Boolean) variables, what would be printed out? Do the exercise without writing code and by drawing expression trees in in module2.pdf.
 

2.6 Video:

 


2.3    Using Boolean variables

 

Let's now use Boolean variables in a few examples.
 

Suppose we wish to solve the following problem:

  • We are given an array of integers and an additional integer.

  • Our goal is to search the array to see if the additional integer is in the array.

  • We are to print "found" if it's there, else "not found" if it's not there.

  • Consider this program:

 

2.7 Exercise: Trace through the program in module2.pdf. Explain why this does not accomplish the task.
 

  • Let's make another attempt:

 

2.8 Exercise: Explain why this does not accomplish the task either (in module2.pdf).
 

  • Instead, let's use a Boolean variable to flag whether we've found the item in the array.

 

2.9 Exercise: Trace through and convince yourself that this works. Try another searchvalue that isn't actually in the array. Will this work if found is initialized to true?
 

  • Note: one can replace if (found == true) with if (found):

 

2.10 Video:

 


2.4    Boolean arrays

 

Just as we created arrays of int's or double's, we can create boolean arrays.

For example:

  • Observe how similar the declaration is to an integer array:

  • Again, space is created using the new reserved word:

 

2.11 Exercise: Suppose we replaced the second for-loop with

Without typing up the program, identify what gets printed out.
 

Next, let's develop an application in steps: counting all the prime numbers less than or equal to some given n.

We'll exclude 2 (a prime number) for the moment, to simplify the code a little.
 

Let's start by eliminating all the numbers divisible by 2 (but starting from 3 onwards because 2 is prime by definition):

  • Conceptually, this is what we're doing:
       Numbers:  3    4    5    6    7    8    9    10    11    12    13  ...
       Remove:        4         6         8         10          12        ...
         

  • Which leaves
                 3         5         7         9          11          13  ...
         

  • Of course, these are not the prime numbers (yet) because they have some numbers divisible by 3, by 5 etc.

  • Notice the general idea:
    • We start by assuming all are prime.
    • Then, we eliminate all that are divisible by 2.
 

2.12 Exercise: Why do we create an array of size n+1 above? Why do the second and third for-loops begin with 3?
 

2.13 Exercise: Modify the above code so that we eliminate both multiples of 2 and multiples of 3. Write your code in PrimeExercise.java.
 

To identify the primes we need to eliminate all numbers that are divisible by some other number, that is:

  • Remove all number divisible by 2.
  • Then, remove all number divisible by 3.
  • Then, remove all number divisible by 4.
  • ... and so on.
  • When do we stop?

Thus, we will replace the second for-loop with this nested one:

  • Thus, we first eliminate all numbers divisible by k=2 (outermost loop).

  • Then, we eliminate all numbers divisible by k=3, etc.
 

2.14 Exercise: Implement the above program (in MyPrimes.java) to count the primes, and confirm that it works.
 

2.15 Exercise: In module2.pdf, trace through the above loop when n=15 by drawing picture of the array and its contents after each outerloop iteration.
 

2.16 Exercise: You should notice some unnecessary iterations through the outer for-loop. What is a more reasonable upper limit for the outer loop?
 

2.17 Exercise: Go back to Module 0 of Unit 0 to examine the first of the two programs on primes.
 


2.5    Reading and writing

 

First, the term boolean:

  • Why such a strange word?

  • George Boole was among the earliest mathematicians who realized that, just like numbers, logical values (true/false) have their own rules of combination (that is, an algebra).

  • The term Boolean algebra now means the "algebra of Boolean variables", where the operators are different from the numeric operators we're used to (like subtraction, division).

  • As we've seen, some Boolean operators are AND, OR, NOT.

  • In Java, these three are represented by &&, ||, !.

  • In case you're wondering ... these three operators suffice for just about everything that's needed from Boolean variables.

  • We use the reserved word boolean: for Boolean variables in Java.

  • Note: many earlier languages did not have such a specific type set aside for Boolean values and instead "faked it" with the numbers 0 and 1.
 

One of the most common uses of Boolean variables is as a flag variable:

  • Consider this example:
         boolean containsNegative = false;
         for (int i=0; i<data.length; i++) {
             if (data[i] < 0) {
                 containsNegative = true;
             }
         }
         
  • Here, we initialize a flag (the Boolean variable containsNegative) to false.
         boolean containsNegative = false;
         

  • Then, when going through the array, we look to see if we need to "flag" that we've found a negative value.
             if (data[i] < 0) {
                 containsNegative = true;
             }
         

  • So, at the end, if it is true that there's a negative value, we can do something:
         // Later in the program ...
         if (containsNegative) {
             // Do something ...
         }
         
 

2.18 Exercise: In MultiplesOf3.java, add code to "flag" whether or not an array of numbers contains a multiple of 3. Start with this template in main:

    public static void main (String[] argv)
    {
        int[] someNumbers = {1, 4, 9, 16, 25};

        // Write your code here ...

    }
     
 

Neatness in writing large Boolean expressions:

  • Consider this example:
            if (((age > 0) && (age < 12) && (withAdult)) || (age > 12)) {
    	    System.out.println ("OK to watch this movie");
            }
         
  • It is hard to read the intention here.

  • Using spaces and multiple lines helps make the intention clear:
    	if ( ( (age > 0) && (age < 12) && (withAdult) )
    	     || 
    	     (age > 12) ) {
    	    System.out.println ("OK to watch this movie");
            }
         
  • Notice the subtle lining up of equivalent Boolean blocks:
    	if ( ( (age > 0) && (age < 12) && (withAdult) )
    	     ||
    	     (age > 12) ) {
    	    System.out.println ("OK to watch this movie");
            }
         
  • That is, the entire expression
    	     ( (age > 0) && (age < 12) && (withAdult) )
         
    is parallel to
    	     (age > 12) 
         
    because the two expressions are on either side of the OR operator ||.
  • It is easy to make a mistake if you don't use meaningful style when writing.
 

Whitespace in expressions:

  • Above, we wrote:
    	     ( (age > 0) && (age < 12) && (withAdult) )
         
  • Some people will leave out the whitespace around operators:
    	     ( (age>0) && (age<12) && (withAdult) )
         
  • Generally, in the early coursework, we'd prefer exploiting whitespace to add clarity.

  • When you are a much more experienced programmer, you can opt for less whitespace.

  • The one big exception is the use of whitespace in the three expresions that comprise a for-loop. We typically do NOT surround the operators with whitespace.

  • Thus, we write
          for (int i=0; i<10; i++) {
              // Whatever ...
          }	     
         
    and NOT
          for (int i = 0; i < 10; i ++) {
              // Whatever ...
          }	     
         
    Why? It's just how the convention around loops has come to be. Perhaps because the added whitespace makes it hard to see the three different pieces of the loop's parameters.
 


2.6    When things go wrong

 

 

2.19 Exercise: In PG13.java type up

        int age = 12;
        boolean withAdult = true;
	if ( ( (age > 0) && (age < 12) && (withAdult) )
	     || 
	     (age > 12) ) {
	    System.out.println ("OK to watch this movie");
        }
     
and identify the logical error.
 

2.20 Exercise: Without writing up the code, identify the error below

	if (age = 12) {
	    System.out.println ("Fine, you can watch");
	}
     
 

2.21 Exercise: In RoundOffError.java, write up

	double x = Math.sqrt (2);
	double y = x * x;
	if (y == 2) {
	    System.out.println ("They're equal");
	}
     
How would you fix the problem?
 

2.22 Exercise: Without writing it up, find the logical error here:

	boolean allPositive = false;
	int[] someNumbers = {1, 2, 3};
	for (int i=0; i<someNumbers.length; i++) {
	    if (someNumbers[i] < 0) {
		allPositive = false;
	    }
	}

	if (allPositive) {
	    System.out.println ("They're all positive");
	}

     
 

2.23 Audio:


On to Module 3



© 2017, Rahul Simha