While working on my forthcoming checkin.to project, I needed to use the MediaWiki API to get the summary paragraph of wikipedia articles pertaining to places. Checkin.to relies on the Yahoo Where On Earth Identifiers (woeid). Yahoo also conveniently offers a concordance API so from the woeid I get the Geonames ID and the Wikipedia page ID among other things. As far as I can tell, the MediaWiki API doesn’t allow you to request page content using the page ID so the first step here is to resolve the page id into a unique page title. This can be done using the query action like so:
http://en.wikipedia.org/w/api.php?action=query&pageids=49728&format=json
It gives a response resembling:
{"query":{"pages":{"49728":{"pageid":49728,"ns":0,"title":"San Francisco"}}}}
Step 2 is to get the actual page content. There are a variety of formats available including the raw wiki markup, but for my purpose the formatted HTML is much more useful. We also need to convert the spaces in the page title to underscores. The request looks like this:
http://en.wikipedia.org/w/api.php?action=parse&prop=text&page=San_Francisco&format=json
And a response resembling:
{"parse":{"text":{"*":"<div class=\"dablink\">This article is about the place in California. [...] "}}}
Step 3 is to parse the resulting article html and extract just the first body paragraph which typically summarizes the whole article. The problem here is that a bunch of other stuff including all the sidebar content comes before the first body paragraph and that other stuff itself can include p tags. jQuery is a big help here, as usual. First, lets wrap the entire resulting wiki page in a div element to give everything a root. Then we can first just the simplings of that wrapper element to find the first root level p tag.
wikipage = $("<div>"+data.parse.text['*']+"<div>").children('p:first');
Below I have the entire resulting function that goes from page id to summary paragraph and appends it to a <div> somewhere in my DOM called #wiki_container. I also perform some optional cleanup including removing citations, updating the relative hrefs to absolute hrefs pointing to http://en.wikipedia.org, and adding a read more link.
function getAreaMetaInfo_Wikipedia(page_id) {
$.ajax({
url: 'http://en.wikipedia.org/w/api.php',
data: {
action:'query',
pageids:page_id,
format:'json'
},
dataType:'jsonp',
success: function(data) {
title = data.query.pages[page_id].title.replace(' ','_');
$.ajax({
url: 'http://en.wikipedia.org/w/api.php',
data: {
action:'parse',
prop:'text',
page:title,
format:'json'
},
dataType:'jsonp',
success: function(data) {
wikipage = $("<div>"+data.parse.text['*']+"<div>").children('p:first');
wikipage.find('sup').remove();
wikipage.find('a').each(function() {
$(this)
.attr('href', 'http://en.wikipedia.org'+$(this).attr('href'))
.attr('target','wikipedia');
});
$("#wiki_container").append(wikipage);
$("#wiki_container").append("<a href='http://en.wikipedia.org/wiki/"+title+"' target='wikipedia'>Read more on Wikipedia</a>");
}
});
}
});
}
As I explained in my last post, Yahoo! claims their Firehose is a real-time streaming API and it’s not. So to make life a bit easier for app developers I wrote a python wrapper that provides a continuous blocking interface to the Flickr polling API. Effectively it emulates a streaming API by stringing together frequent requests to the flickr.photos.getRecent results. And it’s dead simple.
import PyFlickrStreamr
fs = PyFlickrStreamr('your_api_key_here', extras=['date_upload','url_m'])
for row in fs:
print str(row['id'])+" "+row['url_m']
You can download the package from pypi or fork the source code on github. Have fun.
The web has been on a big trend of real-time for the past couple years. Friendfeed was one of the first services to show real-time updates across your social network and real-time feeds took the stage in a big way when Twitter started its streaming API. In April, Yahoo! announced it’s Firehose API claiming “it includes a real-time feed of every public action taken on our network”. The thing is, this isn’t a “feed” or a “stream” in the same sense that Twitter’s streaming API is. It’s a database you can poll with Yahoo’s YQL, an SQL like query language. Sure, the updates may be available in their database in near real-time, but to receive them you need to issue a new request. In fact the only way you know if there are updates is to continuously poll the service. A feed would be something like long-polling with HTTP server push (what twitter does) or PubSubHubbub.
It may be just semantics to some, but this bothers me. To those of us who build applications that publish or consumer real-time information this is a very important distinction. I plan on writing a python library that wraps flickr’s polling API into a “real-time” blocking continuous stream for a project I’m working on. I’ll publish the code on github and post it here when done.
Since everyone is using short urls these days and sometimes we just need to know where that URL leads I wrote this handy little function which finds out for us. Redirection can be a kind of tricky thing. We have 301 (“permanent”) and 302 (“temporary”) style status codes and multiple layers of redirection. I think the simplest approach to take is whenever the server returns a Location http header and the value in that location field is not the same as what you made the request to, we can pretty well be sure that it’s a redirect. The function below uses the http HEAD verb/method to request only the headers so as not to waste bandwidth and recursively calls itself until it gets a non-redirecting result. As a safeguard against infinite recursion I have a depth counter.
import urlparse
import httplib
# Recursively follow redirects until there isn't a location header
def resolve_http_redirect(url, depth=0):
if depth > 10:
raise Exception("Redirected "+depth+" times, giving up.")
o = urlparse.urlparse(url,allow_fragments=True)
conn = httplib.HTTPConnection(o.netloc)
path = o.path
if o.query:
path +='?'+o.query
conn.request("HEAD", path)
res = conn.getresponse()
headers = dict(res.getheaders())
if headers.has_key('location') and headers['location'] != url:
return resolve_http_redirect(headers['location'], depth+1)
else:
return url
I couldn’t find any good examples on simple tween of a skew effect in actionscipt 3 so I thought I’d share what I came up with.
The problem is that skew is not a property on the MovieClip like x or height or others you’re used to tweening with fl.transitions. To apply a skew effect in AS3 you need to use a matrix transform like this:
import flash.geom.Matrix;
var matrix:Matrix = new Matrix();
matrix.b = _y * Math.PI/180;
matrix.c = _x * Math.PI/180;
matrix.concat(target.transform.matrix);
my_mc.transform.matrix = matrix;
or
import flash.geom.Matrix;
var matrix:Matrix = new Matrix(1, _y * Math.PI/180, _x * Math.PI/180, 1, 0, 0);
my_mc.transform.matrix = matrix;
where _y or _x is the skew angle in radians. Unfortunately when you update a property of the transform matrix like
my_mc.transform.matrix.b = _y * Math.PI/180;
it doesn’t update the movieclip. You need to actually re-assign the matrix to trigger an update. So you can’t simply tween the my_mc.transform.matrix.b directly. Here’s my solution.
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.geom.Matrix;
var mymatrix:Matrix = new Matrix(1,0,0,1,0,0);
function reassignMatrix(e:TweenEvent) {
bg.transform.matrix = mymatrix;
}
var bgTweenSkew = new Tween(mymatrix, 'b', Regular.easeOut, mymatrix.b, Math.tan(_y * (Math.PI/180)), 10);
bgTweenSkew.addEventListener(TweenEvent.MOTION_CHANGE, reassignMatrix);
Note this will overwrite the scale and rotation properties, which are a part of the transform matrix. See the Adobe livedocs for more information.
When you use a computer enough it can start to feel like the mouse becomes a part of you. Very quickly you forget about consciously moving it right or left to control the cursor as it becomes second nature. Essentially it is an extension of your physical self, with which you manipulate the screen as naturally as you pick up an object with your hand. Combined with a keyboard it is the only form of input for most ‘serious’ video games in the home because of the level of precision required. I think there are other forms of input that can be used in conjunction with traditional mouse and keyboard for a much richer, more immersive experience.
- Eye tracking
- Voice control
- Video gestures
Eye tracking has been employed in usability and behavioral studies for over a decade, but it has so far been demonstrated only in a very limited sense for actual control input. These two videos demonstrate eye tracking as used for controlling camera movement instead of the mouse and aim instead of what would normally be a physical gun in an arcade.
In the case of a free camera the player moves the camera by looking towards the edge of the screen. When the eyes are centered the camera is still. This is the same kind of control that a joystick uses. Without having tried it myself, I feel like it could be unintuitive because when we look at something we don’t expect it to move away. With the second example you can see that with a fixed camera in place of a physical gun, eye tracking is quite effective, but I don’t see any major advantages over the traditional method.
In first person shooters I feel the best combination will be mouse for camera control and eye tracking for aim. When you look at something on the screen it doesn’t move away – you shoot precisely where you look. Gamers can use the same intuitive interface they’re already used to for moving the character around and firing the weapon. For the quickest, most precise control of aiming, the lighting fast twitch reflex of eye movement is perfect and, in fact, is something players already do.
In 2005, Erika Jonsson of the Royal Institute of Technology in Sweden conducted a study of the methods I described and arrived at similar conclusions:
The result showed that interaction with the eyes is very fast, easy to learn and perceived to be natural and relaxed. According to the usability study, eye control can provide a more fun and committing gaming experience than ordinary mouse control. Eye controlled computer games is a very new area that needs to be further developed and evaluated. The result of this study suggests that eye based interaction may be very successful in computer games.
The problems facing this method are primarily the cost of hardware. Current technologies are used in a limited fashion with academics and usability studies and are generally not available in the mass market. Accurate eye tracking is apparently not an easy thing to do. I’m guessing that, were there a serious market opportunity, some enterprising group of young researchers could simplify the hardware and prepare it for mass production, bringing costs down to reasonable levels for a luxury product.
Voice control can be used for high level commands that might otherwise be accessed from menus or other complex key commands. By using voice it saves the player from having to break from the immersive experience of controlling the character. It has the additional side effect of engaging other parts of the brain and encourages more realistic style of interaction that people encounter in daily life.
The jury is still out on whether people like talking to their computer. I think reception of it will rest, as usual, on the intuitiveness of the commands. The game should never force the player to use voice commands – there always needs to be another path of access – and the player should never have to remember what that command or sequence is. You just say what you want to happen. I think this could be especially interested in non-linear story lines where the options aren’t necessarily clear to the player. Instead of selecting from a menu of pre-defined choices the player could explore (as long as they don’t feel they’re searching in the dark).
Video gestures have been used as a fun, gimmicky activity with the PS3 eye and soon with microsoft’s project natal, but I haven’t seen a use that actually results in interesting game play with what we call “serious” games. One idea is to take hints from the camera and not direct input. When communicating with team mates in multiplayer a user might say a command in voice chat and point in a general direction relative to where he’s looking. The camera could take that hint and cause his character to also point in that direction. This is not something that can be used for precise control, but we can attempt to mimic non-essential body language as added value.
When combined with voice command video gestures could enhance the level of realism and natural interface. For instance the direction of the face could indicate whether the player is giving a command to the game or talking to another person in the room. In story telling dialog, more than one player can input and the video indicates which one of them is talking. Again, I think the best we can do with camera input at this point is imprecise input. Project natal looks like it might do a great job in the casual games space, but we’ll have to see it in the wild controlling games by 3rd party developers.
As a network visualization tool, node graphs are an intuitive method of communicating relationships between entities. I’ve been thinking a lot about the semantic web lately and thought it would be cool to visualize all of the links between articles in Wikipedia at once. I want to pull back and get the 10,000 foot view of the state of modern knowledge, which I don’t think has been done before in a comprehensible way. Chris Harrison’s WikiViz project comes closest but it quickly becomes incomprehensible and is not dynamic.
I have not yet found a tool capable of pulling this off. There are two key ideas that go into representing information at such vast scale. We need to be able to show detailed information in a narrow focus but not get bogged down when zoomed out, which means you need to represent the graph at different resolutions. This has been a problem solved for seeing images at scale. Google earth represents the earth at vastly different resolutions and gigapan is able to zoom into images of many gigapixel size. Second, the kind of information you’re displaying needs to make sense at any height. That means when you’re looking at the graph from 10,000 feet it shouldn’t devolve into a gray blur. Google maps also demonstrates this by removing detail such as building names and street names, cities, and states when you zoom out. Because I’m a gamer I’m inspired by Supreme Commander which developed an innovative way of showing tactical information. You can zoom out to see the playing field as a whole and seamlessly zoom in to examine an area in detail. When zoomed out, individual units become symbols that still convey what the unit is.
At a detailed level a single node could contain basic information including the name, some classification, and perhaps a summery. We can use a sunburst style visualization to represent links. As you zoom out that detail gradually disappears. At a high level less significant articles can be represented by generalized concepts. Higher yet, even more general concepts begin to swallow up the more specific ones. The higher you get the more general the concept. Less significant links between concepts fade into the background. The big challenge is reliably building a concept tree for any node in Wikipedia. A lot of research and effort has gone into that area, but it’s not quite there yet. People would be forgiving of the accuracy to start with.
So here’s a summary of the requirements for a tool to visualize Wikipedia
- Must handle 3.2 million nodes and tens of millions of edges (links)
- Must be able to modify the graph dynamically to highlight changes in real-time. This means we need something other than the standard spring plotting algorithm which runs in computational complexity O(n^2).
- Must be able to represent clusters of nodes symbolically as concepts and gradually move between level of detail
- Must be able to operate with partial graph data. The client application will see only a small slice of the network at once or a high level view of a larger area at a low resolution.
In my brief analysis there are very few tools designed to handle large data sets dynamically. AI3 has a list of 26 candidate tools for large scale graph visualization and although some are visually stunning and some are large scale, none satisfy the requirements above. It seems like the major innovation needed here is a map-reduce style algorithm for undirected graphs. Map-reduce works well with a tree structure, but not as well with unstructured, cyclic graphs. In Wikipedia any node can be linked to any other node and there’s no consistent parent-child relationship. Everything is an “unowned” entity. If a comprehensive and reliable concept hierarchy could be generated from Wikipedia links and text we might be able to use that as the tree-like structure where each level of the tree roughly represents one resolution of the network.
Anyway – that’s something to think on.
Here are some more links of interest:
http://cytoscape.org/screenshots.php
http://arxiv.org/abs/cs/0512085
http://blog.semanticfoundry.com/2009/06/01/dynamic-visualization-introduction-theory/
The problem: people generally have very little perspective of the actual scale of the contributing components of climate change or the effects of different proposed measures to stop it. What percentage of CO2 emissions are a result of city residential electrical consumption vs agriculture vs vehicles? How much of a difference will legislation X make in the big picture? When Obama says that the United States will cut greenhouse gas emission 80% by 2050 what kind of effect does that actually have? What would happen to the weather in 10 years if everyone in the world stopped driving tomorrow?
The solution: Let people build hypothetical scenarios themselves. Design an interface centered around an attractive time line graph indicating climate data in all its various forms including temperature increase, carbon emissions, and sea level. Curious users can click on and off different proposed solutions to see the real overall effect on projected emissions along with dollar cost over time. Group data in terms of current relevancy such as proposals being discussed at the climate summit in Copenhagen this week. Include competing predictions from different agencies and scientific groups to communicate the level of uncertainty.
Extra credit for building a system to automatically pull in current data from a variety of sources.
I haven’t really used this space to send out personal updates as of yet, but that’s partly what I mean it for. In years past I kept a frequent blog about my travels and adventures, but since becoming boring that kind of tapered off. Tonight I’m feeling a little inspired.
I kept up with my nomadic tendencies by moving (somewhat blindly) back to San Francisco last month. The intention is mostly to surround myself with techies and the Bay’s zany brand of artistic expression while staying away from the Midwest’s bone-chilling winter. So far so good. I’m constantly surprised by all the times I hear guys at a bar intensely debating their new iPhone app or walk into a coffee shop at 2 in the afternoon to find it full of people on their laptops adorn with jQuery or facebook or name-your-startup stickers. I’ve already been to a few of silicon valley’s famously excessive dot com parties with flashy performances and dance clubs offering all-night open bar for hundreds of people. And only in San Francisco will you find friday night events taking place in some converted warehouse combining lectures on neuroscience and synesthesia with street art and house music until 2am. My favorite. I’m subletting a room in a nice apartment for the time being (pic, pic).
So far I have tended on reclusive productivity, trying to finish a couple long overdue freelance jobs that have been hovering about for quite some time. I also started working on some exciting startup ideas. Check out tweet-pulse.com for a little tease of one. Mysterious, I know. Others involve more heavily my ambitions for artificial intelligence, but I discover more and more how difficult that can be with no capital and no graduate degree. I’m contemplating graduate school, which would be the expected path, but I really prefer to learn by doing something practical. I would love for someone to pay me to work on something related to robotics while I hone my skills in more abstract machine learning techniques, but those opportunities are few and far between. They do exists – I had one interview for a job I would have loved – but it feels like 90% of the work these days is with web-related ventures.
I’ve had enough of that. In fact, I’m setting a guideline for my upcoming job search that I won’t look at companies which deal only in the web space because frankly I’m tired of that work. I’ve done it for the past seven years both freelancing and fully employed and it lost most of the appeal when it was no longer a theoretical challenge and only an implementation challenge. I like to work on problems that I go to bed thinking about and wake up having been enlightened by some other-dimensional thought pattern. Or perhaps to experiment with methods mysterious enough that the results surprise me.
Over the next 30 days I need to decide which of the three-sided fence I’ll hop over to. I know I would benefit from working with a company on a project larger than myself and with mentors more experienced that me, but I’m scared that I’ll find that work less than fulfilling. I also know I’ll miss, in some ways, being my own boss, which has been my natural state almost exclusively so far. Some of the biggest and most successful names in technology have gone their own way and found it better than any other, but I could just as likely find it longer and more strenuous. The third side of this curious tri-fence is graduate school. Oh what potential, oh what a loss of time. I welcome your counseling.
In the past two months I’ve been randomly contacted by a number of head hunters hiring for positions both in Chicago and on the west coast. In a time when so many people are looking for jobs, some recruiters actually seem to be coming to me. I know that a number of friends in the industry with at least a little proven track record have been experiencing the same thing. One of the keys, it turns out, is to have your own blog and resume (cv) online. Check out this google hit that showed up on my site’s analytics yesterday, for example. “.pdf” and “Java” “chicago” CV
This particular person was in the UK (Chicago financial companies often use London based recruiting agencies). I’ve seen similar searches coming from networks of big companies that we all know.
So keep your resume online, keep it current, and blog.