Wednesday, March 18, 2015

March LiveCode Madness: Building a Clickable Bracket

For the first time ever, I have filled out my own bracket for the upcoming NCAA basketball tournament. For many people here in the USA, this is an important annual ritual. One's bracket simply predicts every winning team in every match-up in the six rounds of the tournament. The tournament starts with a field of 64 teams with half being eliminated after each of the first five rounds. The sixth round pits the two remaining teams in the championship game to crown the national champion. I'm finally participating at the encouragement of my brother, Bill, who happens to teach economics at Butler University in Indianapolis, Indiana. Bill is our family's sports historian with particular expertise in baseball. But this is basketball season and basketball is very big in Indiana. The significance of basketball in Indiana is depicted very well in the movie "Hoosiers." (Trivia: The final championship game in the movie was filmed at Butler Field House where the actual state high school championship game had long been played.)

Basketball is also very big at Butler University. Butler is probably the smallest school ever to appear in the NCAA championship game, having done so in both 2010 and 2011. Unfortunately, Butler lost both times. The loss in 2010 was quite dramatic with Butler, down two points, taking the last shot of the game. Alas, the ball bounced off the rim and Duke won 61-59. The University of Georgia is also playing in the tournament this year and it is conceivable that they could face Butler in the championship game. More on that later.

Like a lot of work places, Bill's colleagues at Butler run a little competition each year where you can enter your bracket. The person with the best prediction wins the competition. Bill enters every year and this year, again with Bill's encouragement, I'm participating too. Our other brother, Mark, is also participating.

To fill out my bracket, I found a PDF online at For those not familiar with what a bracket looks like, here is a quick snapshot:

I find the visual design very appealing. Teams from the midwest and west are on the left-hand side and teams from the east and south are on the right. You can easily see how teams are quickly whittled down until there is one national champion in the center-most box. But, to fill out this PDF, I had to do a whole lot of copying and pasting. The first version I sent to Bill had a serious copy and paste error, which I'm glad I caught soon after I sent my PDF to him. I had Wisconsin winning the game between Kentucky and Buffalo. (Wisconsin is good, but they are not that good.) I showed Wisconsin continuing to win in Kentucky's spot until the championship game, when Kentucky "reappeared." I fixed the PDF and sent my brother an updated version.

But, I found myself wishing that I had found a "clickable" version of the bracket online instead of a PDF. Then, I could have just clicked my way from team to team with each click quickly pasting in the name of my pick in the slot to the right or left. (It's likely there is such a clickable version out there, but I didn't find one in the few minutes I allocated to my search.)

So, I created a very simple and very incomplete version of a basketball bracket using LiveCode. And, I learned something new by creating this little project. In order for the "on mouseUp" handler to work within a field field, the text in the field has to be set to locked. This makes sense because otherwise every time you clicked in the field to type something into it -- such as the names of the basketball teams in round 1 of the tournament -- the on mouseUp handler would take over. But, to enter the first set of team names, the fields need to be unlocked. So, I needed to have an easy way to lock and unlock the text fields, or at least the text fields to the far left or right of the bracket.

I created two buttons - "Lockdown" and "Unlock" - that, well, lock and unlock the text fields. Now, in my little example, I only have 4 of the 64 teams represented. This results in a total of seven text fields (or three open brackets). If I had all 64 teams, that would require 126 text fields (with 62 open brackets). That's a lot of fields to lock or unlock. But, I learned a good trick while creating a previous project based on the fact that LiveCode automatically numbers all fields on a card. With that knowledge, I used the following script in the button "Lockdown" to lock all the fields on the card:

on mouseUp
   put the number of fields on this card into L
   repeat with i = 1 to L
      set the locktext of field i to true
      set the backgroundcolor of field i to red
   end repeat

end mouseUp

The first line just counts up the total number of fields on the card and puts this number into the local variable L.

Then, I create a loop that repeats L times, starting by putting 1 into the local variable i. The next line sets the locktext property of field i (that is, field 1 or field 2 or field 50, depending on what loop it is) to true, thus locking down the field. Each loop automatically adds one to i.

I also went ahead and set the backgroundcolor of locked fields to red. I thought it would be nice to use some color coding to signal to the user whether the fields were in a locked or unlocked state.

