Sam Rides 1000: The Numbers

I've now finished my 1,000 mile challenge, and like any self-respecting geek, I ran a few numbers about my ride. I've posted them here, as well as some thoughts about the experience.

Stats

Start Date: 15 May 2009
Days: 100 Calendar Days
Time: 66.5 riding hours
Final Mileage: 1,003 miles
Miles from Commuting: 830
Miles in organized rides: 79 (Tour de Donut, ULCER 60 mile option)
Number of tire rotations: 792,300
Flats: 0* (After a small celebration at the park, I got a flat on the way home....)
Weight lost: ~10lbs.
Average length of ride: 10 miles
Average Moving Speed: 15 mph
Riding Hours: 66.5
Miles I didn't drive in my car: ~400
Time I didn't spend in my car: 16 hours

Random Facts

Many of my commuting miles were spent on the Jordan River Pathway in Utah County.
I did not listen to music (or anything else) at all.
My legs are now in the best shape they have ever been.
Because there is always a breeze, temperature didn't bother me as much as I thought it would.

Thoughts

When I started this challenge, I felt like 1,000 miles was a huge goal. After having completed it, I still feel like it was a huge goal, but in a different way then expected. Pedaling 1,000 miles was not really that difficult. More difficult was my willingness to sacrifice the time it took to ride each day. I cheated to make it work. By trading 10 minutes of drive time for ~45min of riding, I got 45 min of riding in while only sacrificing 35 minutes of time. Added up cumulatively, 16 hours not spent in a car is quite a lot of time recovered and put to better use exercising.

Part of the reason I enjoyed this challenge so much is the route I take to work. I only travel through one major intersection, and most of my riding is on low traffic country roads or paved pathways. My route allows for many variations I can take for various distances. Having a variety of routes breaks things up, and I didn't get too bored of any one route.

With my route and the fact that I was on a bike, I rarely dealt with traffic. After driving more this last week, I have begun to remember how bad commuting traffic can be while driving home. On a bike, I experience almost none of it.

I accomplished my goal in just over three months. Utah has plenty of weather not conducive to cycling, so part of the year it is very painful to ride. Even so, I feel like almost anyone willing to make a consistent effort can accomplish this same goal. I'll write about my gear in another post, but my bike is a simple mountain bike, and I spent very little on gear, especially when you consider comparable gym fees. How much time did you spend exercising in a gym this year? 66 hours? How much did you spend on membership fees? Yeah, my gear was pretty cheap.

So, will I do it again next year? Definitely. I do hope to be on a road bike though...

Sam Rides 1000: Augmenting the Web

In my previous two posts, I introduced my project and described data collection using my G1 and Google Spreadsheets. Today, I'm going to show you how I used Kynetx Network Services to add my ride stats to my personal blog and to the Google homepage.

Dataset Conversion

Google Spreadsheets, where my stats are calculated, can publish data in a variety of formats. It cannot publish JSON data, so I use Yahoo's YQL to convert the data from CSV to json, with the following statement:

select * from csv where url='http://spreadsheets.google.com/pub?key=rxzHBMZyj1S-HVLy9lFEU7A&single=true&gid=1&range=A12%3AC16&output=csv' and columns='period,miles,hours' and period != ""

(See the raw JSON results)

Building the App

I then build my Kynetx App in AppBuilder, defining the following datasource in the Global block:

dataset ridestats <- "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fspreadsheets.google.com%2Fpub%3Fkey%3DrxzHBMZyj1S-HVLy9lFEU7A%26single%3Dtrue%26gid%3D1%26range%3DA12%253AC16%26output%3Dcsv'%20and%20columns%3D'period%2Cmiles%2Chours'%20and%20period%20!%3D%20%22%22&format=json&callback=" cachable for 2 hours

Since I ride in the morning and the evening, I cache the dataset for 2 hours. This keeps the data fairly current, but still keeps the service fast.

Annotating My Blog

I have two rules, the first of which adds stats to my personal blog:

select using "http://sam.curren.ws/" setting ()

pre {
daymiles = ridestats.pick("$..results.row[0].miles");
weekmiles = ridestats.pick("$..results.row[1].miles");
monthmiles = ridestats.pick("$..results.row[2].miles");
totalmiles = ridestats.pick("$..results.row[3].miles");
milesmessage = <<
<h2>Sam is riding 1,000 miles. Progress:
#{(daymiles > 0 ? daymiles + " Today, " : "")}
#{(weekmiles > 0 && weekmiles != daymiles ? weekmiles + " This Week, " : "")}
#{(monthmiles > 0 ? monthmiles + " This Month, " : "")}
#{totalmiles} Total.</h2>
>>

}

