Monday, February 17, 2014

Scala: What's the difference between Traversable and Iterable?

I'm currently working through the book Programming in Scala, 2nd ed.. I'm in chapter 24 and reading about the Traversable and Iterable traits and the difference between them.

Traversable is a trait with one abstract method, foreach. It's signature is

def foreach[U](f: Elem => U)

Defining this one method for a Traversable allows your collection class to gain several useful methods like

  • map
  • flatMap
  • take
  • drop
  • filter
  • foldLeft, foldRight
  • etc.

Iterable is a trait that extends Traversable and also has one abstract method, iterator. It's signature is

def iterator: Iterator[A]

Iterable defines foreach in terms of this iterator method:

def foreach[U](f: Elem => U): Unit = {
    val it = iterator
    while (it.hasNext) f(it.next())
}

If we can implement foreach in terms of iterator, why have Traversable as a separate trait?

The book provides one reason: that for some collections, implementing iterator may not be easy or may not be efficient. To illustrate this the book uses a Tree data structure as an example.

The Tree data structure is defined as a case class hierarchy:

sealed abstract class Tree
case class Branch(left: Tree, right: Tree) extends Tree
case class Node(elem: Int) extends Tree

I'm a Scala newbie so I couldn't get their Traversable Tree code example to work. Instead I came up with this:

sealed abstract class Tree extends Traversable[Int]
case class Branch(left: Tree, right: Tree) extends Tree {
  def foreach[U](f: Int => U) = left foreach f; right foreach f
}
case class Node(elem: Int) extends Tree {
  def foreach[U](f: Int => U) = f(elem)
}

For the Iterable version I came up with this:

sealed abstract class Tree extends Iterable[Int]
case class Branch(left: Tree, right: Tree) extends Tree {
  def iterator: Iterator[Int] = left.iterator ++ right.iterator
}
case class Node(elem: Int) extends Tree {
  def iterator: Iterator[Int] = Iterator.single(elem)
}

Both fairly straightforward. The problem with the Iterable version is with the efficiency of visiting nodes in the tree. In particular, the implementation of ++ is such that it has to do an extra indirection at every call to next to determine whether to pull from the left or the right iterator.

I think it helps to see what a naive implementation of ++ would look like:

def ++[A](left:Iterator[A], right:Iterator[A]):Iterator[A] =
    return new Iterator[A] {

        def hasNext: Boolean = left.hasNext || right.hasNext

        def next: A =
            if (left.hasNext)
                left.next
            else
                right.next
    }

Every call to next has to first check left.hasNext before returning a value. In a balanced binary tree with N leaf nodes, the depth of the tree is approximately log(N). So to reach a leaf via this added iterator would require an extra log(N) calls to left.hasNext. Therefore, visiting all of the leaf nodes using the iterator would take O(N*log(N)).

But, that's with the naive implementation of ++. The actual implementation, shown below, optimizes by keeping a reference, cur, to the current Iterator. This allows it to avoid needing to check hasNext on the first Iterator on each call to next.

def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new AbstractIterator[B] {
    // optimize a little bit to prevent n log n behavior.
    private var cur : Iterator[B] = self
    private var selfExhausted : Boolean = false
    // since that is by-name, make sure it's only referenced once -
    // if "val it = that" is inside the block, then hasNext on an empty
    // iterator will continually reevaluate it. (ticket #3269)
    lazy val it = that.toIterator
    // the eq check is to avoid an infinite loop on "x ++ x"
    def hasNext = cur.hasNext || (!selfExhausted && {
        it.hasNext && {
            cur = it
            selfExhausted = true
            true
        }
    })
    def next() = { hasNext; cur.next() }
}

So, to a certain degree, this example with the Tree is a little artificial. It's just as easy to implement Tree as an Iterable as it is to implement it as a Traversable and there is no fundamental reason why the performance of visiting all of the leaf nodes needs to be worse than a Traversable implementation.

I think it is reasonable to assume that there might be data structures where implementing an Iterator over their elements could be challenging (either fundamentally so or with regards to efficiency). I just wish I could think of a more compelling example.

Further resources:

Friday, March 29, 2013

Learning Design: An Initial Curriculum

I'm a programmer, not a designer. And in the past, I've been fine with that. I'll do the programming, let the designers do the designing. But now I want to learn how to design. And by design I mean just about everything that design can mean, both things like visual, graphic design and things like usability and information architecture.

Why? What's changed? I would say two things really. First, I think I can learn design (I think anyone can learn just about anything if motivated). I used to think that it just wasn't my talent. I would tell myself that "I can make things work, I just can't make them pretty." Second, I'm curious. I want to learn design now. I have come to appreciate that design isn't just "making things pretty". I think that design is about solving the human side of a problem. Being a programmer means I can solve the technological side of a problem, but that is only half of it. The best code in the world that actually solves a real problem won't do anyone good if it isn't usable. And the more that the user interface to a system delights users the more impact that solution will have in the real world.

I also think that learning design is a better career move than, for example, learning functional programming or how to write event-driven, non-blocking web server code, or whatever the new hotness is. I don't expect to become a great designer, only a decent one. I expect I will still need to work with a "real" designer on at least some of my projects, maybe all. But being able to put together good looking prototypes, being able to communicate better with web/graphic designers, being able to produce decent initial working versions of software, being able to layout and organize displays of information in ways that are helpful and appealing, all of that makes me better able to deliver software solutions and hence make me more valuable to potential employers. Perhaps most importantly to me, as an wannabe bootstrapped entrepreneur, it means I can create more compelling applications and that I can more fully realize the applications that I see in my imagination.

So here's what I'm looking at now as resources for learning design.

Treehouse: Become a Web Designer Adventure

I like the idea of an online course. I think it will be easier to consume and stay on track. I also like that Treehouse covers theory (although maybe a little light on it by the looks of the curriculum) and also practice, how to use the tools of the trade. (But man is Photoshop expensive!)

Non-Designer's Design Book by Robin Williams

