Wednesday, April 26, 2017

Rocky and his friends

Many years after our first meetings, I met two old friends - Walking Man and Mr. Natural.  My first encounter with these two was in the early 1970s while I was an undergrad at Penn. I consider them early philosophy teachers.

Mr. Natural was a Robert Crumb character who frequented his underground comix.  Here is a Wikipedia description of Mr. Natch:
Mr. Natural has strange, magical powers and possesses cosmic insight; but he is also moody, cynical, self-pitying, and suffers from various strange sexual obsessions.
The comic encounter I most remember is this exchange between Schuman the Human and Mr. Natural.
Schuman:  "Mr. Natural, what does it all mean??"
Mr. Natural: "It don't mean sheeit."
My meeting with Mr. Natural occurred at Penn's Institute of Contemporary Art in 2008.  Boy, he hasn't aged a bit.  Must be his lifestyle.

I encountered Walking Man #1 at the Carnegie Museum in 2016.  This was another 40+ year hiatus. He adorned the cover of William Barrett's Irrational Man, a study in existentialism published in 1958.  According to Barrett modern man has had his morality attenuated to the point where he resembles a sculpture by Giacometti.

I read Barrett's book and lots of other existentialist writers while at Penn.  Why?  For the youthful expansion of religious and mental boundaries.  It was like drinking rock gut whiskey -- if you survived you were a real man.  During that time others were fighting in Vietnam to prove their manhood.  I was content to read Nietzsche.

This leads to how I got the nickname "Rocky."  It has nothing to do with Rocky Balboa (1976) but everything to do with the Beatles' Ballad of Rocky Raccoon (1968).

One afternoon at Penn Jimmy V. walked into my dorm room and found me reading some existentialist.  He immediately started singing, "Rocky Raccoon sat in his room, only to read Friedrich Nietzsche."  The rest is history.

Saturday, May 16, 2015

Life Gets Easy

Said the coal to the diamond, "Why so hard?" Said the diamond to the coal, "Why so soft? Life is hard. Be hard!" (paraphrase of The Hammer Speaks story) -- Nietzsche.

Recently life, my life, has gotten easy, not hard.  Let me explain.

For the last three years I have participated in the local Y's sprint triathlon.  "Sprint" means "short," but still 1.5 to 1.75 hours of intense aerobic exercise is pain-inducing.  One of my motivations for doing this was to see how I compare to my peers, and I learned not too well.  Here are my peer group results:

  • 2012: 4 of 6
  • 2013: 6 of 7
  • 2014: 9 of 9

I swore that I would not participate this year but they introduced a new event called Aquabike (500 m swim, 20 km bike, no run).  My time was okay -- 1 hour and 16 minutes.  And I won my age bracket (full disclosure: I was the only one in my age bracket).  Life gets easy.

Here's another example.  I always wanted to teach a calculus course.  Why? Because I never really learned calculus (it's a long story) and I know that the best way to learn a subject is to teach it.  Well I do teach MAT135 Business Pre-calculus and maybe someday the school will schedule me to teach MAT136 Business Calculus.  In any case, these courses are not hard.  Life gets easy.

So maybe Nietzsche is wrong.  Life is not hard.  At least not all of the time.

Monday, April 27, 2015

My First Aquabike Event

Did I participate in the UMLY triathlon this year? No,  Did I try the new aquabike (swim + bike) event? Yes.

The swim event was run entirely different from previous years.  Instead of a wave start where about 12 people swim in the pool at one time, followed by another wave, each swimmer was started about one minute apart and you swam a zig-zag pattern across the pool.  It worked!

I was amazed that I even passed someone in the pool.  This only happens when a) the passer is a very fast swimmer or b) the passee lied about her estimated time for swimming 500 meters.  Let's dispel a) right away as I am not a fast swimmer.  The woman I passed must be really slow, but gave a really optimistic time estimate.

The bike route was longer than before and had quite a few new turns to stay on course.  I had practiced the route the week before, however I still managed to miss a turn.  On the return route there was a cop signalling to me to make a left hand turn from Sugartown onto Church Rd.  Due to a brain freeze I zipped right past him following the route from the previous year.  I quickly realized my mistake, braked hard, and circled back.  I even apologized to the cop for my mistake (did I think he was going to give me a ticket?).  Must have added 20 seconds to my overall time.

A final comment on my placement.  First the good news -- I finished first in my age bracket.  Now the bad news -- I was the only one in my age bracket and was last among the six male finishers.   I still had fun (but no photos at all).

Swim (500 m) 15:13
Transition          5:50
Bike (20 km)   55:54
Total             1:16:17

Tuesday, April 7, 2015

My Last Sprint Triathlon (sort of)

You might think I am really getting faster from year to year.  You would be wrong.  On the day of the race I learned that they shortened the bike route due to potholes on one of the major downhills of the course.  Makes sense -- don't want anyone crashing their bike due to a pothole.  Right before my start I overheard someone say that they changed the running route.  Okay, probably just a tweak to the route that's been used since the event was established.

