Lab03, CISC106, Fall 2007

Goals

By the time you complete this lab, you should be able to:

  1. Explain the difference between two different types of M-files: scripts and function definitions
  2. Demonstrate how to run a script from the MATLAB prompt, and how to call a function from the MATLAB prompt
  3. Explain the idea of an acceptance/regression test script
  4. Take an M-file that defines a function, run a test script on that function, find a bug, and fix it.

You will also get more practice with

  1. Managing directories in MATLAB with the pwd, mkdir, and cd commands.
  2. Saving a sequence of MATLAB commands into a file (a so-called "dot-M" file)
  3. Running existing .m files
  4. Using the diary command to save your work into a file you can submit for grading
  5. Submitting your saved work for grading using "MyCourses" (also known as WebCT).

Lab03 can be done from a SunRay, or from a PC or Mac

The instructions are generally written from the standpoint of working on a SunRay.

However, you can do them from a PC or Mac. Here's how:

  1. First, familiarize yourself with the brief guide to accessing MATLAB on strauss from a PC or Mac written by Terry Harvey. (http://www.udel.edu/CIS/106/tharvey/07F/usingUdelMatlab.html)
  2. Next, if you are using a PC, check out the following links:
  3. Learn about the Emacs text editor in your Unix: Visual Quickstart Guide textbook. You can read about Emacs on pages 91-95. You'll need to use Emacs to edit Matlab files, since you won't be able to access the built-in MATLAB editor.

Once you've looked over all of those pages, you can adapt the instructions below by simply opening two SSH windows to strauss:

Step-by-Step Instructions

 

Step 1: Look over Steps 6 and 7 from lab02

This lab picks right up from steps 6 and 7 of lab02. So you may want to go back and review these steps to refresh your memory.

Note: There was nothing to turn in for steps 6 and 7 of lab02, so you may have been tempted to skip them. If so, you need to go back and actually do them now.

Step 2: Create a ~/cisc106/lab03 subdirectory

Just as we did last week, we need to create a ~/cisc106/lab03 subdirectory. Review lab02, step 3 for a refresher on how to do that.

Step 3: Working with MATLAB functions

In this section, we'll define our own function to compute the area of a pizza. But first, we'll look at some of the built-in functions that MATLAB already has.

MATLAB has many built-in functions, such as sqrt(x) (for square root of x), as well as sin(x) and cos(x). Here are some examples of using built-in MATLAB functions. Try these examples in the command window of MATLAB. As you can see, if you just put a number or a variable into the parentheses, MATLAB will calculate a result.

>> sqrt(36)

ans =

     6

>> sqrt(49)

ans =

     7

>> sin(pi / 2)

ans =

     1

>> sin(3 * pi / 2)

ans =

    -1

>> x = 2 * pi

x =

    6.2832

>> cos(x)

ans =

     1

>> sin(x)

ans =

  -2.4493e-16

>> 
A side note: why is sin(2π) = -2.4493e-16 and not zero?

The answer -2.4493e-16 for sin(x) where x=2π might require some explanation.

You were probably expecting that sin(2π) should be zero—or at least I hope you were expecting that! The answer MATLAB gave, i.e. -2.4493e-16 is the way that MATLAB expresses the number -2.4493 x 10-16, which is scientific notation for the number-.00000000000000024493.

That number is indeed very close to zero. A fact of life is that computers cannot exactly represent the result of any numeric computation involving numbers such as π, because such numbers contain an infinite number of significant digits. However, computers contain a finite number of memory cells, and any particular value that is stored by a computer can only use a limited number of those cells. Thus, many calculations done by computer are only approximations. They are often very good approximations, but they are approximations, nevertheless.

More on MATLAB's built in functions

The built-in functions in MATLAB are so important that your Holly Moore MATLAB textbook devotes an entire chapter to this topic, called (appropriately enough) "Built-In MATLAB functions". When you are finished with this lab, a great next step would be to read through that chapter (with MATLAB handy, to try things out).

Step 4: Copying a MATLAB function M-file called areaOfPizza.m into our account

Next, you are going to copy an M-file that defines a new function into your account. Here's the command:

copyfile /www/htdocs/CIS/106/pconrad/07F/labs/lab03/areaOfPizza.m ~/cisc106/lab03

After you type in this command, type in the ls command to "list your files" and you should see the areaOfPizza.m in the listing of the files.

Step 5: Using a MATLAB function M-file

In this step, first we'll see that when you have a function M-file in your current directory, you can use the help command to learn about how to use it:

Then we'll see how to actually do computations with a MATLAB function M-file.

Step 5a: Using the help command

Now, try the following command: help areaOfPizza

You should get the following result:

>> help areaOfPizza
 areaOfPizza compute area of pizza, given diameter
 
  consumes: 
      diameter: number, diameter of the pizza in inches
  produces:
      area: number, area of the pizza in square inches
      
  examples
      >> areaOfPizza(12)
      ans = 113.10
      >> areaOfPizza(16)
      ans = 201.06
      
  P.Conrad  CISC106 section 99, 09/03/2007
>>

The help text shows you how to use the areaOfPizza function.

Step 5b: Using a MATLAB function M-file to compute results

Now, try typing in one of the examples yourself—for example type areaOfPizza(12) at the MATLAB prompt. You should get a result like this one:

>> areaOfPizza(12)

ans =

  113.0973

>> 

Note that the answer is not exactly the same as the one in the heading, but if you found off the answers to the number of significant digits shown, the answer is correct. MATLAB actually has different formats for displaying output—these affect the number of significant digits shown, and whether the answer is in regular or scientific notation. For example:

>> format long 
>> areaOfPizza(16)

ans =

     2.010619298297468e+02

>> format short
>> areaOfPizza(16)

ans =

  201.0619

>> format short g
>> areaOfPizza(16)

ans =

       201.06

>> 

We can see here that if format short g is selected, the answer shown in the example is exactly correct. Keep this in mind when comparing answers from MATLAB computations to the examples shown.

Step 6: More on Copying M-files

Step 6a: Copying M-files with a wildcard

By now, you may be getting tired of copying files "one at a time" into your directory. So, now, we'll learn a command to copy a lot of files all at once. This command copies all of the .m files that are in the folder for this lab into your ~/cisc106/lab03 folder. The star (*) is called a wildcard. When you write *.m , it means "any file that ends with .m". (Note: See update below if you have trouble with this command).

copyfile /www/htdocs/CIS/106/pconrad/07F/labs/lab03/*.m ~/cisc106/lab03

Type this command in at the prompt, and afterwards you'll find several new files when you type ls

UPDATE: Several students have reported problems with the above command.

Meanwhile, it seems to work fine for your professor, for the TAs, and for some students. We think we've tracked down the problem.

If the command doesn't work for you, try this one instead. It is the same as the command above, except you use !cp instead of copyfile. The explanation point in front of cp tells MATLAB to run cp as a Unix command instead of as a MATLAB command.

!cp /www/htdocs/CIS/106/pconrad/07F/labs/lab03/*.m ~/cisc106/lab03

Our best guess as to why copyfile with a wildcard didn't work for some people: The pattern seems to be that those students who have not yet changed their default shell to either /bin/tcsh or /bin/bash are the ones that experienced the problem. Pretty much all instructors and/or TAs use /bin/tcsh or /bin/bash as their login shell (we'll discuss why, and what that means in lecture.)

What you should do: As soon as possible (right now, perhaps!) please visit http://www.udel.edu/network, click on Change default login shell, and select either /bin/tcsh or /bin/bash. If you aren't sure which one to choose, use /bin/tcsh. This takes overnight to go into effect, so it wont affect your lab today. But it will make working at the Unix prompt a lot easier, and apparently it affects how MATLAB behaves as well.

Step 6b: Copying M-files from one lab directory to another

For step 7 in this labs, we are going to need the howMuchPizza.m file you created in lab02. We can copy that file from your ~/cisc106/lab02 directory to your ~/cisc106/lab03 directory with this command:

copyfile ~/cisc106/lab02/howMuchPizza.m ~/cisc106/lab03

Type this command in at the MATLAB prompt, and then use the ls command to verify that the howMuchPizza.m file got copied over.

Step 7: Script M-files vs. Function M-files

In lab02 we worked with a type of M-file called a script M-file. In step 5 of this lab, we worked with a a function M-file. Now its time to take a look at how these two compare with each other.

Step 7a: Comparing the function M-file areaOfPizza.m vs. the script M-file howMuchPizza.m

Now, let's compare how we might use both of these to solve the problem posed above:

Determine how much pizza (in square inches) you get if you order two regular pizzas (12 inch round) vs. 1 x-large pizza (16 inch round.)

With howMuchPizza.m, the parameters to the problem are hard coded inside the script file. So, we simply type howMuchPizza at the MATLAB command prompt, and we get this:

>> howMuchPizza

totalAreaTwoTwelveInchPizzas =

       226.19


totalAreaOneSixteenInchPizza =

       201.06

>>

With areaOfPizza.m, we do a bit more typing. But notice that we can change the parameters of the problem (e.g. how many small or large pizzas, or the sizes of the pizzas) without doing any additional programming.

For example, while Grottos pizzas are 12" and 16", Pat's pizzas are 12" and 15", and Peace-a-Pizzas are 14" and 16". We can easily make comparisons such as these with no additional programming:

>> areaOfPizza(12) * 2

ans =

       226.19

>> areaOfPizza(16)

ans =

       201.06

>> areaOfPizza(12) * 2

ans =

       226.19

>> areaOfPizza(15)

ans =

       176.71

>> areaOfPizza(14) * 3

ans =

       461.81

>> areaOfPizza(16) * 2

ans =

       402.12

>> 
  

You should not, however, come to the conclusion that this means that script files are "bad" and function M-files are "good". As we will see, they each have their proper use. And, it is often useful to use them together, as we explore in the next step.

Step 7b: Using both script files and function M-files together

One of the files you should have copied into your account back in Step 6 (the wildcard copy step) is this file: comparePizzas.m

Click on the link above to look at the contents of this file. Notice how it uses the areaOfPizza function we defined in areaOfPizza.m to do the computation. Thus we can type simply comparePizzas at the MATLAB prompt and get a list of various amounts of pizza. that we can obtain by buying various quantities and sizes of pies from various shops.

>>comparePizzas

twoGrottosRegular =

       226.19


oneGrottosXLarge =

       201.06


twoPatsMedium =

       226.19


onePatsLarge =

       176.71


threePeace14 =

       461.81


twoPeace14 =

       402.12

>>

This shows that script M-files and function M-files can work together very well.

For example, in Civil Engineering, suppose there is a general formula for determining the maximum load that a particular kind of bridge can hold.

Step 8: A special kind of script: testing script

A special kind of script that we can use with a function M-file is called a testing script. This script is used to test whether the function is working properly. There is a growing movement in software development that suggest we should write a test script before we write the function itself. That way, we will have a way to quickly determine whether our function is correct or not.

Step 8a: A testing script for areaOfPizza.m

Here is an example of a test script for the areaOfPizza function called testAreaOfPizza.m

Take a look at testAreaOfPizza.m by right clicking on the filename above, and choosing "Open Link in New Window"—that way, you can continue to read these instructions, and look at the file, side-by-side.

Note the following things about this file:

  1. This test script uses the words if and else. This is a feature of MATLAB that allows an M-file to "make a decision". After the word if, there is an expression that is either true or false.
  2. Because calculations involving pi are never exact—but, rather, are always approximations—the tests in the script pass if the value is within some tolerance of the expected result. That is,

Now, run this testing script and notice the result. You should see something like this:

>> testAreaOfPizza                                                             
test 1 passed
test 2 passed
>>

Step 8b: Evil programming—deliberately breaking something to "test the test"

Of course, if we are going to have confidence in a test file, we need to know that if the areaOfPizza.m file were truly broken, the test could detect that. So, in this step, we are going to do some "evil programming". We are going to introduce a "bug" (a mistake) on purpose into the areaOfPizza.m file, just to see what will happen. When we are finished, we'll fix it back.

Go to the edit window in the MATLAB user interface, and bring up the file areaOfPizza.m. Find the three lines that compute the result:

  radius = diameter / 2;
  area = pi * radius ^ 2;
  return;

Add in an extra "evil line" as shown below.

  radius = diameter / 2;
  area = pi * radius ^ 2;
  area = -42;   % this is an evil line---remove it later!
  return;

Note that on the evil line, everything after the % sign—all the way to the end of the line—is a comment, and it is ignored by MATLAB. Comments can occur not only a line by themselves, but also immediately after a MATLAB statement.

What will the evil line do?

The evil line will overwrite the correct computation of the area with the number -42 (the additive inverse of a famous number in geek culture). Thus, the function will always produce an incorrect result (since a pizza can never have a negative area.)

Step 8c: Running the test on areaOfPizza.m with our evil line in place

With the evil line in place, we should get the following:

>> testAreaOfPizza                                                             
test 1 failed

expected =

  113.1000


actual =

   -42

test 2 failed

expected =

  201.0600


actual =

   -42

>> 

Step 8d: Now, change it back

Now, take the evil line back out, and run the test again. It should be back to working properly.

Step 9: Understanding the areaOfPizza.m file

In Step 10, you will be writing your own function M-file. So it is important to understand how these files works. We'll start by examining the areaOfPizza.m file more closely.

Visit the following web link to look at the file you copied into your ~/cisc106/lab03 directory.

http://www.udel.edu/CIS/106/pconrad/07F/labs/lab03/areaOfPizza.m

Notice a few things about this file:

  1. This file starts with the following line:

    function area = areaOfPizza(diameter)

    This line indicates that:

  2. The next few lines are a series of comments like this:

    %areaOfPizza compute area of pizza, given diameter
    %
    % consumes: 
    %     diameter: number, diameter of the pizza in inches
    % produces:
    %     area: number, area of the pizza in square inches
    %     
    % examples
    %     >> areaOfPizza(12)
    %     ans = 113.10
    %     >> areaOfPizza(16)
    %     ans = 201.06
    %     
    % P.Conrad  CISC106 section 99, 09/03/2007
    

    These comments are known as the H1 comment. They are special, because they interact with the MATLAB commands help and lookfor. (We'll illustrate this below).

    In this H1 comment, we see the "contract" for the function—what it expects to get (in this case, diameter) and what it promises to produce. There are also some examples of how to use the function, along with what the result should be.

    Finally, we have the programmers name, information about the course and section, and the date the function was created.

  3. The next part of the file is the part that actually gets the work done. In this case, we take the diameter

Step 10: Fixing a broken .m file: areaOfRectPizza.m

In this step, you'll work with two M-files that you should find in your directory (copied when we did the wildcard copy back at step 6).

The two files are:

As you might expect, these files are similar to areaOfPizza.m and testAreaOfPizza.m, except they work on rectangular pizzas, such as the square (16"x16") and the party pizza (18" x 26") advertised by Pat's on this menu excerpt:

There is a problem with areaOfRectPizza.m however. Namely, that it doesn't work. The evil programmer has been at it, and has inserted a line that only ever returns -42 as the area of the pizza. You can verify this by running the testAreaOfRectPizza.m script:

>> testAreaOfRectPizza
test 1 failed

expected =

   120


actual =

   -42

test 2 failed

expected =

   169


actual =

   -42

>> 

So, your task: correct the problem in areaOfRectPizza.m so that the tests in testAreaOfRectPizza.m both pass.

Be sure to also change the author, date, class and section in the comments as appropriate—to your name, class, section, and the date you did the work.

Once this is done, create a diary file lab03.txt in which you run the commands shown below. If you are not sure about how to create a diary file, review the steps near the end of lab01.

 

Step 11: Submit your saved work for grading using "MyCourses" (WebCT).

Log on to MyCourses (WebCT) and find CISC106 (if it is not listed, tell your TA, and email your instructor!)

Follow the instructions for submitting an Assignment in WebCT (submit this as lab03). You should submit two files:

  1. lab03.txt (diary file from part 10)
  2. areaOfRectPizza.m (corrected file from part 10)

And you are all finished!


Grading

  1. lab03.txt (diary file from part 10) 20 pts
  2. areaOfRectPizza.m (diary file from part 10) 20 pts

Generally submitting everything according to instructions: 10 pts.

Due: 09/20/2007
End of lab03 for CISC106, Fall 2007 (50 pts)