I've seen this book recommended on Hacker News and elsewhere more times than I can count. I'm including it with the hopes it will give me a good foundation in the basics of design theory (and practice).

Don't Make Me Think by Steve Krug

Another book that comes highly recommended. I realize this list is a little light on HCI type topics and perhaps I can add some more useability/user experience resources to this list, but I think Don't Make Me Think is a good place to start.

Drawing on the Right Side of the Brain by Betty Edwards

I don't think drawing will directly help me with web design, but I do think it will get the artistic juices flowing. One of the things I've read about this book is that it doesn't so much teach you how to draw as much as it teaches you how to really see. That ability to see clearly will help me to see what is good in other's design and perhaps also help me see how to make my designs better.

Design of Everyday Things by Donald Norman

Another highly recommended book, but I haven't read much about it. Looking forward to reading it.

Copying good designs

What's the saying, good artists create, great artists steal?. As part of my curriculum I'll study and copy design that I find appealing. Why do they work so well? How do they implement those designs?

I've done something like this before when I was working on learning CSS. I took a screenshot of csszengarden.com, copied the HTML and images and wrote the CSS from scratch to match the screenshot. It was a good learning exercise, not just in that I exercised applying what I had learned about CSS but after I was done I also compared what I had done to the csszengarden.com's CSS code and learned from the approaches they had taken.

Notable Mention

In my research, these resources looked interesting and I might use them, but I don't have enough time to do everything.

Sunday, March 17, 2013

Using Codea and Khan Academy to teach computer programming to my daughter

I've been teaching computer programming to my oldest daughter (who is turning 11 soon) for the past couple of years or so. We started out with Scratch and she had a blast with that. After completing a simple game that she designed and developed herself, I asked her what she wanted to do next. She said, "I want to do what you do". She knew from watching me work that the visual programming environment in Scratch is not how "real" programmers work.

So our next step was to give Python programming a try. We got the book Invent Your Own Computer Games with Python and started working through it. Unfortunately, jumping into Python from Scratch was probably a little too tough and the fact that the programs she was creating in Python were completely textual meant that it was less engaging. So I started thinking about what we could do next.

Getting nostalgic for my Atari 800XL

I thought about what computing meant for me when I was her age. Growing up I had an Atari 800XL. What a marvelously simple device compared to what we have available to us today. There were two things that made the Atari 800XL a great first computer for a kid:

  1. No internet.
  2. Simple programming environments (BASIC and Turtle graphics).

That first one is a big deal. We don't let our children use computers unattended because of the inherent dangers of the world wide web. I'm sure my parents never had any such concerns because my Atari 800XL was never networked at all. Because of that I spent a lot of time just playing around on my computer. I remember hours upon hours spent meticulously typing in computer programs from magazines such as Compute! into my 800XL.

