Chapter 8: Arrays and issues in automating a real-world application

This chapter will continue the study of arrays. Arrays are an important way of structuring information and provided in most programming languages. The application featured in this chapter brings several general issues of program development into discussion: automating a real-world application, testing and scaling-up. In this chapter, you will

  • learn about arrays and collections
  • gain experience using loops to manipulate array elements
  • acquire appreciation of what may be required for a computer implementation of anapplication, specifically when it is necessary to program a pause
  • learn favorable ways to test an application
  • get practice using JavaScript arrays, the image collection of the Document Object Model for HTML documents, JavaScript for-loops, and functions setting up timed events.
Motivating Example

NOTE: The motivating example for this chapter, as with the others, is a game. You may question our calling this a 'real-world application', but it is. People, your potential audience of users, have ideas about how this application works in 'real-life', away from computers. When you attempt to produce a computer version of such an application, you need to be aware of these aspects of the application. Similarly, you need to be aware of people's experiences with other computer applications. All these factors must be considered when designing and building applications.

The game Memory, also called concentration, typically is played with a set of cards consisting of some number of pairs of matching cards. Figure 1 shows the opening screen for a Memory game using a small deck of cards. The hyperlink to shuffle the cards may be removed for the final version of the game.

Figure 1. Opening screen for Memory game.

The player clicks on one and then a second of the rectangles.

Figure 2. Screen shot after player moves.

The display shown in Figure 2 will only remain on the screen for a short time before the original screen reappears. This simulates the cards being flipped back. Of course, there are no cards, just image files assigned to specified positions.

If the player clicks on two cards assigned to the same image, that is, a matched pair, then these images remain visible as shown in Figure 3.

Figure 3. Player finds a match.

You will read about how to implement this game and then how to take steps to implement a larger, improved version.

The critical features required for this application include

  • a way to represent the game board, namely the cards as images that can change back and forth between an image representing the common card back and images representing the card face
  • a way for clicking on the card to invoke a function
  • variables representing the state of the game so that the function can distinguish first turn and second turn and, upon the second turn, compare the two card faces
  • a way to simulate shuffling of the cards
  • a way to insert a pause so that the player has time to study the card faces
  • a way to determine when the game is over. There is no way in the basic game for the player to lose, but it is necessary to determine when the player has won by matching all the pairs of cards.
  • a way to prevent a player from clicking on more than two cards. Since there will be a pause after clicking on the second card, a fast player could keep clicking to reveal more card faces.

Introduction to concepts

An array is an aggregation of data. Most programming languages provide arrays, though, as always, the details differ. Arrays allow you, the programmer, to represent sets of values, which eases the implementation of applications that involve sets of things. The code to reference a member of the set makes use of an index value or a key value.A challenge is to not confuse the index or key value with the contents of the array member for that index or key value.

Repeating a sequence of statements, looping, is a common requirement for programming. You may know the number of times you need a sequence of statements to be repeated or it may depend on the value of a variable. Looping is especially useful when manipulating arrays.

The computer implementation of a manual task, a task done 'by hand' in the real-world, can require extra or different steps to work at all or to work in an efficient way. This will be discussed in a general way and then illustrated with the game of Memory.

Testing a program, making sure the application works as required, can take as long as the initial coding. There are ways to make testing easier.

Description: arrays and collections

You have seen JavaScript and ActionScript arrays in previous examples. These were each the simplest type of array: sequences of values, all of the same datatype, with the individual members accessible by index values, numbers going from 0 to 1 less than the number of elements in the array. Assuming the example from Chapter 6,

var options=new Array();

options[0] = "rock";

options[1] = "paper";

options[2] = "scissors";

then the assignment statement

played = options[1];

would assign "paper" to the variable played.

More typically, the index value in an expression involving an array would not be a constant, but a variable.

played = options[answer];

would be interpreted as follows by the language processor:

locate the variable options, confirm that it is an array and determine the length in order to know what are allowable index values (what are the array bounds)

locate the variable answer and extract its value

confirm if the value is an integer within the array bounds

