Flash Player 10.1 and AIR 2.0

Posted in Jon Rose on November 17th, 2009 by jonr

jonr originally posted this on Jon Rose's Blog.

I haven’t been very active with writing for InfoQ.com lately. My lack of activity has been primarily due to time constraints, but has also been because I have been a bit bored with the recent RIA news. So, I was excited to get ‘back in the saddle’ with a post on the release of Flash Player 10.1 and AIR 2.0, as both releases are cause for excitement to anyone developing RIAs. The release will improve the development experience for Flex and AIR developers, but will also serve to move the ball forward in the space.

Here is my write up: http://www.infoq.com/news/2009/11/flash-10.1-and-air-2.0

Habit 2: Confuse Motion With Action

Posted in Dave Rodenbaugh on November 16th, 2009 by admin

admin originally posted this on Lessons of Failure.

We explore the difference between work and heat in today’s habit.

Seven Habits of Highly Dysfunctional Enterprise Developers:

  1. Blame Everyone But Yourself
  2. Confuse Motion With Action
  3. Use Complexity To Demonstrate Intelligence
  4. Keep Important Information Secret And Safe
  5. Fix It Later
  6. Reuse Is Overrated
  7. Principles Are More Important Than Results

Confuse Motion With Action

Lots of people misunderstand the difference between motion and action.  Or in physics terms, the difference between work (energy put into a system that increases the potential of an object) vs. heat (energy expended but with no future value, like friction).   Steve Blank recently made a memorable post on it:

sisyphus

Sisyphus Enjoyed His Daily Routine...right?

Steve: Jim, how are we doing with getting Ansys ported?
Jim: Great, I have a bunch of calls into them.
Steve: How are we doing on the Nastran port?
Jim: Wonderful, they said they’ll get back to me next month.
Steve: How about Dyna 3D?
Jim: It’s going great, we’re on their list

Putting in the effort to look busy is not the same as making real progress towards a goal. I’ve sat in countless meetings listening to this sort of status reporting (at all levels, not just for developers either) and I’m sure you have too.  Oh, wait…you’ve given a status report like that?  Yeah, me too.  Next time you’re tempted to do that, look at the problem differently:

  • What goal do I need to accomplish?
  • What is in my way of doing that?
  • How can I get rid of those obstacles?
<li><a href=”http://www.lessonsoffailure.com/software/seven-habits-highly-dysfunctional-enterprise-developers”>Blame Everyone But Yourself</a></li>
<li><a href=”http://www.lessonsoffailure.com/software/habit-2-confuse-motion-with-action”>Confuse Motion With Action</a></li>
<li><a href=”http://www.lessonsoffailure.com/software/habit-3-complexity-demonstrates-intelligence”>Use Complexity To Demonstrate Intelligence</a></li>
<li><a href=”http://www.lessonsoffailure.com/software/habit-4-never-share-information”>Keep Important Information Secret And Safe</a></li>
<li><a href=”http://www.lessonsoffailure.com/software/habit-5-fix-it-later”>Fix It Later</a></li>
<li><a href=”http://www.lessonsoffailure.com/software/habit-6-reuse-wimps”>Reuse Is Overrated</a></li>
<li><a href=”http://www.lessonsoffailure.com/software/habit-7-principles-important-results”>Principles Are More Important Than Results</a></li>

Related posts:

  1. Habit 5: Fix It Later We examine the power of procrastination in today’s post, and...
  2. Habit 7: Principles Are More Important Than Results Our last installment today is about the Great Ivory Tower...
  3. Habit 4: Never Share Information Lessons from Lord of the Rings, why you really did...

Related posts brought to you by Yet Another Related Posts Plugin.

Seven Habits of Highly Dysfunctional Enterprise Developers

Posted in Dave Rodenbaugh on November 13th, 2009 by admin

admin originally posted this on Lessons of Failure.

With apologies to Steven Covey and Jack Ganssle, who have their own lists on the topic, I bring you the

Seven Habits of Highly Dysfunctional Enterprise Developers:

  1. Blame Everyone But Yourself
  2. Confuse Motion With Action
  3. Use Complexity To Demonstrate Intelligence
  4. Keep Important Information Secret And Safe
  5. Fix It Later
  6. Reuse Is Overrated
  7. Principles Are More Important Than Results

Blame Everyone But Yourself

finger-pointing2

Who me?

There’s always plenty of people on enterprise software projects.  Everyone shares the responsibility…and the blame.  Developers often use this situation to deflect the blame.  I call this the Code Kingdom Problem.  That’s not MY code, it’s YOUR codeI didn’t write that module, S/HE did…And so on.  Maybe this statement rings a bell:

