Chapter 7. Learning About Loops with a Raffle App

In the previous chapters, you used the if-then-else control block several times. The if then else block enables apps to make decisions. It is one of the fundamental computing concepts that is present in any programming language. There is a second fundamental programming concept—the loop, which we will explore in this chapter. A loop allows a program to repeat code. More specifically, in App Inventor, a loop will let us execute a stack of blocks multiple times.

To illustrate the concept of a loop, we will create a digital raffle App in this chapter. In case you aren't familiar with a regular (nondigital) raffle, we will explain. A raffle organizer gives participants a ticket with a number on it and puts a duplicate of that ticket in a bowl. When all the tickets have been given out (and put in the bowl), the raffle organizer then randomly picks a ticket out of the bowl (often times with a blindfold on) and announces the winning ticket number. The participant with the matching ticket number then claims a prize.

Creating a digital raffle app using App Inventor is not a new idea. Others have created similar apps before. For example, http://www.appinventor.org/content/howDoYou/RecordingInfo/phone shows how to create a very simple digital raffle app. We will extend this idea and create a more versatile digital raffle app. For our digital Raffle App, participants send a text message with a specific code to the raffle organizer. The raffle organizer runs the app on his or her phone, which keeps track of all the participants' incoming text messages and phone numbers and selects a random winner. Then, the app notifies the winner that she or he has won and notifies the rest of the participants that they did not win. This is a fun participatory game for a party, event, or a meeting break.

In this chapter, you will learn how to do the following:

  • Create a user interface for the Raffle App
  • Create and initialize a list and a variable
  • Use a texting component to send/receive text messages
  • Add items to a list
  • Select a random winner
  • Notify the winner that he or she has won
  • Use a loop to send the same notification e-mail to all the participants who did not win
  • Clear out the list and the variable

Creating the project and building the GUI

