Part 3

Streamlining MATLAB


Making it easier to perform MATLAB tasks

Creating functions and scripts

Enhancing automation using Live Scripts and Live Functions

Working with classes

Developing apps and building projects

Chapter 8

Automating Your Work


check Creating, modifying, and testing your script

check Using scripts in MATLAB

check Locating script errors

check Making your script run faster

Getting the computer to do the work for you is probably one of the best reasons to use a computer in the first place. Anytime you can automate repetitive or mundane tasks, you free yourself to do something more interesting. MATLAB is an amazing tool for performing all sorts of creative work, but you also have a lot of mundane and repetitive tasks to perform. For example, you may need to generate the same plot every week for a report. Automating that task would free you to do something more interesting, such as discover a cure for cancer or send a rocket to Mars. The point is that you have better things to do with your time, and MATLAB is only too willing to free your time so that you can do them. That’s what scripting is all about: not to make you some mad genius geek, but to automate tasks so that you can do something more interesting.

Remember Scripting is simply a matter of writing a procedure — writing down exactly what you want the computer to do for you, in other words. (You might compare it to a making a movie, with a writer creating the words the actors say and specifying the actions they perform.) You likely write procedures all the time for various people in your life. In fact, you may write procedures for yourself so that you remember how to perform the task later. Scripting for MATLAB is no different from any other procedure you have written in the past, except that you need to write the procedure in a manner that MATLAB understands.

This chapter helps you create basic MATLAB scripts, save them to disk so that you can access them whenever you want, and then run the scripts as needed. You also discover how to make your scripts run fast so that you don’t have to wait too long for MATLAB to complete its work. This chapter helps you understand the nature of errors in scripts, and how to locate and fix them. In the final section, you use the MATLAB Profiler to verify the performance of your script and look for ways to improve it.

Remember You don’t have to type the source code for this chapter manually. In fact, using the downloadable source is a lot easier. You can find the source for this chapter in the \MATLAB2\Chapter08 folder of the downloadable source. (See the Introduction for details on how to obtain the source code.) When using the downloadable source, you may not be able to work through some of the hands-on examples because the example files will already exist on your system. In this case, you can create an alternative folder, Chapter08a, to hold the results of the hands-on exercises.

Understanding What Scripts Do

A script is nothing more than a means to write a procedure that MATLAB can follow to perform useful work. It’s called a script and not a procedure because a script follows a specific format. MATLAB actually speaks its own English-like language that you must use to tell it what to do. The interesting thing is that you’ve used that language in every chapter so far by executing commands. A script doesn’t do much more than link together the various commands that you have used to perform a task from one end to the other. The following sections describe what a script does in more detail.

Creating less work for yourself

The object of a script is to reduce your workload. This concept might seem straightforward now, but some people get so wrapped up in the process of creating scripts that they forget that the purpose of the script is to create less work, not more. In fact, a script should meet some (or with luck, all) of the following goals:

· Reduce the time required to perform tasks

· Reduce the effort required to perform tasks

· Allow you to pass the task along to less skilled helpers

· Make it possible to perform the tasks with fewer errors (the computer will never get bored or distracted)

· Create standardized and consistent output

· Develop a secure environment in which to perform the task (because the details are hidden from view)

Remember Notice that none of the goals in this list entails making the computer do weird things that it doesn’t normally do, or wasting your time writing scripts to perform tasks that you never did in the past. The best scripts perform tasks that you already know how to do well because you have performed them so many times in the past. Yes, it’s entirely possible that you could eventually create a script to perform a new task, but even in that case, the new task is likely built on tasks that you have performed many times in the past. Most people get into trouble with scripting when they try to use it for something they don’t understand or haven’t clearly defined.

Defining when to use a script

Scripts work well only for mundane and repetitive tasks. Sometimes writing a script is the worst possible thing you can do. In fact, many times you can find yourself in a situation in which writing a script causes real (and potentially irreparable) damage. The following list provides you with guidelines as to when to use a script:

· The task is repeated often enough that you actually save time by writing a script (the time saved more than offsets the time spent writing the script).

· The task is well defined, so you know precisely how to perform it correctly.

· There are few variables in the way in which the task is performed so that the computer doesn’t have to make many decisions (and the decisions it makes are from a relatively small set of potential absolute answers).

· No creativity or unique problem-solving abilities are required to perform the task.

