Chapter 2: Programming and Design Fundamentals

In This Chapter

• Clarifying your design ideas

• Working with primitives

• Grasping the basics of programming terminology

The project I detailed in Chapter 1 is known as a soundboard. It’s a very simple soundboard, but it’s a good start for our next project. It plays a short sound when a button is pushed. You built that project fairly blindly, without knowing where you were going or the reasons for the components and blocks. For the remaining projects in this book, I provide three guiding sections at the beginning of each project: a design section, a primitives section, and a progression section. Each project has these elements predesigned for you. However, for your own projects, the process of creating those statements helps you develop applications from your ideas. In this project, the design, primitives, and progression sections are broken down and each item explained.

That SounDroid application you worked on in Chapter 1 has some potential, however, so in this chapter, I show you how to take it through a design process to a second version.

In this chapter, I guide you through the thought processes and steps necessary to arrive at a list for your design goals, primitives, and progression. I explain the design goals and primitives as you move through them. Generally speaking, design goals are what you want your application to do, and primitives are the programming logic and algorithms necessary to accomplish your design goals. The progression is the order that is most logical or necessary for you to follow as you build the application.

Most of the projects in this book require that you download the project files from the book’s companion site. The project files contain images such as the icons, application images, sound files, and so on. When you start a project, download the project files somewhere on your computer where you can easily find them to upload them into App Inventor. See this book’s Introduction if you need instructions on how to download the project files.

Clarifying Your Design Idea

Design processes help take your awesome ideas and make them reality. There is nothing mysterious about a design process, although frequently developers give them fearsome and magical-sounding names such as waterfall model, spiral model, and agile development. These all refer to the same thing: logical steps that developers and programmers use to move an idea from a dream to a fully functional program. You can see a basic outline of the waterfall model in Figure 2-1. You will use a very basic and simplified form of the waterfall process in this chapter to take an idea for our SounDroid project to the next level.

Tip.eps

All App Inventor applications start as an idea. Sometimes, the idea is born of a need, such as the firefighter in Colorado who needed an application to measure friction loss for his fire company, or the father who needed an application to track his daughter’s seizures. These App Inventor apps started as a need, but sometimes, the germination of a new app is simply a desire for a certain game or communication capability. Whatever the seed of an application, it requires some fertilization and tending before it can actually be programmed.

Figure 2-1: The waterfall development process

9781119991335-fg0201.eps

• Your design statements should clarify your original idea. So, if your original SounDroid project idea was something like “I want to create an application to play relaxing sounds,” clarifying the design means identifying what you want it to do, and when and how. Begin by making a simple list of your ideas for activities and actions for your application. Your SounDroid idea might have an idea list that looks something like the following:

• Plays relaxing sounds to aid in relaxation or meditation

• Offers three possible sounds

• Tracks mediation or relaxation time

These are very high-level goals that you need to turn into a design document. The first step is pencil-and-paper programming. Take your idea list, sit down with a piece of paper and pencil, and sketch what you think your application will look like. This is the classic “back of a napkin” approach that can revolutionize a market. For your SounDroid application, you might come up with something like you see in Figure 2-2.

You know that your application is going to be playing sounds, so you want a play button and a stop button for the sound next to an image. You also want a space for displaying the play time. Now you have a good starting point for refining your ideas. As you look at the sketch, you might decide that it would be more graceful and intuitive if the user could just tap the image to start the sound and tap it again to stop the sound. It would also be nice if your application had a relaxing and soothing look. Your next sketch might look like Figure 2-3.

Figure 2-2: A preliminary idea sketch for the SounDroid application

9781119991335-fg0202.eps

Just by giving some more thought to your idea and putting the results down on paper, you have already begun to refine the original list of ideas. Now you can flesh out that list with some specific ideas. Take the sketch and the idea and try to define with words what each element or component of the application will do. Then start listing the specific goals you have for your application. For SounDroid, you might come up with a list like the following:

• Images that are buttons for both play and stop.

• Sounds that play until stopped.

• Three sounds to match images.

• A timer that starts when a sound is played and stops when the sound is stopped.

• A way to display the timer.

• A relaxing non-intrusive background.

• Centered orientation. (Remember from Chapter 1 that all App Inventor components fill in from the top left, so you will have to address this somehow in your implementation of your user interface. You will use a clever method for centering.)

You may go through multiple iterations of this process while developing and clarifying your idea. For more complex applications such as games or calculation applications, a single line in design requirements may be a whole bunch of primitive code when you actually design and build it. A single design goal such as “Find the greatest common denominator from two numbers” ends up being broken down into multiple mathematics operations. In this case, you are well on our way to our next step of developing the conceptual building blocks of how you as the developer will accomplish these goals.

Figure 2-3: A more refined SounDroid application sketch

9781119991335-fg0203.eps

