Wednesday, October 6, 2010

JavaScript Closure Examples

So I am listening to Douglas Crockford's lecture on JavaScript functions. And I need to get this really straight in my head and separate from Java :-)

Crockford defines "Closure" as follows:
The context of an inner function includes the scope of the outer function.
An inner function enjoys that context even after the parent functions have returned.
Crockford presents the following example that includes a global variable, which I renamed slightly and ran in the Google Chrome console:
var names= ['zero','one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var global_digit_name = function (n) {
return names[n];
};
global_digit_name(3);
"three"
typeof global_digit_name
"function"
I am using the JavaScript "typeof" operator to inspect what is being generated. Crockford make the point that this function is making use of a global variable, and that global variables are evil, which I guess I go along with; although I wonder if this example isn't already demonstrating closure, i.e. the global variables are just variables in the global function scope that the local function is getting access to, but perhaps that's not how global scope works in JavaScript, but anyway ... before moving on, let's think how we would so the same thing in Java:
static String[] names = {"zero","one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};

static String global_digit_name(int n) {
return names[n];
}

public static void main(String[] args) {
System.out.println(global_digit_name(3));
}
Here I am using static scopes to create a "global" variable and a "global" method. I can't assign the method to a variable in Java, so I just call it in the main function. Anyhow, back to the JavaScript example, in the name of removing the evil global variable Crockford the presents a slow alternative:
var slow_digit_name= function (n) {
var slow_names= ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return slow_names[n];
};
slow_digit_name(3);
"three"
typeof slow_digit_name
"function"
slow_names
ReferenceError: slow_names is not defined
So the JavaScript advantage here is that the names variable is safely inside the function and can't interfere with other global variables. The Java equivalent is straightforward:
static String slow_global_digit_name(int n) {
String[] slow_names = {"zero","one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
return slow_names[n];
}

public static void main(String[] args) {
System.out.println(slow_global_digit_name(3));
}
In both Java and JavaScript cases the slowness results from reallocating the array each time the method is called which is a bit wasteful. Now comes the JavaScript example that Crockford labels "closure":
var closure_digit_name= (function () {
var closure_names= ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return function (n) {
return closure_names[n];
};
}());
closure_names
ReferenceError: closure_names is not defined
typeof closure_digit_name
"function"
So again we avoided the nasty global variable, but now the object literal closure_names is not allocated each time. Interestingly I can get definitions of the functions defined so far from the Chrome console:

closure_digit_name
function (n) {
return closure_names[n];
}
slow_digit_name
function (n) {
var slow_names= ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return slow_names[n];
}
Which allows us to see clearly that closure_digit_name is not reallocating the object literal each time. Where I am perhaps confusing myself is that I thought by assigning the return of a call to a function to closure_digit_name that we were turning closure_digit_name into an object, but not according to the Google Chrome console which still gives the type of closure_digit_name as a function. I think it is me just confusing myself. Crockford doesn't mention objects being returned, here's what he says (with my minor edit to make it apply to my example - unfortunately I don't have his colour highlighting):
We assign the return value of the outer function to closure_digit_name. The outer function has now returned, digit_name now contains a function, which is the green function. That green function still has access to names, even though names is a private variable of a function that's already returned. That's closure: one function closes over the variables of another function. This turns out to be one of the most important features in JavaScript; this is the thing that it got amazingly right. This is the thing that makes JavaScript one of the world's brilliant programming languages.
In my own words it seems like we are defining a function on the fly that happens to have a variable and a function, so the following longer version should be exactly equivalent:
var my_function = function () {
var closure_names= ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return function (n) {
return closure_names[n];
};
}
var closure_digit_name= my_function();
which Google Chrome confirms, and gives me the advantage of being able to check the contents of my_function:
my_function
function () {
var closure_names= ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
return function (n) {
return closure_names[n];
};
}
Which reassures me slightly as at least I can now see where closure_names is, sort of :-) It really does seem to me to say that by calling my_function() that we get back some sort of object with a function and a variable, but I guess that's part of the JavaScript power, that functions can have other functions and variables, but it does seem slightly odd that the consequence of calling a function is to return a function. Quoting from Crockford's book:
A function always returns a value. If the return value is not specified, then undefined is returned. If the function was invoked with the new prefix and the return value is not an object, then this (new object) is returned instead.
According to which, I would have thought that my_function as I define it above, should return "undefined" and not the function that it contains, but that is what seems to happen. On closer inspection I see that my_function is not just containing the sub-function, it is returning the sub-function, so everything starts to make sense, and the example can be unobfuscated further like so:
var my_function = function () {
var closure_names= ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var my_sub_function = function (n) {
return closure_names[n];
};
return my_sub_function;
}

var closure_digit_name= my_function();
and Google Chrome confirms for me that this does exactly the same thing, and as far as I know there is no simple equivalent in Java. Interestingly I can't access the closure_names variable from the reference I now have to my_function:
my_function.closure_names
undefined
And I guess that is because this really is a function and not an object ..., but it certainly seems to have an object like nature, at least the way I think about them :-)

Sunday, October 3, 2010

Google App Inventor

Had great fun with Google App Inventor over the weekend. Got my beta invite and was able to do wysiwyg interface design and program creation with my app live updating to the phone. It has a very similar programming interface to Scratch, the program from MIT designed to teach programming to kids. I had been playing with Scratch and others with my 5 year old son, and had been disappointed to hear that Apple yanked a Scratch clone from the iPhone because they don't want any other mechanisms for creating apps other than Objective C.

Would be nice if App Inventors layout interface were as good as interface builder for iPhone in the Xcode, and would be great if you could see the java code that was compiled from the Scratch visual programming. Would be interesting to see if I could use this in the mobile programming class I will teach in the Spring ...

So, great fun, although I still think there could be an easier programming interface that would work well for even younger children. Seems to me that you could be able to do things like move sprites and then capture that activity in a macro format, that would then show up as a procedure that could be manipulated. Maybe Google will open source appinventor and then something like that could be created ...

Thursday, September 30, 2010

Learning ChatBots

Chapter 26 in "Parsing the Turing Test" was "Who Fools Whom? The Great Mystification, or Methodological Issues on Making Fools of Human Beings" by Eugene Demchenko and Vladimir Veselov, which had some great suggestions for bot techniques, and made a point about bot learning being hard.
'Teachable bots is an idea that looks logical at first glance, but becomes almost impossible to implement ... let us look at easy examples:

"John's birthday is January 1st, 1980, What is John's birthday?"

It seems so clear! But let's say this another way:

"Bob is 35. How old is Bob?"

Well, now he is 35 and, according to the educated bot, he will be 35 forever! Birthday is a constant date while "age" is a value that changes in time ... we find ourselves in a vicious circle: to be able to learn, a bot should know much more than it is possible to teach it "manually"'
The authors go on to talk about how Cyc might be reaching this critical threshold to actually start learning, but it seems to me that the problem is one of meta-learning. The authors seem to be focused on bots that learn facts of the type "X is Y", which can be queried through "what is X?" type questions. If this were the only type of learning available then there would be no alternative than to "manually" program the bot to know the difference between birthdays and ages. However could the bot not learn, as human children do, that one is constant and the other is variable? The concept I am wrangling at present is that idea that you could have a dialogue with the bot like so:
Sam: Bob is 35. How old is Bob?

Bot: Bob is 35

[A year later]

Sam: How old is Bob?

Bot: Bob is 35

Sam: No, he is 36

Bot: You previously said "Bob is 35".

Sam: Yes, he was 35, he is now 36 because a year has past.

Bot: So "Bob is 36", will that change again?

Sam: Yes, every year on his birthday his age will increase by 1.
Of course the obvious flaw with my idea is that the bot needs to be intelligent enough to understand my explanation, but the idea of a bot that can learn through explanation should be clear. I imagine the teaching new type of knowledge to the bot would be challenging, but am reminded of that paper (which I now can't find!) by Guy Steele which assumes knowledge of all single syllable words, and defines every word of more than one syllable in terms of words of one syllable or other polysyllabic words that have previously been defined.

Anyhow, this method of boostrapping bot knowledge needs a lot of work, and there's probably some critical reason why it just won't work period, but I'm still intrigued by the idea.

Tuesday, September 28, 2010

MegaHAL, Jason Hutchens and AI Ltd (NV?)

So I just read a very interesting chapter by Jason Hutchens in "Parsing the Turing Test", in which he talked a little about his work at AI Ltd (NV?) on mixing a reinforcement learning paradigm with some stochastic word frequency modeling to train an AI. I remember reading about that 10 years ago or so and was really interested to get an update. There was a tantilizing transcript of a HAL/Trainer dialogue where HAL (the computer) was effectively simulating a 15 month old's speech. A quick web search turned up that dialogue in an academic paper:

Treister-Goren, A., Hutchens, J.L.: Creating AI: A unique interplay between the development of learning algorithms and their education. In: Proceeding of the First International Workshop on Epigenetic Robotics (2001)

Trainer: where is daddy?
HAL: daddy gone
Trainer: daddy is at work
HAL: daddy work bye bye
Trainer: yes daddy has gone to work
HAL: daddy work bye bye bye bye
Trainer: do you want to go to the park?
HAL: yes bye bye
Trainer: ok we can go to the park
HAL: take car bye bye
Trainer: we will take the car because the park is far.
let’s pack some things in a bag
HAL: ball now park
Trainer: yes we should put the ball in the bag
HAL: ball now park mommy
Trainer: wait hal, we need to take something to eat
HAL: bananastory? night now
Trainer: we need to take something to eat
HAL: bananas
Trainer: ok we can take some bananas
HAL: monkeys eat bananas
Trainer: you’re so smart hal. do you want to take a
book?
HAL: juice mommy
Trainer: sure we will take some juice as well

Jason's chapter didn't have any references and there were a few points he made that I would have liked further details on, specifically:
"... findings which indicate that appropriate guidance may strongly influence ... aspects of the child's language development ... these findings have spawned evaluation and treatment programs in areas that border on the question of intelligence with developmental language data enabling the treatment of some developmentally delayed populations. It has also proven itself a valuable tool in treating schizophrenic thought disorder where clinicians often find themselves unable to capture the communicative problem of patients to assess their intelligence."
Anyhow the chapter ended on saying there was an exciting future ahead, but a quick web search revealed that Jason left the company in 2001, and I had a little trouble finding more about the company, although finally I found this website:

http://www.a-i.com/

Where I had a reasonable conversation with a chatbot that seemed more advanced than the 15-month old one, but the conversation was not disimilar to an original HAL or Eliza program. The website has lots more to explore including an iPhone app, and apparently the ability to train your own bot and make it public; but I couldn't immediately find what I was looking for, which was something about how the program of training infant AIs was progressing. I'd love to see more recent peer-reviewed papers on this stuff. Maybe I'll find it with a bit more looking.

Wednesday, September 22, 2010

Cyc: Parsing the Turing Test

So I just bought my first book on Kindle. Something I had been putting off, since I don't particularly like the Digital Rights Management that allows Amazon to suspend my access to books that I have paid for. And basically I hate paying for things when I can possibly avoid it, however I was gagging to read Parsing the Turing Test, and my impatience, and lack of luggage allowance on my upcoming trip from Japan to the UK, and so I shelled out $50. I feel a little bad about that, although I console myself that some great work has gone into the book and the author's certainly deserve compensation (although I wasn't able to determine that until after I started reading it) and kudos to Amazon for making the book I bought seemlessly available on my MacBook Pro, Kindle, iPad and iPhone. Now that's handy.

Anyhow, so this will likely be the first of many posts related to particular chapters from the book, but first off I was fascinated to read Chapter 16 "Building a Machine Smart Enough to Pass the Turing Test: Could We, Should We, Will We?" by Douglas Lenat; which describes a series of hurdles apparently overcome in phase 1 of the Cyc project such as dropping absolute truth, consistency, reasoning in particular contexts etc; that have allowed them to complete phase 1.

Lenat goes on to talk about now they are priming the knowledge pump to allow the system to learn by itself, but it's not clear to me why the knowledge pump has to be primed so much first. I find myself wondering why can't all knowledge be provided through interactive dialogues with the system, i.e. have the system proffer answers and explain when it is incorrect. In the chapter Lenat gives an example of a computer trying to decide whether "fear" or "sleepiness" is appropriate for the victim of a robbery, and gives first order logic predicates that allows the answer to be inferred. Could the required predicates be inferred by the machine from a human explanation of which emotion is appropriate? I guess that explanations are often more complicated that the questions they answer, raising further questions in turn ...

Lenat refers a number of times to Cyc learning by itself, certain machine learning issues being as yet unsolved. It seems to me the key is some form of representation and learning process that allows the system to have incorrect assertions explained to it in natural language, and have the system update its model accordingly. I am sure I am being hopelessly naive here, but will have fun testing my ideas.

Any which way, this is certainly making me see Prolog in a new light :-) Can't wait to get started on building a system to enter the Loebner prize competition next year. Although there are many more chapters to read and each is turning over sets of my own assumptions. Lenat already lists the "human frailty" deceptions that would be effective/appropriate for passing the test ...

Friday, September 17, 2010

Live ScreenCast Solution

So I (sort of) successfully used UStream to broadcast a lecture for my Internet Programming class last night. After realizing (again) that the Ustream Producer standalone audio doesn't work (at least for me and a few others ), I switched to recording through the browser and that created a stream that my students were able to see, and I was even able to screencast by using CamTwist, and I was subsequently able to download. Woot!

Unfortunately the resolution was such that the students were only able to read the largest of my powerpoint fonts, and it wasn't really practical to see any of the code examples. Fortunately I had cunningly distributed my slides in advance, so the students were just using the ustream screencast to know where to look in the slides, and for synced audio. Somewhat ridiculously the Ustream comments were only available in the live stream, not in the broadcast window, and I didn't want to have the live stream window open, although I guess I could have muted it, but I worried about my browser crashing. Anyhow, we ended up using Skype for chat and backup audio, but that means that the chat is not synced with the recording, which is a shame for those who were not present.

Anyway, I would really like to broadcast in slightly higher definition, and it seems I could pay ~$200 for UStream Producer Pro, but I am worried that the audio will not work, as in the free version of Producer, and that I won't even get a sufficient boost in resolution from the point of view of the students.

So what I would really like to know is if anyone has managed to successfully live screencast from OSX with a resolution sufficient for handling code examples. Either in UStream or some other solution ...

Wednesday, September 15, 2010

REXML and WADL issues in Chapter 2 of OReilly's RESTful Webservicesw

So I am teaching a course on RESTful webservices and using Sam Ruby and Leonard Richardson's OReilly book as the main text. It's a great book, but things have probably changed in a few Ruby libraries since the book's publication in 2008, so a couple of examples in chapter 2 seem to have some problems. I am on OSX 10.6.4 using ruby 1.8.7

The first issue was:
$ ruby delicious-sax.rb tansaku
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/source.rb:227:in `position': undefined method `stat' for # (NoMethodError)
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/parsers/baseparser.rb:144:in `position'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/parsers/sax2parser.rb:176:in `parse'
from delicious-sax.rb:21:in `print_my_recent_bookmarks'
from delicious-sax.rb:30
I had been searching around for anything on this error, including looking at the source, but had made no progress. I tried to subscribe to the REXML mailing list described here:

http://www.germane-software.com/software/rexml/index.html#id2248285

but got no response, so thought I would try ruby-talk. Unfortunately while I am subscribed to ruby-talk and don't seem to be able to unsubscribe I don't seem to be able to post there. I found at least a partial resolution by chatting with capnregx on ruby-lang irc at Freenode. The solution was to call xml.string to dump out a String object rather than passing in a StringIO which the REXML I am using is, somewhat surprisingly, unable to handle.

I also found a problem in the same chapter with another example involving WADL:
$ ruby delicious-wadl-ruby.rb tansaku
./wadl.rb:1248:in `lookup_param': No such param post (ArgumentError)
from ./wadl.rb:1255:in `each_by_param'
from delicious-wadl-ruby.rb:22
I took a brief look at the source and didn't have any immediate insight. After some more support from capnregex I identified a good approach of running the entire program in irb to see what was being passed back from the server. This is the annoying thing about del.icio.us as a programming example, since it is all over https, so no tracing it with tcpdump.

I got as far as seeing that the appropriate data did seem to be returned, but was residing in get.format rather than get.representation which was a REXML:Element rather than a WADL::XMLRepresentation as one would intuitively expect from the 'each_with_params' method call. get.headers.string appeared to contain the desired XML but not in a format (StringIO) that could be parsed the way the program was attempting. Tabbing on get.headers. suggested that each_by_param was an appropriate method, but gave an undefined method error so I gave up there and decided to drop the WADL example for the moment. We'll come back to WADL in a later chapter, but I am becoming increasingly dubious about it's value. At least the REST community does not seem to have sprung into action around it after the effort the book's authors put in to getting it off the ground.

All files required to run the above are in pastebin:

delicious-sax.rb http://pastebin.com/029SnVEW

delicious-wadl-ruby.rb: http://pastebin.com/Nz5hFGRN
wadl.rb (required by above): http://pastebin.com/AKRAETG8
delicious.xml (required by above): http://pastebin.com/7hUH7uwy

Of course you will need to use your own deli.icio.us username/password combinations for the examples to work :-)

Monday, August 30, 2010

SmartFM Android Study Dictionary v1.1 released

So I even managed to find time for a few performance fixes and have released version 1.1 of the SmartFM Android Study Dictionary to the Android Market.

The main difference is pretty much on the back end with the app using a separate Java client to consume JSON (instead of XML) from the new "unofficial" SmartFM API. This necessitated a performance fix on the main item list view since checking whether there was a sound for an item required a separate HTTP request. This creates the main noticeable different, that you'll briefly see progress indicators for the sound icons when you first get a set of results back.

I was pleased that using ProgressBar, AsyncTask and a cache of my own design was effective in making the list scroll smoothly and I went on to use the same approach for image loading in the sentence list that is part of each individual item view. That's something that was always a performance issue in earlier versions, but only came up for items with more than 3 or 4 sentences.

I'm disappointed not to have been able to add more functionality or fix other minor gripes, but the old version one XML SmartFM API is being discontinued today or tomorrow, so I thought it better to kick out a version that works with the new API, and leave everything else for subsequent releases. "Release Early, Release Often".

Anyhow, I am moving house and starting a new job, so will probably be restricted to bugfixes for the next couple of months, but hope to release some new features and fixes by Christmas. I think my main goals are making the voice search go straight to results without requiring a second click, and pre-loading lots of content so users don't have to wait to download sounds. I think the multiple HTTP requests associated with each individual items could be put into AsyncTasks, to make the item display more responsive ...

The two most frequently requested features are support for some study, and OpenID. I do hope to include a study feature soon. As for OpenID, we'll see ... :-)

To follow my progress subscribe to this blog or the associated Google Group:

http://groups.google.com/group/smartfm-android

Thursday, August 26, 2010

Another SmartFM Android Study Dictionary Beta, all media upload now supported

So I've managed to get all the media upload functionality working against the new API, I think ... If anyone is interested in helping me test the new beta it is available here:

http://www.neurogrid.net/public_html/smart_fm.apk


There are still some performance issues, but I think I have an angle of attack on those (AsyncTasks and some caching structure), so if I'm lucky I can put those in place before the August 31st deadline. Final beta before then I hope ...

One interesting note is that SmartFM now has some pretty impressive automated text-to-speech for Japanese Sentences. Words and sentences now have audio added automatically and at least to my untrained ears it sounds pretty good. Makes all the effort to support sound upload on the Android a little redundant ...

Tuesday, August 24, 2010

The problem with Java, or null-proof logging in Android

So this is really irritating. I keep getting exceptions in Android when my logging string happens to be null, e.g.
Log.d("DEBUG", my_string);
if my_string is null, then I get an exception and execution halts. Not what I want. I want the null nature of my_string to be reported and execution to continue.

The verbose location solution is:
if (my_string != null) {
Log.d("DEBUG", my_string);
}
or:
Log.d("DEBUG", my_string == null ? "NULL":my_string);
but really I'd like to modify the Log.d static method so that check is included by default. Something I could easily do in ruby, but no equivalent I know of in Java that doesn't involve creating some new class and then modifying all my existing calls to this method throughout my code ...

Friday, August 20, 2010

Early Beta of Smart.fm Study Dictionary v2 available for testing

So I've created a stand-along Java client library for the new version 2 of the smart.fm API. I've now used that successfully to create an early beta of the Smart.fm Study Dictionary v2, which is available here:

http://www.neurogrid.net/public_html/smart_fm_2.apk

If you want to help by beta-testing this application you can download directly to your phone by browsing to the above link (ensuring you have set your android phone to allow non-market installs).

I've re-implemented everything that was in the original except the creation & media upload functions - those are planned for next week :-)

Some issues I am aware of are the slowness when downloading or scrolling item lists, and that some items may have sentences from multiple languages inserted. These are due in part to changes in the API and I am working on fixes. I would be most grateful to hear of any other issues or suggestions for changes. My current work TODO list is available at the following link for your perusal:

http://groups.google.com/group/smartfm-android/web/smartfm-v2-todo-list

Wednesday, August 11, 2010

Android Speech Recognition

The Android speech recognition module is great (I use it in my SmartFM Study Dictionary), but it doesn't have much flexibility. I'd really love to be able to use the audio recording component in it for my own audio recording needs, and also be able to submit my own audio rather than being forced to use the existing audio recording component. I think ideally the speech recognition and recording components would be split up. There are a few enhancement requests already filed with Google that I added stars to in order to increase the chances of this happening. If you have a moment please star them as well.

http://code.google.com/p/android/issues/detail?id=4541

http://code.google.com/p/android/issues/detail?id=6930

http://code.google.com/p/android/issues/detail?id=10022

Friday, August 6, 2010

Towards Tatoeba on Android

Great multi-lingual example sentences project at Tatoeba.org. Wish they had an API, but they very kindly provide a dump of their database. 3rd party projects are currently using that. I'm chatting with the Tatoeba guys about an API and hearing that it is an issue of expense, since they are a "a free project run by a student". Makes me wonder if there is a way to use Google App Engine or other cloud computing platform to help them support an API, or Mashery or 3scale something ...

So anyway, I used RazorSQL to take their csv sentences file and convert that into an SQLite database. The conversion took about 10 hours once I had figured out an issue with RazorSQL trying to always find closing double quotes. So then I got an INSTALL_FAILED_INSUFFICIENT_STORAGE error trying to load an Android app with Tatoeba's full set of sentences stored in an sqlite db that was 25 Mb. I was considering that the better approach would be to download the file from a remote location and store on the SDCard, when I realized the problem was actually that I had left the 50Mb SQL Inserts file in the same folder. It got automatically folded into the Android APK file. I removed that and the application ran. Well I say ran, it had the new problem that it couldn't find the Sentences table, but that was my Android SQLite plumbing and not the file size :-)

Fixing that I got a new error, Data exceeds UNCOMPRESS_DATA_MAX (24825856 vs 1048576), which happened when I tried to import the Tatoeba database from resources into the file system. A little research suggested there was a hard limit of 1Mb on resource and asset files in Android packages. So I moved straight to the network download which is what we would need for market release of an app of this kind anyway.

Download from Google docs worked after I added support for 302 redirect, took a long time - but database did get stored on file system, although the DDMS client died, so I couldn't check the details.

Started to feel like it would be faster to wrap my own rails REST layer around db dump ...

So I got the thing displaying a list of sentences but unfortunately on first attempt the UTF-8 characters were mangled. SQLite appears to support UTF-8, so I wondered if this was an android issue. Android is also UTF-8 compliant, so it seems like it was actually another RazorSQL issue. Although the SQL inserts had been created in UTF-8 when I ran them through RazorSQL the double byte encoding had been lost. I was able to re-generate an SQLite file with intact double byte encoding by running the SQL inserts from the command line - which had the added benefit of being hugely faster.

A bit of jiggery pokery later and I had the entire sentences db of Tatoeba displaying in an Android app. Nice to see the ListActivity performantly handling the display of a table with over 400,000 rows.

So that was a fun day, but still to do are:

1) Work out the best option for download; Google Sites has 20Mb limit, and Google docs stared doing some weird virus redirects on the latest file ...
2) Add some basic search to the app
3) Drop in the relations csv and get things all prettied up :-)

Wednesday, August 4, 2010

Forking Codebases

So Cerego is going to discontinue official support of their version 1 SmartFM API as of August 31st, which is a shame, as I use that API in my SmartFM Mobile Study Dictionary app (available in the Android marketplace).

I'm going to be switching over to the unofficial version 2 SmartFM which is JSON rather than XML based, so I'm trying to rework the app before the August 31st deadline. I managed to get some preliminary JSON communications going, and since the android test harness is too damn slow I created a separate standalone non-android Java SmartFM JSON client library. So now I'm just about ready to blast through all the old XML communications and change to JSON, but first I wanted to check that this separate library was actually going to work as an android plugin, particularly since I had pulled in a different JSON library to get the standalone test framework to work.

So I created a brand new Android Shell to check that the linkage worked, and it was good, but I started wondering if I shouldn't be forking my existing codebase since I want to be able to apply small fixes to that, and perhaps pull them directly into the new codebase. Also, I need to work quickly to get this all done by the August 31st deadline, so I likely don't have time for the complete rewrite I would like ("release early, release often"), however maintaining a long term fork seems rather involved. I found a walk through of how to do that:

http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/

On balance it seems more trouble that its worth, so I'm going to work with a new repository and move things over piecemeal. Still I'll try and move code over without trying to fix too much, as experience tells me that trying to fix too many issues at once is asking for trouble. The main issues I want to address are removing global variables and unsightly spaghetti code, making the voice recognition auto search, and streamline the content creation process. Better get that JSON stuff working first though :-)

Friday, July 30, 2010

Teaching Internet Programming at HPU Fall 2010

I'm teaching a course on Internet Programming this fall at Hawaii Pacific University (HPU). If you are interested is understanding more about how fantastically useful webservices from Google, Amazon, Yahoo, Twitter and Facebook can be consumed by 2D web browser Javascript, Mobile Phones, Second Life 3D scripting language and others to create cool mashups, do sign up for this course. I'll cover as many new topics as I can fit in, including HTML5, JQuery, selling goods on the Second Life marketplace, etc.

The full course materials will be online so you can take the course from anywhere in the world, and even if you are not enrolled full time in HPU, you can sign up for single courses by going to the following link:

http://www.hpu.edu/index.cfm?contentID=373

Here's the official course blurb:

CSCI 3632, Internet Programming: Fall 2010

Discover how webservices are changing the programming game. Stop rewriting the same tired code and outsource the heavy lifting to Google, Amazon, Yahoo and others. This course will focus on RESTful webservices, as promoted by the open source community. We'll look at how multiple clients, such as browser-embedded javascript and 3D World Second Life embedded Linden Scripting Language, can access RESTful web services to quickly create useful mashups from the Google Maps & Document APIs, Facebook/Twitter APIs. By the end of this course you'll be fully versed in how to make your own webservices using Ruby on Rails, and how to script light-weight components that leverage them in online 2D and 3D clients.
Taught online by Samuel Joseph, Ph.D.

TextBooks:

RESTful Web Services: Web services for the real world by Leonard Richardson & Sam Ruby. O'Reilly Media. http://oreilly.com/catalog/9780596529260

Scripting Your World: The Official Guide to Second Life Scripting (Paperback) by Dana Moore et al. Sybex. http://syw.fabulo.us/

JavaScript: The Good Parts Unearthing the Excellence in JavaScript, by Douglas Crockford. http://oreilly.com/catalog/9780596517748

Thursday, February 18, 2010

Collaborative Telepresence using Skype

So I've been thinking about what I call "Collaborative Telepresence" for a while now. Basically the idea is that you are mobile and you send a video feed to your friend at their desktop (or also mobile). Your friend sees something of interest in your video feed, indicates it (with a cursor or similar) and that video feed comes back to you in real time so you can see what they are pointing at.

I see this as being useful when you are at the grocery store and your better half is at home and want's to point out what you should buy, but it should work for any situation where you have a "field operative" and an "expert" who is trying to advise from a another location. What will totally rock is when we can do this over mobile phones.

I worked out a way to jury rig a system like this by using Skype. Skype allows you to both transmit video feed from a webcam and also to share your screen. To set things up, start a Skype call and have the "field operative" broadcast video. Once the "expert" can see the video feed, have them share their screen back to the field operative. Specifically the part of the screen that has the incoming video. Then, when the "expert" moves their mouse cursor (sometimes you might need to have them grab a file icon if the cursor is too small) over a part of the incoming remote feed it can be seen by the "field operative".

In order to get the mobile "field operative" flavour I ran a demo that involved strapping a UMPC to my chest - running skype on it, and outputting the video to a pair of heads up display built into a pair of Oakley sunglasses (see image). This allowed me to operate as a "field operative" in my yard with my wife (the "expert") telling me which Mangos were ready to pick off our tree and which were not.

Skype is on Android and iPhone, but doesn't have video support yet. Here's hoping that will come soon so my wife can instruct my activities at numerous remote locations :-)