replace_html("#logo h2", milesmessage);

I set the rule to fire on my blog's domain, and then use the pick() method to extract different totals from the json dataset declared in the Global block. I construct a message string that varies depending on the different stat values. Finally, I replace the text at the top of my blog page with the message.

To run the Kynetx application on my blog, I plant Kynetx tags on my blog. This enables everyone to see the Kynetx Application with no installs or Action Cards. The html tags are available within AppBuilder, and I simply copied them into the template for my blog.

Annotating Google's Homepage

My second rule is activated by an Action Card installed on the user's computer (instructions for installing this are in my first post). My second rule is very similar to the first rule, with some minor difference in inserted HTML and appending the message to the existing site, instead of replacing anything on the page.

select using "http://www.google.com/" setting ()

pre {
daymiles = ridestats.pick("$..results.row[0].miles");
weekmiles = ridestats.pick("$..results.row[1].miles");
monthmiles = ridestats.pick("$..results.row[2].miles");
totalmiles = ridestats.pick("$..results.row[3].miles");
milesmessage = <<
<h2>Sam is riding 1,000 miles.</h2><p> Progress:
#{(daymiles > 0 ? daymiles + " Today, " : "")}
#{(weekmiles > 0 && weekmiles != daymiles ? weekmiles + " This Week, " : "")}
#{(monthmiles > 0 ? monthmiles + " This Month, " : "")}
#{totalmiles} Total.</p>
>>

}

append("#body>center", milesmessage);

Activating Kynetx Rules with an Action Card also requires an update to the Dispatch block of the rule, adding this line:

domain "www.google.com"

I also generate the card inside AppBuilder, providing a custom image that I created using Pixlr

And there you have it. Sam rides 1000 miles, with automated stats provided by Android MyTracks, Google Spreadsheets, YQL, and Kynetx Network Services.

Shameless Plug

Kynetx is a cloud based automation engine, capable of doing the things I've demonstrated and much, much more. If you'd like to use Kynetx Network Services, sign up for an account, and start using AppBuilder.

Sam Rides 1000: Collecting Ride Data using the Android Powered G1

On my Android powered T-Mobile G1, I'm using the free My Tracks application to record my rides. I start recording just before I start, then throw it in my pocket or bag. I stop recording at the end of my ride, then use the Upload to Google option in the map menu. You can upload the track to My Maps within Google Maps, but my rides are very similar, so I usually only upload to Google Spreadsheets.

Uploading to Google Spreadsheets creates a new spreadsheet in Google Docs, with one page for ride data, and another for stats. The program creates a new spreadsheet for each activity type, so I make sure and select Cycling when I stop recording at the end of my ride.

Additional Stats

It's important not to manually change too much on the Log sheet, as the program will get confused, but everything else in the spreadsheet is open to tinkering. In addition to the total miles and total time stats, I wanted to calculate daily, weekly, and monthly totals.

Before I computed those stats, I had to handle the date field uploaded by the My Tracks application. Google Spreadsheets cannot parse the provided date as a date value, so I had to help it along. I created a Dates sheet to accomplish that task. Rather then try and explain what I did, see this spreadsheet, which contains my modifications and formulas:

Sample Spreadsheet with modifications.

I then added some additional stats, first by calculating the start of the date range I wanted to sum, then using SumIf() to only add the mileage and time from the period I wanted.

Finally, I published the Stats sheet of my spreadsheet, so I could use it as a dataset for my Kynetx Application, which I'll explain in a future post.

Sam Rides 1000: An exercise in collecting data and web augmentation

May 15, 2009 was National Ride your Bike to Work day, and I pulled out my bike and rode the 6 or so miles between my house and the Kynetx offices at Thanksgiving Point. I enjoyed it, and rode a few more times in the next week. I was musing how many miles I could ride this summer, and mentioned it to my wife. She promptly challenged me to ride 1,000 miles this summer.

I better say here that I'm not a cyclist. I haven't ridden 1,000 miles in the past 5 years, all combined together. While 1,000 miles might not be much for a cyclist, it is quite the challenge for me.

Tracking My Progress