Getting Primitive with Your Design

After you know clearly what your idea really is and what your application will be expected to do, you must break it down into what each “basic” action or reaction should be. The individual ways in which your design goals are met are called primitives. Much like the primitive shapes — such as circles, squares, rectangles, and triangles — that are used to make up a picture, programming can be broken down to its simplest parts. See Figure 2-4. A program can be broken down into primitive steps such as an event, a reaction, or an input.

Figure 2-4: Primitives used in art composition

9781119991335-fg0204.eps

For your SounDroid project, your last idea clarification list took you pretty darn close to your primitives. In the next step, you need to clearly define what each of the design goal primitives are going to be. One way to get a grip on your primitives is to convert your list of ideas that I talked about in the last section to a bulleted list of primitives. Under each major goal, define the primitive actions to accomplish that specific goal. As you come to understand App Inventor, you will also define the App Inventor primitives here. When you’re first starting on a project, you often have no idea how App Inventor will accomplish a particular task. This lack of knowing how something should be done is one of the primary reasons why you define primitives. The old saying “By the inch is a cinch, by the mile takes a while,” holds true here. Take it step by step. It’s far easier to figure out how to do one step, such as creating a routine to display an image and change it, for example, than it is to attempt to get your brain around an entire gallery project all at once.

Start with your previous list of ideas and begin to define the simplest possible steps to achieve that goal. Your first goal was “Images that are buttons for both play and stop.” If you break that sentence down to its parts, you might get a list like this:

• Images that are buttons for both play and stop.

a. A button has an image.

b. A button plays a sound.

c. The same button should stop the sound.

The first item is obvious because we need a button that uses an image to define its shape and look. Point b and c seem to eliminate the design goal of a single button, but many times, you must start out simply and then combine simple primitives to be more complex. You have the skill to place buttons and place an image on those buttons. So after you understand how to play a sound and stop it, you can then combine those two primitives (placing an image on a button, and playing and stopping a sound) into something more complex. Frequently, how to combine simple primitives is not obvious and requires lots of troubleshooting and experimentation. Clearly defined primitives make the process easier. I guide you through the process of combining your primitives for this second version of SounDroid.

• Three sounds to match images.

a. Wave sound and wave image

b. Rain sound and rain image

c. White noise and white noise image

These primitives are pretty simple to arrive at; however, the last one does require some design decision-making. What will white noise look like on your application? For this project, I have made the decision for you (it looks like static), but this primitive would require some thought and creativity.

Your timer goal is your first real challenge. You want to display for your user the amount of time that he or she has been lulled into restful relaxing nirvana by your application. How that will be accomplished is probably pretty much a mystery to you at this point. That’s okay because you can still describe an algorithm for the primitive action. An algorithm is just a sequence of steps to arrive at a predictable goal.

How would you as a human observer determine how long someone relaxed while sitting in front of you? Most likely, if you wanted really accurate results, you would use a stopwatch to time the passing of the seconds. So for a very accurate report on the lapsed time, you could define an algorithm that said “Start counting seconds when the sound play button is pressed. Stop counting seconds when the sound stop button is pressed. Display the total of seconds counted.” That would certainly give you a very accurate view of the time, but there is usually more than one way to accomplish a goal in programming. For instance, to achieve the goal of tracking the relaxer, you might note the time they started, note the time they stopped, and subtract to find the difference. The latter is a simpler algorithm because it simply records two times and then finds the difference. Whenever you are dealing with time, timing, or dates in App Inventor, the Clock component is the root of your primitive.

So your primitive list under the timer goal might look like this:

• A timer that starts when a sound is played and stops when the sound is stopped

a. A record of when the sound player starts

b. A record of when the sound player stops

c. A record of the difference between the start and stop

• A way to display the timer

This is an easy primitive. Displaying information on the screen is always a fairly easy primitive. With App Inventor, you use the Label component to display information on the screen. It’s not the only way, but it is the primary way to display text to a user.

• A relaxing non-intrusive background

a. An image set as the background of the Screen1 component

Note.eps

The Screen1 component is a default component that every other App Inventor component is placed onto. It has properties like other components, such as background, image, and so on. You cannot place other Screen components currently with the current version of App Inventor. Throughout this book, I show you how to creatively simulate more than one Screen component. I call them VirtualScreens because they are not real screens but can be made to behave as screens.

This too is an easy primitive. You should be careful with backgrounds. Busy backgrounds can be visually distracting and keep your user from seeing important textual elements. It can also make your application look cheap and gimmicky. Backgrounds should be just that: backgrounds, not the focus of attention or distractions.

• Centered orientation. (We need a method to counter App Inventor’s default left/top down arrangement.)

a. Padding elements to center button column