assuming everything is confirmed okay, extract the indicated element of the array

Figure 4 shows two variables, answer and options, with actual contents for the elements of options and n indicating that answer holds something, but exactly what is not known.

Figure 4. Schematic for array and index variable.

You can think of the variable answer as a pointer into the array. Figure 5 shows this.

Figure 5. Schematic showing variable pointing to array element.

Languages differ in what happens when a value is used as an array index that is not within bounds of the array. This could be a number that is too small (less than zero), too big, or a value that is not a number at all.

TECHNICAL NOTE: C++ does not do run-time checking on array bounds! This means that if the value of answer was greater than 2, something would be assigned to played, but not what was intended. Similarly, if the assignment statement was

options[answer] = played;

and answer held an incorrect value, then the value of played would be plopped down in an incorrect location. One of the advantages many see in Java over C++ is the run-time checking on array bounds. You do need to realize that this feature comes with a cost: the run-time check does take time.

END OF TECHNICAL NOTE

The behavior of JavaScript is complex with respect to assignments to a position in an array using an index value that is out-of-bounds. If answerheld an integer value, say 4; played held the string "dirt";and the assignment statement

options[answer] = played;

was executed, then the value held by the options array would be

"rock", "paper", "scissors", , "dirt"

meaning that the item at the 3rd position was undefined, but the 4th position was the string"dirt". JavaScript creates and sets the new element.

An assignment statement

played = options[answer];

would not trigger an error, but later use of the variableplayed might cause an error since it has value undefined.

As you would expect, strongly-typed languages require array variables to be declared. Some languages fix the size of the array at declaration time and some allow the array to grow or shrink in size. Some languages allow flexibility for the ranges of index values: they do not have to be 0 to 1 less than the number of items in the array. For example, in certain languages, the index values could be set to be 2000 to 2005 for a problem involving data stored by the year.

TECHNICAL NOTE: Arrays can be more complex. Some programming languages support arrays in which the elements are not all the same datatype. Some programming languages support multi-dimensional arrays directly. Others provide this feature by allowing one-dimensional arrays in which the elements are themselves arrays.

An associative array holds elements accessible by keys. A key can be any value type. A standard example is a set of values, each associated with a day of the week. The keys are strings spelling out the days. If the associative array is classes, then

classes['Monday']

would show information about Monday classes.If the variable currentday held a string indicating one of the days of the week, then

classes[currentday]

would show information for that day.

Now you may be saying that this is nice, but it would not be that much trouble to encode the days of the weeks as numbers. This is, in fact, what the Dateclass does. Associative arrays provide an alternative approach.

OTHER LANGUAGE NOTE: Associative arrays also can be used when the keys are not known ahead of time. For example, here is an example from php, a language for server-side programming. In php, variable names start with a dollar sign. Assume that $cart is to hold information on what someone has ordered, $product holds the code for the product being ordered and $quantity holds the quantity, then

$cart[$product] = $quantity

would be used to add the order of $qty of $product. The key/value pair, $product/$quantity, has been added to the associative array $cart.

END OF OTHER LANGUAGE NOTE

The Document Object Model that defines how to write code relating to an HTML document specifies several collections, sets of elements with the same name and similar structure. The images collection can be used like an array to reference and set the attributes of <imgtags.

TECHNICAL NOTE: You can read the full specification of the DOM at

EXAMPLE: A common technique in programming is to use parallel structures to represent aspects of an application. For example, two arrays can hold information in which the ithelement of one corresponds to the ith element of the other. In the Memorygame featured in the chapter, an array named faces holds the file names of images that are to be displayed in the corresponding member of the document.images collection.

Description: looping

Looping was an early addition to programming languages. Abstractly, a loop specifies a starting value for the loopor index variable, a condition that determines if the body of the loop is to be executed, and a changing operation for the loop variable. This last operation can be called the incrementing step, but it need not be restricted to adding to the loop variable. The loop variable may be used inside the body of the loop or not. In JavaScript and ActionScript, the for-loop follows the concise syntax of C++ and Java. Any variable can be used, but following a convention established with Fortran many years ago, the name you will see most frequently isi. Assuming that start and last are numbers, the code

