Adam Howitt's Blog

Jan 19
2010

Run your ass off this year!

After another 200 hour programming marathon spread over 4 months I'm thrilled to announce the release of version 3 of WalkJogRun's iPhone App "WalkJogRun Running Routes".

What does it do?

The most significant change version 2 was the addition of 23 training plans created by Coach Jenny Hadfield of Runners World fame. Once you sign up for a training plan and pick a start date you'll get alerts every morning at 6am (silent so they don't wake you) to tell you how far to run, how fast and give you motivation. Tap the find routes button to find a training route in your neighborhood from the 600,000 routes at WalkJogRun.net

What if I've never run before?

We've got plans for beginners, intermediate and advanced runners including one called "Run your first 5k" designed to take you from the sofa to being able to run a 5k race in 10 weeks. We've also got 10k training plans, half marathon training plans and full marathon training plans.

Gimme the nerdy stuff

The programs themselves are delivered as in-app purchases using the StoreKit framework on the device to process payments and then send receipts to the ColdFusion server to register the subscription and begin delivery of the alerts.

The alerts are delivered as Apple Push Notifications generated by ColdFusion. No mean feat I can tell you using Java in ColdFusion to connect to a streaming data socket to send and receive the bytes and then drop the encoded JSON packets off on your phone. The phone gets the alert, opens the app and takes you to the training session for the day to show you your training tip.

Download a copy of "WalkJogRun Running Routes" before it gets too late!

Sep 22
2008

Eclipse Ganymede and Java 6 update 10 RC

Just a word of warning - my copy of Google Chrome suggested I install Java 6 update 10 RC last night to allow me to upload pics to facebook.  

Everything went okay but this morning Eclipse Ganymede was dead with no indication of why except a dialog box containing runtime parameters.  I uninstalled the new Java update and everything is fine again.

Jan 09
2007

Help with OO Problem

I've studied OO at University in the shape of Eiffel, I've programmed OO somewhat lightly in Java and developed OO in CFCs but there are some classes of problem I just don't get.  If anyone reading this could offer insight from their own experience that would be great!  I'll offer problem 1 for now and dependent on the response I might hit you up for problem 2.

"is related to"

I've called this "is related to" because I'm talking about the modelling of relationships between classes.  This comes in the context of how to use objects in a Content Management System.

For example, lets say I have a website with an about us section and in that section, an programmer list with a list of the key skills of each programmer.  There is also a "key skills list" which has a list of programmers who are in posession of the skill.  Programmers own skills but they aren't necessarily composed of those skills e.g. "has a" and this isn't inheritance since programmers aren't a type of ColdFusion.

So, to make it real, under the list of programmers I have Ben Forta, DHH, Adam Howitt, Sean Corfield and Cameron Childress.  If you view the detail for each programmer you will see that all but DHH have ColdFusion experience.  All have MySQL experience and lastly Adam and DHH have dabbled in Rails.  If I navigate to the ColdFusion page I see a list: Adam, Ben, Cameron, Sean with a brief snippet of the full bio under each.

On the ColdFusion page I would fetch the ColdFusion object and dutifully write out each attribute before getting the related programmers:

<h1>#skillObj.getTitle()#</h1>
<p>#skillObj.getBody()#</p>
<h2>Related Programmers</h2>
<ul>
<cfset stProgrammers=skillObj.getProgrammers()>
<cfloop collection="#stProgrammers#" item="programmer">
<cfset currentProgrammer=stProgrammers[programmer]>
<li>#currentProgrammer.getFirstName# #currentProgrammer.getLastName#<br/>
<p>#currentProgrammer.getShortBio()#</p></li>
</cfloop>
</ul>