• A centered orientation is probably the most challenging part of your design requirements. App Inventor does not easily provide for centering elements in the Viewer. However, you can use a clever technique for keeping items where you want them. It works in much the same way that Web designer’s use “padding” to push elements to where they want them to be. Your primitives for pushing your centered items to the center will be empty (and therefore invisible) labels.

Your list of primitives should now be interspersed with your list of design goals. This along with your sketches of your user interface gives you a lot of guidance as you program your application. Keep in mind that goals can change and primitives can be combined or devolved even farther as you get into the nitty-gritty of making your idea come to life.

Starting Easy, Getting More Complex

As with most things in life, you’re better off not attempting too much at once when developing an application. If you try to add too many features, bells, whistles, and kitchen sinks before the basic fundamentals of your program are up and running, your code and even your thinking process can get very muddled up. One of the greatest hindrances to creatively thinking about solving a programing problem is attempting to do things out of their natural progression or logical order.

Progression is the idea of starting with a basic simple level of primitives and then adding other primitives to become more complex. SounDroid 1.0 was pretty basic. Your plan for the next generation of SounDroid has several added layers and levels of complexity. To keep your thought processes clear and to keep the project moving, lay out a progressive roadmap. A roadmap gives you logical progression for your project. For your new design goals, you should split up the actual programming into “milestones” along the road to your completed application. The basic user interface and basic functionality should be working before you start changing them to add more functionality. Because your SounDroid project is, at its heart, a soundboard, it should first play your sounds in the way you want.

Remember that the original SounDroid only played your sound file once. Getting the sound files to loop appropriately will be enough of a challenge without adding the timer or the “pretty” parts of the user interface. SounDroid will have three major versions: SounDroid 1.0, which you built in the previous chapter as an introduction to App Inventor interface; SounDroid 2.0, which you create in this chapter; and then finally SounDroid 3.0, which you build in the next chapter following the primitives and design goals you have laid out in this chapter. Your SounDroid project should have the following milestones:

• SounDroid 2.0

Plays the looping sound for all three sounds

Has the basic user interface in place (buttons, labels, and centering)

• SounDroid 3.0

Displays the time looping sound has played

• Has a polished, pretty interface

Your list of design goals and the primitive actions necessary to make them happen should look something like this:

• Images that are buttons for play and stop

a. A button that has an image

b. A button that plays a sound

c. The same button should stop the sound

• Three sounds to match images

a. Wave Sound and Wave Image

b. Rain Sound and Rain Image

c. White Noise and White Noise Image

• A timer that starts when a sound is played and stops when the sound is stopped

a. A record of when the sound player starts

b. A record of when the sound player stops

c. A record of the difference between the start and stop

• A way to display the timer

a. A label for display

• A relaxing non-intrusive background

a. An image set as the background of screen1

• Centered orientation

a. Padding elements to center button column

Mastering the Fundamentals of Programming Terminology

As you move forward into completing your second version of the SounDroid project, you should get familiar with a few terms that I use consistently throughout the rest of the book. The terms I discuss in the next few section are basics and can have different inflections of meaning in different programming languages. I give you both a general and an App Inventor view of these concepts.

Events

An event is exactly what it sounds like: something that happens. App Inventor has event handlers that are added to many component drawers in the Blocks Editor. (See Chapter 1 for a review of drawers and components in the Blocks Editor) In programming, you use events as triggers to set off a string of reactions or calculations to process data or output something to your user. You have used an event already when you built SounDroid 1.0 in the previous chapter: the when Button.click do event that you used to start the sound playing. Events in App Inventor look like blocks with arms to hold other blocks, as shown in Figure 2-5, which shows some events in the Blocks Editor, with a series of instructions to be carried out when that event occurs. The proper name for these event blocks in other programming languages is event handlers. They “handle” the events and know what to do when they occur.

Figure 2-5: A series of event handlers in the Blocks Editor

9781119991335-fg0205.tif

Methods

Many of the components you add to your project in the Design view have method call blocks in their Blocks Editor drawer. A method is a preset set of instructions and programming that allow you to use the functionality they contain, such as a set of capabilities related to playing audio. You can think of methods as miniature programs that your application accesses the functionality of and then uses to offer functions. In App Inventor, methods enable you to access a lot of functionality that a non-programmer would have a hard time implementing. When you use a method in App Inventor, you call it. Using a block with the call action word on it, as in Figure 2-6, means that you want to use that block’s functionality in your application.

Figure 2-6: A method call being used in an event handler

9781119991335-fg0206.tif

A call in App Inventor may also access functions or capabilities that are inherent to a particular component. Blocks in App Inventor can and frequently do have sockets that allow you to snap in other blocks. For instance, the Split At text block has a socket that allows you to define the text to split and where it should be split by snapping other blocks into it. In App Inventor, any calls to methods that are in component drawers do not have any sockets in them because they are standalone functions. Some calls have sockets that allow you to “plug in” parameters for the method call to act on or to determine the nature of how the call is activated. Many calls are to built-in App Inventor functionality. The built-in drawers in the Blocks Editor contain lots of calls to functionality such as call WaveSound.Play, which would be used to play a specific sound , as shown in Figure 2-7.