“Hey Bob, since you wrote that parsing module and the bug that came up seems to be a parsing error, why don’t you fix it?

Tempting though this may be, consider the collateral damage caused by this causal remark:

  • Bob may resent you pointing out his failures
  • Bob may not want to collaborate with you on future work
  • Bob may not recommend you on future jobs
  • Bob may spit in your coffee when you’re not looking

Rather than risk Bob’s heinous salivary wrath, why not proactively fix the problem (Cooperative Code Sharing), or help Bob find it and suggest a fix if Bob is struggling with it? (Pair programming).  Bottom line:  Their is no MY code vs. YOUR code.  It’s OUR code. If you’re on the project, you share it all–failure, success, or mediocrity.  You can’t have pride of ownership without ownership.

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

Flex: Monospace Fonts and Sizing Text Components

Posted in Eric Daugherty on November 11th, 2009 by admin

admin originally posted this on EricDaugherty.com.

For a recent project I wanted to simulate an 80x24 terminal window in a Flex application. To accomplish this I needed a fixed width (monospace) font and the ability to size the text control for the current font. Here is what I did:

First, I needed a monospace (fixed width) font. You can embed your own fonts in a Flash SWF, but that was overkill for this effort. You could specify a specific font, such as 'Courier New' that is monospace. However, there can be issues if the client's device does not have the specific font face. Device Fonts often serve as a fallback font if the specific font requested does not exist on the user's device. In this case, I didn't want to select a specific font, I just wanted the default monospace font. So I used the _typewriter font (the other types are _sans and _serif).
<mx:text id="myText" fontfamily="_typewriter" />
Once I had a monospace font, I needed to determine the proper size of the control for an 80x24 terminal. I started by simply setting the text control to an 80 character wide (and then 24 character high) string and noting the size, but I needed something that would work easily at runtime. I created this quick helper method that would resize my control:
private function setSize(control:mx.controls.Label, charWidth:int, charHeight:int, defaultText:String = "") : void {

var testString:String = "0";
var width:int = control.width + (control.measureText(testString).width * charWidth);
var height:int = control.height + (control.measureText(testString).height * charHeight);

control.text = defaultText;
control.width = width;
control.height = height;
}
I set this method to be called when the container's creationComplete event fired. This method assumes that the control is set to an empty string initially, and accepts an optional defaultText parameter if you wish to initialize it.

The measureText method returns the size of the text, but not the surrounding control borders, so I added the default control size to the text size to achieve the proper control size.

Simplicity is the goal

Posted in Dave Rodenbaugh on November 10th, 2009 by admin

admin originally posted this on Lessons of Failure.

My first day of Physics class in high school, we were given English homework:  find the definition of the word Parsimony.  My teacher was trying to underscore a point about the study of physics–while it explained the most complex of phenomena, the underlying theories and equations usually boiled down to a certain level of simplicity.  And as a corollary, if you found yourself trying to add in all kinds of complexity to an explanation, chances are you were running down the wrong road.  Which is not to say physics wasn’t filled with contradictions, despite my teacher’s mighty attempt to make it all seem elegant and grand.  I struggled with Quantum Mechanics because it violated every rule of simplicity learned to date in science.  And String Theory too.  Even Occam’s Razor is still one of my favorite things to trot out when folks are getting too mired in their own story.

Yet, we do the same things as developers all the time.  Brian Kernigan of C language fame has a famous quote:

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

In other words, if you are at the limit of your skills in WRITING the code, you are far beyond your reach in debugging and MAINTAINING the code for the time to follow.  Where does the complexity come from?  That’s easy–we’re constantly trying to optimize the code.  That nagging voice pops up in my head when I start appending Strings in Java–”Ooooh.  That’s TERRIBLE.  That could be performance bottleneck!  You’d better optimize that…” 

Take a deep breath and step away from the StringBuilder. Donald Knuth said it best:

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.”

Premature optimization is the root of all evil.

When Donald Speaks, You'd Best Listen.

Yes, we mean that string code, or that database query, or whatever you’re working on.  I mean MOST of code you write.  We code for the unexpected and then accidentally mire ourselves deep in complexity all for the sake of optimization. 

It’s easy to forget the 80-20 rule (80% of the program execution time will be spent in 20% of the code).  There’s also a 90-10 variant of the rule (which makes the point even more harshly).  Let’s put this rule another way.  Your optimizations and complexity are completely wasted in 80% of your code

