Posts Tagged ‘Python’

The Magical History Tour – Mashing up Google Latitude, Tropo and historical info

Monday, December 13th, 2010

The avatar you see on the map is  for John Paul Jones,  and it’s parked in front of the John Paul Jones House in Portsmouth, New Hampshire. If Admiral Jones were still alive, he could dial my Moveble History app, and let Wikipedia read to him about the house that bears his name . He could then press any key to hear about the next closest site, from the National Register of Historic Places (NRHP). But since he’s not, we’ll just let him stay parked there to offer a  demo to any passing Internet visitor.

This mashup follows the “moveable” paradigm I first laid out with Moveable Weather, and followed with Moveable Tides. The basic components are Google Latitude, Voxeo Tropo, and a geotagged dataset,  in this case a download of the NRHP, which we pump up by loading into a geohash.

The user interface for this mashup is extremely simple: If the user doesn’t change location between clicks, then each time he presses a key, the proximity search will cast a wider net, to find historic places that are further and further distant. However, if  he does move, then the proximity searches will begin from the new location. Plunk your Google Latitude avatar down in Times Square, or Gettysburg, and starting learning about the history around you.

I invite you to explore my source code, with associated wiki, to learn more. I’d like to give a special shout out to some of my favorite programming tools, including

  1. XSLT for wrestling XML into submission
  2. the geomodel Python module, for performing proximity searches
  3. the BeautifulSoup Python module, for wading into heavily marked-up HTML, to emerge with clean text for Tropo to pronounce

Finally, I leave you with a bit of Python code, which shows how you can get Voxeo to talk about distances in a kindler, gentler fashion, for your users:

    def get_sayable_distance (self, distance):

        miles = (distance/1000) * .62                          
        num_miles = "%.0f" % miles
        num_miles = int (num_miles)
        fraction = miles - num_miles
        if (num_miles == 1):
            mile_sing_plur = "mile"
        else:
            mile_sing_plur = "miles"

        if ((fraction < .15) and (num_miles < 1)):
            feet = miles * 5280
            feet = "%.0f" % feet
            return "about %s feet" % feet
        else:
            if (fraction < .15):
                fraction_part = ''

            if (fraction > .15):
                fraction_part = "a quarter"

            if (fraction > .35):
                fraction_part = "a half"

            if (fraction > .65):
                fraction_part = "three quarters"

            if (fraction > .90):
                fraction_part = ""
                num_miles = num_miles + 1

            if (num_miles):
                if (fraction_part):
                    say_miles = "%s and %s %s" % (num_miles, fraction_part, 
                                                             mile_sing_plur)
                else:
                    say_miles = "%s %s" % (num_miles, mile_sing_plur)
            else:
                if (fraction_part == "a half"):
                    say_miles = "a half a mile"
                elif  (fraction_part == "a quarter"):
                    say_miles = "a quarter of a mile"
                elif  (fraction_part == "three quarters"):
                    say_miles = "three quarters of a mile"
            say_miles = "about %s" % say_miles
        return say_miles

Scaling Your Twitter Support, Part 2: Triggering Alerts on Keywords

Thursday, December 9th, 2010

twitterlogo-shadow-2.jpgIf you want to scale your usage of Twitter and do more than just set up a “night service” (discussed in Part 1 and Part 1a), how about we create an app that triggers alerts based on keywords that appear in replies or mentions directed to your account?

In our Developer Jam Session webinar last week (recording and slides available), I demonstrated this app, but I thought I’d walk through it here. To use this app, you need a (free) Tropo account and you need a Twitter account to which you can attach the app.

NOTE: If you are not sure about how to link Tropo apps to Twitter, you may want to visit this step-by-step walkthrough first.

The code for this example is available from Github and you can use the raw URL if you want to get a version you can easily copy/paste.

Once attached to a Twitter account, the app will receive all replies (messages starting with your Twitter ID) or mentions (messages including your Twitter ID) and act as follows:

  • Convert the message to all lowercase for easier matching.
  • If the tweet includes the word “fail”, send out a SMS to someone so that they can know to go online and look at the Twitter stream.
  • If the tweet is a “reply” and includes the word “help”, sind back a message with a URL and send out a SMS alert.
  • If the tweet is a reply and includes the word “faq”, reply back with the URL to a FAQ.
  • If the tweet is a reply and includes the word “documentation”, reply back with the URL to the documentation.