· All the resources required to perform the task are accessible by the host computer system.

· The computer can generally perform the task without constantly needing to obtain permissions.

· Any input required by the script is well defined so that the script and MATLAB can understand (and anticipate) the response.

Believe it or not, you likely perform regularly a huge number of tasks that fulfill all these requirements. The important thing is to weed out those tasks that you really must perform by yourself. Automation works only when used correctly to solve specific problems.

Creating a Script

Creating a script can involve nothing more than writing commands. In fact, the sections that follow show a number of ways in which you can create simple scripts without knowing anything about scripting. It may even strike you as quite odd that scripting feels much like writing commands in the Command Window. The only difference is that the commands don’t execute immediately. That’s the point of these following sections: Scripting doesn’t have to be hard or complicated; it only needs to solve the problems you normally solve anyway.

Writing your first script

MATLAB provides many different ways to write scripts. Some of them don’t actually require that you write anything at all! However, the traditional way to create a script in any application is to write it, so that’s what this first section does — shows you how to write a tiny script. The most common first script in the entire world is the “Hello World” example. The following steps demonstrate how to create such a script using MATLAB:

1. Click New Script on the Home tab of the menu.

You see the Editor window appear, as shown (highlighted) in Figure 8-1. This window provides the means to interact with scripts in various ways. The Editor tab shown in the figure is the one you use most often when creating new scripts.

Snapshot of using the Editor window to write a script manually.

FIGURE 8-1: Use the Editor window to write a script manually.

2. Type disp('Hello World');.

The disp() function tells MATLAB that you want to display something onscreen. In this case, you display a string directly onscreen, but you can also display variables.

Remember When working with a script, you end each line with a semicolon to avoid displaying values that you don’t want to display as part of the script output. You could simply type the string without a semicolon and without using the disp() function, but then the intent of the line of code becomes unclear. You may forget what the line of code does in the future if you leave out the details.

3. Click Run on the Editor tab of the Editor window.

You see a Select File for Save As dialog box, as shown in Figure 8-2. MATLAB always requests that you save your script before you run it to ensure that your script doesn’t get lost or corrupted in some way should something happen when it runs.

Snapshot of MATLAB always asks to save the work before running a script.

FIGURE 8-2: MATLAB always asks you to save your work before you run a script.

4. Create or select the MATLAB2\Chapter08 directory, type FirstScript.m in the File Name field, and click Save.

MATLAB saves your script to disk. All your script files will have an .m extension.

Tip Note that if the file isn’t found in the current folder or the MATLAB path, you see another MATLAB Editor dialog box like the one shown in Figure 8-3. (As an alternative, you may see a dialog box that states that MATLAB can’t run the file and provides only the Change Folder button.) You have two options to run the script:

· Change Folder: Change the current folder to match the saved location of the file. The Current Folder window content will change to match the save path for the script.

Snapshot of the directory you use to store the script must be the current directory or in the MATLAB path.

FIGURE 8-3: The directory you use to store the script must be the current directory or in the MATLAB path.

· Add to Path: Add the saved location to the MATLAB path so MATLAB can find the file to run it. The added folder will appear in bold type when you view it in the Current Folder window.

Simply click the box’s Change Folder button to make the dialog box disappear. This change will make all the scripts found in this chapter accessible. If you don’t see this box, continue to Step 5.

5. Select the MATLAB Command Window.

You see the following script output:

>> FirstScript

Hello World

The output is telling you that MATLAB has run FirstScript, which is the name of the file containing the script, and that the output is Hello World.

Using commands for user input

Some scripts work just fine without any user input, but most don't. To perform most tasks, the script must ask the user questions and then react to the user’s input. Otherwise, the script must either perform the task precisely the same way every time or obtain information from some other source. User input makes it possible to vary the way in which the script works.

Listing 8-1 shows an example of a script that asks for user input. You can also find this script in the AskUser.m file supplied with the downloadable source code.

LISTING 8-1 Asking for User Input

Name = input('What is your name? ', 's');

disp(['Hello ', Name]);

The input() function asks for user input. You provide a prompt that tells the user what to provide. When you want string input, as is the case in this example, you add the 's' argument to tell MATLAB that you want a string and not a number. When the user types a name and presses Enter, the value is placed in Name.