Let’s figure out the real cost of this: Suppose you spent an extra 8 hours per week working, debugging and perfecting that kind of code for 3 months on the project (in addition to your regular work).  You spent 96 extra hours on the project (a whopping two+ weeks!) and of those hours, almost all of them were a waste since they didn’t lend any real value to the end product.

Ouch.

The Rules of Simplicity are quite simple (c’mon, you knew it was coming):

  1. Make your code as simple as possible.
  2. If you think it needs to be optimized, run it through a profiler.  And then see Rule #1.

Simple code yields clear benefits over complexity to everyone:

  • Quicker maintenance
  • Easier extension
  • Fast bug fix times
  • Shorter up-to-speed times with new developers
  • Lower frustration levels with support engineers

Think any of those isn’t important?  Try spending time as a support engineer of your product sometime and maybe you’ll feel differently.  Or sit with a support engineer for a day and see how they have to work with, explain, and sometimes apologize for problems in the product.    Or just wait six months and try, just try to fix that extra clever code of yours.

I can hear the whines coming already:  “But what about an extra layer of indirection for database portability?”  Or maybe “the communication layer abstraction so you could talk to an ESB in the future, surely I have to plan for it”?  The answer is NO.  Unless you need it NOW, you ain’t gonna need it.

Complexity is our mortal enemy as developers.  It makes all of us dumber in the end.

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

Drunk on Software Special Episode from Adobe Max (Best Ever)

Posted in Drunk On Software, Jon Rose on November 6th, 2009 by jonr

jonr originally posted this on Jon Rose's Blog.

We have posted a special Drunk on Software episode from Adobe Max 2009. I personally find this to be one of our most entertaining episodes (not overly useful, but entertaining). So, hopefully it will make you smile on this Friday.

Honestly, this episode makes me wonder if our recipe for Drunk on Software success is more of Chet and less of James and I.

Original Post

Interactive Visualization with Axiis

Posted in Justin Shacklette on November 4th, 2009 by admin

admin originally posted this on Saturnboy.

Continuing my Quest for Cool, one of my favorite aspects of data visualization is user interaction. Interactive visualizations are not only cool, but they can be extremely useful getting information to the user.

Here is a screenshot from Google Analytics showing the main line chart of visitors:

google-analytics

When you rollover one of the points, you get a popup telling you the exact number of visitors on that date. This simple rollover, while cool, is not particularly useful to me. If I wanted to know exact numbers, I’d look at an Excel printout. Thankfully, we can use Axiis to provide something much better.

Column Stack Chart

I’ll use Axiis to show two different visualization options for the same data. I made some artificial visitor data per day. Here it is as a vanilla line chart I grabbed from Excel:

data

Not very exciting, but the classic weekend lulls make our dataset a little hard to follow. In XML, it looks like this:

<visitors>
    <week label="A">
        <day label="Sun" val="0.2" />
        <day label="Mon" val="1.6" />
        <day label="Tue" val="2.0" />
        <day label="Wed" val="2.4" />
        <day label="Thu" val="1.8" />
        <day label="Fri" val="1.6" />
        <day label="Sat" val="0.4" />
    </week>
    <week label="B">
        <day label="Sun" val="0.3" />
        <day label="Mon" val="1.2" />
        <day label="Tue" val="1.8" />
        ...
    </week>
    ...
</visitors>

Since the data per day is a little annoying, let’s try to smooth it out by collecting up the day data into weeks. This is easy to do in Axiis by using the ColumnStack layout. Recall that Layouts in Axiis specify how incoming data will be rendered to the display. Here’s an abbreviated snippet of code showing the relevant parts:

<axiis:DataCanvas id="dc" ...>
    <axiis:layouts>
        <axiis:HBoxLayout id="myLayout" ...>
 
            <axiis:layouts>
                <axiis:ColumnStack id="myStack" ...
                    dataProvider="{myLayout.currentDatum.day}"
                    dataField="val" />
            </axiis:layouts>
 
            <axiis:drawingGeometries ... />
        </axiis:HBoxLayout>
    </axiis:layouts>
</axiis:DataCanvas>

First, we use an HBoxLayout layout to render our weeks into columns (the dataProvider is the visitors.week array), and inside that we use a ColumnStack layout to render our days stacked one on top of another (the dataProvider is the current week’s day array).

Here is the result (view source enabled):

Flash is required. Get it here!

The column stack chart is nice because it enables us to distinguish the macro trend over the weeks, traffic is obviously dying off from week A to week H. But it does a poor job illuminating intra-week data. For example, it’s hard to tell how Monday of week A compares to Monday of week B.