The second one, simple programming environments, is important too, but there are plenty of those to be had. Turtle graphics was particularly good because I could get the gratification of generating a visual effect of some sort. Probably the most advanced turtle graphics program I wrote (which wasn't very advanced, but I was proud of it at the time) was one where I animated a simple line drawing of a bird flapping its wings. I could control the bird's position on the screen by using a joystick. That was a lot of fun.

So this got me to thinking. Could I set up a computing environment for my daughter that would be easy for us to monitor, allow her to just waste time playing around with different ideas and approaches, and allow her to create graphical programs?

Enter Codea

I thought, what if she could have a turtle graphics like program on our iPad? She (like everyone in the family) just adores our iPad. If she could create graphical programs on the iPad, especially if they could respond to touch and what not, I thought she would get a big kick out of that.

The iPad still suffers from the problem of having unfettered access to the internet, but an app that serves as a self-contained environment would minimize the chance that she would ever even end up in Safari. Also, it's not too hard to keep an eye on her using the iPad while in the same room with her.

While Codea is a great programming environment, it's not the the best learning environment. I tried coming up with my own lessons, and I also found some Codea tutorials online, but nothing was really clicking. She did spend some time just exploring and playing with Codea, but that only goes so far.

And then we found Khan Academy

Khan Academy has video lessons and an integrated code editor. Like Codea, it offers a Processing like API. There are a few nice things about Khan Academy.

First, they have a series of tutorials that my daughter is able to watch and progress through at her own pace. The tutorials are in sync with actions in the code editor, so she can pause the tutorial and experiment with the code at any point. Also nice, the video tutorials are narrated by a woman. It might seem like a minor thing but I've noticed that my daughter has picked up on the fact that the computer programmer profession is male-dominated, so any reinforcements that, yes, girls program too, is always nice.

Second, the code editor and the graphical display are side by side. You can see the effect of your code changes as you type them. Codea requires you flip between code editing and running your code.

Third, Khan Academy has gamification! You can earn achievements and badges. You can create a "spin-off" of one of the example programs, make it cooler, and then other Khan Academy users can vote on them. Turns out this is very cool for an 11 year old!

So far, Khan Academy seems to be the most perfect environment to learn computer programming that we've found yet.

Since Khan Academy and Codea both use the Processing API, we've experimented with moving code between the two environments. There are some slight syntactic differences between JavaScript (Khan Academy) and Lua (Codea) of course. Codea also has the vertical axis flipped compared to Khan Academy. Khan Academy names some things differently and has some different API methods like:

  • strokeWeight instead of strokeWidth
  • point(x ,y)
  • triangle(x1, y1, x2, y2, x3, y3)

Here's an example of how I translated the Intro to Animation lesson into Codea (point and triangle aren't used below, but they are used in some Khan Academy programs so I'm including them here just for illustrative purposes):

-- KA-Intro to Animation

-- vim: set ts=4 sw=4 et ai filetype=lua:

function setup()
    print("Hello World!")
end

function strokeWeight(weight)
    strokeWidth(weight)
end

function point(x, y)
    line(x, y, x, y)
end

function triangle(x1, y1, x2, y2, x3, y3)
    myMesh = mesh()
    myMesh.vertices = {vec2(x1,y1),vec2(x2,y2),vec2(x3,y3)}
    myMesh:draw()
end

function initKhan()
    -- Khan Academy setup
    -- set a default stroke "weight" (codea calls this width) and color
    stroke(0, 0, 0, 255)
    strokeWeight(1)

    -- translate and scale into Khan Academy coordinate system
    translate(0, 400)
    scale(1, -1)
end

function draw()

    initKhan()
    -- this is the draw loop! everything inside this
    -- function will be run over and over again.
    background(252, 255, 214)
    noStroke()

    -- position of the car
    x = 10

    -- draw the car body
    fill(255, 0, 115)
    rect(x, 200, 100, 20)
    rect(x + 15, 178, 70, 40)

    -- draw the wheels
    fill(77, 66, 66)
    ellipse(x + 25, 221, 24, 24)
    ellipse(x + 75, 221, 24, 24)

end

So that's where we are so far. I'm hoping we can work toward a project this year, like making a mobile app game or something.

Saturday, March 09, 2013

How do you set up for multi package Python development?

Or, how do I use my models outside of a Pyramid application?

I've developed a little Pyramid app as a mobile backend version of FuelMyRoute.com. As natural, I've defined the database models inside the application. But, now I want to develop a new gas price data importer piece of code that will live outside of the Pyramid web application. This importer will need to make use of the same models as defined in the Pyramid app. So what to do?

Well, ideally I would have the models defined outside of the Pyramid app in its own package. So I would end up with three packages: the Pyramid app is a package, the models are a package, making the importer code a third package. The importer package would depend on the models package, just like the Pyramid app.

Now, in Python there are lots of mechanisms to pull this off. First we could just manipulate the sys.path in each package to pull in the needed dependencies. Second we could set a PYTHONPATH to pull in the other packages. But the way I decided to do it was to install the packages into a virtual environment. I got this idea from the Pyramid tutorial/documentation where it has you do a python setup.py develop into the virtual environment for the app. python setup.py develop is basically a way to symlink in your package into the system path of the virtual environment.

Here are the three packages. Each package name is prefixed with gptp-, which is just an codename for an earlier version of FuelMyRoute.com.

  1. gptp-models - Defines the SQLAlchemy models
  2. gptp-pyramid - The Pyramid application, depends on gptp-models
  3. gptp-importer - Gas price data importer code, depends on gptp-models

Here's the setup.py file for the gptp-models package:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from setuptools import setup, find_packages

# http://pythonhosted.org/distribute/setuptools.html#basic-use
setup(
    name='gptp-models',
    version='0.1dev',
    packages=find_packages(),
    install_requires=[
        # <0.8 includes stupid stuff like 0.8b2, so have to defensively prevent
        # alphas, betas etc. http://stackoverflow.com/a/14405269/1419499
        'SQLAlchemy<0.7.99',
        #... additional dependecies
        ]
)

This is just about as barebones as it can get for a setup.py. I believe that only name, version and packages are required. This package depends on SQLAlchmey, amongst other things, so I've included that to illustrate how to declare dependencies.

Here's the setup.py for gptp-pyramid:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import os

from setuptools import setup, find_packages

here = os.path.abspath(os.path.dirname(__file__))
README = open(os.path.join(here, 'README.txt')).read()
CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()

requires = [
    'pyramid<=1.3.99',
    'SQLAlchemy<=0.7.99',
    'transaction',
    'pyramid_tm',
    'pyramid_debugtoolbar',
    'zope.sqlalchemy',
    'waitress',
    'gptp-models',
    # .. more dependencies ..
    ]

setup(name='gptp',
      version='0.0',
      description='gptp',
      long_description=README + '\n\n' +  CHANGES,
      classifiers=[
        "Programming Language :: Python",
        "Framework :: Pylons",
        "Topic :: Internet :: WWW/HTTP",
        "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
        ],
      author='',
      author_email='',
      url='',
      keywords='web wsgi bfg pylons pyramid',
      packages=find_packages(),
      include_package_data=True,
      zip_safe=False,
      test_suite='gptp',
      install_requires=requires,
      entry_points="""\
      [paste.app_factory]
      main = gptp:main
      [console_scripts]
      initialize_gptp_db = gptp.scripts.initializedb:main
      """
      )

There's more going on here, but most of the extra stuff is stuff that was auto-generated by Pyramid. The important thing is that on about line 18 the package gptp-models is listed as a required dependency.

Finally we have gptp-importer's setup.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from setuptools import setup, find_packages

# http://pythonhosted.org/distribute/setuptools.html#basic-use
setup(
    name='gptp-importer',
    version='0.1dev',
    packages=find_packages(),
    install_requires=[
        'gptp-models'
        ]
)

About what you might expect at this point.

So now with my three packages set up, I can proceed with setting up a virtual environment. I'm using Python 3.3 so I set up the virtual environment with the built in pyvenv command and install distribute and pip into it, using this script, named bootstrap-pyvenv:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/sh

# Create Python virtual environment
pyvenv $1

# install distribute and pip
curl -O http://python-distribute.org/distribute_setup.py
$1/bin/python distribute_setup.py
$1/bin/easy_install pip

# Clean up
rm distribute*

So I run:

bootstrap-pyvenv gptpenv

Then, activate the environment and run python setup.py develop in each package, starting with gptp-models of course:

source gptpenv/bin/activate
cd gptp-models
python setup.py develop
cd ../gptp-importer
python setup.py develop
cd ../gptp-pyramid
python setup.py develop

Okay, so that's set up. But how do I get Pyramid to use my models that are defined in a separate package? Here's what my models.py looked like before I made my changes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from sqlalchemy import (
    Column,
    DateTime,
    Float,
    ForeignKey,
    Integer,
    String,
    types,
    )

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.orm import (
    relationship,
    scoped_session,
    sessionmaker,
    )

from zope.sqlalchemy import ZopeTransactionExtension

from datetime import datetime
from shapely.wkb import loads
from struct import pack, unpack

from geo.proj import ProjectedPoint, utm_projector

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

# ... start defining my models here ...

I moved my models into gptp-models/models.py and updated the pyramid models.py to be:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import models
from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    )