for (i=start; i<=last; i++) {

}

establishesias the loop variable initialized to hold the value start as specified by the assignment statement in the first position within the parentheses. The expression following the first semi-colon, theconditional expression, directs the language processor to compare the value of i and last. As long as i is less than or equal to last, the body of the loop, the code between the brackets, is executed. Then the variable i is incremented by 1 as indicated in the expression i++ and the process repeats. If start is not less than or equal to last, the loop body would not be executed even once. Assuming that start is less than last, the body is executed (1 + last-start ) times.

The format allows any three expressions in the three positions within the parentheses. For things to work, the second expression needs to make sense as a conditional and the last expression should change the value of the loop variable in such a way as to ensure that the loop will terminate. A loop that does not stop is called an infinite loop. Some language processors will detect such a situation and some will not.

OTHER LANGUAGE NOTE: If you need to extract all the entries in an associative array, a different type of loop construct is required. The language php has theforeachfacility. To extract all the order information from the shopping cart example suggested above, there would be a loop

foreach ($cart as $pid => $qty) {

}

The body of the loop would be repeated for each key/value pair in the array. In the body, the code would reference the key as $pid and the value as $qty.

END OF OTHER LANGUAGE NOTE

EXAMPLE: The Memory application uses looping for shuffling the cards.

Description: array operations: push, pop, and slice

There are multiple ways to assign values to an array variable. In JavaScript, the statement

var models = new Array();

defines models to be an array variable, but does not assign a value to the variable. You can assign the whole array or assign values to elements of the array as was shown previously in the options example.

An array variable can be set up with values in the declaration statement.

var models = [

"heart",

"crane",

"frogface"

]

TIP: The multiple lines used in the declaration of models makes it easy to add new elements. However, you still need to be careful to put commas after each entry except the last one.

Another technique for adding elements to an array is to use the push method. Assuming that models is still the array with 3 elements as declared and initialized in the previous code, the statement

models.push("box");

will add an element to the end of the variable. Think of a stack of dishes in a cafeteria and you are pushing an item at the top of the stack. The models array is now

["heart","crane","frogface", "box"]

The pop method performs two tasks. It removes the last element from the array and returns that value. So after the statement

last = models.pop();

is executed, the variable last has the value "box" and models is back to being

["heart","crane","frogface"]

TECHNICAL TIP: The push and pop operations are called LAST-IN/ FIRST OUT processing, also known as stack processing.

The splice method combines removing and adding elements to an array. The name is intended to invoke the action of cutting something out and grafting something in its place. The method has 2 or more parameters. The first parameter indicates the position where the splicing is to start; the second parameter is the number of elements to be removed. The splice method can have 1 or more optional parameters after these first 2. These parameters are values to be added, spliced, into the array.

Assuming the models array is

["heart","crane","frogface", "box"]

the models.splice(1,2) will change the array to be

["heart", "box"]

Following this with models(0,1,"bird","fox","purse");

will make the variable be

["bird","fox","purse", "box"]

Description: computer versus real-world version of an application

When automating a task or application that exists in a manual version, one strategy is to take the manual way as a model and implement each step. This may or may not work and, if it does work, it may not produce the best results.

EXAMPLE: When people play the Memory game that is the featured example of this chapter, a player turns over one card and then another to reveal the faces. If the cards match, the player takes them off the board. If the cards do not match, the player flips them both over so the cards are face down again. One implementation of the game would require the player to use the mouse to choose the cards and then touch the cards again to restore them to the face down position. Most people would suggest letting ‘the computer’ handle the flipping over or taking away as appropriate. This computer version differs from the original game: the tasks of the player have changed. The tasks are similar to other computer games.

However, there is one additional issue for the game builder to address. The computer implementation needs to include a step that the real-world game did not have: the program must enforce a pause to make sure the player sees the unmatched cards. If a pause is not inserted into the program, the player would not see the second card. Putting in a pause will require setting up a timed event.