Remember The disp() function outputs text without assigning it to a variable. However, the disp() function accepts only a single input, and the example needs to output two separate strings (the 'Hello ' part and the Name part) as a combined whole. To fix this problem, you use the concatenation operator ([]). The term concatenation simply means to combine two strings. You separate each of the strings with a comma, as shown in the example.

When you run this example, the script asks you to type your name. Type your name and press Enter. In this case, the example uses John as the name, but you can use any name you choose. After you press Enter, the script outputs the result. Here is typical output from this example:

>> AskUser

What is your name? John

Hello John

Copying and pasting into a script

Experimentation is an essential part of working with MATLAB. After you get a particular command just right, you may want to add it to a script. This act involves cutting and pasting the information. When working in the Command Window, simply highlight the text you want to move into a script, right-click it, and choose Copy or Cut from the context menu. As an alternative, most platforms support speed keys for cutting and pasting, such as Ctrl+C for copy and Ctrl+X for cut.

Copying and cutting places a copy of the material on the Clipboard. Select the Editor window, right-click the location where you want to insert the material, and choose Paste from the context menu. (The pasted material is always put wherever the mouse pointer is pointing, so make sure you have the mouse cursor in the right place before you right click.) As an alternative, most platforms provide a speed key for pasting, such as Ctrl+V. In this case, you place the insertion pointer (the text pointer) where you want the new material to appear.

The Command History window succinctly stores all the commands that you type, making it easy for you to pick and choose the commands you want to place in a script. The following list provides techniques that you can use in the Command History window:

· Click a single line to use just that command.

· Ctrl+click to add additional lines to a single line selection.

· Shift+click to add all the lines between the current line and the line you clicked to a single line selection.

The result is that you end up with one or more selected lines. You can cut or copy these lines to the Clipboard and then paste them into the Editor window.

Tip Using other sources for script material is possible, and you should use them whenever you can. For example, when you ask for help from MATLAB, the help information sometimes includes example code that you can copy and paste into your script. You can also find online sources of scripts that you can copy and paste. Checking the results of the pasting process is important in this case to ensure that you didn’t inadvertently copy nonscript material. Simply delete the unwanted material before you save the script.

Converting the Command History into a script

After experimenting for a while, you might come up with a series of commands that does precisely what you’d like that series to do. Trying to cut and paste the commands from the Command Window is inconvenient. Of course, you could select the commands in the Command History window, copy them to the Clipboard, and paste them from there, but that seems like a waste of time, too.

Remember In reality, you can simply make a script out of the commands that you select in the Command History window. After you select the commands you want to use, just right-click the selected commands and choose Create Script from the context menu that appears. MATLAB opens a new Editor window with the selected commands in place (in the order they appear in the Command History window). Save the result to disk and run the script to see how it works.

Continuing long strings

Sometimes you can’t get by with a short prompt — you need a longer prompt in order to obtain the information you need. When you need to create a longer string, use the continuation operator (…), which many people will recognize as an ellipsis. Listing 8-2 shows an example of how you can use long strings in a prompt to modify the UserInput example shown in Listing 8-1. You can also find this script in the LongString.m file supplied with the downloadable source code.

LISTING 8-2 Asking for User Input in a Specific Way

Prompt = [

'Type your own name, but only if it isn''t ',…

'Wednesday.\nType the name of the neighbor ',…

'on your right on Wednesday.\nHowever, on ',…

'a Wednesday with a full moon, type the ',…

'name of\nthe neighbor on your left! '];

Name = input(Prompt, 's');

disp(['Hello ', Name]);

This example introduces several new features. The Prompt variable contains a long string with some formatting that you haven’t seen before. It uses the concatenation operator to create a single string from each of the lines in the text. Each substring is self-contained and separated from the other substrings with a comma. The continuation operator lets you place the substrings on separate lines.