In addition to making a few bike repairs and buying some commuting tires for my mountain bike, I immediately cooked up some geeky ways to track my progress and share my results with my family and friends.

I'm a (BIG) Android fan, and so I'm using my T-Mobile G1 as a cyclometer. I'm using the My Tracks application, which records both the route of my ride and my ride stats. After my ride, the app uploads my stats to a Google Docs Spreadsheet, where stats are calculated. I'll share more about that in a future post.

To share my progress, I'm using Kynetx Network Services (KNS) to augment my personal blog with my stats. If you are reading this post on my blog, look at just under the title for my updated stats. KNS pulls my ride stats from the Google Spreadsheet and annotates my website. All I had to do was plant some javascript tags in my blog's template to activate the Kynetx Application that makes the change.

My friends and family don't visit my blog EVERY day, so I've also produced an Action Card that displays my ride stats on Google's home page. KNS allows me to augment websites for anyone that has my Action Card installed. I'll explain more about how I wrote my Kynetx Application in a future blog post, but for now, you can install my "Sam Rides 1000" card to track my progress on Google's home page.

Installing The Action Card

An Action Card is a type of Information Card that allows your web experience to be augmented with a Kynetx Application. You activate the application by installing an Action Card Selector if you don't already have one, and then installing the card. You can disable or remove the card if and when you don't want to use the application.

  1. Verify you have a supported browser: IE/FF on Win, FF on OSX
  2. Install Azigo
  3. Install the Sam Rides 1000 Action Card

Then, browse to Google's main page to see my stats: http://www.google.com

When I finish a ride and update my stats, you'll see the new numbers. If I'm falling behind, be sure and give me a nudge!

I'm enjoying my T-Mobile G1

I was one of the folks to pre-order the first Android phone, the T-Mobile G1. The G1 launched today and is available at T-Mobile locations. I pre-ordered mine (and one for my wife) and received it yesterday afternoon. I've had several requests for a review, so I'll post a few initial thoughts here.

First, I love the phone. Early reviews called it brickish, ugly, and all sorts of horrible names. I find it to be none of those things. In fact, the phone is smaller then I was expecting.

Getting the phone setup was VERY EASY. On first boot, you enter your Google account information, or set up an account if you don't already have one. Within a minute or so, my contacts were downloaded from Gmail, I had a mail alert, and my calendar was available.

I bought a black phone, and my wife the bronze color so we could tell them apart. The bronze color is much nicer then I expected, but the lighter keyboard on the bronze model was slightly harder to read. The keys on the black model were very easy.

I'm not in a T-Mobile 3G area, and I knew that when I ordered the phone. I find the EDGE speeds to be just fine for most uses of the phone. I was able to listen to a podcast within seconds of starting the download, and I find most apps to be responsive when sending and receiving data. The mail app is particularly nice, as it caches data locally and handles sending email in the background.

The capacitive screen is flush mounted, like the iPhone. It's a little smaller then the iPhone screen, but the same resolution. It doesn't feel cramped, and the color is great.

The selection of apps in the Android Marketplace is a little thin at the moment, but user submission will open on Monday. There will also be an Over The Air firmware update in the next day or so, which contains minor updates and fixes.

I'm sure I'll have more to say later, but I wanted to mention these few things that I hadn't found on other websites and reviews.

AndroidGuys.com: Getting Ready for the T-Mobile G1

This morning, AndroidGuys.com posted an article describing a few things you can do to get ready for the T-Mobile G1. I draw special attention to this article, as it is my first blog post on a blog besides my own.

I look forward to participating with the rest of the AndroidGuys, and you should see more of my posts there in the future. I am eagerly awaiting my G1 (8 Days!), and I'll be sure to post some thoughts and reviews.

Why iPhone users should love the T-Mobile G1

Every group of users has a few extremists, and I have run into quite a few of the Apple iPhone variety lately. Most of the negative comments about the first Android phone come in the form of an iPhone fan trash talking the G1. I find these types of comments very interesting, because iPhone users should be pretty excited about the G1.

Before I collect even more of the comments I'm talking about, understand that I'm not claiming that all iPhone users should be ready to convert. I'm talking about the positive effects of competition, and the ultimate win for users of either device.

It is clear that the iPhone has influenced the design of the G1. It will also be clear over the next year or so that the Android phones will influence the features of the iPhone. While I am sure that Apple is not about to adopt the physical design of the G1, there are other things there that Apple will be sure to emulate.