Interactive Column-in-Column Chart

Another option to visualize our simulated visitor data is empower the user. Start with a super simple column chart of the aggregated week data, and allow the user to drill down into the day data via some interaction. The implementation I’ve chosen below uses an inset column chart to show the day data when the user mouses over a week column.

In order to display week data, we first need to pre-process our day data to aggregate it into weeks. Axiis makes this trivial with DataSet:

var ds:DataSet = new DataSet();
ds.processXmlString(myXML.toXMLString());
ds.aggregateData(ds.data.object.visitors, "week.day", ["val"]);

The aggregateDate() method walks our XML hierarchy and rolls up aggregates of day.val at every level. When processing is complete, visitors has a new aggregates object that contains day_val_sum (and min, max, and average) for all the days in the entire data set. And one level down, week also has a new aggregates object that contains day_val_sum for just the days in that week.

Next, we construct our visualization using a pair of DataCanvas objects and a pair of BaseLayout layouts, one for the main column chart showing aggregated week data, and the other for an inset column chart showing just the current week’s day data. Here I’m using the same column-chart-the-long-way code as I used last post.

<axiis:DataCanvas id="dc" ...>
    <axiis:layouts>
        <axiis:BaseLayout id="myLayout" ...
            itemMouseOver="mouseOverHandler(event)">
 
            <axiis:drawingGeometries>
                <degrafa:RegularRectangle id="myBar" ... />
                <degrafa:RasterText id="myBarLabel"... />
            </axiis:drawingGeometries>
 
            <axiis:referenceRepeater ... />
 
            <axiis:states>
                <axiis:State
                    enterStateEvent="mouseOver"
                    exitStateEvent="mouseOut" ... />
            </axiis:states>
        </axiis:BaseLayout>
    </axiis:layouts>
</axiis:DataCanvas>
 
<axiis:DataCanvas id="dc2" ...>
    <axiis:layouts>
        <axiis:BaseLayout id="myLayout2" ...>
 
            <axiis:drawingGeometries>
                <degrafa:RegularRectangle ... />
                <degrafa:RasterText ... />
            </axiis:drawingGeometries>
 
            <axiis:referenceRepeater ... />
        </axiis:BaseLayout>
    </axiis:layouts>
</axiis:DataCanvas>

The interaction is achieved by the itemMouseOver event on the main column chart’s layout. Note that we are not listening for events on the columns themselves, rather we listen on the parent BaseLayout. The layout is responsible for attaching individual listeners to all of its children as they are rendered to the display. Layouts have events for all possible mouse interactions, including click, double-click, mouse over, mouse out, etc. This is one of the nicest features of Axiis. Since user interaction is managed by the layout and not by the rendered geometry, I change whatever I want about the geometry or how it is rendered and user interactions are preserved. The code is also pleasantly clean.

What’s more, the main column chart uses an Axiis State to create a visual rollover effect on the columns. The State is used to trigger some visual changes (column stroke weight is increased and label font is bolded) on mouseOver and then reverts the changes on mouseOut.

Here is the event handler attached to the itemMouseOver event on the layout:

private function mouseOverHandler(e:LayoutItemEvent):void {
    //change dataset to current mouseOver'd column
    myLayout2.dataProvider = e.item.data.day;
 
    //set color
    var color:uint = myPalette.colors[e.item.index];
    myPalette2.colorFrom = color;
    myPalette2.colorTo = PaletteUtils.darker(PaletteUtils.darker(color));
 
    //hide text
    insetText.visible = false;
}

The LayoutItemEvent event contains all kinds of useful information when it arrives at our handler. First, we set the dataProvider of our inset chart using the day data from the highlighted week column. Next, we use some Degrafa color magic to set the colors of the inset’s columns from the color of the highlighted week column. And finally, we hide the reminder text.

Here is the result (view source enabled):

Flash is required. Get it here!

The end result is a fairly cool visualization that does a good job initially hiding unnecessary information, but later reveals it upon user interaction. For example, toggle back and forth between week B and week C. You can easily see a shift in traffic to the first half of week C compared to week B.

Postscript

I recently discovered another amazing data visualization framework. Protovis is an awesome Javascript library created by some hella smart dudes at Stanford. If I ever needed to do any visualizations on the web, and was banned from using Flex, I’d definitely use Protovis.

Files

iTunes Export 2.0 – Now Supports OS X!

Posted in Eric Daugherty on November 3rd, 2009 by admin

admin originally posted this on EricDaugherty.com.

