App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android...

16
Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

Transcript of App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android...

Page 1: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

Android Programmingwith App Inventor for Android

(draft 1, 1/2010)

David Wolber

Page 2: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

Table of ContentsChapter 7: Conditional Blocks ............................................................. 3

If and Ifelse Blocks ............................................................................. 4Sample: Calling a random friend from a set of friends. ............................ 5Sample: Mastermind........................................................................... 7Summary .........................................................................................10Problems..........................................................................................10

Chapter 8: Iteration .......................................................................... 11Computing the Sum of the First Three Numbers.....................................12Computing the Sum of the first N Numbers ...........................................14A Bug in the Program.........................................................................15Problems..........................................................................................16

Page 3: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

Chapter 7: Conditional BlocksChapter 6 discussed lists and the for-each repeat block that repeats somefunction on every item of a list (e.g., texting a list of friends). This chapterdiscusses apps that branch to execute different functions based on somecondition.

Most interesting apps consist of event-handlers that are not linear recipes,but contain conditional branches and repeat loops. We discussed the for-each repeat block in chapter 6 and how an app can continually branch up inthe code to execute some functions over an entire list of data. Such codemight be described as "perform this function n times, where n is the numberof items in the list".

We can also define event-handlers that perform a function 0 or 1 time,based on some boolean condition. Such event-handlers can be describedwith the following flow chart:

Here, when the event occurs, we execute operation A, then only executeaction B1 if some condition is true. If the condition is false, we execute B2.

Conditions are questions such as "has the score reached 100?" or "is arandom number 1 or 2". Such examples are simple; in general, you cancode any complex logic with nested if-else conditions and various logicaloperators.

Page 4: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

If and Ifelse Blocks

Control blocks allow you to put conditional branches and loops into theevent-handlers of your App Studio program. You'll find such blocks in theControl drawer of the built-in palette:

Let's first look at an simple example where we set the text of a label to "Youwin" when a score reaches 100.

The first thing we do is to drag an if-then-do block into the program area.Then we build a condition to plug into the "test" slot.

Conditions are boolean, meaning they return a result of true or false. Theygenerally test the value of properties and variables using the followinglogical operators:

These operators can be found in the Math and Logic drawers.

For our sample, we'll drag in an = block:

The condition we want to check is "is the variable score equal to 100".Assuming we've already defined the variable score, we can find a block for itin the My Program drawer of My Blocks. We use a number for the 100. Westick those two items into the slots of the =, and the whole = block into theslot of the if-then-do:

Page 5: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

If the test evaluates as true, we want to tell the end-user they've won:

Note that if the test is false (score not equal to 100), the action within the if-then block doesn't happen. In fact, nothing happens. If you want a false testto trigger an action, you can use an if-then-else block.

Sample: Calling a random friend from a set of friends.

Suppose you wanted an application you could use when you were bored--you press a button and a random friend is called. You could use a random-integer block to randomize the selection, then an if-then-else block to setthe phone number to one of the choices:

In the above sample, we use a global variable RandomNum to hold therandom number returned from the random-integer function. This number

Page 6: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

will be 1 or 2 based on the from and to arguments given.

After setting randomNum to either 1 or 2, we compare it to the number 1 inthe ifelse test. If the randomly generated number is 1, we set the phonenumber to 3779199. If it is not 1, the ifelse test is false, so the else-doblocks are executed and the PhoneNumber is set to 3594787.

If we wanted to choose between more than two numbers, we'd place an if-then or if-then else within else clause of the first if-else:

If the first test is true, the first then-do branch will be executed. If it is false,then the else branch is executed, which immediately runs another test. So ifthe first test is false, and the second true, the second then-do is executed. Ifboth tests are false, the else-do branch at the bottom is executed, and thethird number (2423428) is called.

Note that this modification only works because we also modified the toparameter of the random integer so that a number between 1 and 3 isgenerated.

Page 7: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

When one control construct is placed within another, we say it is nested.We'd say that the event-handler above has a "nested if-else". By usingmultiple levels of nested if-else blocks we can write app behaviors thatchoose between n choices, instead of just two or three.

Sample: Mastermind

Mastermind is a great thinking game. There are many on-line versions of it,including the one at http://www.irt.org/games/js/mind/. The game (app)generates a "secret code" of four colors. The player then continually tries toguess the code, receiving feedback on each of the guesses. The feedbacktells the player how many colors are in the right position (exact matches)and how many are the right color but in the wrong position (partialmatches).

Let's build an Android version of this app. In the process, will make use ofsome of the conditional (if-else) and iterative (foreach) blocks we've beendiscussing.

Iteration 1: Toggling through colorsIt's always a good idea to start with something simple, then build oncomplexity. We'll start with some simple functionality. Let the user choosebetween three colors by clicking a button. On each click, the button shouldchange to the next color in the sequence, and when it reaches the third(last) color it should change color to the first color in the sequence.

First, we create the components for this initial iteration. We are only going toprogram one color, but we'll add two color buttons now, as well as a Guessbutton and a feedback label.