The biggest issue at hand is the ability of Android phones to run background processes. Android's architecture allows for applications to perform background tasks, yet allows the operating system to suspend tasks quickly to allow for answering calls and other phone related tasks. The applications that can be built with Android will have a technical leg up on iPhone apps in this important aspect.

It won't be long before Apple follows suit. They will need to allow some sort of background processes in order to match the level of application sophistication and usability of Android Apps.

Also at issue is the restrictions that Apple places on developers with their restrictive NDAs and practice of denying apps that compete with Apple products in any way. Their recent changes to some NDAs are a sure sign they are feeling pressure from a more open platform.

This is where iPhone users gain. By pushing each other's limits, Apple and Google will produce some great technology, and both iPhone fans and Android fans will gain. So seriously, everyone calm down a little, and enjoy the market pressures bring even greater phones to all of us.

Android + Google Contacts API = Awesome

Android's address book syncs with the configured GMail account's address book. The GMail address book provides a group feature, allowing you to group your contacts together for easy management. Android can sync with some or all of these groups.

This allows entering phone numbers online instead of using the phone's small keyboard and screen. It also allows entering an email address from your phone, and having that available the next time you send an email from your desktop. In addition, you can import contacts into the address book from a CSV file. All these features are available right now, with no programming required.

While this is pretty cool by itself, it is made more powerful by the Google Contacts API, which allows programmatic access to your GMail address book. This opens all sorts of cool features that are not natively part of the address book on either GMail or an Android phone.

Businesses can sync the company address book to employee phones, including updates made on the phone. Those changes can then be synced to other employee phones very quickly.

Using a third party service, you could also allow shared groups between individuals, so my wife and I can share the 'family' group, and both always have current numbers, no matter who enters the information.

Perhaps the most powerful possibility is the integration between your address book and existing social networks. When I update my contact information, that information can be automatically updated in the contact lists of my authorized friends, and that information is quickly synced to their mobile phone.

The Contacts API uses oAuth, a mechanism for allowing access to your contacts without giving up your password. This standard access method means that you can use 3rd party services without worrying about your email being compromised, or unauthorized access to your Google Checkout purchases.

I'm looking forward to the options available as I seek to make my contact list management a little nicer.

The Android Unlock Screen

Smartphone security is a big issue. Not only can a thief make calls on your account, but they have access to your email, your calendar, your entire contact list, and everything else that is important. Here, I take a quick look at methods used to secure Apple's iPhone and Google's Android platform.

With the iPhone, Apple introduced an intuitive "slide to unlock" control that prevents accidental touches on the screen. Because the slider is so easy to recognize and use, many kids can figure it out immediately. For this reason, and for additional security, the iPhone also has a keylock feature that accepts a 4 digit pin number.

Google's new Android phone operating system combines the concept of the slide to unlock feature and the security code, with a grid of 9 dots. The unlock pattern requires touch at least 4 dots, and unlocks the phone when the correct pattern is entered.

This combination is an excellent combination of the two concepts, but how does it measure up to the security of the iPhone's 4 digit pin?

4 digit pass codes (using numbers) allows for 10,000 combinations. The math for the pattern combinations is more complicated, but Cedric has done it for us. With a 4 dot pattern, there are 1624 combinations. It gets better with 5 dot patterns (7152 combinations) and on, for a grand total of 389,112 total combinations.

So how does Android's pattern compare to the iPhone's pin? The Android pattern is likely to be used more then then iPhone's pin lock, but at the simple end of the possible patterns, there are far fewer combinations.

I prefer the Android approach, for two reasons. First, the dot screen is likely to be used by far more people then the iPhone's pin lock. Second, the dot screen allows the uber-paranoid to use a full 9 dot pattern, greatly increasing the possible combinations. Even with only 1624 options for a 4 dot pattern, it would take over 27 minutes to try every combination, with 1 second per attempt. Add some delay between failures, and you can easily stretch that time to over 9 hours. That's good enough for me.

As far as actual security is concerned, that's a longer discussion. The low combination count of the dot screen can be easily augmented with exponential delays between tries. Security holes elsewhere in the system can easily render the unlock screen useless, etc. Credentials can be removed after a certain number of login failures. Time will tell which one can be 'proven' to be more secure.

In the meantime, I'm looking forward to dreaming up my own unlock pattern.