Obviously, you could make it do more… and make it a bit smarter – for instance to also search on “docs” – but this is mostly a demo of what you can do.

Now, to use this app yourself, you’re going to need to do two things:

  1. Replace phone number with your cell phone.
  2. Replace Twitter ID (“tropohelp”) with your Twitter ID

Here is what the full source code looks like. I’m using Python, because that’s how I roll, but you could apply the same ideas in other languages.

text = currentCall.initialText.lower()

if text.find("fail") > -1:
    message("Whoa! " + currentCall.callerID + " is tweeting a fail",   {"to":"tel:+14075551212", "network":"SMS"})

elif text.find("@tropohelp") == -1:  

    if text.find("help") > -1:
        say("Tropo lets you build apps that interact via voice, SMS, IM and Twitter. See http://www.tropo.com/ for more.")
        message("Tropo help request from: " + currentCall.callerID, {"to":"tel:+14075551212", "network":"SMS"})

    elif text.find("faq") > -1:
        say("The Tropo FAQ is at https://www.tropo.com/docs/scripting/faq.htm")

    elif text.find("documentation") > -1:
        say("Tropo docs are at https://www.tropo.com/docs/")

Now lets walk through it. First, I take currentCall.initialText, which contains the tweet message, and convert it to lowercase and put it in the text variable.

text = currentCall.initialText.lower()

Next, if that tweet includes the word “fail”, I’m going to use the message command to send out a SMS to get someone to look at it. I’m using the python “find” method which will return “-1″ if the text is NOT in the string – otherwise it will return the location of the text in the string.

if text.find("fail") > -1:
    message("Whoa! " + currentCall.callerID + " is tweeting a fail",   {"to":"tel:+14075551212", "network":"SMS"})

Next I check to see if the message is a “reply”, i.e. a message directly to the Twitter account. If so, I check the message for different keywords and take actions.

The reason for not sending messages out in reply to a “mention” is that it may be harder to guess exactly what the person is looking for based purely on a keyword. With a message sent to the account (a “reply”) you have a better chance of replying with accurate info.

The way I know is by testing whether or not the Twitter ID (“tropohelp” in this case) is in the tweet. If it is a “reply”, Tropo strips out the Twitter ID from the very beginning of the tweet (allowing you to treat it very much like an IM message or SMS message).

So I am testing for the absence of the Twitter ID to show that it is a reply:

elif text.find("@tropohelp") == -1:  

    if text.find("help") > -1:
        say("Tropo lets you build apps that interact via voice, SMS, IM and Twitter. See http://www.tropo.com/ for more.")
        message("Tropo help request from: " + currentCall.callerID, {"to":"tel:+14075551212", "network":"SMS"})

    elif text.find("faq") > -1:
        say("The Tropo FAQ is at https://www.tropo.com/docs/scripting/faq.htm")

    elif text.find("documentation") > -1:
        say("Tropo docs are at https://www.tropo.com/docs/")

That’s it! A simple and easy way to test for keywords in tweets and take actions based on what you find.

Have fun with it… and if you develop some cool improvements to the app, please drop us an email or leave a comment here.

P.S. And remember the duplicate tweet issue when you are testing your app!

Scaling Your Twitter Support, Part 1a: Tweaking the “Night Service” app a wee bit

Thursday, December 2nd, 2010

If you look closely at the code for nightservice.py that I mentioned yesterday in the post about 5 sample Twitter apps (and also posted the source code to Github), you’ll see that it is slightly different. Here was the original I wrote about back in May:

from datetime import *
answer()

if datetime.now().hour not in range(12,21) :
    if currentCall.initialText.find("@stratohelp") == -1:
        say("Our offices are currently closed. We will reply to your tweet as soon as we can but in the meantime, please visit our web site at www.tropo.com")

hangup()

And here is new version:

from datetime import *

if currentCall.initialText.find("@stratohelp") == -1:
    if datetime.now().hour not in range(12,21) :
        say("Our offices are currently closed. We will reply to your tweet as soon as we can but in the meantime, please visit our web site at www.tropo.com")

Two main differences:

1. You no longer need to include “answer()” and “hangup()”. It just made sense to make those defaults. You still can include them if you have some need to do so… for instance using “hangup()” if you want to do some post-call processing after a call is terminated… but you don’t need to do so.