In the button "Unlock" I simply changed true to false in the "set the locktext" line. I also changed the background color to yellow. Here's a snapshot of the screen in the unlocked state:

[ Get the free LiveCode Community version. ]

Here's a snapshot of the screen after the fields have been locked down, thereby allowing the user to click on the fields to make selections, going from left to right:

I then added a script to each field that put a copy of whatever text is in that field to the next field to the right. Here's an example:

on mouseup
   put me into field "r2g1t1"

end mouseup

I labeled all the fields with a scheme that would be helpful if I later choose to continue building this project with a complete bracket. This scheme starts with the tournament round number, then the game number, then the team number. So, "r2g1t1" means round 2, game 1, team 1. Using this scheme, I think I could automate the script for the fields so that each would know what field to send their contents to. For now, I just hard coded the destination.

Looking Forward to the Day When LiveCode Exports to HTML5

As I write this, many of us are waiting anxiously for news on the RunRev company's efforts to enhance LiveCode to allow projects to be exported to HTML5. This project would be a perfect candidate for this feature because I could then embed this project within a web page. Then, I would have legions of basketball fans flocking to my clickable bracket maker site. As I understand it, exporting to HTML5 will essentially convert LiveCode scripts to Javascript. The company began the effort to add this feature to LiveCode about eight months ago with a timeline to completion of one year. So, I keep my fingers crossed everyday that the company will send out an announcement that this feature is finally ready.

One Last Bit of Basketball Trivia While Pondering Who Might Win This Year's College Championship

Here's a final piece of basketball trivia. As I understand it, dribbling evolved from a loophole in the original rules of basketball. The game was invented in the late 1800s by James Naismith, a Massachusetts teacher who wanted a safe, indoor game. The idea was to have players continually pass the ball to teammates to move the ball down the court with the goal of getting the ball into a peach basket mounted up high at the end of the opposing team's side of the court. It was against the rules to run while holding the ball. At some point, someone figured out that if you bounce the ball you are not technically holding it, so this was a way for the player to move about without breaking the rules. Ah, American ingenuity.

So, who do I predict will win the tournament this year? Yes, it is possible for my school - The University of Georgia - to meet my brother's school - Butler University - in the NCAA Basketball Championship game. But, even with the little I know about college basketball, I know the odds of this happening are very, very, small. So, despite the fact that I show above Butler beating Kentucky in round 4 of the tournament (also known as the "Elite 8"), I'm predicting Kentucky will go all the way this. But, then again, stranger things have happened.

Oh, one more thing ... what exactly is a hoosier, anyway?

Thursday, March 12, 2015

Creating a Reference Letter Writing App with LiveCode: New and Improved Design

Yes, I just couldn't help myself. After creating the initial prototype of a reference letter writing app "just for fun," and then realizing there was a much better design strategy just as I was finishing it, I just had to follow through on building the new design. Recall from my previous posting that it occurred to me - late - that a much better approach would be to use "piped" or replaceable text to build a letter template within a simple text field. This allows the user to simply paste in a letter template, or write a new template from scratch. Categories can then be embedded with the use of open and close braces, such as {myRating}. (The survey tool Qualtrics calls this feature "piped" text, hence the origin of my use of the term, but I think "replaceable text" is clearer, so I'll use that term from here on out.)

The resulting app works very well. I even added the feature where the app automatically saves the most recent letter template, addressee information, candidate information, and all the categories created up to that point.

I have also changed the name of the app to "Report and Letter Writing App" to reflect the extended range of uses I think the app could be used for. For example, I see myself using it to quickly generate student feedback on low stakes assignments. But, I can easily see uses in fields other than education, such as a doctor who needs to write a short patient report.

Here's a video demonstration of the app:

How the App Works

Using the app involves a four-step process. In step 1, the user is given a blank text field within which to write a letter template. At any point, the user can create a category for replaceable text. Adding the category to the letter template is done simply by double-clicking on the category name. The category can be updated as often as one wishes with as many choices for the replaceable text added as desired.

In step 2, the user enters basic information for the candidate - name and gender - and the name and address to whom the letter is addressed.