Notice the use of the double single quote (isn''t) in the text. You need to use two single quotes when you want a single quote to appear in the output as an apostrophe (isn't), rather than terminate a string. The \n character is new, too. This is a special character that controls how the output appears, so it is called a control character. In this case, the \n character adds a new line. When you run this example, you see output similar to that shown here:


Type your own name, but only if it isn't Wednesday.

Type the name of the neighbor on your right on Wednesday.

However, on a Wednesday with a full moon, type the name of

the neighbor on your left! John

Hello John

Everywhere a \n character appears in the original string, you see a new line. In addition, the word isn’t contains a single quote, as expected. The following list shows the control characters that MATLAB supports, and defines how they are used.

· '': Single quotation mark/apostrophe

· %%: Percent character

· \\: Backslash

· \a: Alarm (sounds a beep or tone on the computer)

· \b: Backspace

· \f: Form feed

· \n: New line

· \r: Carriage return

· \t: Horizontal tab

· \v: Vertical tab

· \xN: Hexadecimal number, N (where N is the number of the character you want to display), where sprintf('\x0041') would produce a capital letter A

· \N: Octal number, N (where N is the number of the character you want to display), where sprintf('\0101') would product a capital letter A

Remember Note that control characters don’t work with disp(). When using disp('\x0041'), you see an output of \x0041, rather than a capital letter A. However, you can use control characters with functions such as sprint() and fprintf().

Adding comments to your script

People tend to forget things. You might know how a script works on the day you create it and possibly even for a week after that. However, six months down the road, you may find that you don’t remember much about the script at all. That’s where comments come into play. Using comments helps you to remember what a script does, why it does it in a certain way, and even why you created the script in the first place. The following sections describe comments in more detail.

Using the % comment

Anytime MATLAB encounters a percent sign (%), it treats the rest of the line as a comment. Comments are simply text that is used either to describe what is happening in a script or to comment out lines of code that you don’t want to execute. You can comment out lines of code during the troubleshooting process to determine whether a particular line is the cause of errors in your script. The “Analyzing Scripts for Errors” section, later in this chapter, provides additional details on troubleshooting techniques. Listing 8-3 shows how comments might appear in a script. You can also find this script in the Comments.m file supplied with the downloadable source code.

LISTING 8-3 Using Comments to Make Code Easier to Read

% Tell MATLAB what to display onscreen.

Prompt = [

'Type your own name, but only if it isn''t ',…

'Wednesday.\nType the name of the neighbor ',…

'on your right on Wednesday.\nHowever, on ',…

'a Wednesday with a full moon, type the ',…

'name of\nthe neighbor on your left! '];

% Obtain the user's name so it can

% be displayed onscreen.

Name = input(Prompt, 's');

% Output a message to make the user feel welcome.

disp(['Hello ', Name]);

Compare Listing 8-3 with Listing 8-2. You should see that the code is the same, but the comments make the code easier to understand. When you run this code, you see that the comments haven’t changed how the script works. MATLAB also makes comments easy to see by displaying them in green letters.

Using the %% comment

MATLAB supports a double percent sign comment (%%) that supports special functionality in some cases. Here’s how this comment works:

· Acts as a standard command in the Command Window.

· Allows you to execute a portion (a section) of the code when using the Run and Advance feature.

· Creates special output when using the Publish feature.

The following sections describe the special %% functionality. You won’t use this functionality all the time, but it’s nice to know that it’s there when you do need it.


When you add a %% comment in the Editor window, MATLAB adds a section line above the comment (unless the comment appears at the top of the window), effectively dividing your code into discrete sections. To add a section comment, you type %%, a space, and the comment, as shown in Figure 8-4.

Snapshot of the %% comment adds section lines to the code.

FIGURE 8-4: The %% comment adds section lines to the code.

Tip When opening a standard script file containing a %% comment, you see a dialog at the top of the script file that asks whether you want to open the file as a Live Script. Chapter 11 tells you about working with Live Scripts, which are interactive documents managed in a single environment called the Live Editor. A Live Script can combine:

· MATLAB code

· Formatted text

· Equations

· Images

Remember As with standard comments, the %% comment appears in green type. The line above the comment is your cue that this is a special comment. In addition, the position of the text cursor (the insertion point) selects a particular section. The selected section is highlighted in a pale yellow. Only the selected section executes when you click Run and Advance. Here’s how sections work:

1. Place the cursor at the end of the Prompt = line of code and then click Run and Advance.

Only the first section of code executes. Notice also that the text cursor comes to rest at the beginning of the second section.

2. Click Run and Advance.

The script displays a prompt asking for a name. The editor highlights the third section of code. Only the second section of code executes. You don’t see the script output.

3. Type a name and press Enter.

The script accepts the name provided and places it in Name. However, there is still no output.

4. Place the cursor at the beginning of the second section and then click Run and Advance.

You are asked for your name as in Step 2, and you need to enter a name and press Enter as in Step 3. However, you don’t see any output.

5. Click Run and Advance with the text cursor at the beginning of the third %% comment.

You see the script output (the correct output, in fact) without being asked for a name.

6. Perform Step 5 as often as desired.

The application displays the script output every time without asking for any further information. Using this technique lets you execute just the part of a script that you need to test rather than run the entire script every time.

Tip You can make small changes to the code and still run a particular section. For example, change Hello to Goodbye in the code shown previously in Figure 8-4. With the third section selected, click Run and Advance. The output displays a goodbye message, rather than a hello message, without any additional input.


The section comments let you easily document your script. This section provides just a brief overview of the publishing functionality, but it demonstrates just how amazing this feature really is. To start with, you really do need to create useful section comments — the kind that will make sense as part of a documentation package.

When creating the setup for the script you want to publish, you need to define the output format and a few essentials. The default format is HTML, which is just fine for this example. However, if you don’t make one small change, the output isn’t going to appear quite as you might like it to look. On the Publish tab of the Editor window, click the down arrow under Publish and choose Edit Publishing Options. You see the Edit Configurations dialog box, shown in Figure 8-5.

The Evaluate Code option evaluates your script and outputs the result as part of the documentation. Unfortunately, MATLAB can’t evaluate input() functions as part of publishing the documentation for a script. As a consequence, you must set Evaluate Code to false. Click Publish. MATLAB produces an HTML page like the one shown in Figure 8-6.

Snapshot of modifying the configuration options as needed to ensure that the script will publish correctly.

FIGURE 8-5: Modify the configuration options as needed to ensure that your script will publish correctly.

Snapshot of the published documentation looks quite nice.

FIGURE 8-6: The published documentation looks quite nice.

Considering the little work you put into creating the documentation, it really does look quite nice. In fact, it looks professional. When working with complex scripts, documentation like this really does serve a serious need. After you’re done admiring your work, close the HMTL page and the Edit Configurations dialog box.

Revising Scripts

Scripts usually aren’t perfect the first time you write them. In fact, editing them quite a few times is common. Even if the script does happen to attain perfection, eventually you want to add features, which means revising the script. The point is, you commonly see your scripts in the Editor window more than once. Here are some techniques you can use to open a script file for editing:

· Double-click the script’s filename in the Current Folder window.

· Click the down arrow on the Open option of the Home tab and select the file from the list. (The list contains every kind of file you’ve recently opened, not just script files.)

· Click the down arrow on the Open option of the Editor tab and select the file from the list. (The list will include only the most recently used script files.)

· Click Find Files in the Editor tab to display the Find Files dialog box. Enter a search criteria, such as *.m (where the asterisk is a wild-card character for all files) and click Find. Double-click the file you want to open in the resulting list.

· Locate the file using your platform’s hard drive application (such as Windows Explorer in Windows or Finder on the Mac) and double-click the file entry.

Warning It’s a bad idea to make changes to a script and then try to use it without testing it first. Always test your changes to ensure that they work as you intend them to. Otherwise, a change that you thought would work could instead cause data damage or other problems.

Calling Scripts

Creating scripts without having some way to run them would be pointless. Fortunately, MATLAB lets you use scripts in all sorts of ways. The act of using a script — causing it to run — is known as calling the script. You can call scripts in these ways:

· Right-click the script file in the Current Folder window and select Run from the context menu that appears.

· Select the script file in the Current Folder window and press F9.

· Type the filename on the command line and press Enter. (Adding the extension isn’t necessary.)

· Type the script filename in another script.

Remember The last method of calling a script is the most important. It enables you to create small pieces of code (scripts) and call those scripts to create larger, more powerful, and more useful pieces of code. The next step is creating functions that can send information in and out of those smaller pieces of code. (You see the topic of functions explored in Chapter 9.)

Improving Script Performance

Scripts can run only so fast. The resources offered by your system (such as memory and processor cycles), the location of data, and even the dexterity of the user all come into play. Of course, with the emphasis on “instant” in today’s society, faster is always better. With this in mind, the following list provides you with some ideas on how to improve your script performance. Don’t worry if you don’t completely understand all these bullets; you see most of these techniques demonstrated somewhere in the book. This list serves as a reference for when you’re working on creating the fastest script possible:

· Create variables once instead of multiple times.

· Chapter 10 shows how to repeat tasks; creating variables inside these loops (bits of repeating code) is a bad idea.

· An application made up of smaller files might inadvertently re-create variables, so look for this problem as you analyze your application.

· Use variables to hold just one type of data. Changing the data type of a variable takes longer than simply creating a new one.

· Make code blocks as small as possible.

· Create several small script files rather than one large one.

· Define small functions rather than large ones.

· Simplify expressions and functions whenever possible.

· Use vectors whenever possible.

· Replace multiple scalar variables with one vector.

· Rely on vectors whenever possible to replace sparse matrices.

· Avoid running large processes in the background.

Analyzing Scripts for Errors

Ridding an application of errors is nearly impossible. As complexity grows, the chances of finding every error diminishes. Everyone makes mistakes, even professional developers. So, it shouldn’t surprise you that you might make mistakes from time to time as well. Of course, the important thing is to find the errors and fix them. The process of finding errors and fixing them is called debugging.

Sometimes the simplest techniques for finding errors are the best. Working with your script in sections is an important asset in finding errors. The “Using the %% comment” section, earlier in this chapter, describes how to create and use sections. When you suspect that a particular section has an error in it, you can run the code in that section multiple times as you look in the Workspace window to see the condition of variables that the code creates and the Command Window to see the sort of output it creates.

Adding disp() statements to your code in various places lets you display the status of various objects. The information prints right in the Command Window so that you can see how your application works over time. Removing the disp() statements that you’ve added for debugging purposes is essential after the session is over. You can do this by adding a % in front of the disp() statement. This technique is called commenting out, and you can use it for lines of code that you suspect might contain errors as well. In addition, you can comment out debugging code that you use to troubleshoot your application in case you need it again later.

MATLAB also supports a feature called breakpoints. A breakpoint is a kind of stop sign in your code. It tells MATLAB to stop executing your code in a specific place so that you can see how the code is working. MATLAB supports two kinds of breakpoints:

· Absolute: The code stops executing every time it encounters the breakpoint. You use this kind of breakpoint when you initially start looking for errors and when you don’t know what is causing the problem.

· Conditional: The code stops executing only when a condition is met. For example, a variable might contain a certain value that causes problems. You use this kind of breakpoint when you understand the problem but don’t know precisely what causes it.

To set an absolute breakpoint, place the text cursor anywhere on the line and choose Set/Clear in the Breakpoints drop-down list on the Editor tab. When you set an absolute breakpoint, a red circle appears next to the line. To set a conditional breakpoint, place the text cursor anywhere on the line and choose Set Condition in the Breakpoints drop-down list. Type a condition, such as x == 1, in the dialog box that appears. Later chapters in the book demonstrate the use of breakpoints.

Creating error-handling code is also important in your application. Even though error handling doesn’t fix an error, it makes the error less of a nuisance and can keep your application from damaging important data. Chapter 18 provides you with more ideas on how to locate and deal with errors in your script using error handling.

Using the MATLAB Profiler to Improve Performance

The MATLAB Profiler can help you locate the parts of your code that take too much time to execute. This allows you to spend your time efficiently in modifying the code to run faster. One way to profile your application is to click Run and Time on the Editor tab. MATLAB runs your code and displays a Profiler window like the one shown in Figure 8-7 when your code completes running.

Snapshot of viewing the run time for the scripts which tells how efficient they are.

FIGURE 8-7: Viewing the run time for your scripts tells you how efficient they are.

You can also interact with the MATLAB Profiler programmatically by calling various functions. The following list provides a short overview of the functions and their purpose:

· profile status: Tells the current status of the Profiler, such as whether the profiler is on.

· profile('info'): Displays a list of Profiler data elements. You can display a particular data element by adding a period and its name to the function, such as profile('info').FunctionHistory, to see the function history.

· profile on: Turns the Profiler on. You can add the function history feature by adding the -history switch.

· profile off: Turns the Profiler off.

· profile resume: Restarts the Profiler without clearing its history.

· profile clear: Clears the Profiler statistics.

· profile viewer: Stops the Profiler and displays the results in the Profiler window, shown in Figure 8-7.

You can support our site by clicking on this link and watching the advertisement.

If you find an error or have any questions, please email us at Thank you!