2. Switched the order of the IF statements. My main reason for doing this was so that I could add an “else” statement so that the app performs some action during work hours. My personal interest was that from a demo point-of-view, it’s rather lame to tweet a message to a demo app and receive, well, nothing if it is during “work hours”. The resulting code looks like this:

from datetime import *

if currentCall.initialText.find("@stratohelp") == -1:
    if datetime.now().hour not in range(12,21) :
        say("Our offices are currently closed. We will reply to your tweet as soon as we can but in the meantime, please visit our web site at www.tropo.com")
    else:
        say("Our offices are open. We'll reply back to you soon.")

That’s why I made the changes to the code. Have fun with it… and if you build a cool Twitter app on Tropo please let me know and I’d be glad to feature it here in the blog.

Want to play with building Twitter apps on Tropo? Here’s source code for 5 sample apps.

Wednesday, December 1st, 2010

twitterlogo-shadow-2.jpgIf you listened to yesterday’s Developer Jam Session, a good part of it discussed building Twitter apps on top of Tropo (slides are available). I’ve made the source code available from our Github account at:

https://github.com/tropo/tropo-twitter-samples

You are welcome to copy/paste that code into your own Tropo account and start building Twitter apps! (and Tropo accounts are free if you don’t have one already)

The five sample apps are:

  • twitter-helloback.js – A one-line “hello world” example that in reality is rather pointless, but shows all you need to do. It was written in JavaScript but could be done in any language. You can see this in action by sending a tweet to @tropohello
  • nightservice.py – An improved version of a python app I wrote about earlier this year that could be used to provide a “night service” when your staff goes home for the evening. You can try this app by tweeting to @stratohelp
  • twitter-keywordalerting.py – Scans Twitter replies or mentions for certain keywords (fail, faq, help, documentation) and then either sends someone a SMS alert or replies back with specific messages. You can try it out by tweeting to: @tropohelp
  • clubtropo.js – A simple JavaScript app that replies back with a message if you send it the correct phrase. Could be used for a contest or to let people RSVP. My colleague Justin Dupree wrote up a great step-by-step walkthrough on how to get started with this app. You can try it at, of course: @clubtropo
  • yahooweather.py – A new version of the python weather app I first wrote about back in March (and wrote later about how to tweak it for different channels). Tweet a US ZIP code to the app and it will tweet back the latest weather conditions. Try it out at: @danweathertest

I’ll probably add some more apps to the repository over time as we have some other good Twitter samples (and please contact me if you have a sample app you would like to contribute).

If you do try these out in your Tropo account, remember to watch out for duplicate tweets when you are testing. (I’ve been caught by this in testing any number of times.)

Have fun with it… and we’re looking forward to seeing what you will build with Tropo and Twitter!

P.S. Speaking of Twitter, are you following us on Twitter? We’re at @tropo, @voxeo, @phono and more…

Using One Line of Python with Tropo to Send SMS Notifications

Tuesday, November 23rd, 2010
Burmese python 2

Flickr credit: tambako

All day yesterday, when people were calling my Toddler Amusement Line app to try it out, I was getting a SMS text message on my iPhone each time someone called the app – complete with their Caller ID…

AND ALL IT TOOK WAS *ONE* LINE OF CODE!

Building off my colleague Chris Matthieu’s great post, “Get Notified When Someone Mentions You On Twitter, I simply added this one line to the end of my Tropo app (broken onto two lines here for display purposes):

message("TAL call from:" + currentCall.callerID, 
   {"to":"tel:+14075551212", "network":"SMS"})

Obviously, that’s not my real cell phone number… but you get the idea. I’m using the “currentCall.callerID” session variable and just appending that after a little bit of text. (“TAL” was my acronym for “Toddler Amusement Line”.) Here’s what the full app looked like:

import time

for i in range(0,10):
    for text in ("hi", "hello", "how are you"):
        say (text)
        time.sleep(2)

say("Thank you. Goodbye.")

message("TAL call from:" + currentCall.callerID, 
   {"to":"tel:+14075551212", "network":"SMS"})

If you want to try it out yourself… just head on over to Tropo and set yourself up with a free developer account.

Something Fun and Quick To Make – the Toddler Amusement Line!

Monday, November 22nd, 2010
Toddler on a phone

Flickr credit: danyork

Noticing this weekend: a) how much our 18-month-old loves to play with the phone; and b) how limited her actual “conversation” is with anyone on the phone… I decided to have a wee bit of fun and make an app that would “talk back to her”. And thus was born the Toddler Amusement Line!