Next, we open the blocks editor to code the toggling behavior. We'll first

Page 8: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

program the behavior for the first color button (ColorButton1). We'll assumethat the button has an initial background color of blue, and that clicking thefirst time should change it to Cyan, clicking a second time should change itto Green, and a third time back to Blue. The user should be able to continuethis sequence forever to choose their color.

When Color1Button is clicked, we check the background color of the buttonand compare it to Blue. If it is Blue, we set it to Cyan. If its not Blue, theouter else-do is executed. This causes a second check, and the backgroundcolor is compared to Cyan. If it is Cyan, the color is set to Green. If it is notCyan, the inner else-do is executed, and it is set to Blue.

Note that if the first test, Color1Button.BackgroundColor = Blue, is true, thebackground color is set to Cyan and the even-handler ends-- the else-do andthe inner test, Color1Button.BackgroundColor = Cyan, is never checked. SoBlue will change to Cyan.

On the next click, the first test will be false, the second test will be true, andthe color will change to Green.

On the third click, the first test will be false, the second will also be false, sothe inner else-do will be executed, changing the color to Blue. On the fourthclick we'll be back to where we started, and the first test will be true.

Mastermind Iteration 1A. Toggling through colors using a list.

We could program the second color button (and the third and fourth) in thesame manner by writing a similar event-handler for Color2Button. However,

Page 9: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

for the purposes of comparison, let's write it using a list of colors instead ofa nested if-else. The advantage with this alternative solution is that our codewill work even if we change the colors or number of colors that shouldappear.

The first step is to define a list variable for the colors:

This variable will be defined when the app starts up.

Along with the colors list, we need to keep track of the current color. Forthis, we'll define another variable to use as an index. Note that this strategyis similar to how we used an index "questionNumber" in the quiz application.For this one, we'll call it currentColor and we'll start it at 1:

Now we're ready to code the click event for Color2Button. On the click, we'llfirst add one to the currentColor. The we'll use an if-then block to handle thecase when we're at the last color in the list (we'll reset currentColor to 1).Finally, we'll use select list item to set the background color to the nextcolor:

Page 10: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

Take a good look at this event-handler and analyze it side-by-side with theevent-handler above for Color1Button. Both event-handlers will cause thesame behavior, just in different ways. The first uses a nested if-else tochoose the next color, while the latter uses a list and an index variable tochoose the next color.

The advantage of the latter method is that the list can be modified and theapp will still work. As most apps work with dynamically changing data, this isa very important difference.

Summary

Conditional blocks allow for the specification of complex behaviors anddecision-making in an app. This chapter provided some examples ofconditional behavior, including nested conditions that allow for choosingbetween multiple alternatives. In the next chapter, we'll examine even morecomplex behaviors and continue with the Mastermind sample.

Problems

Complete the following and document on your portfolio:

1. SaveAs your ball animation program into BallGame. Modify the programso that it reports a win when the player has touched the ball 3 times.

2. Write a callRandomFriend which randomly calls one of your friends whenyou run the application. Put at least three numbers into the randomizer anduse an if-else and a nested if-else.

3. Complete a quiz application:• The first question should be displayed on startup.• When the user clicks next, the next question is displayed.• When the user clicks next on the last question, the first question is

displayed again.• When the user enters an answer and clicks "Answer", the app checks

the answer and reports either "correct" or "incorrect, the answer is..."showing the correct answer.

• You should have two lists, one for questions and one for answers, anduse an if-statement to check if the answer is correct.

Page 11: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

Chapter 8: IterationThe previous chapter discussed lists and methods for iterating through a list,that is, applying some operations repeatedly to items in a list. This chaptercontinues the discussion of iteration and introduces the while-do block. Inthe chapter, you'll learn how to write mathematical apps such as one to sumup the first n numbers and another to compute factorial(n).

Computers are great at doing the same task over and over. They never gettired. As the chapter 4 discussion of the for-each block showed, the blockswithin an event-handler need not be linear "recipe" like programs, but cancontain repeat loops that execute some operations over and over.

In App Inventor, there are two blocks for specifying repeatable code: thefor-each and the while-do. The text everyone in a list app in Chapter 4 useda for-each block to text all the phone numbers in a list.

The while-do is a bit more complicated to use, but it is more general thanthe for-each: whereas the for-each is specifically for repeating operations oneach item of a list, a while-do can repeat any operations. Furthermore,whereas the for-each always repeats once for each item in the list, with thewhile-do the programmer can specify that the operations repeat while anyarbitrary condition is true (the converse way to put it is that the programcan repeat until any arbitrary condition becomes false.

With a while-do, the app checks a condition, and if its true, executes some

Page 12: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

operations (B in the diagram). After completing B, the app loops back upand rechecks the condition again. If its still true, B is repeated. If it is false,the app "pops out of the loop" and continues with C.

Computing the Sum of the First Three Numbers

What is the sum of the first 3 numbers? What is the sum of the first 5numbers? The first N numbers? How did your brain compute it?

The hard thing about programming is usually not the problem we aresolving: most of us can add up 1+2+3=6. The difficult part of it is breakingyour thought process down so that you can instruct a computer to do thesame thing.

When you add up the first so many numbers, your brain probably uses twomemory cells-- one is a counter for the new number you're adding, and onefor a "running sum". So you begin with 1 as the couner and 1 as the sum.Then you get the next counter 2 and add it to your sum, giving you 1+2=3as the sum. Then you get the next counter 3 and add it to the running sum,which is 3. This gives you a new sum of 6. Then you get 4 and add it to therunning sum, giving a new sum of 10. And so on.

If we were to trace these memory cells, we'd get:

counter sum1 12 33 64 10

This is how your brain works, but how do you get an app to do the samething? This is where a while-do comes into play.

Let's start by writing an app that sums the first 5 numbers. Later, we'llgeneralize it to sum up the first n numbers, where n is some number inputby the user. Here's pseudocode for what we want:

set counter to 1set sum to 0repeat while counter is less than or equal to 6:

add the counter to the running sumincrement counter

Now let's convert this pseudocode into an App Inventor app. First, we need

Page 13: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

to define two variables, which we'll call "counter" and "sum":

Next, we drag in a while-do block from the Control drawer of the built-inpalette:

Note the the while-do has a test just like with the if and ifelse blocks. Withboth, the app performs the blocks inside if the test is true. The difference isthat with the while-do, the app loops back up and checks the test again eachtime after executing the inside blocks. A while-do does something 0 or moretimes. An if does it 0 or 1 times.

In this case, we want to add up the first five numbers, so we want to repeatwhile the counter is less than 6. We'll add one to the counter each time sothat at some point it will become 6 and the app will "pop-out of the loop".Here's how we fill in the while-do block:

When we reach the while test the first time, the value of counter is 1. Since1 is less than 6, the app will execute the operations within the while-do, inthis case the modification (set) of the sum and the modification (set) of thecounter. So sum becomes 0 +1 = 1 and counter becomes 1+1 = 2.

counter sum

Page 14: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

2 1

After the counter is modified, we reach the bottom of the while-do (note thatthe blocks to modify TotalLabel.Text are below the while-do loop and will notbe repeated). When the bottom is reached, the app loops back up and re-tests the while test (counter<6). Now counter is 2 which is still less than 6.So we repeat the blocks within the while again. This time sum becomes2+1=3, and counter becomes 2+1=3:

counter sum3 3

We loop back up and test, and counter is still less than 6. After we repeattwice more, we have:

counter sum5 10

When we check the test, counter (5) is less than 6, so we go in the whileagain. sum is changed to 15 and counter to 6:

counter sum6 15

Now when we loop back up and check the test, it is false. When the whiletest is false, we "pop out of the loop" meaning we don't again repeat theoperations within it. Instead, the app jumps to the blocks below the whileloop, in this case the blocks to display the sum in TotalLabel.Text. Thecorrect value 15 is displayed and the event-handler is complete.

Computing the Sum of the first N Numbers

Changing the app so that it can add up numbers up to any number n theuser enters is relatively straight forward. We just introduce another variable,n, and set it to the value of the textbox in the user interface above thewhile-loop. We then modify the test so that it no longer tests that thecounter is less than 5, but less than n+1:

Page 15: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

Now if the user enters a 5 in the NText text box, the variable N will be set to5 and the while-do will repeat 5 times. And in fact, the app will display 15 inthe TotalLabel.Text box, just as with our previous solution.

If the user closed the app and re-started it, then typed in a 3, the app wouldcorrectly display 6 as the sum.

A Bug in the Program

Now let's consider the case when the user enters a number and clicks theSumItButton, then enters a new number and clicks it again, withoutrestarting the app. Specifically, assume the user first enters a three andclicks, then enters a 2. After correctly answering 6 the first time, the appwould report that the sum of numbers from 1 to 2 is also 6! Watson, wehave a bug! Can you step through the app to see what the problem is?

The problem lies in the fact that counter and sum are only initialized whenthe app starts, based on the variable definitions. In our scenario, after theapp correctly computes the sum of 1 to 3 as 6, the values of the variablesare:

counter sum4 6

When the user then enters a 2 in NText and clicks the SumItButton again,those values are still in counter and sum-- they are not re-initialized, eventhough we really want to start over.

The solution is to initialize the variables within the event-handler so that

Page 16: App Inventor 7-8 - USF Computer Sciencewolber/bookChapters/App_Inventor_7_8.pdf · Android Programming with App Inventor for Android (draft 1, 1/2010) David Wolber

each time the SumItButton is clicked, the computation begins anew. Here isthe fixed solution:

Because the initializations of counter and sum are within the event-handler,the sum will be computed correctly every time.

Problems

1. Write a factorial(n) application.

2. Write the text all numbers in a list app using a while-do instead of a for.