from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = models.Base

The import models imports my models from the gptp-models package (could probably be namespaced better, but this suffices for now). The line

1
Base = models.Base

is just a convenience so that I can continue to import Base from the Pyramid models.py.

That's basically it. I just need to update the imports elsewhere in the app. For example, in my views.py I had

1
2
3
4
5
6
7
# ...
from .models import (
    DBSession,
    GasStation,
    GasPrice,
)
# ...

which becomes:

1
2
3
4
5
6
7
8
9
# ...
from .models import (
    DBSession,
)
from models import (
    GasStation,
    GasPrice,
)
# ...

Other Approaches to the Multiple Python Packages Problem

I asked about what people do in this situation on Twitter:

Pradeep Gowda replied with

I think that would probably be the better way to go for a larger project and multiple developers. For what I'm doing, since it's just me and a side project, the setup described above is sufficient.

Pradeep shared the following benefit of going the local pypi approach:

He also shared this link on how to set up a local PyPI.

So that's another option that is worth considering too.

Sunday, February 10, 2013

CodeMash 2013 Part II: Sessions

In my previous post, CodeMash 2013 Part I, I covered the "precompilers" (that's CodeMash-ese for "tutorial" or "workshop") that I attended. The last two days of CodeMash, Thursday and Friday, are devoted to technical talks and presentations (although there's a lot more going on than just technical talks like open spaces, KidzMash (for the younger geeks), the bacon bar, etc.).

Continuing with my plan from the first two days I decided to mostly focus on

  1. Mobile web development/PhoneGap
  2. Javascript MVC Frameworks/Single page applications

Thursday 9:45 AM: Performance, Productivity. Pick Two with Dart

Seth Ladd gave a talk on Dart. It's an ambitious project to create a new way of building web applications. At the heart of it is Dart, a optionally statically typed language that is reminiscent of Java and that can compile down to JavaScript.

My overall impression is that Dart is a lot to chew off. Seth showed what the JavaScript code looks like that Dart can compile to. I found it rather bizarre looking, not at all like the nice output you get with CoffeeScript. One question I had going in is if you can call third party JavaScript libraries. You can but you have to use some sort of bridge to do so (which he didn't have time to show). With CoffeeScript, it's trivial to call third party libraries.

So it's interesting and the tooling is pretty cool, it just feels like you'd end up cutting yourself off from a big chunk of the web community going with Dart.

Thursday 11:00 AM: Machine Learning - Understanding the Past

This was a fantastic talk by Seth Juarez on using machine learning techniques to help make sense of your data. He went over unsupervised learning methods like K-means clustering and principal component analysis. He's put his slides up here in case you're interested.

Thursday 1:45 PM: HTML 5 and the Great Mobile Debate

This was a great talk about the current state of developing cross platform mobile applications and whether it makes sense to develop those apps using HTML 5. Andy Glover gave this talk; he wrote up a blog post covering his main points.

In summary, Andy suggests not using HTML 5 and if you want to target multiple mobile platforms with a single codebase, he suggests you look at one of the cross platform frameworks such as Appcelerator, Xamarin, Corona or Unity. The main points of his argument are

  • mobile browsers are even more fragmented than native APIs. Here he pointed out how even the most advanced mobile browsers don't support all of HTML 5 (he used conformance testing tools like rng.io and fmbip.com). I'm not sure I agree on this point; there's an awful lot in HTML 5 and a browser doesn't need to support all of it to be perfectly fine to target with a mobile web app. But he does have a point that simply making a mobile web app doesn't mean you don't have to deal with fragmentation issues.
  • HTML rules on the desktop because it's easier to distribute an app as a web application than as a native blob of bits. The web's strength on the desktop doesn't matter on mobile because on mobile the software distribution problem is a solved problem.
  • Consumer apps with a great user experience (examples he used were Flipboard and Angry Birds) have set the bar really high for the UI quality of a mobile app.

The talk was very thought provoking, although I think HTML 5 and PhoneGap are perfectly fine for an app in the enterprise or B2B space. I don't think I would use HTML 5 to make a game or a consumer app (well, maybe as a kind of prototype of a consumer app), but I do think it has a place in the enterprise.

Thursday 3:35 PM: Lessons from Two Years of Backbone.js

Chris Nelson presented on lessons learned using Backbone.js. This was a packed talk that I was unfortunately late to so I didn't take the greatest notes. I also can't find his slides online. Wish I could find them because he had some interesting material on stuff like how to do composite views in Backbone.js. Lesson learned: show up early to get a good seat :)

Thursday 4:50 PM: Client/Server Apps with HTML5, Play, CoffeeScript, and More

James Ward gave a whirlwind tour of a very modern web application development stack using Play, CoffeeScript, Bootstrap and more. He tore through the slides but 1 hour just wasn't enough time to complete the whole thing.

Friday 10:45 AM: The Native/Mobile Web: Beyond the Basics with PhoneGap

JC Grubbs gave a talk on some of the real world concerns with building a PhoneGap app, like how to deal with performance issues or how to create a build process to target multiple mobile platforms. His slides are here.