You call the number and it simply loops through saying a canned set of phrases (currently “hi”, “hello”, “how are you”) 10 times with a pause between each. You can try it yourself at:

+1-617-870-3360
Skype: +990009369991480349
SIP: sip:9991480349@sip.tropo.com

Here’s all it took in python on Tropo:

import time

for i in range(0,10):
    for text in ("hi", "hello", "how are you"):
        say (text)
        time.sleep(2)

say("Thank you. Goodbye.")

I start out setting up a loop to go through the inner for loop 10 times. Main reason to do this is so that I don’t create an infinite loop running on Tropo. If the caller hangs up before the app is done, the loop will just keep going and then end. If they stay on, they’ll just get the “Thank you. Goodbye.” message.[1]

The inner loop just cycles through a series of phrases, saying each one, waiting 2 seconds and then saying the next.

If you’d like to experiment with creating an app like this yourself, here’s all you have to do:

  1. Go over and login to Tropo (you can create a free developer account if you don’t already have one).
  2. Create a new application.
  3. Choose “Tropo Scripting” as the type.
  4. Give it a name.
  5. Click on “Hosted File” and choose “Create a new hosted file for this application”
  6. Give it a file name ending in “.py” (I used “tal.py”)
  7. Copy/paste the python code above into the “File Text” area. (Tip: when you move your mouse over the code, some icons will appear in the upper right corner of the block of code – the second icon will copy the code to your clipboard.)
  8. Click “Create File”.
  9. Click “Create Application”.
  10. Start calling!

That’s it… your app is now ready to be called via either Skype or SIP. If you want to add a regular old phone number to it, just click the “Add a new phone number” link and choose from one of the available area codes. (There is no cost for a US phone number – they are free to developers.)

Now, as an added bonus, you could use one of the various international voices available for the “say” command and change the sound of the outgoing text-to-speech. For example, here the app has been changed to be a British female voice:

import time

for i in range(0,10):
    for text in ("hi", "hello", "how are you"):
        say (text, {"voice":"kate"})
        time.sleep(2)

say("Thank you. Goodbye.")

You can see the full list of available male and female voices in the “say” command reference or read our two previous blog posts with more examples about the female and the male voices.

Have fun! And may it amuse your toddler… or anyone else who calls ;-)


[1] And if you do the math, the inner loop is probably 3 seconds for each text (1 second to say and 2 to wait). 3 pieces of text at 3 seconds each equals 9 seconds for the inner loop. Do that 10 times for a total of 90 seconds. I don’t know about your toddler, but mine has probably put (or thrown) the phone down well before 90 seconds and has moved on to something else :-)

Congrats to Ted Gilchrist on his Tropo / Google Latitude app being “Mashup of the Day”!

Monday, November 15th, 2010

Congrats to Ted Gilchrist for his “Moveable Weather” app being chosen as Programmable Web’s “Mashup of the Day” for today, November 15, 2010. Ted wrote about Moveable Weather at some length on this blog and has more info at his project wiki on Google Code. Ted went on to create a variation on this called Moveable Tides which he also wrote about here. Ted was also the creator of the python library for the Tropo Web API and continues to experiment with various ways to mashup Tropo and location-based services in particular.

Congrats to Ted for being chosen today!

programmableweb.jpg

A New High Water Mark for Voice Mashups

Friday, October 29th, 2010
You’re at the helm of your three-masted schooner on a blustery fall day; it’s starting to dust up, and it’s spitting rain. You see the harbor jetty ahead, but you need to know the set of the tide. Do you reach for your smart phone and fumble around with the touch screen, looking for that tide chart app?  Not likely.

Instead you grab your trusty phone, smart or not, and clap it to your ear. Over the air comes a soothing voice from Voxeo, calmly reading you the local tide information, straight from NOAA. That’s Moveable Tides, quick in and quick out, when you need it.

Moveable Tides is a slight variation on the  Moveable Weather app I presented in my last blog post here. It shares the same design elements,  and much of the same code, refactored now, to accept more variations on this theme.  It taps into data coming from the National Oceanographic and Atmospheric Administration (NOAA), and runs on the Google App Engine platform.

As was the case with Moveable Weather, the Tropo piece is easy to code. Just for fun, I’ve again set it up in a continuous loop, so an armchair sailor can check the tides all over the coastal US, simply by cruising around on an iGoogle page.