Remember.eps

For the purposes of App Inventor, a call can be considered a prepackaged set of instructions that offers you functions and capabilities. Remember that the definition of a call is different in other, more traditional programming languages.

Figure 2-7: Built-in call blocks in the Blocks Editor

9781119991335-fg0207.tif

Properties

The components in App Inventor have settings that can be changed to affect the way they look, act, or interact in your application. These settings are call properties, and their values change the way the component functions or looks. You can for instance, change the background color using the BackgroundColor property in the Properties column when the Screen1 component is selected.(You saw some examples of that in the SounDroid tutorial in Chapter 1.) Some properties change the look and feel of a component, such as the size, font, and color properties. Some components have properties that change (make or break) the functionality of the component. Components such as the Sound player won’t actually play a sound unless the sound source property has a correctly spelled reference to an uploaded sound file.

Some, but not all, properties can be changed by adding a block from the component’s drawer and plugging the property value you wish to use into its socket. Figure 2-8 shows a sound component that has not had the source property value set in the Design view. Instead, the set sound1.source to block is used to plug a value into the sound component’s source property. Whenever you use a property’s block to change a property’s settings, it overrides any value you have typed into Design view.

Figure 2-8: A property value being set using the property set block in Blocks Editor

9781119991335-fg0208.tif

Variables

A variable in App Inventor is a more complex concept than any I’ve discussed so far. You must understand that a variable in App Inventor shares many of the same features as variables in more traditional programming languages, but is still vastly different. Variables are created or defined from the Built-In blocks drawer labeled Definition. To create a variable, drag the variable block from the Definitions drawer onto the workspace and give it a unique name. When you do this, it creates blocks under the My Blocks tab in the My Definitions drawer. These blocks allow you populate and reference the variable. (See Figure 2-9.)

Figure 2-9: Defined variables populate the My Definitions drawer

9781119991335-fg0209.tif

You should look at variables in App Inventor in two ways:

• As a named storage box that we can put information into

• As a named reference to information that is previously stored

In the first case, you are defining a variable. That is to say, you are placing words, numbers, and data into a box so you can get to them later. You could imagine a variable as a cardboard box with a masking-taped magic marker label on the side. After you label your cardboard box with a label that says something like NumberDates, you can refer to it in conversation without having to say something clumsy like “The box with 11/13/2010, 5/3/1945, and 12/25/1976 in it.”

The second way of looking at variables in App Inventor is as a reference to your box with the masking tape label. The magical thing about masking tape labels is that they can be duplicated. You can tell someone, for example, to “Fetch all the pictures from a picture box that has the dates on it that match the dates listed here” and hand them a piece of masking tape with NumberDates written on it. In App Inventor, you define a variable using the Blocks Editor whenever you need to store information that you will refer to, display, or use later in your application.

Procedures

In your application, you may have a set of instructions that you want to use more than once — perhaps a mathematic series of steps to find the hours, minutes, or seconds from milliseconds stored in a variable. A procedure allows you to create containers of reusable instructions. A procedure is created exactly like any other definition in App Inventor: by dragging the blocks from the Definitions drawer on the Built-In tab of the Blocks Editor to the Blocks Editor workspace, as shown in Figure 2-10. Then every time you want to use that series of mathematical steps (or whatever instruction you want to reuse), you can call that procedure exactly the same way you can call a built in method. The call block is located in your My Definitions drawer.

Figure 2-10: Defined procedures place a call block in the My Definitions drawer

9781119991335-fg0210.tif

A procedure then is a subroutine — a series of instructions that you want your application to step through and that you want to isolate for debugging or for reuse. In our previous example of using a procedure to store some mathematic steps, if the mathematical result keeps coming out wrong, you know exactly where to start troubleshooting without hunting all through all of your blocks.

There are two distinct types of procedures in App Inventor: standalone procedures, which are the kind I’ve already described, and procedures with arguments. Procedures with arguments behave exactly like the previous description of a standalone procedure, with one exception. A procedure with arguments allows you to pass information into the procedure and have that information processed and a value returned to your application to be used as you like. When you use a procedure with arguments, you define as many arguments as you like and blocks for those arguments are created in the My Definitions drawer.

Note: Procedures with Result has an in depth explanation and example in the second part of this book. As well as being used in projects. Procedures are important concepts and should be considered part of clean graceful programming in App Inventor.

You will use procedures, procedures with arguments, variables, and method calls throughout the following chapters as you put together a series of projects to help you become comfortable with all the incredible power that App Inventor gives you.

..................Content has been hidden....................

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