Stats.dart

Posted

This past weekend I attended the Silicon Valley incarnation of the Happy Hour global DART hackathon. On Friday night, there was a short presentation, pitches, and team formation. After dropping off one of my teammates at the Caltrain station, I was itching to code something in Dart as a ramp-up to the large amount of coding I knew I'd be doing on Saturday. I decided to port Stats.js to Dart.

Stat.js is a performance monitor that allows you to determine the frame rate and number of milliseconds it takes to render your scenes. It's a great tool to have when you are creating animations with Canvas2D or WebGL. Stats.dart is a more Dart-y version. It was completed in a couple hours on Friday night and Saturday morning thanks to Dart's familiarity.

To use it, instantiate a Stats object by calling new Stats() somewhere in your code and call the update() function in your render loop.

Below we can see screencaps of the FPS and MS calculations

Stats.dart FPS Display Stats.dart MS Display

As this was a quick hack, I will probably be continually cleaning up some things.

Github: https://github.com/jwill/stats.dart

Behaviorial Driven Development with whenever.js

Posted

There are some things I have seen in my developer life that have totally bewildered me. Some of these things were jarring just because of their newness, others never lost their feeling of being a bad idea. Whenever.js is one of the latter. Whenever.js, surprisingly not a testing framework, takes Behaviorial Driven Development (BDD) out of the testing realm and brings it into development.

Instead of writing simply JavaScript code, you get to write conditions, linking code, AND JavaScript code. Below is a behavior that does nothing by itself but describes the conditions under which you should change the text on a button.

    whenever('Click Me!').is('clicked').then('Change the text to "Clicked!"')

Next you have to link from the behavior to HTML elements. The following snippet links 'Click Me!' with an anchor tag decorated with a click-me class.

    whenever.definitions.add({
      'Click Me!': 'a.click-me'
    })

Finally, you need to define the action that will be taken, in this case changing text on a button.

    whenever.actions.add({
      'Change the text to "Clicked!"': function(){
        $(this).text("Clicked!")
      }
    })

Whenever.js is interesting in the respect that it can allow designers and product people who don't code to take a more direct role in UX. It could work well with small applications, I think it quickly loses its luster on a big application. The 9 lines of code listed above can be summed up in a one-linerr

    $('#a.clickme').click( function() {
        $('#a.clickme').text('Clicked!')
    });

I like the idea of whenever.js as a cool architectural project but couldn't recommend using it in anything but demoware.

CoffeeScript Lately+ Add-on for Todo.txt

Posted

Unsatistied by the ramp-up time and extra libraries needed to run my todo.txt lately+ add-on posted in the last blog post, I decided to write a CoffeeScript version for Node.js. I thought it would avoid the ramp-up needed for groovyclient and be faster to boot.

One of the good things about building on top of Node is that you have alot of libraries to draw upon. A quick Google search surfaced a libraries to parse and manipulate dates in a way similar to Groovy and another to produce colored console text, moment and colors reqpectively. Both of the aforementioned are available as npm packages. To run our script, we need to install the dependencies along with our todotxt-coffee package.

    npm install moment
    npm install colors
    npm install todotxt-coffee

We can see that much of the heavy lifting is done by the CoffeeScript library and most of the logic below is determining what and how to print it. colors decorates strings with a properties for a base set of colors and styling(underline, bold, italic, etc) but you can create your own as well.

   printTask = (d,r) ->
        console.log d.format('YYYY-MM-DD').green + r.yellow

    printTasks = () ->
        if project is undefined
            for task in todos.list
                date = moment(task.date().toString().trim())
                restOfLine = task.raw().substr(12)

                printTask(date, restOfLine) if startDate <= date
        else
                tasks = todos.byProject(project)
                for t in tasks
                    date = moment(t.date().toString().trim())
                    restOfLine = t.raw().substr(12)
                    printTask(date, restOfLine) if startDate <= date

This and my other add-ons live here

CoffeeScript Library for Todo.txt

Posted

You may have read my posts about todo.txt (here and here) and know how much I like it. I was a little unhappy with the ramp-up time when running it in Groovy and wanted to see if I could get it faster. Also, though Groovy can be a crucial tool for Java developers, generally devs are more likely to have Node.js installed. It's the new hotness you know.

So I set about creating a CoffeeScript library for use with Node. This library closely tracks to todo.txt-gem in terms of features though it does change the function names to camel-case. When I'm less lazy, the following will find itself into a proper README file.

Installation

    npm install todotxt-coffee

Loading Tasks

    {TodoList} = require ('todotxt-coffee')

    # Instantiate list of Tasks
    tasks = new TodoList(["(A) stop +p +c", "@c @b blah +c"])

    # Load tasks from done file
    tasks = new TodoList("/Users/jwilliams/Dropbox/todo/done.txt")

Querying Individual Tasks

    task.contexts()     # => ['@context1', '@context2'] 
    task.date()             # => 'YYYY-MM-DD'
    task.priority()     # => "(A)"
    task.projects()     # => ['+project', '+project2']
    task.raw()              # => "Full text of task"