My notes:

  • Structuring a project
    • src - source code
    • www - js and css get concatenated to this directory
    • ios
      • www -> ../www/ - symlink in the www folder to the respective container app
    • android
      • www symlinked likewise
  • Typical stack
    • Zepto/JQuery
    • backbone/underscore
      • template rendering performance
    • moment.js / gui tools / data libs / JQuery Mobile
    • jasmine / rake-pipeline / sass / ejs
  • GUI Toolkits
    • JQuery Mobile
    • iUI
    • Sencha Touch
    • Ratchet
      • this is actually a prototyping toolkit but JC pulled out the UI stuff from it to create mobile web UIs
    • Media queries
    • Icon Fonts
      • scales automatically
      • icomoon - Chrome app for browsing icon fonts
    • Flex box / fluid layout
    • scrolling
      • webkit-overflow-scroll: touch
      • avoid scrolling libraries
    • iOS Bounce
      • you can turn this off with a PhoneGap setting
  • Local vs Remote data
    • use Backbone sync plugins that handle saving dirty records and flush when online
  • Debugging
    • test in browser - there are PhoneGap shims
    • iOS remote debugger
    • debug.phonegap.com - weinre
    • JSlint
  • Testing
    • Jasmine / QUnit
    • Capybara / Cucumber
  • Performance
    • Tap vs click
      • use touch events
    • JS vs CSS animations
      • use CSS animations
    • clean the DOM
    • Page everything - no infinite scroll
    • Web workers (iOS 5.1+)
    • Plugins
      • can use them to get native performance
  • Deployment
    • TestFlightApp
    • PhoneGap Build
  • Backbone/JQuery Mobile
    • use JQuery Mobile for styling/UI, but disable ajax based navigation
    • backbone router is flaky on iOS

Friday 1:45 PM: Building Rich User Experiences Without JavaScript Spaghetti

This was a talk on using some design patterns to make more maintainable JavaScript code. The speaker Jared Faris and if you're interested, I believe the same talk is available to view online at InfoQ. Here are my notes from the talk:

  • Decouple code that has multiple concerns
  • Write small, discrete bits of code
  • Think of UI components as separate JS objects
  • put DOM stuff in separate layer
  • Mediator pattern
  • Observer pattern
  • Pub/sub - Postal.js (Event routing)
  • Chrome has a de-minifier
  • EJS templates
  • JQuery doTimeout plugin - a better setTimeout
  • Signature Pad - capture a signature in a HTML5 canvas
  • SimpleDialog2 - better modal dialog for JQuery Mobile

Friday 3:35 PM: AngularJS: The HTML of the Future

This was a very interesting talk for me because I really hadn't seen any AngularJS before. John Lindquist demonstrated how to create your own directives which basically is a way to create your own HTML elements.

What else?

Well there's the waterpark, right? You can't go to CodeMash and not spend some time in the waterpark. The family and I had a good time there on Thursday night.

Also, there's KidzMash, a parallel conference with cool computer programming activities for kids. I took my youngest daughter (7 years old) to one session where she learned how to "program" me by creating a list of simple instructions (step, left, right) that I would then follow on a grid that had been taped into the floor. My oldest daughter (10 years old) has been programming in Scratch, Python and a little Lua and JavaScript recently, so I took her to a talk on using a Windows Kinect device to create programs that respond to gestures. That was a lot of fun too (now she wants a Kinect!).

All in all, it was a great conference. I learned a lot, and I expect I'll be digging deeper into some of things I was exposed to over the next couple of months. I hope I get to go back to it next year.

Sunday, January 27, 2013

CodeMash 2013 Part I: Precompilers

This year I went to CodeMash, a fun, eclectic software development conference held at the Kalahari Resort in Sandusky, OH. I learned quite a bit and had a great time. There were so many good sessions that it was hard to decide which ones to go to. To help me decide I decided to focus in on two areas I'm currently interested in:

  1. Mobile web development/PhoneGap
  2. Javascript MVC Frameworks/Single page applications

The first two days of the conference, Tuesday and Wednesday, were devoted to half and full day workshops/tutorials that CodeMash calls Precompilers.

Tuesday AM: PhoneGap tutorial

My first precompiler on Tuesday was Developing Mobile applications with PhoneGap by Ray Camden. You can find the presentation and the labs on GitHub.

The highlight of this presentation was the discussion on how to test mobile web applications and the various tools that are available.

Probably the coolest one I saw was Ripple. Ripple is a mobile web application emulator that can run as a Chrome extension. You can simulate different devices and different frameworks (I believe it can emulate the PhoneGap API so you can test your code to some extent). You can change network settings and geolocation data. You can also fire off mobile specific events like deviceready. The user documentation is hosted on Blackberry's website Ripple is currently an Apache Incubator project.

There were some other tools that looked interesting and were demoed but I haven't yet played around with them. First, you can connect the desktop Safari browser to the mobile Safari browser running in the iOS Simulator. You can use all of the normal Safari developer tools but they work with the web page in mobile Safari. Very cool. The second tool I'll mention is Edge Inspect which takes that same idea and extends it so you can remotely inspect mobile web code running on an actual device. Edge Inspect is a freemium service so you can try before you buy and perhaps get a lot of use out of it without spending a dime.

