CPSC 110-08: Computing on Mobile Phones
Spring 2012

Procedures, Functions, Arguments
Due: Friday 3/9 (before class)

CS Principles

This homework addresses the concept of abstraction again, this time focusing on functions and parameters (or arguments). The student will be introduced to functions as re-usable programming abstractions and will see how parametrization can be used to generalize a specific solution. It addresses the following learning objectives.

Introduction

In programming procedural abstraction is the use of procedures to help manage the complexity of programs.

In general, abstraction is the ability to filter out information that is not necessary to a problem and to generalize those details that are significant.

In previous lectures we have seen how to define and use procedures. A procedure is a named module that can be called or invoked at one or more places in the program. A procedure contains an algorithm in its do slot.

We have already used the following block to define procedures that perform a sequence of actions but do not return a result:

We now want to learn to define and use special types of procedures that do return results. These are typically called functions. A function is procedure that takes 0 or more arguments and returns a value. In App Inventor a function is defined using the following block:

Notice the additional slot labeled return at the bottom of the block.

Built-in Functions

You are already familiar with built-in functions in App Inventor. For example, you've been using the random integer function, which takes two arguments, from and to and returns a random integer between from and to inclusive:

A function's arguments are place holders into which you can place values. For example, the following use of the random integer function will return a random number between 1 and 100:

You can call or invoke a function (or a procedure) in the blocks editor by right-clicking and using the "Do It" option:

Note that we don't always want to plug literal values, like 100, into an argument slot. We can also plug in the value of a variable.

Invoking a function produces a value and that value can be placed inside of any slot that takes a value:

Defining Your Own Functions

App Inventor gives us the ability to write our own functions using the procedureWithResult block. Note that it has an open slot for an argument and an open slot for a return value and a do slot where we can place a sequence of statements:

To see how this works, let's define a trivial function that calculates the square of any number and then call the function and pass it the argument 10.

Note that calling our square function looks similar (except for the colors) to calling the random integer function.

In this case the function is so simple that there is nothing to "do" other than perform the calculation and return the result. So we can just put our calculation in the return slot.

Of course, we wouldn't typically define a procedure for such a simple calculation. So let's look at a more likely example.

Using Arguments Makes Functions More General

Our simple square function contains an argument where you plug in the value that you want to square. So, rather than having to define separate functions to calculate specific values -- e.g., squareOf10, squareOf2, squareOfMinus3 -- you define a much more general function, square(X) where any value can be plugged in for X.

Thus, arguments make our functions and procedures more general, giving them wider application. This generality is an important characteristic of procedural abstraction.

Pythagorean Theorem Example

Suppose your app needs to calculate the hypotenuse of a right triangle. You probably remember the Pythagorean Theorem from high school geometry -- i.e., the formula for calculating the length of the hypotenuse of a right triangle based on the lengths of its other two sides. The length of the hypotenuse is equal to the square root of the sum of the squares of the other two sides:

c = √ a2+ b2 

Hypotenuse Algorithm

The Pseudocode algorithm for computing the hypotenuse is quite simple. The only thing we need to do is return the square root of the sum of the squares of a and b:

# Comment: A function to compute the hypotenuse
# Notice that we put the parameters, a and b, in a list following the function's name.

To hypotenuse(a, b):
   Return: sqrt(a * a + b * b)

Here again, there is nothing to "do" besides perform the calculation so we just return the result of calculating √ a2+ b2 .

Note that we don't need a global variable to calculate the hypotenuse. We can just return the value of the hypotenuse.

Parameters

A parameter (or an argument as they are called in App Inventor) is a place holder in a function or procedure definition. When you call the function you substitute a value for the parameter and the function uses that value in its computation.

For example, the hypotenuse(a,b) function has two parameters, a, and b. When I call this function, I would replace a and b with specific values. For example if I call hypotenuse(4, 3), it will compute √ 42+ 32  = 5.

The values that are used as arguments don't have to be literal values like 4 and 3. They can be values contained in variables. For example, suppose that we have set X to the value 5 and Y to the value 12. Then when we call hypotenuse(X,Y), it will compute √ 42+ 32  = 13.

The values that we plug into a parameter can also be the result of a function call. For example, what value would Var be set to by the following algorithm:

Set Var to hypotenuse(sqrt(9), sqrt(16))

Here is how this would look in App Inventor:

Another Algorithm

Another way of defining our hypotenuse function is to use a global variable, Hypotenuse, and break the computation into several steps storing the intermediate results in Hypotenuse, and then returning Hypotenuse as the function's result:

# Comment: A function to compute the hypotenuse
# Notice that we put the parameters, a and b, in a list following the function's name.

To hypotenuse(a, b):
   Set Hypotenuse to a * a
   Set Hypotenuse to Hypotenuse + (b * b)
   Set Hypotenuse to sqrt(Hypotenuse)
   Return: Hypotenuse

Here's a function that will perform this algorithm in App Inventor:

(NOTE: Unlike in most programming languages, in App Inventor, argument names have global scope, rather than local scope, which means we can't reuse the argument names a, and b, in this function definition. So we use a1 and b1.)

Testing Our Function with "Do-It"

Before you use your function in your app, you should test it by calling it. To do this, you will need to pull out the call function block from the My Definitions drawer.

If you right-click on a call to the function, you can test it using App Inventor's Do-it option, as shown here:

Important Difference Between Procedure Call and Function Call

A procedure call is a statement and it can go anywhere that a statement can go in a program. For example, it can go in a do slot. Recall this example from the FairCoin app, where we Call InitializeTheExperiment to do some initialize operations for us:

A function call produces a value, which cannot stand alone the way a statement can. Therefore the value has to be put into a statement or into another expression. For example, look how we put the result of calculating the hypotenuse into the slot that takes a text value.

Homework Exercises

  1. Write a Pseudocode function named celsiusToFahrenheit to convert from temperature in Celsius to temperature in Fahrenheit using the formula:
    F = 9⁄5C + 32.

    According to this formula 100 degrees Celsius is 212 Fahrenheit (the boiling point of water) and 0 degrees Celsius is 32 degrees Fahrenheit (the freezing point).

    This function should take 1 argument, C, that represents the temperature in Celsius. And it should return the equivalent temperature in Fahrenheit. Copy the style of the pseudocode examples given above.

  2. Convert your Pseudocode into an App Inventor function. Create a new app called TemperatureConverter. You don't have to create a user interface for this. Just open up the blocks editor and define your celsiusToFahrenheit function using the procedureWithResult block. Then open the emulator and, when it is running, try testing your function using the "Do It" options.

Post your Pseudocode and a picture of your App Inventor function on a Portfolio page.

In Class

In class each of us will create a converter app for some conversion that we are interested in.