This HTML version of the book is provided as a convenience, but some math equations are not translated correctly. The PDF version is more reliable.
Chapter 3 Scripts
So far we have typed all of our programs “at the prompt,” which is fine if you are not writing more than a few lines. Beyond that, you will want to store your program in a script and then execute the script.
A script is a file that contains MATLAB code. These files are also called “M-files” because they use the extension .m, which is short for MATLAB.
You can create and edit scripts with any text editor or word processor, but the simplest way is by selecting New→Script from the File menu. A window appears running a text editor specially designed for MATLAB.
Type the following code in the editor
x = 5
and then press the (outdated) floppy disk icon, or select Save from the File menu. Either way, a dialog box appears where you can choose the file name and the directory where it should go. Change the name to myscript.m and leave the directory unchanged.
By default, MATLAB will store your script in a directory that is on the search path, which is the list of directories MATLAB searches for scripts.
Go back to the Command Window and type myscript (without the extension) at the prompt. MATLAB executes your script and displays the result.
>> myscript x = 5
When you run a script, MATLAB executes the commands in the M-File, one after another, exactly as if you had typed them at the prompt.
If something goes wrong and MATLAB can’t find your script, you will get an error message like:
>> myscript Undefined function or variable 'myscript'.
In this case you can either save your script again in a directory that is on the search path, or modify the search path to include the directory where you keep your scripts. You’ll have to consult the documentation for the details (sorry!).
The filename can be anything you want, but you should try to choose something meaningful and memorable. You should be very careful to choose a name that is not already in use; if you do, you might accidentally replace one of MATLAB’s functions with your own. Finally, the name of the file cannot contain spaces. If you create a file named my script.m, MATLAB will complain when you try to run it:
>> my script Undefined function or variable 'my'.
The problem is that it is looking for a script named my. The problem is even worse if the first word of the filename is a function that exists. Just for fun, create a script named abs val.m and run it.
Keeping track of your scripts can be a pain. To keep things simple, for now, I suggest putting all of your scripts in one directory of your own.
Exercise 1 The Fibonacci sequence, denoted F, is described by the equations F1 = 1, F2 = 1, and for i ≥ 3, Fi = Fi−1 + Fi−2. The elements of this sequence occur naturally in many plants, particularly those with petals or scales arranged in the form of a logarithmic spiral.
The following expression computes the nth Fibonacci number:
Translate this expression into MATLAB and store your code in a file named fibonacci1.m. At the prompt, set the value of n to 10 and then run your script. The last line of your script should assign the value of Fn to ans. Try outputting ans with both format short and format long. Notice, especially with the long format, that the answer is not exactly 55 as it should be for F10. This is due to things like rounding errors as the expression was being calculated.
3.2 Why scripts?
Unfortunately, the great power of scripts comes with great responsibility, which is that you have to make sure that the code you are running is the code you think you are running.
First, whenever you edit your script, you have to save it before you run it. If you forget to save it, you will be running the old version.
Also, whenever you start a new script, start with something simple, like x=5, that produces a visible effect. Then run your script and confirm that you get what you expect. MATLAB comes with a lot of predefined functions. It is easy to write a script that has the same name as a MATLAB function, and if you are not careful, you might find yourself running the MATLAB function instead of your script.
Either way, if the code you are running is not the code you are looking at, you will find debugging a frustrating exercise! And that brings us to the Third Theorem of Debugging:
You must always be 100% sure that the code you are running is the code you think you are running.
3.3 The workspace
>> x=5; >> y=7; >> z=9; >> who Your variables are: x y z
The clear command can also remove specified variables.
>> clear x y >> who Your variables are: z
>> disp(z) 9
But it’s easier to just type the variable name.
>> z z = 9
3.4 More errors
Again, when you try something new, you should make a few mistakes on purpose so you’ll recognize them later.
The most common error with scripts is to run a script without creating the necessary variables. For example, fibonacci1 requires you to assign a value to n. If you don’t:
>> fibonacci1 Undefined function or variable 'n'. Error in fibonacci1 (line 9) diff = t1^n - t2^n;
The details of this message might be different for you, depending on what’s in your script. But the general idea is that n is undefined. Notice that MATLAB tells you what line of your program the error is in, and displays the line.
This information can be helpful, but beware! MATLAB is telling you where the error was discovered, not where the error is. In this case, the error is not in the script at all; it is, in a sense, in the workspace.
Which brings us to the Fourth Theorem of Debugging:
Error messages tell you where the problem was discovered, not where it was caused.
The object of the game is to find the cause and fix it—not just to make the error message go away.
3.5 Pre- and post-conditions
Every script should contain a comment that explains what it does, and what the requirements are for the workspace. For example, I might put something like this at the beginning of fibonacci1:
% Computes the nth Fibonacci number. % Precondition: you must assign a value to n before running % this script. Postcondition: the result is stored in ans.
A precondition is something that must be true, when the script starts, in order for it to work correctly. A postcondition is something that will be true when the script completes.
If there is a comment at the beginning of a script, MATLAB assumes it is the documentation for the script, so if you type help fibonacci1, you get the contents of the comment (without the percent signs).
>> help fibonacci1 Computes the nth Fibonacci number. Precondition: you must assign a value to n before running this script. Postcondition: the result is stored in ans.
That way, scripts that you write behave just like predefined scripts. You can even use the doc command to see your comment in the Help Window.
3.6 Assignment and equality
In mathematics the equals sign means that the two sides of the equation have the same value. In MATLAB an assignment statement looks like a mathematical equality, but it’s not.
One difference is that the sides of an assignment statement are not interchangeable. The right side can be any legal expression, but the left side has to be a variable, which is called the target of the assignment. So this is legal:
>> y = 1; >> x = y+1 x = 2
But this is not:
>> y+1 = x y+1 = x | Error: The expression to the left of the equals sign is not a valid target for an assignment.
In this case the error message is pretty helpful, as long as you know what a “target” is.
Another difference is that an assignment statement is only temporary, in the following sense. When you assign x = y+1, you get the current value of y. If y changes later, x does not get updated.
A third difference is that a mathematical equality is a statement that may or may not be true. For example, y = y+1 is a statement that happens to be false for all values of y. In MATLAB, y = y+1 is a sensible and useful assignment statement. It reads the current value of y, adds one, and replaces the old value with the new value.
>> y = 1; >> y = y+1 y = 2
When you read MATLAB code, you might find it helpful to pronounce the equals sign “gets” rather than “equals.” So x = y+1 is pronounced “x gets the value of y plus one.”
To test your understanding of assignment statements, try this exercise:
Exercise 2 Write a few lines of code that swap the values of x and y. Put your code in a script called swap and test it.
3.7 Incremental development
When you start writing scripts that are more than a few lines, you might find yourself spending more and more time debugging. The more code you write before you start debugging, the harder it is to find the problem.
Incremental development is a way of programming that tries to minimize the pain of debugging. The fundamental steps are
When this process works, you will find that your changes usually work the first time, or the problem is obvious. That’s a good thing, and it brings us to the Fifth Theorem of Debugging:
The best kind of debugging is the kind you don’t have to do.
In practice, there are two problems with incremental development:
If you find yourself writing more than a few lines of code before you start testing, and you are spending a lot of time debugging, you should try incremental development.
3.8 Unit testing
In large software projects, unit testing is the process of testing software components in isolation before putting them together.
The programs we have seen so far are not big enough to need unit testing, but the same principle applies when you are working with a new function or a new language feature for the first time. You should test it in isolation before you put it into your program.
For example, suppose you know that x is the sine of some angle and you want to find the angle. You find the MATLAB function asin, and you are pretty sure it computes the inverse sine function. Pretty sure is not good enough; you want to be very sure.
Since we know sin0 = 0, we could try
>> asin(0) ans = 0
which is correct. Also, we know that the sine of 90 degrees is 1, so if we try asin(1), we expect the answer to be 90, right?
>> asin(1) ans = 1.5708
Oops. We forgot that the trig functions in MATLAB work in radians, not degrees. So the correct answer is π/2, which we can confirm by dividing through by pi:
>> asin(1) / pi ans = 0.5000
With this kind of unit testing, you are not really checking for errors in MATLAB, you are checking your understanding. If you make an error because you are confused about how MATLAB works, it might take a long time to find, because when you look at the code, it looks right.
Which brings us to the Sixth Theorem of Debugging:
The worst bugs aren’t in your code; they are in your head.
Imagine that you are the owner of a car rental company with two locations, Albany, and Boston. Some of your customers do “one-way rentals,” picking up a car in Albany and returning it in Boston, or the other way around. Over time, you have observed that each week 5% of the cars in Albany are dropped off in Boston, and 3% of the cars in Boston get dropped off in Albany. At the beginning of the year, there are 150 cars at each location.
Write a script called car_update that updates the number of cars in each location from one week to the next. The precondition is that the variables a and b contain the number of cars in each location at the beginning of the week. The postcondition is that a and b have been modified to reflect the number of cars that moved.
To test your program, initialize a and b at the prompt and then execute the script. The script should display the updated values of a and b, but not any intermediate variables.
Note: cars are countable things, so a and b should always be integer values. You might want to use the round function to compute the number of cars that move during each week.
If you execute your script repeatedly, you can simulate the passage of time from week to week. What do you think will happen to the number of cars? Will all the cars end up in one place? Will the number of cars reach an equilibrium, or will it oscillate from week to week?
In the next chapter we will see how to execute your script automatically, and how to plot the values of a and b versus time.
Are you using one of our books in a class?We'd like to know about it. Please consider filling out this short survey.