My question is how do you implement getProgrammers and what do the classes look like?  My initial thought is that there is a Programmer class and a Skill class.  Now for the chicken and the egg: does a programmer has a struct of skills (order isn't important) or does the skill have a struct of programmers (again, order not important).  Or both?  What do I store? The struct of class instances (programmer objects) or the struct of ids?  If I use a struct of objects, the call getProgrammers has all the information it needs to print this page.

If I store the ids of the objects then I increase cohesiveness by requiring the method to call a function to instantiate the skill class for each id. Storing the ids creates a new issue - I have to load each skill one by one, making multiple database calls for each page request instead of a single database call to load all related skills.  In the current system, I load all skilll attributes with one query, all related programmers with another then display them to the screen.  

The biggest issue I am having trouble understanding is what gets stored in memory.  We don't really have a Programmer or a Skills page, but model the employee structure and skills profiles of clients in the service industry.  Some clients have over a thousand employees with experience or skills selected from a list of over a hundred.  Adding up the potential number of objects, some clients may have over 5,000 content objects which may be called by any number of pages at a given time.  The current procedural approach works but we're trying to see if there is a better OO design to fit the purpose.

Mar 02
2005

Eclipse uncovers ColdFusion's Secret Powers

If you have ever seen a tech tip about ColdFusion leveraging the built in hidden methods of Java and wondered "how the heck do they know this stuff?", Eclipse can help you see the wizard behind the curtain.

Yesterday I was doofing around trying to discover a way to access the SQL statement passed by cfquery and cfstoredproc so I could log it on my production server without duplicating the code block. I figured, if CF knows what the parsed statement is, why can't I access it after the statement executes as, say, cfquery.parsedSqlStatement. I know it exists because if my code errors, I see it in the resulting error dump.

I started out looking for posts that utilize some of these hidden Java methods and came across Sam's post on "Handling file uploads without CFFILE". The important snippet was
cls = s.getClass();
stringCLass = cls.forName("java.lang.String");
Armed with this info I started to experiment by dumping out the stringClass variable to see the list of methods.

Next I threw a DB error deliberately and expanded the stack trace to get a list of CFClasses which were involved in the error. I constructed this little test:

<cfquery datasource="ll_site" name="qTest">
select * from object_tb
</cfquery>
<cfset cls = qTest.getClass()>
<cfdump var="#cls.getName()#">
<cfset stringClass = cls.forName("coldfusion.sql.QueryTable")>
<cfdump var="#stringCLass#">

Unfortunately my research stopped there because there just wasn't much to see. No properties or methods easily listed to help me on my quest. This was when I had a brainwave. Eclipse is a Java development tool, ColdFusion comes as a deployable ear file and has a list of classes: maybe Eclipse can see more than just a .ear file!

So I opened Eclipse, created a new Java project and set the location of my EAR file as the directory under "Create project at external location". Create a name for the project and hit Finish. Eclipse then prompted me to switch to the Java perspective (from CFEclipse which is my default) and to my amazement, I see a list of jar files and packages! I click to expand cfusion.jar and it expands to show me a list of coldfusion packages. I click to expand coldfusion.sql and I see a list of classes and properties. I expand SqlImpl.class and see methods and properties which I may be able to leverage.

So I'm still no closer to getting the exact SqlStatement because I'm still unsure as to how to access the property I need. If anyone following these steps is able to point this out I would greatly appreciate it.

Now THAT is something Homesite and Dreamweaver can't do ;-)

Jul 13
2004

He3 SQL Integration

In case you hadn't heard, I am helping code He3 as part of the RichPalette.com team. My specific focus is to deliver the SQL editor and database integration features.

This is of particular interest to me as a corporate IT Application Development programmer since 60 to 80 percent of my day is spent writing ad-hoc queries to support our user base. The remainder of my work on new development is focused on delivering ColdFusion interfaces and SQL Server stored procedures to deliver more efficient versions of components of our ERP system.

I've essentially started from the point of "what do SQL Query Analyzer and Enterprise Manager offer me that I find useful and what do I wish it would do?". I've solicited the input of many local developers at the last Atlanta ColdFusion User Group meeting about SQL IDE's and asked for the best and worst features of Toad, SQL *Plus and also some Eclipse SQL IDE's.

I will be publishing a list of the initial SQL features soon to test interest levels. I thought I would throw the floor open to anyone who reads this blog for further suggestions until I can get the public bug tracker and feature request page configured. So have at it. There have already been some excellent suggestions across other blogs about non-SQL features.

Which databases are you guys and gals using with ColdFusion? My assumptions are SQL Server, Oracle, Access and MySql. What else would you need to see support for?

Jun 21
2004

Fame, Dodgeball, dynamic images, bad jokes and PHP

This weekend I read a PHP and MySQL book cover to cover, watched Dodgeball at the Regal 24, met the lead singer of Keane and then was caught on camera in the background of a Fox 5 Atlanta outside broadcast this morning while I sipped my coffee and read the closing chapter of the Benjamin Franklin book.

As a veteran CFer and SQL Programmer I was intrigued to read about PHP and MySQL in "PHP and MySQL Web Development, Second Edition" by Luke Welling and Laura Thompson. Learning a new language is always going to reveal some interesting things and one that was particularly intersting was the availability of the GD libraries to allow the creation of dynamic images. This was of relevance to a recent thread on CF-Talk where someone brought up the idea of CAPTCHA images from a CF only standpoint. PHP uses the GD libraries to generate GIF, JPEG and PNG images which allow you to combine text and images on the fly for buttons or, indeed, CAPTCHA images. I reviewed the C code to implement this and it struck me as something which could be easily migrated to CF as a custom tag.

Imagine being able to call
<cfdraw imageName="myImage" height="300" width="300" format="JPG">
 circle(10,100,50,red);
 text(verdana,10,50,50,black);
</cfdraw>
to see a dynamic JPEG image of a circle at 10,100 50 pixels wide in red with some black text over the top in Verdana 10px font at 50,50.

That would be fun. The book was a little disappointing from an established programmer perspective. I would guess that 80% of what someone with existing programming skills would need to know to write code in PHP with MySQL is presented in the first 258 pages. Then pages 259 through 436 offer some advanced topics including the dynamic image information before the remaining 350 pages describe 8 example applications and offer some information on building large projects and debugging them.

A great book I recently finished was "Eats, Shoots and Leaves" by Lynne Trusse. I heard an interview with Lynne on NPR and thought the book sounded like fun. The British author takes a dicatatorial stance on the issue of punctuation and its abuse (note the correct absence of an apostrophe in its). Not only did I learn about the subtle mistakes in my own writing but I have a keener eye for spotting errors elsewhere. The book is a quick read with delightfully humorous examples taken from the media and her local environment. One example which stands out is the sign "Book's, DVD's and CD's" - where book's should be apostropheless since it is a plural whereas CD's and DVD's is correct since the apostrophe indicates the contraction of the word discs to d's.

Pick up a copy of "Beginning Java Databases" for an incredibly good account of writing Java to connect to a database, run queries and extract metadata about the database. Here the first 60 pages are a "what you need to know" quick-start guide to querying a database followed by a more detailed discussion of SQL concepts and JDBC application development. I have thoroughly enjoyed the book and it is empowering in many ways since it takes what you know about databases in ColdFusion and escalates you to the underlying principles.

Watch Dodgeball with Ben Stiller and Vince Vaughn. Seriously. It makes great light relief after a week of geeky books and it has to be my favorite movie of the year so far, ranking as high as Old School, maybe higher.

...and finally, after the Keane concert at the Cotton Club in Atlanta on Friday night I had a surprise opportunity to chat with Tom Chaplin, the lead singer of Keane. For the uninitiated, Keane's album "Hopes and Fears" is number one in the British album chart and they are making waves on US radio stations currently with "Somewhere only we know". There is a good review of the band at MetroWest Daily News. The fun part was knowing that this has the potential of another Coldplay. I saw Coldplay at the Reading-Leeds festival in 1999 when the band were new to the scene but still with a good crowd. When I moved to the US in 2000 I saw them play at a small club, maybe Metro, and there were fewer than 100 people there. Big contrast with the 2002 concert I attended in Atlanta at the Gwinett Civic Center where I strained my eyes to make out the band members on the stage from the rediculously priced seats I bought for Melissa and I.

Dec 02
2003

Pt 2: Howitt's Anagram Theory

Here is my code for the Anagram program so far:

public class Anagram {
   String initialWord;
   StringBuffer anagrams=new StringBuffer();
   
   public Anagram(String word) {
   //constructor for an anagram
      this.initialWord = word;
   }
   
   public void makeAnagram (String separator) {
   //to create an anagram call this method with the separator you wish to use
   //in the resulting StringBuffer to separate words e.g. "<br>" for web apps
      anagrams.delete(0,anagrams.length());
      makeAnagram("",this.initialWord,separator);
   }
   
   public String deleteAt(String word, int pos) {
   //this method takes a string and returns the same string less the character
   //at the position specified by the integer pos
      if (pos > 0 && pos < word.length()-1) {
         return word.substring(0,pos)+word.substring(pos+1,word.length());            
      } else {
         if (pos==0) {
            return word.substring(pos+1,word.length());            
         } else {
            if (pos == word.length()-1) {
               return word.substring(0,pos);            
            } else {
               return word;   
            }
         }
      }
   }
   
   private void makeAnagram (String wordStart, String word, String separator) {
   //this is the recursive method which actually generates the list of anagrams
   //initially wordStart is the empty string but as it loops into the code it loops over
   //all the possible word beginnings
      String wordCopy = word;
      for (int i = 0; i< word.length(); i++) {
         //hide dupes: only run this word if it is the first instance of the letter in the word
         if (word.indexOf(word.charAt(i)) == i) {
            //remove the current character from the letters to be passed to the
            //next recursion since we are adding it to the wordStart segment
            wordCopy=deleteAt(word,i);
            if (word.length() > 1) {
            //complex case - current word is longer than 1 character so the current
            //character is added to the wordStart segment
               makeAnagram(wordStart + word.charAt(i),wordCopy,separator);
            } else {
            //trivial case - word length is 1 so only 1 permutation
               if (anagrams.length() == 0) {
                  //our list shouldn't start with a list separator
                  anagrams.append(wordStart).append(word);
               } else {
                  anagrams.append(separator).append(wordStart).append(word);
               }
            }
         }
      }
   }

   public int countInstances(String word, char letter) {
   //this method determines how many copies of a specific character are in the string
      int i=0;
      while (word.indexOf(letter) >= 0) {
         word=word.substring(word.indexOf(letter)+1,word.length());
         i++;
      }
      return i;
   }
   
   public static double factorial(int x) {    
   // This method computes x!
      if (x < 0)
       return 0.0;
      double fact = 1.0;
      while(x > 1) {
       fact = fact * x;
       x = x - 1;
      }
      return fact;
}
   
   public double calcAnagram () {
   //This method uses my theory - Howitt's Anagram Theory to calculate the number
   //of unique permutations possible for the given words.
   //THEORY: UniquePermutations = factorial(word.length)
   //            divided by the product of the factorials of the count of instances of each
   //            letter in the word. e.g. aabbbc would be 6!/(2!*3!*1!) = 720/(2*6*1) = 60
      String word = this.initialWord;
      double factSum = 1;
      for (int i = 0; i< word.length(); i++) {
         if (word.indexOf(word.charAt(i)) == i) {
            factSum = factSum * factorial(countInstances(word,word.charAt(i)));
         }
      }
      return factorial(word.length())/factSum;
   }

}

Here is the code to test it:

public class TestAnagram {
   public static void main(String[] args) {
      Anagram words = new Anagram(args[0]);
      String separator;
      //if a "y" is passed as a second variable, then display the anagrams else don't
      //if a 3rd argument is supplied, it is used as the separator to display the anagrams
      if (args.length >= 2 && args[1].indexOf("y")>=0) {
         if (args.length >= 3) {
            separator = ",";
         } else {
            separator = "<BR>";
         }
         
         words.makeAnagram(separator);
         System.out.println(words.anagrams);
      }
      System.out.println(words.calcAnagram());
   }      
}

Dec 01
2003

Howitt's Anagram Theory

I am reading Dan Brown's "The Da Vinci Code" and in addition to the fact that it is a great read chock full of geek codebreaking goodness, it renewed my interest in anagrams.

Employing my best Java to write an anagram generator I am trying to work out the quickest way to generate all the possible anagrams of a sentence in as little time as possible.

During my search I came across what appears to be a solid fact about anagrams (please post a comment if you find it to be inaccurate): the total number of unique anagrams generated from an input string n characters long will be n! (factorial) divided by the the product of all the u! (factorial) where u is a unique character in the input string e.g. aaabb will be 5!/(3!*2!) = 10

I haven't found a case where this doesn't work but similarly don't have a full mathematical proof either.

Sep 23
2003

Flash Scrabble/Wordblog With Scoring

The scoring for the wordblog/puzzleblog site was simple to add. I've also changed the alpha settings of the letter tiles so you can still get an idea of which bonuses exist underneath the letters. Please leave feedback in the comments section if you find bugs, think it could be done differently or just to say you like it! (and of course give your best words/scores):

Flash Scrabble/Wordblog Minus scoring

This is the almost complete application for the wordblog/puzzleblog site. Please leave feedback in the comments section if you find bugs, think it could be done differently or just to say you like it!