Querying Todo Lists

    tasks.byContext('@context')
    tasks.byPriority("A")
    tasks.byProject('+project')

It's on Github here.

Enjoy.

Creating an Groovy add-on for Todo.txt

Posted

Even though I've only been using Todo.txt for a couple days, I've fallen in love with it enought to figure out how to write an add-on. Because it uses a lightly formatted text file, if you have a good grasp of String manipulation and File I/O, you are off to the races.

One of the add-ons that I installed with Todo is lately. It gives you a listing of the tasks you have completed in a certain threshold. I loved the add-on but my list is a combination of my work and personal tasks. I wanted a way to be able to grab the tasks for a specific project (mainly because my team has daily standups). So I decided to build an addon in Groovy.

Making Todo.txt invoke Groovy

The snippet below shows the code for the bash script that will execute our Groovy file. I took the lately script file and adding another argument to specify the project.

    #!/bin/bash

    action=$1
    flag=$2
    project=$3
    shift

    [ "$action" = "usage" ] && {
        echo "  Recently comlpeted tasks:"
        echo "    lately+"
        echo "      generates a list of completed tasks during the last 7 days."
        echo "      Optional argument (integer) overrides number of days."
        echo "      Optional argument (String) project name."
        echo ""
        exit
    }

    [ "$action" = "lately+" ] && {
             groovy ~/.todo.actions.d/lately+.groovy "$TODO_DIR" $flag $project
    }

The lately+ Groovy script runs by parsing the argument list and then working through the done.txt file line by line to see if the completed task falls in the threshold or is from the specified project.

Colored Text with JANSI

The JANSI project allows you to use Java to print colored text and use console effects like blinking and bolding. As opposed to having to bundle a jar I used @Grab to automagically download the dependency.

    @Grapes(
        @Grab(group='org.fusesource.jansi', module='jansi', version='1.8')
    )

JANSI works well inside print and println. You print text by grabbing a static Ansi instance, setting foreground/text (fg) colors and printing text with a. You can reset to default console colors by calling reset. The following snippet prints the date in green and the task description in yellow.

    println ansi().fg(GREEN).a(date).fg(YELLOW).a(" "+restOfLine).reset()

After I got a basic script working, I started to benchmark it. Whereas the old lately command runs in 0.044-0.069 secs, the Groovy version took between 2.078s for a warm JVM and 5.918s for a cold JVM. For a command that would be run once a day, this isn't totally awful but it's not fun. So I set out see if I could get it faster.

Speeding Groovy with GroovyServ

GroovyServ is a library that runs a Groovy server in the background with a fully loaded JVM. Its groovyclient keyword is a drop-in replacement for groovy. With GroovyServ, I was able to get the run time down to 0.274s to 0.338s. You do get a hit for initial startup of the JVM but that can't be avoided if you want to use Groovy. GroovyServ pipes your content to the server and back so you lose all of the formatting from JANSI, which is a bummer. Speed doesn't come at no cost.

Full lately+.groovy file

    #!/usr/bin/env groovy
    @Grapes(
        @Grab(group='org.fusesource.jansi', module='jansi', version='1.8')
    )
    import org.fusesource.jansi.AnsiConsole
    import static org.fusesource.jansi.Ansi.*
    import static org.fusesource.jansi.Ansi.Color.*
    /*
            Enhancement of the Lately add-on
            Adds the ability to specify a project

            Arguments:
            1. TODO_DIR
            2. Number of days (optional, default is 7)
            3. Project name (optional)
    */
    def dir, days, project

    dir = this.args[0]
    //Optional
    if (this.args.size() > 1)
        days = this.args[1]
    else days = 7
    if (this.args.size() > 2)
        project = this.args[2]

    // Get Done file
    def file = new File(dir+File.separator+"done.txt")

    def today = new Date().clearTime()
    def startDate = today - new Integer(days)

    AnsiConsole.systemInstall()
    println()
    print(ansi().fg(RED).a("Closed tasks since ${startDate.format('yyyy-MM-dd')}"))
    if (project != null) 
        print( ansi().a(" for Project: ${project}").reset())
    print "\n\n"

    file.eachLine {
        def line = it
        // Get date portion
        def date = line.substring(2,12)
        def restOfLine = line - 'x ' - date
        def d = Date.parse('yyyy-MM-dd', date)

        if (startDate <= d && project == null)
            println ansi().fg(GREEN).a(date).fg(YELLOW).a(" "+restOfLine).reset()
        if (startDate <= d && project != null && line.contains(project))
            println ansi().fg(GREEN).a(date).fg(YELLOW).a(" "+restOfLine).reset()
    }

    AnsiConsole.systemUninstall()

If you want to install lately+, just drop the two files (lately+ is the name of the bash script) into your ~/.todo.actions.d directory and provided you have Groovy on your path, you're off to the races.