Foundations
We Programmers Need Etudes
Why musicians have a leg up on us programmers
Jun. 16, 2005 03:00 PM
Have you ever noticed the correlation between musicians and programmers? Some of the best programmers I know are or have been musicians. I recently had a class where 70% of the students were active musicians - some even with CDs of their work.
Perhaps one of the reasons for this pairing is that both musicians and programmers have their heads immersed in abstract concepts while their fingers (literally!) translate these into tangible "products." Musicians take concepts such as keys, scales, and silence and combine these into melodies that can be played; programmers take concepts such as types, variables, and encapsulation and combine these into programs that can be run.
Both endeavors, under their respective skins, are based on mathematics. (When computer science began to be taught at universities, it was an offering of the Mathematics department.) Both musicians and programmers learn a catalog of patterns, which they commonly use. And both music and programming require a high degree of both creativity and discipline: one without the other is not enough to achieve on the highest levels.
But musicians have a leg up on us programmers: they have etudes. An etude, literally a "study," is a piece of music written for purposes of practicing or displaying technique. For every instrument, study books (etudes) are available to help musicians learn specific techniques and practice in particular areas.
Etudes are helpful because they recognize that, in order for something to be truly useful, it must become natural and easy for you to use. It's paradoxical but true: to achieve such effortlessness, you must expend a great deal of effort, and to achieve mastery, there's nothing as helpful as practice. It's all very good, for example, to know that a certain bit of information might be represented as XML, but without intimate familiarity with XML in general and ColdFusion's processing of XML in particular, you're unlikely to use XML on a real programming project.
There's surely no shortage of programming books that explain concepts (such as XML), but there's a dearth of structured practice pieces that test how well you can translate from the conceptual to the tangible. In short, we programmers need etudes.
My plan, over the next several months, is to help provide just such practice pieces. I hope you'll find them helpful and I'd love to get your ideas on subjects for etudes (hal@halhelms.com).
This month's etude deals with ColdFusion arrays. You can download the solution from www.halhelms.com/etudes/1.cfm. Ready?
Problems
- The following table represents the average monthly prices for gold for the years, 1994-1996. Create an array to store this information. (Note: The month names and years are part of the array.)
- Programmatically determine: what month had the highest average for all three years?
- Programmatically determine: what year had the highest single monthly price for gold?
- Sort the gold array by the average price of all months in ascending order. For example, suppose the average price of gold was: 1994 - 376.58; 1995 - 372.92; 1996 - 384.23. Then, the array's first element should be the prices for gold during 1995, followed by 1994 and finishing with 1996.
- Remove the non-price information in the gold array above - that is, the abbreviations of the months in the first row and the year numbers in the first column.
Solutions
- What's needed is a two-dimensional array. There are two options for this. To conserve space, we'll just get you started with creating the array. If you really get stuck, you can download the full program.
Option A: Create a monolithic two-dimensional array and populate it See Listing 1.
Option B: Create a series of single-dimensional array and "stack" them See Listing 2.
Whichever way you opt for, it's important to understand that you're producing exactly the same array. If you <cfdump> both goldA and goldB, you'll see they're identical. The reason? A two-dimensional array is nothing more than an array of arrays. Similarly, a three-dimensional array is just an array of arrays of arrays. And while you can't create more than three-dimensional arrays in a monolithic fashion, you certainly can by stacking arrays.
Understanding that multi-dimensional arrays are nothing other than arrays of arrays will also help you use ColdFusion's various array functions, most of which are meant to work with one-dimensional arrays. Does that mean that these functions can't be used with multi-dimensional arrays? They certainly can - if the argument you supply to the array function is a one-dimensional array.
For example, consider the ArrayAvg function. This function requires a one-dimensional array. Pass it a multi-dimensional array (such as our gold arrays) and the function will throw an exception.
But you can use the ArrayAvg function - if you provide it with single-dimensional arrays:
<cfset avg1994 = ArrayAvg(goldA[2]) />
In this example, goldA[2] points to the single-dimensional array of goldA:
Now, while the ArrayAvg function doesn't produce any errors, it also doesn't produce the correct answer because it will average the entire row, including the "1994" found in the first element.
- Each of these problems helps reinforce the idea that multi-dimensional arrays are simply arrays of arrays. See Listing 3.
- To determine the year with the single highest monthly price for gold. See Listing 4:
- I'm not going to show you the code for this one, because I hope you'll work through this one on your own. I'll give you a couple of hints, though. You won't be able to use ArraySort. You'll need to come up with your own sorting algorithm. Sorting algorithms have received a lot of study (and argument). If you already have your own favorite one, by all means use it. If you're unsure of how to do a sort, look at Listing 5. It uses an insertion sort to sort a one-dimensional array. I'm asking you to sort a two-dimensional array, but by now this shouldn't create any great problems: you know a multi-dimensional array is nothing but stacked single-dimensional arrays Listing 5.
Unless you're an old pro with arrays (and sorting algorithms), this will probably cause you some grief, but that's the point of etudes: to place you in a contrived situation so that you can work on specific weak areas. Work through it and only download the answer if it's a choice between that and flinging yourself out of the window. (My personal philosophy is to prefer the admission of defeat to the act of defenestration - but that's just me.)
- After that last problem, this one is easy:
<cfset ArrayDeleteAt(goldA, 1) />
<cfloop from="1" to="#ArrayLen(goldA)#" index="rowNumber">
<cfset ArrayDeleteAt(goldA[rowNumber], 1) />
</cfloop>
Well, that's a good start on an etude for ColdFusion arrays. Hopefully, you'll be inspired to create your own problems to work on.
About Hal HelmsHal Helms is a well-known speaker/writer/strategist on software development issues. His monthly column in CFDJ contains his Musings on Software Development and he has written and contributed to several books. Hal holds training sessions on Java, ColdFusion, and software development processes. He authors a popular monthly newsletter series. For more information, contact him at hal@halhelms.com or see his website, www.halhelms.com.