Finally I'll mention weinre which wasn't mentioned (and to be honest I've not used it but have heard of it) but is in the same vein and is a free and open source project.

Tuesday PM: Choose Your Own Application

From the guys at SRT Solutions comes the very fun Choose Your Own Application!. You should seriously check this out. Remember those Choose Your Own Adventure books from when you were a kid? This is the same idea except you choose your software stack. You can choose to use JavaScript or CoffeeScript, Backbone or Knockout, ASP.NET or Rails or Node.js, and finally you can choose to deploy to Heroku or Azure.

I chose to use JavaScript with Backbone with a Node.js backend, deployed to Heroku. The app they have you create is a StackOverflow like web site where users can submit questions and vote on them (very simplistic implementation). One cool part of the design is that it uses Socket.IO to push updates via WebSockets (which ended up falling back to long polling on Heroku as I recall). You can open up two browser windows, create a question in one window and see it update in the other window. It's a good way to see the power of a Javascript MVC framework like Backbone; the model is updated in the background and the view immediately reflects it.

If you want to see what the code looks like, I've pushed my code to GitHub: https://github.com/machristie/chooseyourownapplication-bbjsnodeheroku. I found Heroku ridiculously easy to get set up with and a really simple and powerful way to deploy out a website. The combination of GitHub and the free usage tier of Heroku is especially nice for an exercise like this because you can easily publish the code and the working implementation for something you are learning or some new approach you are trying and would like feedback on.

You can see my running implemenation here http://cyoa-mchristie.herokuapp.com/.

Wednesday AM: Atomic Scala

This session was presented by Dianne Marsh and Bruce Eckel. The idea was to present concepts in Scala one at a time (or one "atom" at a time). I think they're intended audience is first time programmers or at least programmers who don't have a Java background. In any case the pacing of the tutorial was way too slow, especially for a session with an advertised level of intermediate. They were kind enough to give us a pre-publish version of their book, Atomic Scala, and going at my own pace I would probably find it useful for learning Scala. We'll see.

Wednesday PM: Real-world JavaScript Testing

The Atomic Scala session was actually full day but I skipped out on the second half and went to Justin Searls' session on real world JavaScript testing. This was a great session that combined presenting on lessons learned in the wild with a fun hands on lab. His slides and the code for the lab are up on GitHub. The talk started with how to use Jasmine, a JavaScript unit testing framework. They then added to this by featuring various jasmine addons and other techniques for making writing unit tests easier:

  • jasmine-fixture for easily adding elements to the DOM that are expected by the tests
  • Using Coffeescript which allows for a cleaner syntax making the tests more readable
  • jasmine-given for "Given", "When", "Then" style testing.
  • lineman is used to automatically compile CoffeeScript with lineman run and automatically run your tests (or specs) with lineman spec. The nice thing here is that the testing framework was also remote driving a Chrome browser window (or headlessly) to re-run the tests and display the test results. This gave immediate feedback: write a test, save, test is run and status displayed; update production code, save, test is re-run. You can see what working with lineman is like by watching this screencast:

This was an extremely nice and productive setup. We paired up and worked on creating a test for a fibonacci calculator web application. It was tough since I didn't know CoffeeScript or Jasmine, but very rewarding as it helped me see how I would actually use this to test real code. I've posted my solution on GitHub.

TODO: I want to dive more into this setup and see how it is actually working. There are a lot of moving parts here and I'm not familiar with most of them. But I'm hoping I can use this setup or one like it for my JavaScript code.

Conclusion

Well, the first two days were kind of mentally exhausting! But it was fun to be thrown into the deep end and have to figure out a bunch of stuff using frameworks and languages that I'm not familiar with. Definitely worth it to do the Precompilers if you are going to CodeMash.

Next week I'll blog about the other two days of CodeMash.

Sunday, November 11, 2012

Pyramid, MySQL, and Python 3

For the impatient

Assuming you have Python 3 installed with distribute and virtualenv and also MySQL, create a virtualenv

virtualenv --no-site-packages --distribute myenv

Then activate your environment

source myenv/bin/activate

Create the following requirements file (save to requirements.txt):

#oursql==0.9.3 but need special Python 3 build https://bugs.launchpad.net/oursql/+bug/1051512
https://launchpad.net/oursql/py3k/py3k-0.9.3/+download/oursql-0.9.3.zip
pyramid==1.3.4

Then run:

pip install -r requirements.txt

The longer version

I'm currently working on an Android app version of FuelMyRoute.com. The website currently uses TurboGears (version 1.0.something I'm afraid). I thought about using the website as the backend for the mobile app but wanted the freedom to experiment and potentially do things much differently in a separate mobile backend. I also wanted to work on a more modern stack. The TurboGears team has essentially joined forces with the Pyramid team, so I took a look at Pyramid. I liked what I saw, and with version 1.3 it can run on Python 3.

So let's see if we can get a Pyramid/SQLAlchemy/MySQL site working on Python 3. The first thing I ran into is that it was hard to find a good Python MySQL driver that works on Python 3. For years I've been using the trusty if somewhat antiquated MySQLdb Python module. It looks like development has slowed to a halt on MySQLdb so I took a look at alternatives.

First alternative I explored was MySQL Connector/Python. I like that Oracle is sponsoring the development and it is a pure Python library. However, I hit upon a major bug that made it a deal breaker. I've subsequently learned that this bug has been fixed so I'll probably give it another try in the future.

Second alternative I looked at was OurSQL. I'm not sure if it is a fork of MySQLdb, but it seems fairly similar. It does have some benefits over MySQLdb , not the least of which is Python 3 support. One catch is that you can't just "pip install oursql" under Python 3. There is a distinct branch of code for the Python 3 support. To install the Python 3 branch of OurSQL you can use the requirements.txt file above, or for just OurSQL you can do

pip install https://launchpad.net/oursql/py3k/py3k-0.9.3/+download/oursql-0.9.3.zip

I also ran into an issue with Python 3 and one of Pyramid's dependencies, zope.interface. That's why zope.interface is listed in the requirements.txt file with version 3.8.0. But this is fixed now https://github.com/Pylons/pyramid/issues/604. Just make sure you get the latest 1.3 bugfix release. At the time of this writing, that is 1.3.4.

To get started with SQLAlchemy, just run the following to create a Pyramid scaffold project using SQLAlchemy:

pcreate -s alchemy MyProject
More info here: http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/project.html

Saturday, July 09, 2011

How to dynamically change the Tweet Button's tweet text

Looked around on the internet for a way to dynamically change the tweet text of the Tweet Button, but didn't find a good solution. Most of what I found involved setting the text when the page is being rendered server side or client side. But what I need for FuelMyRoute.com is a way to dynamically update the tweet text based on the user's activity in the page after it has rendered. (Specifically, based on the route provided by the user, I want to update the tweet text to say something specific about how much the user has saved per gallon of gas.)

The solution I went with uses the iframe Tweet Button, and basically you just need a bit of javascript to manipulate the URL that configures the iframe Tweet Button. I went with the iframe Tweet Button over the javascript Tweet Button because the javascript one manipulates the DOM and replaces your anchor tag with an iframe, etc. You could theoretically dynamically change the tweet text for the javascript Tweet Button but it would be a little brittle, being dependent on how the javascript Tweet Button renders itself.