In preparation of using the Raffle App, the raffle organizer will give two pieces of information to everyone who wishes to participate in the raffle: the organizer's phone number and a code. The raffle organizer can distribute this information by either sharing them verbally or writing then down for everyone to see. The participants will then send a text message to the raffle organizer's phone number with the code typed in the body of the text message. When the app (running on the raffle organizer's phone) receives all of the text messages containing the code, it will save the all the senders' phone numbers in a list. Then, the raffle organizer will click on a button to randomly select a winner from the list of phone numbers. The winning phone number will be displayed on the raffle organizer's phone screen, and the app will also send a text message notification to the winner's phone indicating that he or she has won. Meanwhile, the app will notify the rest of the participants that they did not win.

Creating a new project

You will start by creating a new project. At this point, this step will probably be very familiar to you as you have already done this several times in the previous chapters. As shown in the following screenshot, click on the Start new project button after logging into App Inventor. Then, in the following pop-up message box, give an appropriate name for this app. We will use the name Digital_Raffle.

Creating a new project

Creating the User Interface (UI)

Now that we have created a new project, it is time to add the first component that we will use, a Label. The raffle organizer will create a code to share with all the participants. Since the raffle organizer may conduct several raffles, we will use a label to display the code on the organizer's phone. For this app, we chose the code: I want to win. We will program the app to compare this code, I want to win, to any text message that the raffle organizer's phone receives. If it is a match, the app will save the associated phone number into a list. As shown in the following screenshot, drag a Label from the User Interface Palette drawer onto the Viewer:

Creating the User Interface (UI)

At this time, we would like to reiterate the importance of naming components appropriately. Proper naming helps programmers when they are creating behavior in the Blocks editor. Additionally, appropriate names make it easier to understand the logic of the code. Lastly, should you decide to extend this app six months after first creating it, aptly named components will help you remember the purpose of each component.

Given that, rename Label1 as CodeLabel. To rename Label1, select Label1 in the Components column. Recall that selecting a component will make its background green on the screen, which indicates that it is active. Then, click on the Rename button at the bottom of the panel. In the pop-up window, enter the new name.

We will use this label to display the code (text) I want to win. Enter I want to win (without the quotes) in the Text property box. To make the code easily visible, we make the FontSize property 45. Finally, set Width of this label to Fill parent.

Creating the User Interface (UI)

Next, we will add a button right below CodeLabel. This is the button that the raffle organizer will click on to select a winner. Drag a Button from the User Interface palette onto the Viewer, as shown in the following screenshot:

Creating the User Interface (UI)

Rename Button1 to WinnerButton. By default, the Text property of the button shows Text for Button1. Change the Text property to something more informative by clicking in the text box and typing Pick Winner. Also, change the Width property to Fill parent so that the button is of the same width as the label above it.

Creating the User Interface (UI)

After adding CodeLabel and WinnerButton, add a third component, another label, to display the phone number of the winner. Just like the CodeLabel, Drag another Label below WinnerButton and rename it, WinnerLabel. Since we will only use this label after a winner is selected, thus delete everything under the Text property, so that WinnerLabel does not show anything. To have a consistent look, set the Width property to Fill parent.

Finally, set the FontSize property to 35 so that the winner's phone number when displayed is not too small. The following screenshot shows the app after WinnerLabel is added and configured:

Creating the User Interface (UI)

Since the Raffle app might be used many times, we need to have a mechanism to reset the app. For this purpose, add one more button below WinnerLabel. Rename it ClearButton, change the Width property of the button to Fill parent, and finally, change the Text property to Clear, as shown in the following screenshot:

Creating the User Interface (UI)

Next, we need some way for the app to send and receive text messages. For this, use the Texting component. You will find the Texting component in the Social Palette drawer. Drag the Texting Component onto the Viewer. As shown in the following image, the Texting component is a Non-visible component and is housed below the Viewer. We do not need to set any properties for this component.

Creating the User Interface (UI)

This completes the GUI of the Raffle app. In the next section, we will program the behavior of the app in Blocks editor.

Programming the behavior of the Digital Raffle app

To summarize, when the app receives text messages from participants, if a text message contains the indicated code (in this case, I want to win) in the body of the message, then the sender's phone number is added to a list. When the raffle organizer clicks the WinnerButton, the app will randomly select a winner from that list of phone numbers. Then, the app will send the winner a text message notifying him or her of the win. The app will also send text messages to all the other participants letting them know that they did not win.

We will achieve all of this by completing the following substeps:

  • Create and initialize a list and a variable
  • Receive text messages, and if the code matches, add the sender's number to the list
  • Select a random item from the list (winner)
  • Send a winner notification
  • Send other participants a notification letting them know that they did not win

Creating and initializing the variable and list

For this app, we will need a list to store all the participant's phone numbers. And we will also use a variable to temporarily store the winning number. To create the list and the variable, go to the Variables blocks panel and drag the topmost block initialize global name to as shown in the following screenshot. Do this twice.

Creating and initializing the variable and list

Double-click on "name" inside both the blocks and type in new names, ListOfNumbers for the list and WinningNumber for the variable, as shown in the following screenshot:

Creating and initializing the variable and list

Whenever you (as a programmer) create a list or variable, you need to initialize it with an initial value. For our list, we want to start out with an empty list. App Inventor makes this easy. In the Lists blocks, select the create empty list block, as shown in the following screenshot, and connect it to the initialize global ListOfNumbers to block:

Creating and initializing the variable and list

For the WinningNumber variable, we will initialize it to be 0. In the Math blocks, select the 0 block (shown in the following screenshot) and connect it to the initialize global WinningNumber to block:

Creating and initializing the variable and list

After completing these steps, the initialization blocks for the list and the variable will look like the following screenshot:

Creating and initializing the variable and list

Receiving text messages from participants

In this section, you will learn how to receive text messages from participants and store their numbers in a list.

We added the nonvisible Texting1 component in the Designer tab when we created the UI. We will use this component to send and receive text messages. As shown in the following screenshot, this component has a single gold event block, when Texting1.MessageReceived. Whenever the raffle organizer's device receives any text message, this event will get triggered.

Click on the when Texting1.MessageReceived event block to add it to the Viewer. As shown in the following screenshot, this event has two associated variables—number and messageText. Whenever a text message is received and this event is triggered, the number variable contains the sender's phone number and messageText contains the content of the message.

Note

When you want to store some data, you can create global variables. In previous steps, we explicitly created our own global variables called ListOfNumbers and WinningNumber and initialized them. Once you create a global variable, any block in your app can use that variable.

On the other hand, when an app is running, various events might also need to temporarily store data and hence, may need a variable. These variables, which are built into blocks, are called local variables. They appear in a block and can be accessed by hovering over them with a mouse. Their existence is limited to a particular event. Other blocks of the app cannot use them. In fact, if you try to use a variable outside the event block that they are a part of, you will get an error message. Examples of local variables are number and messageText; they are associated specifically with the block, when Texting1.MessageReceived.

Thus, the number and messageText variables store important data related to the when Texting1.MessageReceived event block. Whenever a text message is received, this event is triggered and the information related to the text message (the sender's number and the message text) is placed into these two variables and can be used by the blocks within that event.

Receiving text messages from participants

Since the raffle organizer's phone can receive text messages unrelated to the raffle at the same time that it receives raffle text messages, we want to filter out the raffle related text messages. This is the main reason we include the code (I want to win) in our design, to filter out raffle related text messages.

Recall that the messageText variable associated with the when Texting1.MessageReceived event contains the text of the message. So, once a text message is received, we want the app to check whether the messageText variable matches I want to win or not. Can you think of what type of block we would use to determine whether or not the code matches?

If you thought of an if then block, you are right! Do you recall where to find it? Select an if then block and connect it to the when Texting1.MessageReceived event. As you already know, we need to plug in a condition block into the if socket. In this case, we want to match two texts. App Inventor makes this easy. As shown in the following screenshot, in the Text blocks, select and connect the compare texts block to the empty if socket:

Receiving text messages from participants

Since we want to check whether the two texts match, click on the downward pointing triangle next to the less-than sign and select the equals sign, as shown in the following screenshot:

Receiving text messages from participants

Hover the mouse pointer over the light orange messageText variable in the event block. This will trigger a pop-up window, as shown in the following screenshot. Select the getMessageText block and place it within the first opening in the compare texts block to the left of the equals sign. This block will get the text from the incoming text message (any text message):

Receiving text messages from participants
Receiving text messages from participants

For the second opening, we want to input the code we created so we can compare it to the text message received. If you recall, in the Designer property, we set the Text property of Codelabel to our code, I want to win. So, under Screen1, go to the CodeLabel blocks and select the CodeLabel.Text block.

Insert the CodeLabel.Text block into the opening to the right of the equals sign in the compare texts block, as shown in the following screenshot. We have now programmed the app to check to see whether the text message (messageText) matches the Text property of the CodeLabel (the code, I want to win).

Receiving text messages from participants

Adding the phone numbers of all the participants to the list

If the text message indeed contains the correct code, we know that the text message came from a raffle participant. Thus, we want the app to add the sender's phone number to the list that we created earlier. To do this, go to the List blocks and select the add items to list block, as shown in the following screenshot. Add it to the then opening of the if/then block.

Adding the phone numbers of all the participants to the list

The add items to list block needs two pieces of information, which we will attach to the empty sockets—the name of the list to add items to and the item to be added. To specify the list, go to the Variables block and select the get block and connect it to the list socket of the add items to list block.

Adding the phone numbers of all the participants to the list

Then, click on the downward pointing triangle of the get block and select global ListOfNumbers from the drop-down menu as shown in the following screenshot. When we initialize a global variable, like we did for ListOfNumbers, it is then available for us to use throughout the app. This is why the name appears in the drop-down menu as an option.

Adding the phone numbers of all the participants to the list

As we mentioned before, the number variable associated with this Texting1.MessageReceived block contains the sender's phone number. You can use the get number block to access this number. Hover your mouse over number variable to view the pop-up window, as shown in the following image. Select the get number block and connect it to the item socket of the add items to list block.

Adding the phone numbers of all the participants to the list

The following screenshot shows the completed set of blocks for receiving text messages:

Adding the phone numbers of all the participants to the list

Thus far, we have programmed the app to do the following: receive text messages, verify that the message texts contains the I want to win code, and if so, add the sender's phone number to the list that we created (ListOfNumbers). If the text message does not match the CodeLabel Text, then nothing happens (the phone number does not get added to the list.)

Selecting a winner

When designing the UI, we added a WinnerButton that the raffle organizer will click to randomly select a winner. App Inventor also makes this easy. We will use the pick a random item block to select a winner from ListOfNumbers. You can find the pick a random item block under the Lists Blocks, as shown in the following screenshot:

Selecting a winner

Since the raffle organizer will click a button to pick a winner select the WinnerButton.Click event (found in the WinnerButton blocks). Next, go to the Variables blocks, select a set to block, and place it within the WinnerButton.Click event. In the set to block, click on the downward pointing triangle and select global WinningNumber. Connect to this block with the pick a random item block that we selected earlier. The pick a random item block has an open socket indicating a list. Can you figure out which block would connect to it? Since we want the random item (phone number) to be selected from our list of numbers, copy and paste the get global ListOfNumbers block from the add items to list block (in the previous section) and connect it to the pick a random item block. The following screenshot shows the completed set of blocks up to this point:

Selecting a winner

What exactly are we coding here? We are programming the app to select a random item (phone number) from the list (of all the phone numbers) and store it in the WinningNumber variable (set global WinningNumber to block). You might be wondering why do we need to do this. As it will be evident later in this chapter, we will reuse this winning number several times. Hence, we need to temporarily store it somewhere.

Once we get the winning number, we want the app to display the winning number on the organizer's phone. To do this, we will set the Text property of WinnerLabel to WinningNumber. As shown in the following screenshot, select set WinnerLabel.Text to (under the WinnerLabel blocks) and connect it to the get global WinningNumber block (which you will find in the Variables block drawer). It will be listed just as an orange get block, and you will need to click on the downward pointing triangle to select global WinningNumber from the drop-down list. Your blocks should resemble those in the following screenshot:

Selecting a winner

Let's recap. We have programmed the app to randomly select a winner (phone number) from all the participant phone numbers (global ListOfNumbers), we will have saved the winning phone number into the Variable Global WinningNumber variable and displayed the winning number in WinnerLabel. The next step is notifying the winner by sending a text message to the winning number.

Notifying the winner

The non-visible Texting1 component that we used before to receive the text messages from participants will be used here again. To send a text message to the winner, we will set both the Texting1.Message property and the Texting1.PhoneNumber property. Find the set blocks under the Texting1 blocks. Select and place them inside the WinnerButton.Click event, as shown in the following screenshot. For the Texting1.Message property, connect a blank Text block and type in the message "Congratulations!! You won". For the Texting1.PhoneNumber property, copy and paste the global WinningNumber block and connect it to the empty socket.

The Texting1 component has a purple block called call Texting1.SendMessage. This is the block that actually sends a text message. The PhoneNumber property of the Texting1 component is used for the recipient's number and the Message property is used for the body of the text. Hence, it is important to set these two properties correctly before actually sending the text with the call Texting1.SendMessage block. As shown in the following screenshot, go to the Texting1 blocks again, and drag the purple call Texting1.SendMessage block and place it at the bottom of all the blocks:

Notifying the winner

We have now coded the Raffle app to send a congratulatory notification to the winner.

Notifying everyone else

Usually, the winner is excited to have won, and announces aloud that she or he has won. But in case this doesn't happen, we want to send a notification message to all the participants who did not win to ensure that no one is left wondering about the raffle outcome. It seems logical to send a "Sorry, You did not win" notification to all the items in ListOfNumbers, since it is storing all of the participants' phone numbers. However, there is a flaw to this logic. Can you guess what the problem is? Currently, ListOfNumbers contains all of numbers, including the winning number. So, before we use the ListOfNumbers as the source for the "Sorry" notification, we need to remove the winning number from this list.

As shown in the following screenshot, we will use the remove list item block to remove the winning number. You can find remove list item in the List blocks. This block needs two pieces of information (hence, the two empty sockets): the name of the list and the position (index) of the item to be removed. Specifying the name of the list is easy. Just copy and paste and connect the global ListOfNumbers block.

Notifying everyone else

Finding the position of the winning number is a little more involved. We will need to add another List block, that is, the index in list block to figure out this position. As shown in the following screenshot, connect the index in list block to the empty index socket in the remove list item block:

Notifying everyone else

Note

Index is the position of an item in a list.

The remove list item block can remove an item from a certain position. First, we need to figure out the position of the winning number (the thing) in the list. Then, we will use this position to remove the winning number.

The index in list block finds the position of the item specified in the thing socket from the list specified in the list socket. So, we will copy and paste, connect the get global WinningNumber block to the thing socket, and add another get global ListOfNumbers block to the list socket. Your code will look as follows:

Notifying everyone else

Let's recap. We have identified the position of the winning number in the list and have removed the item at that position, thereby removing the winning number from the list. Now, we are ready to use this list to send a notification to the participants who did not win.

Just like the notification message we created for the winner previously, we will reuse the Texting1 component to send out notifications to all the participants who did not win. Copy and paste the set Texting1. Message to block (that will copy the attached text block). Change the text in the Text block from "Congratulations !! You won" to "Sorry, You did not win". Feel free to change this message and personalize it to your liking.

Note

Note that blocks execution is always top down. So effectively, the winning number is removed from ListOfNumbers before the notification is sent to the losing participants. And, Texting1.Message set to the block message "Sorry, You did not win." overwrites the previous text message "Congratulations!! You won".

Notifying everyone else

An important difference between sending the notification to the winner and this notification is that this notification will be sent to all the numbers in the list ListOfNumbers, except the winning number. Essentially, this means that we need to repeat the set Texting1.PhoneNumber to block, followed by the callTexting1.SendMessage block—once for each item in ListOfNumbers. And this brings us to the concept of loops!

Using loops

A basic programming concept present in any programming language, including App Inventor, is called loop. Loops let us repeat code and thus we will use a loop here. We will place two blocks in the loop: set Texting1.PhoneNumber to and call Texting1.SendMessage.

Loops are available in the Control blocks drawer. There are different types of loops. We will use the for each item in list loop, as shown in the following screenshot. Select the for each item in list loop and place it at the bottom of the when WinnerButton.Click event. This loop requires us to specify a list that will be used in conjunction with the loop. The loop lets us repeat whatever block we place within the loop once for each item in the associated list. While the loop is running, during any iteration, the corresponding item from the list will be placed in the item variable as well. When the loop executes for the first time, the first item of ListOfNumbers will be available in the item variable associated with the loop. Similarly, when the loop executes for the second time, the second item will be available in the item variable and so on:

Using loops

This loop will execute as many times as the number of number of phone numbers in ListOfNumbers. To specify the list, just copy and paste and connect the get global ListOfNumbers block to the empty list socket in the loop.

Using loops

Now that the outline of the loop is ready, we need specify the body of the loop. First, drag the set Texting1.PhoneNumber to block into the do part of the loop, as shown in the following screenshot:

Using loops

Next, hover your mouse over the item variable in the for each item in list block, and drag the get item block and connect it to the empty socket in the set Texting1.PhoneNumber to block, as shown in the following screenshot:

Using loops

Next, copy and paste and place the purple call Texting1.SendMessage block into the do part of the loop at the very bottom, as shown in the following screenshot:

Using loops

This loop accesses each item on the list one at a time, sets it as Texting1.PhoneNumbers, and sends out a text message to that phone number. So, this loop is allowing us to repeat the set Texting1.PhoneNumber to block, followed by the call Texting1.SendMessage block multiple times (for each item in ListofNumbers).

The digital raffle is now complete. The winner has been notified of the win and the rest of the participants have been notified that they did not win (note that a prize of some sort is usually given to the winner).

Clearing out the list and variable

After using the Raffle app, if you want to conduct another raffle with a different group of participants, you will need to clear out the list ListOfNumbers the variable WinningNumber, two things that were expressly created by us (the programmers). The other variables used in the app were local variables (number and messageText from the Texting1.MessageReceived event). These were not created by us, but rather generated by the blocks themselves; thus, these are used and cleared out automatically by the program.

There are two ways to clear out the list and variable to reset the app. The first way doesn't require programming. You can simply close the application and reopen it. This will reset the list to empty and the WinningNumber to 0. Can you guess the second way to reset the app? If you recall, we created a ClearButton feature for the UI in the Designer. We can program this ClearButton to clear out the app.

In the ClearButton blocks, select the ClearButton.Click event. This block will help us clear out the list that stored the participants' phone numbers and the variable that stored the WinningNumber. Recall when we started coding the app, we initialized our global variables. We set list to be empty and the variable to be 0. So now, in the when ClearButton.Click event, add blocks to do the same thing. You've already programmed this once before in this app, so we imagine that you will be a pro at configuring these blocks again. But, just in case you need a review, select the set global ListOfNumbers block and connect it to the create empty list block, and select the set global WinningNumber block and set it to 0. Your final set of blocks will resemble the following screenshot:

Clearing out the list and variable
..................Content has been hidden....................

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