In step 3, the user simply makes the choices from all of the replaceable text categories that are appropriate for that particular candidate.

In the final step, the letter is generated and the user simply copies the resulting letter to the clipboard for pasting into a word processor or online form.

This app version still has many limitations - hey, I created it very quickly after all! For example, only the most recent letter template is saved along with all categories created to date. An obvious design feature would be to let the user save any number of letter templates with only the categories relevant to that letter.

Try It Yourself

I made a standalone version for both Macintosh and Windows - download and uzip it if you would like to try it for yourself. Be aware that both copies will make a folder titled "RLWA Program Files" in your documents folder that contain the app's management files. If you delete that folder or its contents, you will lose all of your work.

Macintosh Note: The first time you try to open it, you will likely get a message saying that it "can't be opened because it is from an unidentified developer." This is due to the Gatekeeper function that has been recently implemented in Macintosh OS X, which by default is set to only allow the opening of applications that were obtained through the Mac App store. Fortunately, it is easy to change your security settings to allow your Mac to open the app. Here are two short videos that show how to do this: (this explanation is better, but the audio quality is poor)

Windows Note: This is an untested version, but it seemed to work just fine using Windows 7.

Programming Challenges

There were all sorts of interesting challenges to building this app and I learned many new LiveCode skills as a result. Below are two examples.

Identifying the Location of the Category Insertion Point

One challenge was learning how to note the location of the focus within a text field. I used the following script and attached it to the field "letter" on the card where one builds the letter template to accomplish this:

global varInsertion

on mouseleave
   put the selectedChunk of field "letter" into varInsertion
   set the itemDelimiter to space
   put item 2 of varInsertion into varInsertion
end mouseleave

What's somewhat cool about this script is that it only triggers as the mouse leaves the text field. The idea being that one could click at the point where you want to insert a category, followed by moving the mouse to the spot on the screen where the categories are listed. This movement of the mouse guarantees that the last insertion point would be noted.

Here's how it works. Consider the following sentence: "The purpose of this letter is to support the application of George Bailey."

If the word "George" is selected, the following would be put into the variable varInsertion:
char 61 to 66 of field 1

When the focus (i.e. blinking I-beam) is immediately before the "G" of George, the following is given:
char 61 to 60 of field 1

All I really want is the first number - 61 - which is the second item in the string if one uses the space character as the delimiter between items. The variable varInsertion is then used by the field containing the list of categories on the same card:

global varInsertion

on mousedoubleup
   put "{"&the selectedText of field "dynamic text"&"}" after char varInsertion-1 of field "letter"
   focus on field "letter"

end mousedoubleup

This script is only triggered when the user double-clicks on one of the available categories. The category name is then entered after the varInsertion point with braces added to each side. You might notice that I had to subtract one from varInsertion to get it to work properly.

The only small problem is that if you double-click on two categories in succession, the second always goes in front of the first, which is counter-intuitive to me. I've not been able to solve that problem, but it is a relatively minor annoyance. Otherwise, all works great.

Allowing for Cutting, Copying, and Pasting

One unexpected challenge was figuring out how to get the simplest of text functions to work within the standalone version of the app, namely cutting, copying, and pasting. These text functions worked just fine when I was building the app, but they simply didn't work in the standalone version (using the typical shortcut keys). I found this very puzzling, but luckily I came across an article in one of the LiveCode forums that addressed the issue. To resolve it, I simply had to add the following code to the stack script:

on copyKey
   copy the selection
end copyKey

on cutKey
   copy the selection
   delete the selection
end cutKey

on undoKey
end undoKey

on pasteKey
end pastekey

I've noticed this issue in other projects I've built, so it's good to finally get to the root of the problem and solve it.

Final Thoughts

Yes, what started out as a fun project just to prove I could do it to some of my colleagues has turned out to be a very nifty little app. Similar to the first version, I created this second version in about a week working on it here and there. So, not much time was needed, thanks to the wonderful programming environment of LiveCode and especially LiveCode's excellent text processing features. I learned some great new LiveCode commands and developed a few new programming skills along the way that will come in very handy I'm sure for future projects. I definitely see myself coming back and working on the app to develop it into a full-fledged app worthy of sharing.