Now as I completed the swim, and finished the bike ride, I started the run which is the most god-awful physical experience one can bear.  Getting off the bike my legs are crampy and I start running with tiny strides because it feels like elastic bands are attached between my legs.  I don't feel like running 5 meters let alone 5 kilometers.  Soon I discover that they completely re-routed the course.  I have no idea how far I've run or how far I still have to go.  I ask a volunteer at a water station and just get a "I don't know."

Okay, I finished but I vowed this was my last sprint triathlon.  Why? Besides hating the run at the end, I hate the training prior to the event.  A heavy training day (even a light training day) leaves me exhausted for the rest of the day.  I also have a light headache which I learned is called an "exercise headache." Only a sick man would do this to himself.

Final note: This posting was written in 2015 almost a full year after the event.  I was going to give up this event when the Y announced a couple of variations:
- sprint triathlon (500 m. swim, 10 km. bike, 5 km. run)
- duathlon (5 km. run, 500 m. swim, 5 km. run)
- aquabike (500 m. swim, 20 km. bike)

Now that aquabike event looks interesting...

Thursday, November 21, 2013

How Does Twentyfour Challenge Work?

Download Twentyfour Challenge (it's free) for Android and iOS from these locations:
Google Play
iTunes Store

The Phonegap Diaries describe how the Twentyfour Challenge app was built, but they don't really describe how it works. That's what I'm going to do here.

You probably guessed that the app has a built-in (recursive descent) parser that processes what is in the expression text box on the solver screen.
Within the app the text box does not permit data entry. If it did the user could just type in the goal number (say 24) and would immediately be rewarded with solving the problem. While parsing the code, it also builds an expression tree reflecting operator precedence for this ANTLR grammar (ANTLR is not used within the app):

grammar twentyfour;
solution:	expr ;
expr	:	multExpr ('+' multExpr | '-' multExpr)*
multExpr:	atom ('*' atom | '/' atom)*
	|	'(' expr ')'
RATIONAL:	'0'..'9'+ ('/' '0'..'9')+;

The parser and rational expression evaluator are at the heart of the application, but where do the problems come from? The problems (and there are hundreds of them) are pre-programmed within the application. Each has this form:

// lvl :goal:   tuple1   :   tuple2   :     solution
    "4 : 24 : 6,10,15,6  : 2,10,15,10 : ((15-10)*6)-6"

A valid problem must have these properties:
  1. One of the tuples must yield a solution whereas the other must not
  2. The correct tuple values must appear in the solution expression.
  3. The solution expression must evaluate to the goal
Note that there may be more than one valid solution expression using the correct tuple. This just reflects the fact that 4 = 2+2 and 4 = 2*2. Only one of these valid solutions is pre-programmed, but the user can enter either solution to get the correct answer.

This brings up the subject of hints. I tried lots of alternative versions of the 24 game from the iTunes store. Most use four operands and some of the problems would stump me for minutes on end. All of the programs have a timer which makes you nervous as the seconds keep ticking away. If only the app would give me a hint!

That's it! in the next version of Twentyfour Challenge I will make the app both harder and easier. I will implement a level 4 of difficulty (that is, four operands) and I will implement a hint function at all levels of difficulty.

So how do hints work? There are two contexts -- the problem screen (below) and the solver screen.

Here the hint has been given as the incorrect tuple is disabled. The user should click the active tuple and move to the solver screen.

On the solver screen the hint button progressively shows the solution to the problem in the hint area (below).

Is this the best design for hints? Maybe not, but it certainly was easy to implement using regular expressions. The program examines the canned solution and extracts the operands from it. Here's the regular expression used to extract integer operands:

game.hintNumbers = game.problemSolution.match(/(\d+)/g);
game.hintSolution = game.problemSolution.replace(operand, "?");

When hints are given it just substitutes these numbers back one by one.

At first I though the hints should build on the progress the user has made on her own. It would suggest the next operator or operand (or clear a bad operator/operand). This was very hard to implement. Keep it simple, Sam!

Finally I should mention a back office application I wrote (thankfully) in Java that generated level 3 (three operands) and level 4 (four operands) problems. I had to write this program to guarantee that the pair of tuples for level 4 problems had the desired property of one correct and one incorrect tuple (the incorrectness had to be guaranteed).

This was done by brute force computation. The program generates four random integers and then all possible expressions using them as operands. It then evaluates each expression tree and records the results. Here's some output from the program:

	"4 : 24 : 8,11,15,9 : 6,9,18,8 : ((9-8)*18)+6",
//                                6-((8-9)*18)
//                                ((9/18)*8)*6
//                                6/((18/9)/8)
//                                ((6/18)*8)*9
//                                9/((18/6)/8)
//                                ((9-8)*6)+18
//                                18-((8-9)*6)
//                                ((6*9)*8)/18
//                                ((6*9)/18)*8
//                                8/((18/6)/9)
//                                (6*9)*(8/18)
//                                (6*9)/(18/8)
//                                (6/18)*(9*8)
//                                (9*8)/(18/6)
//                                (6+18)*(9-8)
//                                (6+18)/(9-8)
//                                (6*8)*(9/18)
//                                (6*8)/(18/9)
//                                (9/18)*(6*8)
//                                (6*8)/(18/9)
//                                (9-8)*(6+18)
//                                (6+18)/(9-8)
//                                (9*8)*(6/18)
//                                (9*8)/(18/6)
//                                (8/18)*(6*9)
//                                (6*9)/(18/8)

Obviously this problem has tons of solutions, but there is no solution involving [8,11,15,9].

Friday, October 11, 2013

Phonegap Diaries: Summary

Here's a bullet point summary of my lessons learned.

Bright Spots

  • Phonegap lives up to its promise
  • JQuery Mobile also lives up to its promise.  It game me a better UI and excellent portability
  • Translation from Java to Javascript is not too difficult.
  • There exist real unit testing tools for Javascript


  • <audio> tag and its API had spotty implementation (not working on iPad2 and Galaxy devices).  Why it works on some devices (iPhone4 w. iOS6) is beyond me.
  • JQM documentation needs significant improvement
  • Apple process for releasing to iTunes store is both lengthy and bizarre
  • Lost all i18n capabilities using HTML5 / javascript


  • iOS upgrade on a device is irreversible
  • is good source of info but can mess you up:
    •             right answer to a different problem
    •             right answer for a specific version of JQM (or phonegap, or css, ...)
  • javascript type system is tricky.  
    • For example $mobile.changePage("problem_screen?newProblem=false") cases a transition to the problem screen.  The parameter passed is 'false'.  But 'false' evaluates to true.  Huh? 'false' is a string that needs to be converted to Boolean false.

Unsolved problems

  • Can all information for platform generation emanate from "config.xml?"
  • What is the best way to detect and report javascript errors?
  • What can be done to speed up application load time (5-8 seconds)?

Plans for the Future

I plan future versions of Twentyfour Challenge that include these features:
  • a new level using four numbers
  • a "give me a hint" function during game play
And I'm waiting for feedback from a couple of middle school math teachers whom I know.

Phonegap Diaries: Process


This article discusses the process used to develop Twentyfour Challenge.  First you have to understand the project structure.

Project Structure

Below is the file structure for Twentyfour Challenge as a PhoneGap project:

|____Twentyfour                 <= PhoneGap project root
| |____.cordova
| |____.svn
| |____merges
| |____platforms
| | |____android                <= imported into Eclipse/Android
| | | |____AndroidManifest.xml
| | | |
| | | |____assets
| | | | |____www
| | |____ios
| | | |____build
| | | | |
| | | | | |____www
| | | |____ Twentyfour.xcodeproj    <= imported into XCode
| |____plugins
| |____www              <= source code here! Dreamweaver site root
| | |____config.xml
| | |____css
| | | |____index.css
| | |____img
| | | |____logo.png
| | |____index.html                 <= main page
| | |____js
| | | |____index.js    
| | |____res
| | |____spec
| | |____spec.html

Most of my work is under that www folder and this is what really needs to be under source control.  There are platform specific changes that need to be made under android and ios folders also.

Development Process

After some fits and starts I got into this basic cycle:
  1. Write new html and/or javascript within DW
  2. From DW launch Chrome on index.html page
  3. Set breakpoints on pageinit events within application
  4. Execute application looking for errors/exceptions/bugs
  5. Fix errors/exceptions/bugs in DW
  6. Repeat

Simulator Testing

Periodically I would test the application in either an AVD (Android Virtual Device) or the iOS simulator.  Cordova CLI made this incredibly easy to do:

cordova build ios
cordova emulate ios

The last command will launch the ios simulator and give you a feedback on the look and feel and basic functionality.  But it gives you no information about what's going on within the application.  So you must use XCODE (Eclipse for Android) and launch the simulator (AVD for Android) from there.  This will show any errors that ios detects so you can correct them.

Device Testing

At some stage you have to start testing on a physical device.  You will need to use Eclipse with the ADT to run your app on an Android device, or XCODE to run it on an ios device.

On Android I only tested on my current smartphone – a Samsung Galaxy Stellar model.  On ios I tested on an iPad2 and several iPhone4s.


Don’t forget those icons!  Whereas there are a reasonably small number of icons to develop for Android there are an unreasonably large number of icons to develop for ios.

Don’t forget the all of those screenshots and splash screens that you have to provide.


The process I describe should include all of the rabbit holes that I went down trying to find solutions to my problems; however, I choose not to mention them.  Google (and stackoverflow) should be mentioned as primary development tools as these were the only means for getting unstuck when I was stuck.

Other postings: