UPDATE 2: ok, this greasemonkey script is now outdated.. please use the firefox plugin instead. it has it's own url here. Everything below this point is just history now
I have recently started using sparkpeople to track my diet and exercise (we'll see how long that lasts). It's a nice site for the most part, but there are a few features I'd like to see… so instead of just begging for them through official channels, I've started to create them on my own.
The nutrition tracking page shows you your target calories, carbs, fat and protein and the number you have used for the day, but it doesn't show how many you have left of each.
Greasemonkey is a firefox add-on that allows you to install scripts that can interact with web pages as you surf them. You can use this to add additional functionality to web sites you use regularly or combine functionality from multiple websites together.
I have created a greasemonkey script that adds a “remaining” stat to the nutrition page, it looks like this:
If you have the greasemonkey add-on installed, you can click here and install the script. It should do its thing any time you are on your nutrition page.
UPDATE: I am just going to update this post as I add things to this script… I have now added some summary stuff in the side bar, it looks like this:
History has been made it's very exciting…. Now that that's out of the way… New boss, same as the old boss… From “hope and change” to “more of the same”…
Four years from now things will be the same or worse. The trajectory is pretty much set. Obama will have a mediocre approval rating, so will congress, we will still be at war in the middle east, millions of Americans will not have health-care, the country will still run on coal, oil and gas, unemployment will be between 6 and 10%, lobbyists will still rule Washington… there will be no changes of substance (at least none that originate in Washington DC).
Millions who just had the most exciting political moment in their lives will have their faith in the system torn down anew. Their dreams of telling the grand kids how they played a part in the coming of the new dawn in American history will turn to ash before their very eyes.
The 2010 election will re-balance congress a bit (that season should be starting any day now). That tighter congress combined with mild resistance from the left to Obama's centrist nature, the economy and TWOT will keep meaningful change from happening and the machine will continue to slowly consolidate power while maintaining the status quo. Drastic change is dangerous to both parties in that it could open the door for people with actual ideas and jeopardize political careers that span decades if not generations.
The problems run much deeper than the president; they're pervasive and systemic. Here's an example:
My ballot… all filled out (mostly blank)… (I wrote in Bob Barr, just because I feel the Libertarian party should be on the ballot in every state, not because I like him). Note the complete lack of actual contests, all races are either Republican vs. Democrat or an uncontested Republican or Democrat. How is this a choice? I don't even think I know a single person who's views are represented by the platform of either party. These people represent the political establishment, therefor the establishment always wins. The politicians always win, the political machine always wins.
Congratulations to our new president, I look forward to some more refreshing mediocrity.
There have been a few occasions where I have wanted to express historic prices in terms of their inflated value or vice-versa.. e.g. $100 dollars in 2007 was worth about $63 in 1990.
This is actually a very simple thing to calculate… we take the CPI from 2007 (207.34) and the CPI from 1990 (130.65) and do the computation thusly:
I have written a grails service that grabs the latest CPI data and does this for me… it's just groovy, so it should be easy to use outside of a grails app.
class InflationService {
boolean transactional = true
// this is where the live CPI data lives
String cpiURL = 'ftp://ftp.bls.gov/pub/special.requests/cpi/cpiai.txt'
// map of year to CPI average String -> double
def cpiMap = [:]
// track the last time we updated from the source data,
// for long lived apps we don't want to get stale.
long lastLoadTime = 0;
// always use the current year as the target year
double calculateCurrentDollars(String fromYear, double value) {
refreshCPIData(false)
GregorianCalendar date = new GregorianCalendar()
def year = date.get(Calendar.YEAR)
// not sure what the CPI table looks like in january...
// this should account for no record for the current year...
// more that 1 missing year is a serious problem
def toYear = String.valueOf((cpiMap[String.valueOf(year)] != null) ? year : year-1)
return calculateYearDollars(fromYear, toYear, value)
}
double calculateYearDollars(String fromYear, String toYear, double value) {
refreshCPIData(false)
def toCPI = cpiMap[toYear]
def fromCPI = cpiMap[fromYear]
// here's the actual math...
// pretty simple when you final get down to it // TODO - check for nulls or zeros and throw exception.
return value * (1.0 + ((toCPI - fromCPI) / fromCPI))
}
// refresh cpiMap if last update was more than 1 day ago
// OR forceUpdateNow param is true.
public void refreshCPIData(boolean forceUpdateNow) {
long oneDay = (1000 * 60 * 60 * 24)
// update once per day. (or if forced)
if (forceUpdateNow || (lastLoadTime + oneDay) < System.currentTimeMillis()) {
lastLoadTime = System.currentTimeMillis()
// grab the "tabular" data right from The Man
cpiURL.toURL().text.eachLine {yearLine ->
// find all the lines that start with a year..
// these are the useful bits of the doc
if (yearLine.matches(/^\s+\d\d\d\d\s.*/)) {
// split the line up into individual values
def yearList = yearLine.split(/\s+/).findAll {it.size() > 0}
// the first item is the year.. hang onto that
def year = yearList[0]
// the rest of the values are CPI values for each month
// (some averages at the end that we ignore)
yearList = yearList.tail().collect {Double.valueOf(it)}
// average all 12 months for every year...
// except the current year could have less than 12 months
int idx = yearList.size() < 12 ? yearList.size() - 1 : 11;
cpiMap[year] = yearList[0..idx].sum() / (idx + 1)
}
}
}
}
}
It shouldn't matter which direction you want to do the conversion in.. 1990 dollars to 2007 dollars or 2007 dollars to 1990 dollars. The data starts in 1913 (the year the federal reserve was created) and runs about a month behind.. so I write this in September 2008 and the CPI is available through August 2008.
The aspamaday blog is a fun blog.. The author turns spam subjects into little works of art. Today I sent in a spam subject I received (Who Needs Sex When You Can Steal DNA)… less than two hours later, he made this.
xkcd is a great web comic… nerdy, smart, creative, and fun… It's one of my favorite RSS feeds. Today's comic is brilliant as always… but I felt like I had a slight improvement to make
I bought the audio book (and hard cover) version of Cory Doctorow's new book Little Brother. It's delivered as a 163 megabyte MP3 file, over 11 hours of spoken word… I have listened to dozens of audio books delivered as podcasts, but I only have one “normal” audio book (The Areas Of My Expertise by John Hodgman… hilarious) which I bought through iTunes, it is broken into 3 (2.5 hour) parts, which is still a bit long for an “episode”. I really prefer the podcast episode per chapter form factor because it caters to my various neurosises and gives me a feeling of progress and accomplishment even when I don't really deserve said feeling.
I listen to my podcasts in three places, my iPhone, my Apple TV, and through iTunes on my MacBook Pro (Holy fanboy, Batman). While the synchronization between the three is pretty good, it can mess up and lose my place in an audio file. This usually isn't an issue because I rarely need more than a sitting to complete any particular file. I suspect that I'm not going to finish an 11+ hour audio book in a sitting… or even 11… so there is bound to be frustration and cursing as I lose my place repeatedly somewhere in the syncing madness.
After some Googling, I found AudioSlicer. In under 30 minutes I had the book split into 26 named sections, intro, chapters 1-21, epilogue, afterword, bibliography, and credits and copyrights. Here is my .split file (unzip it) which you can use with AudioSlicer to split the MP3 you purchase into the same chapters (if you have a mac). When you “Export Splitted” make sure “Filename Format” is “[trackNumber]_[title]_[album]_[artist]“.
Now I could just import these files as a playlist in iTunes, but that's not how I roll… I want everything to be a podcast. Here is the iTunes friendly RSS based podcast feed i created (you'll need to follow the rest of the steps to make that useful, you can't just click that link and subscribe).
Now, take the mp3 files you created, and the podcast feed, and put them in a directory named “lb”… now put that lb directory in “/Library/WebServer/Documents/”. If you have web sharing enabled (System Preferences -> Sharing -> Web Sharing) you should now go to iTunes (or whatever) and go to Advanced -> Subscribe to podcast and paste in “http://localhost/lb/little_brother.xml”
Once the downloads are complete you should have something that looks like this:
All the files are served up locally and should not be available on the network at-large. Once all the chapters are downloaded into iTunes (or whatever) you can delete the lb directory and disable your web sharing (if you don't need it for other stuff, obviously).
I hope this is helpful to someone besides me… if anyone finds an easy way to split the file up on Linux or Windows, let me know.
Some technical wishes for Roller… I wish there were a generic way to pass values provided through the admin UI to the themes. For instance, analytics, adsense and google reader stuff.. I could then make this theme available to others with all those features ready to go out of the box. Not that this theme is particularly good.. but I think there are some cool technical aspects to it that could make life easier for people less technically inclined…
I wish I didn't have to restart Roller to apply theme changes. It seems like there should be at least an option to use the theme resources directly. Maybe that's just me wanting Roller to be a content management system when it's not.
I wish I had time to dig into the Roller source code.
All in all, I like it.. it's a cool system that's relatively easy to maintain and I have full control.
I've been working on this theme a little..
I added a tag cloud on the right and a list of old posts. I'll try to tag each post pretty well so that maintains good utility.
Each post now has a few social bookmarking links under it. You most likely know what they are, and if you don't, they probably won't make your life any better. Leave a comment if there's some service you really like.
I have also added a widget from my RSS reader. I'm subscribed to dozens of RSS feeds from a pretty wide variety of topics. Any I flag as “shared” will appear in that box on the right. I don't flag very many… but I think they're usually pretty good
Check out this TED talk by Johnny Lee about how he has used the Nintendo Wii controller (just the $40 controller) to create really cheap projection touchscreens and more.
I just found out about TED fairly recently, and I’ve been watching the videos voraciously ever since. If you’re not familiar with TED it’s a yearly conference where some of the worlds most innovative and intelligent people give talks from 5 to 40 minutes in length. It’s been going on for 20+ years, and has featured household names in science, politics, entertainment and just about any field you can think of. Most amazing are the people who most of us have never heard of, like Johnny Lee, with some incredible new invention, idea, insight or even just a great story.
I could go on.. there are very few that I would say are not worth seeing, and there are hundreds out there, with more published all the time. The full podcast feed is here.
DonorsChoose.org is the type of service that would replace most of the functions of government in my perfect world. Match people who want to give charity with people and organizations in need. This particular effort is focused on private funding of various school programs at all levels of primary education. Here are over 100 Maine programs you can support. There are opportunities in every state.
We could apply this approach to just about anything! Schools, libraries, small business grants, victim support organizations, environmental research, scientific studies. Big charitable organizations can break out budget needs at a more regional and micro scale. The red cross could put out a call for marketing funds for an upcoming blood drive in a specific region or to provide shelter for a family faced with leaving their home due to fire or flood. A regional library could have specific micro funds for expanding specific collections allowing you to donate to fill out the computer science stack without supporting the purchase of religious texts or some other range of the Dewey Decimal System. The possibilities are endless.
Donors Choose is also using technology to its advantage, with region and keyword based RSS feeds! If there were more organizations like this I'd be tempted to create a MaineDonors site which would aggregate all the local charitable RSS feeds into a one stop shop for local giving.
How fun would it be to give away some percentage of the thousands of dollars the government takes from me each year to local causes that actually have an impact on my life and those around me directly? Direct giving inspires community involvement and could contribute to a feeling of responsibility for our neighbors, without forcing it on us or disconnecting the distribution of money from the act of giving as our current tax system does.
I digress, as usual… The point is: this is a really cool organization and concept that deserves our support.
Check out this video where Steven Colbert uses the election to raise money for Donors Choose programs… how cool is that?