Enough jibber jabber, on to the code! You start by adding an iframe Tweet Button to the page:



Then you need this function which updates the text parameter of the iframe Tweet Button's query string (which of course will cause the button to reload):



You can try it out right here. Click on the Tweet Button below and preview the message, which should be "Replace Me":



Now click on the button below which will call updateTweetButtonText('I just dynamically updated the text of a Tweet Button!'); and then click on the Tweet Button again to see that the preview tweet has been updated:



Tuesday, December 08, 2009

A Review of Homeschooling

Imagine you are a parent of a child attending a school. Your child brings home one of her exams and on this exam is a question the answer to which is marked incorrect. Your child asks you why it’s incorrect. To the best of your ability you can’t tell why it is incorrect. It seems plainly correct. So you tell her so and hope that this will help her feel better about her results. Normally, that would be it, but it just so happens that this mark has caused her to not make honor roll. Blissfully assuming the teacher just made a mistake you call the teacher to see about correcting the error. But you get stonewalled. Eventually you are granted an audience with the principal. You explain the situation, and, to your surprise, the principle replies:
Yes, the answer is correct. But that answer is a fourth-grade answer, and your daughter is only in the second grade. She isn’t supposed to know that yet.
Stunned you say “Excuse me?” The principal continues:
It wouldn’t be fair to the other children if we gave her credit for the answer. You see, you are a devoted couple, married, and you help your daughter study, and there are children in her class whose parents are divorced, or who don’t speak English. Your daughter is ahead of them because you work with her. It wouldn’t be fair to the others if we gave her credit for what she knows as a result of that advantage.

Now, what would you do? For Gregory and Martine Millman, as they recount in their book, Homeschooling: A Family’s Journey, this was their tipping point to take their child out of school and begin an experiment in homeschooling. Their book is part memoir of a homeschooling family and part defense of the legitimacy of homeschooling. They share and reflect on their personal philosophy towards homeschooling, a philosophy that encourages flexibility and spontaneity and that is grounded in the recognition of the importance of the relationship between a student and a teacher.

They spend a considerable portion of the book defending their decision to homeschool their children while also decrying the current state of public schools. As a homeschooling parent, much of this felt like preaching to the choir. But I related quite well to the fact that they continually suffered from doubts as to whether they were doing the right thing, so it is very understandable that they spend so much effort making a case for homeschooling. There also went on a myth busting spree, and there were a few myths that surprised me. For example, they cite studies that show that there is no correlation between expertise in a subject area and the ability to teach it. Another study they cite showed that whether a parent had a teacher’s license or not had no effect on a student’s test score. I looked up that study and found that it also found no correlation in test scores between families that use a “full service” curriculum (this is basically, I gather, a “school in a box” type thing with complete curriculum materials and even scripts for the “teacher”) and those that do not. I found this interesting because when I talk to other people about our decision to homeschool I’m often met with a response like “Oh, I couldn’t do that” and I explain, almost as if I’m making an excuse for myself, that my wife, Tracy, is a former, licensed teacher. But the Millman’s argue, and the studies show, that anyone who wants to homeschool can.

Their philosophy on homeschooling is to create an environment where there is freedom to explore what pique’s the child’s interest. Of course, there is structure, but there is also the flexibility to take advantage of opportunities. For example, they mention a time when some workers came to their house to take away a tree that had fallen down in a storm. Since it was a fairly noisy undertaking, it would have been hard to stick to the schedule. So, they made a learning opportunity out of it. They looked at and noted not only the mechanics of the operation but also the social dynamics of the workers and their boss.

Another important aspect of their philosophy is to provide personal attention and develop the whole child. They place a lot of emphasis on the relationship between the student and the teacher. This relationship is grounded in the practice of emulation; the student emulates the teacher in learning how to learn. The importance of relationship is manifold. For example, there is also the relationship to the subject matter being studied, to really appreciate it for its own sake and not as a means unto an end; in schools, that end is too often a standardized test. They point out that in schools the student learns how to relate to the institution, what its rules are and how to “work the system”, but this kind of relationship is obviously not academically sustaining.

This is not a handbook on how to homeschool; they present a simple homeschooling philosophy that they have developed within their family which they illustrate with several anecdotes. But there is some concrete homeschooling advice. Chapter 3 contains some curriculum advice, materials they have used and found useful, for several academic subjects. But perhaps the most practical chapter is the one on choosing a college. They offer several insights into the admissions process from the perspective of homeschoolers. For example, colleges often require that they have a transcript with grades and such although ultimately they don’t trust the grades reported by homeschooling parents. There’s a list of 18 tips on how to better navigate the admissions process and when our children are reaching that stage of life I know that this chapter will be a handy reference. I also liked how they look at going to college as really “joining” a college, for life and as a family.

Overall, it was a very inspirational book for me as a homeschooler. I was inspired by their adventurous spirit in seeking out educational opportunities wherever they may be. Their holistic approaches to education, their value of developing the whole child, and their emphasis on the importance of relationship have encouraged me to incorporate those same ideas in our own homeschooling.

Sunday, October 04, 2009

New Music: Company of Thieves, Matisyahu and more

I listen to WFPK radio online during the workday and All Songs Considered podcast during my work commute. They have both introduced me to some great music, and here are some of my recent favorites. Hope you enjoy them as much as I did.

Pressure by Company of Thieves



One Day by Matisyahu



Never Forget You by Noisettes



Animal by Miike Snow



40 Day Dream by Edward Sharpe and the Magnetic Zeros



Border Reiver by Mark Knopfler

Saturday, June 06, 2009

Combining blogs

Summary: I'm combining my personal and professional blogs. All my posts will go into this blog. If you only care to get my technology related posts, please update your feed reader to subscribe to just the Technology Related Entries.

