Creating bug-free code isn't easy and can take a lot of testing, especially on larger projects. I could have had you add the code to the graphing movie to prevent the error from occurring in the first place, but it's good practice to do a little bug hunting, because you are sure to be doing it in the future.
Open the graph movie, then open the Message window. Enter the following:
theMonth = 12 theYear = 2012
This is to insure you'll be trying to select data from a month that doesn't have any, because you want to reproduce the error.
Play the movie and use the Message window to call the showMonth method.
It doesn't matter what type of data you try selecting, as there is no data. I default to biking because I ride a bike. Now when you press Enter you will receive an error message similar to the one you received in the main movie. However, because you're in the proper movie you now have the option to debug the code.
Press the Debug button within the error dialog to open the Debugger. The debugger opens. A green arrow indicates the line of code causing the problem:
maxAvg = avgList.max()
If you scroll through the list of variables, you'll see that the avgList variable is an empty list. This is causing the max function to fail, as it can't find the maximum value in an empty list.
To fix the error you could of course add an if statement that would check the avgList variable to see if the list was empty. You could do this by comparing the variable to an empty list like:
if avgList =  then
Or you could check to see if the count of the list is zero:
if avgList.count() = 0 then
Either tactic would alleviate the symptoms, but they don't fully address the problem. If you scroll to the top of the variable list in the debugger, you should find that the data variable is also an empty list.
This is the real issue. When you call showMonth(), it calls getdata in order to execute the SQL SELECT command. The result of the query is then returned and a conditional test is performed to see if the result is a list or not:
if ilk(data) <> #list then
If the type of the data variable is a list, the display method is called, with data being passed as an argument. The problem is that even though no data was selected from the database, an empty list is still returned and passed to the display method. You could add a check so that the display method is called only when there is actual data in the list, but that would cause another small issue. If the display method is not called, the graph titlethe month and yearwouldn't be updated. You want to add a check after the title of the graph is set, but before you do anything with the empty list.
You can make the change to the code right within the debugger.
Scroll the code section of the debugger to the display method. Here is the line that sets dataCount to the count of the list:
dataCount = data.count()
Immediately after it, add this line of code:
if dataCount = 0 then exit
Now the graph title cast member will still be set properly, even when there is no data to graph.
While you're editing, you may want to uncomment the line in the showMonth method that calls showError in the Stage movie. You may even want to add a test so that you call showError when running as a MIAW and do the trace otherwise. Of course, you may just want to duplicate showError into the graph movie and not worry about testing at all; I'll leave that up to you.
Close the debugger, then rewind and play the movie.
There's just one more cleanup task to do, and it's easier shown than explained.
Use the Message window to set the global variables theMonth, and theYear to values containing data. So far, I've used July 2004 for the examples. In the Message window execute the following:
theMonth = 7 theYear = 2004 showMonth("B")
You should see the graph of the biking data.
Change the globals in the Message windows to a date containing no data and then run showMonth again:
theMonth = 7 theYear = 2012 showMonth("B")
The graph's title changes but the previously drawn graph remains. There are a couple of ways this can be fixed. You could use imaging Lingo to make an image of the blank stage and then copy pixel that onto the stage each time the graph is called. But you've already seen how to do that. Instead, you'll use a single line of code that seems like it shouldn't do what it doesbut it does.
Double-click the Main Script to open it. Add the following line of Lingo as the very first line of the display method:
the stageColor = the stageColor
By setting the stage's color to itself, this odd little line of code has the effect of clearing the Stage image back to its original state, before you drew into it. More technically, that line forces Director to do a low-level redraw of the Stage. Currently, stageColor is undocumented in Director, though you can find more information about it on Macromedia's Web site, or by searching Google.
Close the script window and save the movie. Open the mytrainer movie and play it. Display the graph for a month with data, then for a month without data.
The graph no longer produces an error when viewing months with no data, and it also erases any old data that may have been present.
Before finishing this lesson, you should consider two more cleanup tasks involving the Arca database Xtra and the graph movie. This isn't absolutely necessary to do, but it's good coding practice. The Xtra should be released from memory when you are finished with it, just as the MIAW should.
You can release an Xtra by setting the variable containing its instance to zero. A MIAW can be released by using the forget method, available to windows. You can take care of both of these cleanup tasks in the stopMovie handler of the application.
Stop the movie and open the Main Script from the scripts cast. Add the following three lines of Lingo to the bottom of the stopMovie handler:
_global.myDB = 0 if _player.windowList.getOne(window("graph")) then window("graph").forget() end if
First, setting myDB to zero releases the Xtra from memory. Next, a check is done to insure that the graph window is in the windowList before attempting to forget it. If you try to forget a window that is not present, you will generate an error.
Save the movie.
You can go back and add finishing touches now, or make any changes you feel are appropriate. You may want to change the calendar so that it also displays the average speed, instead of only having the averages available on the graph. You can reference the code in the graph movie to figure out how to calculate the average speed.
Finally, if you decide to use the log on a regular basis, you will probably want to add a Delete button to the Flash dialog in order to allow deleting data that was mistakenly entered, such as the test data. To do that, just follow what you learned about selecting and inserting data, and apply it to using the SQL DELETE FROM command.
The training log is now complete, and you can move on to the next lesson. There, you will learn about packaging the movie for placement on a CD as well as cross-platform authoring.
To learn more about using and managing windows in your movies, you should read the section on MIAWs in the Using Director part of Director's Help. The Director developer section on Macromedia's web site also has articles on MIAWs that will help you.