This release of iTunes Export marks a milestone and major transition of the development focus. The prior releases, 1.0-1.6 were all build using the Microsoft .Net Framework, which limited deployment to Windows. With this release, iTunes Export now fully support Windows and Mac OS X.

The Graphical User Interface version has been ported to Adobe Flex and is deployed as an AIR desktop application. The Command Line version is an update of the Scala version I developed earlier this year.

iTunes Export exports your iTunes playlists as M3U, WPL, ZPL, and MPL files, allowing you to setup playlists in iTunes and use them with other software or devices.

The primary focus of this release was to enable Mac OS X support. However, in addition to this, the copy files (songs) logic has been revamped. There are now three options:
- FLAT - Copies all the songs into the output directory
- ITUNES - Retains the iTunes structure (Artist/Album)
- PLAYLIST - The 'original' copy logic that copies the songs into a directory per playlist.

The new version can be downloaded from the project homepage: http://www.ericdaugherty.com/dev/itunesexport/

As this is a major new release, please keep an eye out for any bugs or issues that may appear. If you find any issues or have questions please email me (eric@ericdaugherty.com). Please include which application and version (GUI or Console, 2.0 etc.) of iTunes Export and which Operating System version.

Developers Are Not Presidents

Posted in Dave Rodenbaugh on November 2nd, 2009 by admin

admin originally posted this on Lessons of Failure.

I (heart) open source.  Deeply.  There are at least a few dozen libraries that I couldn’t live without anymore.  Tons of indispensable products like MySQL, Apache, Tomcat are part of my standard toolkit.  But the community hubris that goes along with it…Fuggetabouddit.  A recent quote by Django guru Jacob Kaplan-Moss concerning the balance of complex projects, features, release schedules and project management (collectively referred to in the quote as “these issues”) got my hackles up (full read here if you like):

“Open source cleanly avoids these issues by letting technical voices have the last say.”

Really?  So developers are now the President AND Congress? We write AND approve the laws?

Unfortunately, I think Jacob has missed the forest for the trees in this case.  From a broader perspective, the larger software product ecosystem looks like this:

Customers <-> Marketing <-> Engineers

We have Customers who have a need.  Marketing determines their desires, figures out features they want and asks the Engineers to build the product for the Customer.  (Obligatory Office Space joke)  Customer gets something that is Useful.  Everyone is happy.800px-PC_Load_Letter

In Open Source things are a bit different–we leave out the middlemen because we’re building tools and frameworks mostly.  We change the Customers a bit because Joe Six Pack, Joe Biden or your Grandma sure-as-heck aren’t going to be putting Django on their machines anytime soon and we get:

Engineers <-> Engineers

Open source sure has something easier to deal with than the earlier picture.  And no WONDER the developers get the final veto…chances are, they’re CUSTOMERS.  It’s great the Django has the luxury of saying to their developers, “Well, we’re not going to add in the toolbar to the next release” because in reality, that’s not a major loss to their customers.  They’re smart enough to find it on their own.  They are used to cobbling together things to get their end product working.  They’re highly technical and like to tinker.  They’re innovators and early adopters in Geoffery Moore’s terms.  They understand PC Load Letter (NSFW) on their printers.  But they’re the easiest groups to deal with when you’re a technical person.  It’s the other groups that are hard–and they’re the ones that make up a real product.

There’s a distinct difference between a project and product.  Project managers (like Jacob on Django) are responsible for the successful delivery of a project — a one-time endeavor with a goal, scope, deadline, budget, and other constraints. A project manager will work to align resources, manage issues and risks, and basically coordinate all of the various elements necessary to complete the project.  Product managers, on the other hand, are responsible for the overall and ongoing success of a product. Once the project to build the product is complete and the project manager has moved on, the product manager remains to manage the product through the entire lifecycle.  These two roles are often at odds with each other, but it’s clear that Django doesn’t need or have a product manager because Django doesn’t fit into the category of a mainstream product.  It won’t be sold or marketed like Photoshop or Excel.  You won’t have customers that nicely follow Moore’s technology adoption curve.

Feature set balancing for real products and serious projects requires more than just a bunch of architects sitting in an ivory tower with a REJECTED stamp and red ink pad.  There are revenue considerations to be made, customers that would buy your product because you now have feature X, and competitive analysis to determine market viability.  None of which has anything to do with the purity of the code base, what your UML diagrams look like or how clean you keep SVN.

Sorry Jacob.  That may work for Django but you might want to look at some broader, successfully released products before pounding your chest about the reason for your wild success on a project.

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.