It’s worth it however, to massage the NOAA output a bit. There’s a standard routine, I call humanize_the_time, to make the times sound right.  Also, here’s a bit of Python to cause the state abbreviations to be expanded. STATE_ABBREV is a Python dictionary of state names, along with their abbreviations.

m = re.match('.*([A-Z]{2}).*', place)
if m:
    abbrev = m.group(1)
    if abbrev in my_globals.STATE_ABBREV:
        state = my_globals.STATE_ABBREV[abbrev]
        place = place.replace(abbrev, state)

This code, along with the rest of the Moveable Weather project, can be found on my Google Code page, along with documentation. You can also head on over to the Moveable Weather web page, to try it out. I hope it inspires you to create your own location-based mashup with Google Latitude, and Tropo.

A Perfect Storm: Mashing up Tropo with Google Latitude

Tuesday, October 12th, 2010
I just created a web app, for free,  that enables anyone in the continental United States to call a special phone number and get their local weather read to them. They can then hop in their car, drive 500 miles down the highway, call the same number, and get the updated weather.  Dont’ you just love 2010?

My particular interest is voice mashups. I’ve been using Voxeo tools for a few years to delve into such areas as talking calendars,  location-based voice notes, and on-the-fly driving directions. Most of the time, a crucial piece of the mashup is the tie-in with some rich stream of data, often provided by a Google web services. In recent years, the maturation of OAuth as a standard has provided for a really slick user experience. Signing up for one of these mashups, as far as the user is concerned, amounts to handing your app a “valet key” revocable at any time. No need to ask for passwords, which for many folks, would be a bridge too far.

As anybody who has played with Google data services can tell you, Python is a lingua franca down there in Mountainview. It was the first language to be offered with Google’s App Engine, and every Google data service with an API supports it. So it was with great enthusiasm that I took on the task of providing the initial Python implementation of the Tropo WebAPI. With that task completed, as of late last summer, we can all get down to the business of creating cool and powerful mashups using Python.

The Demo

Sometimes a demo can be worth 10,000 words, so let’s get right to it. I’ve written the Moveable Weather demo so that it can run in a continuous loop. You call the access number to kick it off, and it reads your local weather to you. Then, you travel somewhere else, and press any key, and it will read you the weather in your new location. This demo is best performed while travelling on a high speed train, so you can see how the weather reports dynamically change. However, if this is impractical for you, it’s still possible to have the experience by using Google Latitude on iGoogle, as described below.

Setup

First, you’ll need a consumer Google account, such as you get with GMail.

  1. Visit http://moveable-weather.appspot.com and follow the prompts to sign up for the app. During signup, you’ll be asked to join Google Latitude, if you haven’t already done so. You’ll also be asked to agree to share your location data with Moveable Weather. Don’t worry, you can revoke it at any time. And if you choose to just travel virtually, you won’t be disclosing anything more intimate than the track of your mouse.
  2. During signup, Moveable Weather will assign you an 8-digit password. The first time you call in to Moveable Weather, you’ll enter this password, and an association will be created between your mobile phone, and your member account , which has access to the data. on Moveable Weather.
  3. (Optional, but recommended.) Go to the Google Latitude site, and follow the link to setup Google Latitude on you iGoogle page. This helps you minimize your carbon footprint, as you race around the country.
  4. Call back Moveable Weather, and this time it will tell you the weather at your current location. Then go someplace else far away, and hit any key. You’ll get read the weather at the new location.

About the Code

Most of the complexity in the coding and setup  for Moveable Weather exists outside the realm of Tropo. And this is as it should be. A key design goal of Tropo was to enable web programmers to readily access the power of a voice interface, without having to first master VoiceXML programming.

I include some code below that show’s how I dealt with authentication for this voice app. The trickiest part of the authentication is handled by some some OAuth routines supplied by a Google engineer, on the Latitude group mailing list. The problem remained of how to pair this authenticated user with their cell phone number.

I decided on a simple scheme, where, upon web signup for Moveable Weather, a user is issued an 8-digit password. The first time the user calls in, they’ll be asked to supply this password. Here’s a piece of the implementation, in Tropo:

class TropoCheckPassword(webapp.RequestHandler):
    def post(self):
        """Check the user's 8-digit password. This password was assigned
        when they first authenticated. If we find a match in the datastore,
        we associate the incoming phone number with the member account that
        was retrieved. """
        cellnumber = self.request.get('cellnumber')

        # This is how we get at the result was was posted to Tropo.
        json = self.request.body
        result = tropo.Result(json)
        password_attempt = result.getValue()

        try:
            q =  model.Member.all().filter('passw =', password_attempt)
            members = q.fetch(1)
            member = members[0]
        except:
            member = None

        #  #1. Create a Tropo object we will use to post back to the Tropo engine.
        trop = tropo.Tropo()
        if (member):
            member.cellnumber = cellnumber
            member.put()
            trop.say ("Congratulations. Password entry accepted. From now on, when you call this number, you'll get the weather report of your current Google latitude location.")
        else:
            trop.say ("Sorry. That password was not correct.")
            choices = tropo.Choices("[1 digits]").obj
            trop.ask(choices,
                      say="Press any key to try again.",
                      attempts=3, bargein=True, name="confirm", timeout=5, voice="dave")
            # Redirect back to try again.
            trop.on(event="continue",
                     next="/tropo_multi_weather.py?id=%s" % cellnumber,
                     say="Ok, good luck.")

        # Render all the code, from #1. to here, to a json object.
        json = trop.RenderJson()
        # Post the json code back out to the Tropo engine.
        self.response.out.write(json)

The conversation between your app and the Tropo engine is handled using JSON, but the Tropo Web API for Python shields you from the details.

Coding using the Tropo Web API is pretty simple, once you grasp the basic idiom When you are POSTing to Tropo, you first build a JSON object embodying all your commands, and then you “render” it to JSON, and then you write it out. Likewise, when you receive a POST from Tropo, you read the JSON piece, and then unpack it to its various components. In this way, the conversation between you and Tropo proceeds.

An Ongoing Effort

There are lots of details about  Moveable Weather that I won’t go into here, but that are covered in this project’s Wiki. There’s information there about geohashes, bulk loading of data, etc., and also, of  course, the complete code itself.

Moveable Weather is just  a proof of concept, at this point, a framework that you can adapt and expand.  I’m eager to see what the Tropo community chooses to build on top of it. As for me, I’m going to create some more examples, and scratch some more personal itches. For example, a few years ago I wrote a voice application that tapped into NOAA data and told you the local tide info, after you entered your zip code. That should be pretty easy to adapt.

I’ll race you.

http://moveable-weather.appspot.com

Announcing the 10.10.10 GWOBorg Hackathon

Thursday, September 30th, 2010

Tropo is joining Heroku and Geeks Without Bounds to sponsor a hackathon on 10.10.10 to build +) GWOBorg applications to help save the world!

GWOBorg Logo+) GWOBorg (Geeks Without Bounds) is an international coalition of passionate problem solvers working together to assist people whose survival is threatened by lack of access to technology or communications due to violence, neglect, or catastrophe.

What is the 10.10.10 Hackathon?

This hackathon unites geeks all over the planet who are interested in creating applications that help people communicate more easily in situations where human lives are threatened.

We’ve identified some excellent free and open-source crisis-management platforms as well as group collaborative platforms (“The Platforms”), and we want to challenge developers to extend these platforms across the globe.  You can set up your own, or use one of the  ”sandbox” versions we will have running.

The Platforms we’re focusing on are:
  • UshahidiUshahidi is a free and open source platform that any person or organization can use to set up their own way to collect and visualize information. The core platform allows for plug-in and extensions so that it can be customized for different locales and needs.
  • Sahana - The Sahana project aims to provide an integrated set of pluggable, Web-based disaster management applications that provide solutions to large-scale humanitarian problems in the relief phase of a disaster.
  • Open AtriumOpen Atrium is an Drupal-based “intranet in a box” that has group spaces to allow different teams to have their own conversations. It comes with six features – a blog, a wiki, a calendar, a to do list, a shoutbox, and a dashboard to manage it all.

How to Participate

All you have to do is sign up to participate and then, during the hackathon, head to your local hacker/maker or co-working space and start coding.  Or create and develop from home –  you can participate anywhere just by signing up and developing.   If you do, you can qualify to win prizes (see below).

The 101010 +) GWOBorg Hackathon officially begins 10am EST on 10.09.10.  In order to qualify for a prize your app must be completed no later than 7:00am EST on 10.10.10.  Winners will be announced during the GWOBorg live broadcast at 1:10pm EST on 10.10.10.