Archive for December, 2007

26
Dec

Managing social info streams: a modest request

   Posted by: rew   in General, Tech

Chris Brogan and Clarence Smith Jr. (am I supposed to just say “@chrisbrogan and @dykc” to appear more ‘linked-in’ and whatnot?) just posted a collaborative piece about managing the (many, many) streams of information from sources like Twitter (or any aggregator, like Google Reader, I’d add).

My immediate thought is that this is a perfect task for adding intelligence on the client side. For instance, I would love to have more options in Twitterific for controlling the incoming tweetstream.

With a ‘pause’ feature, if @InterestingDude is temporary at ReallyBoringConfFest07, and will be until Thursday, I’d love to be able to put him on “pause” until then, so that I don’t see all his excited tweets about impromptu hallway meetings with ReallyBoringPeople and ReallyBoringProjects.

But I don’t want to quit following @InterestingDude permanently; I’ve just lost interest for the next few days. I don’t want to have to remember to re-follow him, either; I just want to skip the next couple of days (or hours or whatever) of tweets from him.

The problem Chris and Clarence are examining is how to get more of the info that’s interesting and less of what’s not, when the “interestingness” isn’t always determined by the person or the topic. The ability to follow tweets or blog posts by “interesting people” is a start, but only a very primitive one. There are lots of fascinating people doing fascinating work, but who have hobbies that bore me to tears (and vice versa). There are a very few people who write so well that it hardly matters what they’re doing, I just enjoy reading their writing. And there are many, many people who normally would not be of interest to me at all, except when they happen to have seen/talked to/read/bought/tripped over the very piece of information which is extremely relevant to something I’m working on or discussing with other people.

Perhaps I should just quote Chris and Clarence a bit:

The problem arises when the people you follow are initiating and participating in conversations that you do not find interesting at all. [...] Said another way: I might like YOU, but not be into every little thing you are into. [...] How can we catch your tweets about social computing but skip the tweets about being stuck at JFK for a 3 hour delay?

It’s not that YOU should have to twitter differently, but rather, we should have a way to adjust the lens on what comes through our “interestingness” gate. And of course, this is all relative to whatever you’re interested in, who, and often times where. For instance, if we’re visiting Seattle, we might want to get MORE about the area around us than less, in case something newsworthy is happening (like avoiding a traffic jam).

They also (briefly) consider the personal/social implications of such filtering:

How do we on/off the conversational flow of people in such a way that we receive more of what’s interesting to us (again, very relative), without it signifying anything negative about a person?

This I don’t find as compelling, partly (perhaps) because so far I only have an extremely limited scope of friends (in anything resembling the traditional sense) who are Twittr/Whatevr users. But I feel pretty confident that the notion of any social implications of being filtered or un-followed (is that a word?) will adjust with the tools. As people spend enough time swimming in the flow of social network infostreams, it will become more apparent that social standing with a person is largely disconnected from how much of your socnet output they’re consuming at any given time (perhaps it will always have more to do with which parts of our output they consume than how much).

C&C continue:

Why can’t we have a system that’s partly like Flickr’s “interesting” and “favorites” system, that helps train Twitter (and other networks) to predict which conversations will matter to us? Something more than keywords. How do we apply this same thinking to the people we currently “follow?” What if Clarence loves when Chris talks about data centers, but doesn’t care about Chris’s current trip to New York City? How could we “gate-on” based on information, and then “gate-off” when the interestingness vanishes? [...] How could we build tools that turn on and off our view of someone’s Twitter stream based on things like: location, context, content?

This is where I think there’s a big ol’ gaping opportunity for an interesting next-gen aggregator. How many different ways are there to arrange the panes in a blog reader? Well, OK, there’s a zillion, but the point is, how many of them are enough better to compel me to change to them? Just like with the mail client, the things that really are going to motivate people to change en masse will be the addition of “intelligence” to make managing the burgeoning information therein easier.

The “pause” thing would be cool; but man, a client that could determine what I was interested in at the moment, and help me find “more of this and less of that”, would really pique my interest. Whether it did it by reacting to explicit actions like tagging or even rating (3 stars or 4?) tweets or people, or by implicit observation of my behavior (in the same vein as how Google Reader’s “Select by Auto” works), it would be a great step in the right direction.

Plus, you know, a pony. And an aeroplane. And a perpetual motion machine. I mean, it can’t hurt to ask, right?

16
Dec

Dan Fogelberg, RIP

   Posted by: rew   in Music

In the “well, that just sucks” department, Dan Fogelberg died today at 56 years old, after a long struggle with prostate cancer.

Dan Fogelberg, to me, was one of those artists whose great songs (”Longer”, “Auld Lang Syne”, “The Leader of the Band”) were just spectacular, amazingly poignant and brilliant, ones that just resonated with something already inside me, and whose other stuff was just this side of un-listenable. I think it was something about the ’70s, as Al Stewart (”The Year of the Cat”, “On the Border”), Gordon Lightfoot (”Sundown”, “If You Could Read My Mind”) and a few other of that era were the same way for me.