A couple of years ago, when I started blogging, I decided (as I had seen others doing) to create two blogs: one for blogging on work related things and one for blogging about everything else in my life. The main reason for having two blogs was so that people who are interested in my technology, work-related writings (i.e., coworkers and colleagues) could subscribe to and receive only those and likewise for my personal blog posts. In the meantime, however, Blogger.com has added the labeling feature which allows me to create feeds of subcategories of this blog.

So going forward every technology related blog post will be tagged with the technology label. I've created a feed just for these posts. Otherwise, if you subscribe to this blog in the normal way, you'll get all entries. Maybe I'll create other feeds for other sub-categories, but for now I'll leave it at


What will I be writing about going forward? Without making any firm commitments, here are some things that I would like to post about in the near term future
  • Adobe Flex (which I've been learning about and using at my current job)
  • Homeschooling and parenting
  • Book and movie reviews and discussions
  • I've become interested lately in better code design and also software development processes, so I hope to blog on what I've learned and will be learning about these in the future
  • Python, specifically the TurboGears framework
Your feedback and comments are welcome. Here's to writing more blog posts and writing them more regularly!

Tuesday, November 04, 2008

How to use custom ant tasks in a WTP generic ant publisher

Before creating the Eclipse Pluto Server Plug-in, I had an Ant script to publish my portlets to a Pluto server. That Ant script used the Maven2 ant tasks to download the needed Pluto ant task jar and its dependencies. This Pluto ant task is needed to rewrite the portlet's web.xml so that it contains the Pluto server's invoker of the portlet. When I first created the plug-in and needed a way to get the Pluto ant task jar, I looked for how to include it with the plug-in jar but I couldn't figure out how to expose it to the Pluto ant publisher script I created as part of the WTP generic server definition. So, I used the Maven2 stuff I already had, and it worked pretty well for me. However, it was never ideal.

Recently, actually by accident, I figured out how to make ant tasks in a plug-in available to a WTP ant publisher. I stumbled upon the Eclipse ant extension point documentation, specifically, the part about Extra Ant Classpath Entries. Not sure how I missed this before, but it's basically all right there. There's also the org.eclipse.ant.core.antTasks extension point which allows you to expose ant tasks to your ant scripts in Eclipse. Since it wasn't immediately obvious to me at first, I thought I would post how I got it working. It's actually quite simple once you know what extension points to work with.

Here's what I added to the Pluto Server Plug-in plugin.xml to define the Pluto ant task

<extension point="org.eclipse.ant.core.antTasks">
<antTask name="pluto.assemble"
class="org.apache.pluto.ant.AssembleTask"
library="lib/pluto-ant-tasks-1.1.6.jar"
eclipseRuntime="false"/>
</extension>


But of course this ant task has dependencies. To make it's dependencies available to it, you'll just need to add extraClasspathEntries


<extension
id="pluto-assembletask-classpath"
point="org.eclipse.ant.core.extraClasspathEntries">
<extraClasspathEntries library="lib/castor-1.1.1.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/cglib-full-2.0.2.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-beanutils-1.7.0.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-cli-1.0.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-digester-1.8.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-io-1.3.1.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-lang-1.0.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/commons-logging-1.0.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/commons-logging-api-1.1.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/pluto-descriptor-api-1.1.6.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/pluto-descriptor-impl-1.1.6.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/pluto-util-1.1.6.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/xercesImpl-2.6.2.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/xmlParserAPIs-2.6.2.jar" eclipseRuntime="false"/>
</extension>


I'm not quite sure why, but the eclipseRuntime attribute needs to be set to false to get this to work. The docs say

eclipseRuntime - indicates whether this extra classpath entry should only be considered for builds run in the same VM as Eclipse. The implied value is true, when not specified.

So I can only guess that this means that the WTP ant publisher doesn't run in the same VM as Eclipse? Anyhow, I tried it both ways, and it only worked with the value of false.

From my ant publisher script, nothing special, I just reference the pluto.assemble task (I gave it that name). Here's the snippet where I use it:

<target name="assemble" if="portletxml.exists">

<pluto.assemble webxml="${module.dir}/WEB-INF/web.xml"
portletxml="${module.dir}/WEB-INF/portlet.xml"
destfile="${webxml.with.portlet.mapping.file}" />
</target>

Previously I had to define the task with a <taskdef> tag, but I no longer need that.

Pluto Server Plug-in 1st beta of 1.0.0 released

This past weekend I created a 1.0.0.b1 release of the Eclipse Pluto Server Plug-in. Biggest change is that I got rid of the hack I had in there using Maven to download the Pluto ant task and dependencies needed to publish a portlet to Pluto. I now bundle the ant task jar and its dependencies with the plug-in (a topic for a future post). Having Maven do the download was something that would work most times but had problems. For example, some users have not been able to get the plug-in to work with a proxy server setup (see issue #3).

It likely won't get picked up as an update in Eclipse; you'll need to go into the Update Manager and install it as a new feature. And don't forget to use http://pluto-server-plugin.googlecode.com/svn/trunk/pluto.server.update as your update site. If you try it out, let me know. I'd like to make the 1.0.0 release soon.

Saturday, August 02, 2008

Could not publish to server NPE bug fixed!

I finally had some time to sit down and try to figure out the "Could not publish to server NPE bug". Turns out to be a bug in WTP 2.0.2, bug #219627. The WTP team released a patch and then later they made a full 2.0.3 release. However, if you download the latest version of Eclipse Europa (for JEE), it still has the older 2.0.2 version of WTP. Which I believe explains why there have been so many reports of this problem.

So the fix is to run the update manager in Eclipse and get the most recent updates for WTP. I confirmed this by reverting my Eclipse config to WTP 2.0.2 and was able to reliably reproduce the issue. Reverting back to WTP 2.0.3 got the deploy to Pluto working again.

I added a FAQ page for the project with a FAQ also explaining the issue. I also verified that the Pluto server plug-in works in Ganymede.

Many thanks to campi, by the way. I basically ran a Google search based on the stack trace campi posted to find others who had run into the same issue but with a different plug-in. And that eventually got me to the Eclipse bug and the resolution.