I actually sang “Longer” to my wife in our wedding, and at least she liked it. :) It’s just sad, and it makes me feel old, when artists I grew up with start dying of, well, natural causes, for lack of a better word.

And I have to say, with Keith Richards still alive, perhaps Billy Joel was right: Only the good die young. And speaking of old, you know I’m feeling it when I start talking about 56 as ‘young’.

p.s. - One of the funniest Bloom County strips ever (and yes, I know how much that’s saying) had Opus sputtering, “Who’s Dan Fogerburp?” after his girlfriend Lola Granola scandalized him by admitting to having a Dan Fogelberg tattoo. Alas, we never found out where it was, which was apparently more scandal than Opus could have handled.

13
Dec

Stock market reacts to CFC news…oddly

   Posted by: rew   in Business, Finance

OK, prepare to be astounded with my ignorance. And please, if you are, enlighten me.

Marketwatch reported today that Countrywide reported that mortgage loan fundings for November 2007 were down 40% from November 2006.

The market has peeled off another 5% from CFC’s price today, though CFC’s been so volatile lately that it might be a little imaginative to call it a “reaction” to the news. It could be “reacting” to a butterfly landing on some institutional trader’s window and causing him for some reason to remember to unload another 100k of the shares. I don’t know.

Still, it’s interesting that this is being reported is that “CFC reports mortgage fundings down 40%”, as though this is the real news. But didn’t we already know that things are worse than last year? That’s not news any more. The news - the thing that is unexpected (or was to me) and of immediate interest - is that its total mortgage loan fundings were up 5 percent from the prior month. Why isn’t that the headline? When was the last month that CFC saw mortgage loan funding up from the prior month?

Again, I realize that there can be seasonal factors that make some months stronger than others, and so normally, comparing year-over-year makes more sense. But given that we’ve seen a massive dislocation and an ongoing effort to reprice mortgage risk, the huge year-over-year decline is already priced in. It seems to me.

Really, this isn’t about CFC, but about how financial reporting, and maybe most reporting, has to fit the current template. “CFC Mortgage funding up” doesn’t fit the “We’re all going to die because the 4% of the mortgage market in sub-prime loans is going to have above-average failure rates for a while” template. So the news, whatever it is, has to be reported in such a way that the template remains undisturbed (at least, that is, until the next template comes along).

Disclaimer: As you may have guessed, I am currently long CFC (though not in a big way).

9
Dec

Google Charts’ simpleEncode in Ruby

   Posted by: rew   in Programming, Ruby

I couldn’t resist. Note the is_numeric? method, which is not very pretty Ruby (I should open up a base class somewhere and put it there), but it works and is only syntactic sugar anyway, to make the simpleEncode method itself a little nicer to read.

Note that it produces slightly different output than the PHP one, namely because Ruby handles integer arithmetic a little differently, thus the round() method was not needed here. If I changed this line:

      chartData < < simpleEncoding[simpleLength * val / maxValue];

to this:

      chartData < < simpleEncoding[(simpleLength * val.to_f / maxValue).round];

the output is identical. But visually they’re nearly indistinguishable when charted, as the difference amounts to (literally) a rounding error at any given point.

def is_numeric?(arg)
  Float arg rescue false
end

def simpleEncode(values, maxValue=-1)
  simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  simpleLength = simpleEncoding.size - 1

  # Just ignore any non-numeric values                                                               

  maxValue = values.select{|f| is_numeric?(f) }.max if maxValue < 0

  chartData = 's:'
  values.each do |val|
    if is_numeric?(val)
      chartData << simpleEncoding[(simpleLength * val.to_f / maxValue).round];
    else
      chartData << '_';
    end
  end
  return chartData;
end
9
Dec

Google Charts’ simpleEncode in PHP

   Posted by: rew   in PHP, Programming

The docs for the new Google Charts API include a Javascript function called simpleEncode. It demonstrates encoding a data set into a “Simple encoding” as expected by the API. You can read the docs to see more about how this works (as well as the other two encoding methods if you need more granularity), but I didn’t catch on the first time through. So herewith, a quick explanation in my terms of what’s going on, followed by a PHP function which does the same thing.

The ‘Simple encoding’ converts your data values into an alphanumeric string, composed of upper- or lower-case letters or the digits 0-9. But to do it right, you have to realize what it’s expecting. For the purpose of the Google Chart, those values (ranging from ‘A’ at the bottom to ‘9′ at the top) represent the 62 discrete points you can plot using Simple encoding. If you have a graph which needs more than 62 discrete points, you’ll need to use one of the other encodings. But as the granularity guidelines say, don’t overestimate the granularity you really need for your chart. Remember that charting is about visualization, and unless your chart is quite large (and Google charts are limited to 300,000 pixels), there may not be much visual clarity gained by maximizing granularity.

More importantly, regardless of which encoding you use, you still need to understand this key point: Your data has to be mapped proportionally onto the available data points for the encoding you choose. This is simple once you get it, but maybe not so simple at first. So let’s try an example. Let’s say you want to plot this series of data points:

1, 3, 11, 8, 4, 2, 9

If you just chart those numbers directly without encoding them, Google will interpret them essentially as “a dot 1% of the way from the bottom”, “a point 3% of the way from the bottom”, “a dot 11% of the way…”, etc. You’ll get a graph like this.

That’s probably not what you were after. But if you encode it properly, you’ll end up with a chart like this.

Much better, don’t you think?

So the whole trick is to take your data points, figure out what the maximum and minimum values you want to display are, and then proportionately adjust each value in your data points to map them onto the available graph points.

In our hypothetical data set, 0 is the lowest value we’re going to plot, and 11 is the highest. Proportionately mapped, 3 would be about 27% of the way between 0 and 11, 8 about 72%, 9 about 81%, etc. The letter ‘R’ is about 27% of the way from from A all the way up to 9, so 3 encodes to ‘R’. ’s’ is about 72% of the way up, so 8 encodes to ’s’, and so on.

OK, so the following PHP function takes a one-dimensional array and an optional maximum value (used if you wanted, for instance, to specify the highest visible value on the graph, even if none of your data points go that high). If you don’t specify a maximum value, the function will calculate the highest value from among your data points and use that.

It returns a string representing the Simple encoding of your datapoints, prepended by the ’s:’ specified in the Google Charts API. In short, it does exactly the same thing as the sample Javascript function provided in the API docs, only it doesn’t require you to specify a max value.

So

print simpleEncode(array(1, 3, 11, 8, 4, 2, 9))

returns ’s:GR9sWLy’, which you can see if you ‘view image’ on the second graph above is what I used to create it.

No magic here, I just thought it might be useful to someone.

function simpleEncode($values, $maxValue=-1)
{
  $simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  $simpleLength = strlen($simpleEncoding)-1;

  if ($maxValue < 0) $maxValue = max($values);

  $chartData = 's:';
  foreach ($values as $currentValue) {
    if (is_numeric($currentValue) && $currentValue >= 0) {
      $chartData .= $simpleEncoding[round($simpleLength * $currentValue / $maxValue)];
    } else {
      $chartData .= ‘_’;
    }
  }
  return $chartData;
}
9
Dec

Googly-charting goodness

   Posted by: rew   in PHP, Programming

The new Google Chart API is just awesome. I can say that with confidence, because even I was able to get it working in no time flat.

I have a web app (mostly PHP) I use to manage some sales data, and I used to graph my data using PHPlot. PHPlot is a nice PHP graphing package; at the time I started using it, it was the best I could find. Still, while I realize I’m not the brightest frog in the pond, it took me quite a few hours of noodling around with PHPlot to get it to look like I wanted a couple of years ago when I implemented it.

Well, I’m proud to say that after about an hour this morning, I had completely duplicated my existing graph using the new and hotness.

One reason that it didn’t take me long is that the Google Charts folks (do they have their own nickname? Chooglers?) made a decision to return something from whatever mess you send them, even if it’s not what you wanted. This many seem like a small thing, but it didn’t happen by accident. There’s a significant amount of magic going on behind the scenes to return some semblance of a graph from the most twisted parameter arguments. But it’s a big, big deal because it makes it so much easier to incrementally make it look how you want.

What’s more, because it’s REST-based, you can right-click on an image generated by Google Charts, wherever you see one, and see the URL, which will contain all the options, right there for you to copy and even change. And since each image is just a URL, you can try variations, and they’ll all be in your web history, so if you make a misstep, the last known good one is but a back-button click away.

I love this thing! I’ve posted a bit of PHP that I hope will be helpful, along with a quick explanation of something that initially threw me about the chart data you have to send to Google Charts.

6
Dec

Google Reader needs a history view

   Posted by: rew   in Tech

I’m a big fan of Google Reader. But one thing that annoys is that I can’t find a history view that would let me go back through my own reading trail. Shared items, sure, but while I don’t necessarily want my reading history public, at least I should be able to see my history, shouldn’t I?

I frequently read a post and then later decide I want to go back to it, and have no idea where it was. I often know about when I read it (if it was very long ago, I probably wouldn’t remember about it anyway), but that doesn’t help me without a history to browse through.

This is made worse by the fact that not only do I subscribe to more blogs than I can keep up with, I also frequently read links from other prodigious link sharers (like Scoble and Chris Brogan), and so there’s a good chance I don’t even subscribe to the blog where the item was actually posted.

That’s just a huge oversight. Or maybe I just haven’t found it yet. If you know of a way, please let me know. If you’re one of our Google overlords, please add it.

6
Dec

Seasonal haiku

   Posted by: rew   in General

All-new, completely original haiku that I just now wrote, all by myself:

Dashing through the snow
In a one-horse open sleigh.
O’er the fields we go.

I wrote (from my own fertile imagination) this second stanza to this epic seasonal haiku-cycle, but I don’t think it’s as good (though the last trill is very Basho-like, and that’s a good thing):

Laughing all the way
Bells on bob-tails ring, making
Spirits bright. Oh, what fun!

6
Dec

Meta-haiku

   Posted by: rew   in General

Hey, you hear that sound?
That’s the sound of seventeen
Syllables ringing.

There’s lots more such drivel here.