
All Roads Lead to Jack
dom - aprile 20, 2008, 17:27:01
Twitter mapping software, source, known issues
One evening, while browsing Twitter, I noticed something funny: choose a twitterer; then, click the first Twitter profile image in that twitterer's "Following" block. If you continue to do this for each twitterer you encounter, it's extremely likely that you'll end up at Jack Dorsey's Twitter page. This worked for virtually every twitterer I follow, and it even seemed to work for most people on the public timeline.
While there are some obvious exceptions (twitterers who don't follow anybody and are just status updaters, like twitter_status), as well as circular references (which Jonathan Rentzsch pointed out), it's amazing how well this rule holds.
Well, maybe not if you consider who Jack Dorsey is. He's one of the employees of Twitter, Inc. and is likely the first one to ever have a Twitter account, given this interesting observation.
From that observation, though, sprang a fun problem to be tackled: how do twitterers relate to one another? Who a twitterer follows is public knowledge, so wouldn't it be cool to see if you could figure out the shortest distance between any two given twitterers? It's the "six degrees of separation" question all over again, applied to a social network which allows the public to have the necessary information to answer the question. It's just begging to be to have someone come along and answer it.
There was just the right mix of interest, motivation, procrastination, and knowledge that I decided to tackle the problem.
This is exactly why I love Twitter: by getting into the habit of writing down what you're thinking, others can give you pointers, useful links, advice, etc. Google is expansive and broad, but Twitter can provide specific knowledge that Google would be hard-pressed to give you.
What's great about this project is that the bar wasn't too high, so I could get meaningful results from the project relatively quickly. (In my "main" "profession" as a student, this has recently become a problem for me, so instant gratification was a pretty important ingredient.) Twitter allows you to get a list of who a twitterer followers incredibly easily and in a well-defined format. Cocoa provides frameworks that allows me to extract info from this XML format quickly and without too much trouble. I remembered enough from my undergraduate CS classes to know how to tackle this kind of problem, and Twitter was able to provide me with some ready-made classes, through Jonathan Wight, a friend on Twitter.
Chain Search Theory and Practice
And so I started coding up the app. The first issue to tackle was how to guarantee that the path between two twitterers the app finds is, in fact, the shortest path between those two twitterers. This is not only important just in terms of curiosity, but given how the search will expand exponentially, the app needs to prioritize somehow so that the search won't take days.
I remembered from CS class about a priority queue. With a regular queue, you feed objects to the queue, and when you query the queue for the next object, you receive objects in the order in which they were inserted. This is the "first in, first out" (FIFO) model, as opposed to the "first in, last out" model for stacks. Think of a stack as an airplane full of people: if you're the first on and you go to the back of the airplane — so as to optimize the loading time — then you'll be the last off, because it'll faster for people in front to get off first. Unfortunately, airplanes don't work like this in practice; for some reason, airlines stupidly load people in front rows first. This is probably because first class and business class are typically at the front of the plane.
A priority queue, however, slightly modifies how a regular queue works. Each object you feed into a queue is given a priority, and as you may have guessed, objects with higher priority come out of the queue first, even if they weren't necessarily the first object into the queue.
The priority queue is perfectly suited to tackling the shortest path problem. One of our assignments in CS class was precisely this: to find the shortest distance between two cities given a map of destinations and distances between certain destinations. The priority, in this case, is the distance: since you want the shortest path between two cities, shorter paths should bubble up to the top of the priority queue.
In solving this problem, you create a priority queue of partial paths. From the origin, you get a list of neighbors from that origin. Create partial paths from the origin to the neighbors, and feed them into the priority queue, using the distance as the priority. Then, take the first partial path from the queue (which will necessarily be the shortest partial path), and repeat. When you add a new city node to a partial path, you also modify the priority of that path by adding the existing distance and the distance to the new node. Using this method, you'll eventually find a path between your two cities that is guaranteed to be the shortest path.
Note that bigger numbers usually indicate higher priorities, whereas we want smaller distances to have higher priorities. In my app's source, I actually start from zero and subtract one each time I add a new node. Thus, the priority is the opposite (or the "additive reciprocal") of the distance.
This is exactly how my app works. In practice, the problem applied to Twitter is a bit simpler, because each step in the chain is the same distance in the virtual world (as opposed to potentially different distances between cities in the physical world). But to a priority queue, that's just a detail. My app simply adds one to the distance each time I add another node to the partial chain.
There are a couple other wrenches that Twitter throws into the equation. First, there's no guarantee that there actually is a path between any two given twitterers. Consider the case of two twitterers, each following each other but following no one else. If you tried to initiate a search for a path between one of those twitterers and a twitter outside their reciprocal circle, you'd end up searching through all of Twitter — or at least all of Twitter that's connected to your start twitterer.
Unfortunately, there's no way to solve this problem. It's impossible to know if a given twitterer is isolated from any part of Twitter. If this is the case, my app runs until it has encountered all nodes connected to the starting node. But with an estimated 880,000 people on Twitter, that'll be a long time. Given the exponential nature of Twitter, however, it's highly likely for there to be no isolated communities. It only takes one twitterer on Twitter to follow one member of that isolated group to make the community "connected" and my app able to find the connection.
To be fair, all people who follow more than 100 people aren't blowhards. I would put the bar closer to 500 or maybe 1000.
The other problem is with Twitter "blowhards". I'm tempted to call them "spammers", but that's a bit disingenuous. Twitter blowhards are those twitterers who follow a ridiculous number of people — sometimes into the thousands — that it's impossible for them to actually keep up with the tweets in their personal timeline. There's just no way. I follow 58 people and already I am overwhelmed with the Twitter backlog, sometimes.
While Twitter blowhards aren't an exception in theory, they are with Twitter in practice. When fetching a twitterer's list of people who they follow, by simply visiting "http://twitter.com/status/friends/%@.xml", where "%@" is the Twitter name of the twitterer in question, Twitter only returns the first 100. This means that I'm unable to access info on some connections. As an example, I follow Jonathan Rentzsch and he follows me as well, but you wouldn't know that if you downloaded his Friends XML file.
How does this affect my app? Well, it simply means that my app can only find the shortest path based on the available data. Calculating a path between Rentzsch and me means going through Bill Bumgarner instead of using the direct connection. Again, however, given the highly interconnected and exponential nature of Twitter, typically this only adds one more degree of separation than is actually necessary.
I've already mentioned how easy it is to get the list of people a given twitterer follows: simply visit "http://twitter.com/status/friends/%@.xml" with the twitterer's Twitter name in place of "%@". NSXMLDocument, a standard class in Cocoa starting with Mac OS X 10.4 Tiger, also makes it easy to extract info from that XML file. I don't have to do any text scraping whatsoever. It's too bad, though, that you have to know a twitterer's name and password in order to get the list of people who follow them. This makes it impossible to create two-way graphs of Twitter. It's also a strange restriction, given that you can still figure out a twitterer's followers by visiting their Twitter pages.
Optimization
Now you've got an app that finds the shortest path between two twitterers given the available information. Now what?
Well, these searches aren't trivial, and may take a while. So what can we do to speed things up?
There's one trivial optimization that can speed things up considerably. With Twitter, people are connected to so many other people that there's bound to be twitter loops, where one twitterer follows another, who follows another, who follows the first twitterer. Any twitterer chain that contains a loop is guaranteed to not be the shortest distance between two twitterers. This isn't to say that the priority queue will ever favor chains with loops. In fact, using this method, you'll never get a chain with a loop as the shortest path since that same chain without the loop would have been encountered first using the priority queue.
But these chains with loops still gum up the system. A chain of twitterers with distance 2 that contains a loop, such as me following @rentzsch who follows me again, will be prioritized in a queue over a chain that does not contain a loop, but which is nevertheless longer such as @buzz to @manton to @SenorDanimal to me.
Again, I want to emphasize that this doesn't mean the chain with the loop will end up being the winning chain. That same chain without the loop would have a shorter distance and thus a higher priority, so a chain between the two endpoints that doesn't have that loop would already have been found by that point. That the chain with a loop comes off the top of the queue simply means that there is no chain between the two endpoints that is shorter than the chain with the loop.
We don't like these chains with loops. And despite them being seemingly innocuous since they're never "winning" chains, they still cause the app to go slower because it wastes time using these chains at all. Preventing them is simple: stop them from getting into the queue in the first place. Keep a global list of nodes that have already been encountered, and don't add them on to the end of any more chains. (In practice, this means simply adding each Twitter name to an NSArray, and then calling containsObject: at every node that is encountered.) This prevents any given twitterer from appearing in any given path more than once.
But wait!, you might say. This excludes more than just simple loops! If I encounter @boredzo from @simX in one path, keeping a global list of nodes that have already been encountered will prevent @boredzo from appearing in any other path besides the one from @simX, even if @boredzo isn't in that path! For example, if I encounter @simX --> @boredzo, then @simX --> @timburks --> @boredzo will be barred from entering the queue!
Ah, but this is good. @simX --> @boredzo is shorter than @simX --> @timburks --> @boredzo. And since @boredzo is the end twitterer of both partial chains, we know that the set of subsequent chains that will be spawned from both of these chains will be identical, except for this initial part. So why not go with the shorter path anyway, and not make the app search the same paths twice over?
Are there any other optimizations that we can add? None that I can think of, at least given the limitations of a single computer. I can imagine a method of giving further priority over certain paths based upon their "proximity" to the ending node. For example, if I wanted to find a path to @rentzsch, I know that he has a strong following in the Mac community. So I could prioritize partial paths that end up in this community, like @schwa, @cbarrett, and @bwalkin. It's possible that they may not follow @rentzsch, but they have a higher likelihood of doing so since they're in his community, as opposed to someone like @sandrift, who might be more connected with geologists.
This kind of data, however, requires a "pre-scan" of the Twitter community, and given how large Twitter is, this seems infeasible not only in terms of time but also in terms of resources on disk. This would probably be more appropriate if my app were a web app, where any chain searches would add to the collective "knowledge" of the web app, in contrast to discrete desktop apps that can't communicate past searches or following data with each other.
How about optimization not in terms of graph theory, but in terms of structuring the program to minimize general bottlenecks? One of the main issues in this case is simply that it takes time to download the friends XML files. How do I eliminate that as a bottleneck? Two ways: multi-threading and caching.
Instead of downloading the XML files just as I need them, which necessarily requires the app to wait for the download, why not prefetch the XML files in the background beforehand so that they're ready to be used as soon as the need arises? My app does indeed do this, using new objects in Mac OS X 10.5 Leopard called NSOperation and NSOperationQueue.
When the app encounters a twitterer node, it needs to download the list of people that twitterer follows in order to add new chains to the partial queue. However, it doesn't use these chains immediately, because we're using a priority queue — adding a node to a chain increases its length and decreases its priority, so simply adding another node might mean that there's another, shorter chain that needs to be attended to first.
But we already have a list of the people who that person follows, and eventually we'll need the friends XML files for those people too! So when a new chain is added to the queue, the friends XML file for that last node is queued up to be downloaded. The beauty of this is that since the priority queue still uses a FIFO method for chains of the same priority, the prefetch operations will be initiated in exactly the order they'll be needed! The prefetch operations are just offset to be earlier than when the XML files are actually needed, but they're still in the same order. So there'll be no bottlenecks where an XML file being downloaded is not the one currently needed. Most of the time the XML files will be fully downloaded by the time they're needed, but if not, we're guaranteed to be currently downloading the XML file that we need the most.
I'm actually using another queue for the XML file prefetching, but this one is a simple queue, not a priority queue, since everything will already be in the order we need them. NSOperationQueue is also really handy, because it can take care of dependencies and automatically distribute operations across multiple threads. In this case, dependencies aren't an issue, since, as demonstrated earlier, the XML files are already in the desired order. (There could be a problem with detecting whether a given XML file download is completed or not, but I'll address how I handle that in a bit.) All I had to do was subclass NSOperation and create the self-contained code that downloads the required XML files. The only communication that these NSOperations have with other parts of the app are the initialization (where the name of the twitterer is passed to the NSOperation), and a notification that the NSOperation sends out if there's an error downloading the XML file.
As noted before, NSOperation and NSOperationQueue are Leopard-only, so this limits my app to run on Leopard only as well. I tried manually managing threads by spinning off a thread per XML download, but this created so many threads that it consistently crashed my Mac to the login screen. I also tried manually limiting the number of threads myself using a counter, but this posed problems of its own. (In fact, I implemented an activity window that monitors how many NSOperations are in the NSOperationQueue. If you're doing a search between two random twitterers from the public timeline, this number can easily reach 100,000, because the number of nodes that are encountered grows exponentially. No wonder that spawning one thread per download causes significant problems.)
By default, NSOperationQueue seems to allow 70 or so NSOperations to be running concurrently on my Mac, but in my experience that made the user interface of other apps go pretty slowly while the search is running. NSOperationQueue allows you to fine-tune this number, so currently my app limits the number of concurrent operations to 30, making its CPU usage stay consistent at about 50% (or 100% of one core if on a dual-core Mac). This makes it feasible to run a search in the background.
One other benefit of NSOperationQueue is that it allows me to cancel operations that are no longer needed. Consider the point in time where my app finally finds a chain between the two twitterers. But since XML prefetch operations are initiated one degree of separation before the files are actually needed, there will still be thousands of operations left in the queue that will continue to download XML files if the app remains open. NSOperationQueue can discard any operations that have not yet been initiated, and if you write your code correctly, you can even have currently running operations stop without completing.
In short, NSOperationQueue was just too good to pass up. So, yep, if you want to use my app, you'll have to shell out the $129 for Leopard or get a new Mac. :P
Question for the reader: how many times will a given XML file be used per search?
I mentioned that caching was another method of optimization. Each XML prefetch operation simply downloads the XML file to disk, where it is (virtually) instantaneously accessible to my app. But that's not the only reason why these XML files are stored on disk. If you complete one chain search and then initiate another, my app doesn't have to redownload the XML files for each node all over again.
Of course, if a twitterer follows some new people, or decides to de-follow some, my app won't know this because it found an existing XML file on disk and decided it didn't need to fetch the file from the internet again. This problem can be mitigated by checking the modification date of the XML file and discarding it if it's more than a week or so old. My app currently doesn't do this, but it's a modification that I'm definitely going to implement soon. (Besides, there's a workaround: you can just delete the cache files and this will force my app to redownload the XML files.)
Cache files for my app live in ~/Library/Application Support/Degrees of Tweetdom/ . I decided to house them here instead of in the "Caches" folder because they have a significant effect on how fast a search completes.
What's the disk usage of these cache files? Well, they can range anywhere from 4 KiB to 124 KiB or so each. I have a cache folder that currently contains just under 150,000 XML files and takes up 3.29 GiB on disk. Clearly this is not a trivial amount of space. But with disk space so plentiful and cheap, and with the cache files so easily removable, I find this is a small price to pay for an interesting, experimental app. (One other potential optimization that I'm considering is downloading the XML file and reformatting it so that it's simply a return-separated list of people that twitterer follows, and stripping out all the extraneous XML that's included. This has the potential to significantly cut down on disk space.)
I mentioned earlier that I didn't need to use the dependencies feature of NSOperation. In this case, it'd be difficult to check whether a given operation was finished without having to perform an expensive search through all currently queued operations (which easily gets into the tens of thousands). Instead, since the operations saves the XML file atomically ("atomically", not "automatically" — that is, it writes to a temporary file, and once it's finished writing, it moves the file to its correct location), I can simply check whether that XML file exists yet using NSFileManager. If the file does exist, then it's ready to be used (guaranteed by the atomic write). If not, I tell the app to wait for a second and then check again. If it doesn't find the XML file in 10 seconds, it times out, discards that chain, and moves on to the next chain from the priority queue.
Maps
Well, if you've gotten this far, I'm sure I've whet your appetite for something even cooler. Yes, folks, if you can search for a chain, then you can do searches for multiple chains, and from multiple chains you can make a map. So why not have my app automate all that, too, and build maps of Twitter users, too?
That's what I said. And my app does. Heehee, it's so much fun!
Again, though, I want to direct your thought impulses to the nature of the problem. How does one implement a map creation program like this?
Well, we've got the fundamental part down: we can find the shortest path between any given two twitterers with enough time and disk space (with the information available). Creating a map simply means that you're finding multiple chains between multiple pairs of twitterers and graphing the results on the same page.
That's easily done. Given a list of twitterers, simply create a list of all possible pairs between themselves, and then find the shortest chain between each pair. Then graph the results. Simple, no?
Well, sure. But there are all sorts of things that crop up: first off is the fact that we only have information on who people are following, not who is following someone. This means it's a directed graph; relationships are only one way: you can only follow someone else. (That you can be followed is simply a side-effect of them following you.)
The implication is that if you are following someone, that person does not necessarily follow you back. The relationship is not commutative or abelian; the shortest path from @mdmunoz to @command_tab (@mdmunoz --> @bwalkin --> @command_tab) is not the same as the shortest path from @command_tab to @mdmunoz (@command_tab --> @timburks --> @mdmunoz). That's why it's a bit misleading to talk about the "shortest path between two twitterers".
The upshot is that if you're graphing the shortest paths between three twitterers, you actually need to perform 6 searches, not 3. Graphing four twitterers means performing 12, not 6. You're doing twice as many searches as you might think you need to do. For random twitterers, this is a significant amount of time.
Now think about how you would actually do the searches. Would you just perform them one after another? If so, you might completely pass up one chain between two twitterers while looking for a chain between two others, only to re-follow the very same thousands of partial chains later to find that chain you passed up. For example, searching for a chain from @buzz to @boredzo will pass through @buzz to @command_tab on the way. It'd be much faster to specify a single start twitterer and an array of end twitterers, and capture all of those chains in one path. Then start a new search with a different start twitterer. This reflects the current state of my app right now.
But there are further optimizations. What happens if one chain between two twitterers is completely contained within a chain between two other twitterers? @rentzsch --> @iTod, for example, is completely contained within the chain @boredzo --> @rentzsch --> @iTod --> @gruber. How do you detect that? For each chain, do you check whether any other twitterer pair also exists in that chain? It's possible that would cause the app to go slower than a dumb search. I don't know the answer to this question.
One technique I'm considering is to monitor chain searches for other twitterers in the search. When an end twitterer is encountered, add all twitterers in that chain to an array associated with that end twitterer. When that twitterer is again the end twitterer in another search, you can effectively "short-circuit" the search if you encounter any of the other twitterers that existed in that one chain.
For example, let's say I'm searching for a path from @boredzo --> @gruber, and I find @boredzo --> @rentzsch --> @iTod --> @gruber. I add @boredzo, @rentzsch, and @iTod to an array associated with @gruber. Now, if I'm searching for a chain from @mdmunoz to @gruber, I can stop if I find a chain from @mdmunoz to @boredzo or to @rentzsch or to @iTod, since I already know a chain from them to @gruber.
But does this preserve the property of shortest chains? If I encounter one of those intermediate nodes, I now have a valid chain, but do I have the shortest chain? Can I guarantee that using this method? (Any actual insights into these questions would be greatly appreciated.)
Now that I've made your brain weep considering those questions, consider this one: how do you even graph the results? Graphing a chain is easy: it's just nodes on a line. But for a map, how do you guarantee that nodes don't overlap one another on the graph? How do you minimize the crossing of arrows indicating followship? How do you minimize the space taken up by the graph? Do you start with a given twitterer in the graph and draw radially outward? Do you start with a given chain in the graph and draw those nodes in a line? How do you proceed to lay out the other nodes?
This problem in itself gave me headaches and was potentially larger a hurdle than I could handle. Luckily, some great minds over at AT&T have tackled this problem and have an open source graph visualization solution in graphviz. With graphviz, you simply describe the connections in a graph, and graphviz does all the layout for you. Awesome.
Even better, graphviz is licensed under the Common Public License, which allows you to use the code in both open source and proprietary projects, and only requires you to divulge source changes made to graphviz, not to anything it links to. It's a liberal license, compared to the draconian nature of the GPL which bars you from linking to GPL code in proprietary apps. (You still can use GPL code in proprietary apps provided you're simply launching the app and running it rather than linking to it in your code, but that significantly limits its usefulness. Still, GPL-licensed code is not all bad; it's been used in Mac OS X, Acquisition, and Airfoil, all of which are proprietary, commercial products.)
graphviz is pretty cool in that it offers a few types of graphs (hierarchical, radial, energy minimized, and circular), and it allows you to modify many attributes of the appearances of nodes, edges, or the graph. Unfortunately, it doesn't allow you to fine-tune the graph by moving the nodes around slightly. Nor does it allow you to modify the position of node labels, so you either have to use an annoying hack to define a sub-graph for each node (in which case the label appears unacceptably far away from the node), or you have to disable node names entirely. My app disables node names and uses the Twitter profile images instead.
The great thing about graphviz, though, is that you simply produce a text file (file extension .dot) that defines the relationships between various nodes, and then the graph gets rendered by graphviz. Then you export that picture to whatever format you want. This means that you can easily change the .dot file and re-render the graph to modify its appearance.
So let's get to some maps! Maps of Twitter are so much fun, it's ridiculous. I'm practically like a little kid in a candy store waiting for these maps to be produced by my app.
Here's the first Twitter map ever made (that I know of, anyway). I created this by manually searching for the chains between each pair of seven twitterers, and then I manually copied the profile pictures and created the graph in OmniGraffle. It's decent, although it's kind of laid out haphazardly.

The seven nodes that are outlined in double-red lines were the main nodes, and the other nodes are intermediary nodes required to get between the main nodes. Note how with 7 main nodes, 18 intermediary nodes are brought into the mix. It's also interesting how the intermediary nodes stayed within the Twitter Mac community, since the main nodes are all also within the Twitter Mac community.
Let's see how graphviz lays out this same map:

Here the lines are much smoother, and the total length of lines is minimized by strategically placing as many nodes close to each other as possible when appropriate. graphviz uses the concept of "rank", where nodes at the top of the graph are more important and connected and nodes near the bottom are less important and less connected in this graph. This graph represents graphviz's "hierarchical" graph style.
This next graph is extremely fascinating to me:

Can you figure out why?
The map above is the same map as before, but with a "simX" exclusion policy in place. This means that no paths found by my application are allowed to go through me. I anticipated that the change would radically alter the graph — the original seven nodes that I picked were all people whom I follow. Because of that, I thought that many of the shortest chains would go through me. In fact, if they follow me, then the shortest chain to any other main node would be two.
But if you compare the previous two graphs, they're largely the same! The positions of the various nodes have changed, but the relationships largely haven't. Besides me, the only other twitterers that have been removed from this graph are @bbum and @SenorDanimal. There are no new nodes compared to the old graph, either. This illustrates just how interconnected the Mac community is on Twitter. In fact, you could potentially define an "interconnected" parameter based upon how much the relationships and intermediary nodes change if you remove a given node from a graph. If I graphed one twitterer from the Mac community, one from my mini-geology community, and a real life friend, removing me from the graph would probably significantly change the relationships and nodes on the graph (and the time taken to find the shortest paths).
Here's a graph of a different set of main nodes, not all in the Mac community:

This one was pretty interesting because two people whom I follow, @ivanov, a real-life friend, and @anwnn, a friend with whom I interact with on Twitter, both follow and are followed by @stilldavid. I had made a one-degree-of-separation friend out of a previously three-degrees-of-separation-friend without even knowing it.
It's revelations like this that make this app so interesting to me. And it involves mathematics, computer programming that's within my reach, friends, the internets — my cup overfloweth!
Degrees of Tweetdom Binary, Source, Usage
Yeah, yeah, yeah, I know, you want your grubby little hands on this app. Fine. With one stipulation: I can haz ur grafs? Just link them to me (@simX) on Twitter or in the comments to this entry; I don't care if I don't know anybody on the graphs, I just want to see them!
You're also welcome to use and extend the app as you see fit, but again, I would like to hear about what you're doing with my app and see any improvements you've made.
So without further ado, u can haz linkz! But please, keep reading for a few things you need to know.
- Degrees of Tweetdom 0.3 (now with mapping capability!)
- Degrees of Tweetdom 0.3 source
- pixelglow's Mac OS X GUI for graphviz, version 1.13 (v16)
Now for a word from our sponsors about how to use Degrees of Tweetdom.
Both the "Twitterer Chain Finder" and "Twitterer Mapper" windows will appear on startup. You can use the former to find the shortest path between two twitterers, or you can use the latter to create the files necessary to generate a map, but not both at once. The mapper uses the chain finder window. (This'll be changed in a subsequent version.)
In the mapper window, use commas to delimit each twitterer you want on the graph, and each twitterer you want to exclude from the graph. Don't put spaces after your commas, use just a comma between each twitterer's Twitter name.
Don't worry about capitalization of Twitter names. Degrees of Tweetdom will correct that for you automatically. However, it can't correct typos, so take a look at the log for the Twitterer Chain Finder window (not the Twitterer Mapper window) to make sure you haven't made any typos — it'll give you a summary of nodes from which it's starting, nodes at which it's ending, and node which it's excluding.
Graphs will not be displayed in Degrees of Tweetdom. DoT creates a folder on your Desktop called "DoT Twitterer Map", inside of which will be all the profile images you'll need and a file named "twitterer-map.dot". This latter file describes the relationships between all the nodes. You'll need to open it in graphviz to get an image. Be aware that currently, DoT always writes to this same location, so if you want to save the .dot file that describes a graph's relationships, move it to a different location before creating a new map!
Please note, I highly recommend using the PPC-only, version 1.13 (v16) of pixelglow's GUI for graphviz. This is because it's the latest version that seems to recognize custom images to use for nodes on the map. There's a package for the universal binary of GUI version 2.18, which includes tools to use from the command line, but they generate blank nodes with custom images. I'm not sure why this is. Rosetta is your friend, however, and it still runs well and reasonably fast on my MacBook Core 2 Duo.
Also, pixelglow's GUI for graphviz can export to a wide variety of formats (and I suspect that the command-line tool can, too). png is a good format for the web, but if you want to fine-tune the graph, you can export to .ps, .svg, .pdf, and other vector formats. However, none of the vector formats seems to understand custom images, either, and Degrees of Tweetdom suppresses node labels, currently. I've found that OmniGraffle can natively open .dot files, so if you modify the .dot file that Degrees of Tweetdom creates to use labels (open the .dot file with a text editor), you can get the node labels to show up in OmniGraffle and you can re-create the graph manually yourself. There seems to be no way to get OmniGraffle to recognize custom images as well as understand node relationships and reproduce exactly the graph that graphviz does, unfortunately.
If anybody finds otherwise, please, please let me know.
I think that's it! I hope you enjoyed this run-through of my thought process as I was creating this program, as well as any maps that you create. Have fun mapping Twitter!
Tips Permalink

FCC Hearing on Network Neutrality at Stanford
gio - aprile 17, 2008, 23:25:22
entirety of my live-tweeting session plus commentary
In February, the Federal Communications Commission (FCC) held a hearing on network neutrality at the Harvard Law School in Boston. The impetus for the hearing was the revelation that Comcast, a prominent internet service provider (ISP) in the U.S. was actively blocking traffic based upon the protocol it was using; in particular, Comcast was blocking BitTorrent traffic and causing disruption to people trying to download legitimate items, such as World of Warcraft updates and public domain songs.
"Network neutrality" is a broad principle that applies to internet access. Essentially the term means that ISPs should not degrade or block internet traffic based on the type of traffic. This allows all internet traffic, regardless of source, destination, or content, to be treated equally by ISPs. Comcast's selective blocking of BitTorrent traffic is a violation of network neutrality.
Net neutrality is a principle that, de facto, has governed the internet for the past decade or so. There has been no explicit law in the United States mandating network neutrality, but there had never been an instance of an ISP violating the principle of net neutrality until the discovery of Comcast's actions.
Unfortunately, Comcast effectively blocked access to the hearing in February to people who were genuinely interested in the debate, by paying people to take up seats. That caused the FCC to schedule an additional hearing. That hearing was today, and was held at Dinkelspiel Auditorium here at Stanford University. Since I live on the Stanford campus, I thought it would be a good idea to go and listen, and to voice my support for net neutrality.
I ended up live-tweeting the whole event. I arrived at around 12:45 PM, and the hearing continued until 7:30 PM. It was a long day of typing. For easy access, here is a reproduction, in chronological order, of my tweets of today's FCC hearing. Nothing has been edited.
I recommend reading my tweets before proceeding to the following commentary.
| At the FCC net neutrality hearing. Signed up for public comment; they'll pick randomly at 4:30 PM from those who signed up. | 12:00:37 |
| Commissioner: "The internet is a wiki environment." I guess. | 12:04:30 |
| The name tags of the commissioners sitting at the table are in a comically small font that it's impossible to read at all. | 12:13:17 |
| Larry Lessig is here! | 12:15:08 |
| OH CRAP he's (Lessig) doing his annoying PowerPoint presentations. | 12:16:02 |
| P.S. @simX[4] is a quote from Commissioner McDowell. | 12:17:20 |
| @DarksideHalo: It's so small I can't even tell. | 12:17:46 |
| WHAT THE HELL Lessig. "e2e" (end-to-end) is not a canonical acronym. Spell it out! | 12:19:19 |
| Lessig says that "e2e" is now known as "network neutrality". Uh, no. | 12:20:03 |
| Lessig *is* arguing for network neutrality and noted that providers (ISP) conspire against the public. | 12:20:50 |
| Lessig: "We should be conservative. Conservative with a small 'c'." Lol. | 12:22:10 |
| Lessig is making the analogy of the electricity grid — another open "anybody can do anything" grid — as a model for the internets. | 12:23:30 |
| Lol, Lessig showed a pic of Harvard Law School from Second Life, because he couldn't find a real pic. | 12:28:25 |
| Lessig (paraphrasing): "You don't talk about 'trust' of corporations just like you don't talk about 'trusting' a tiger with your child." | 12:30:36 |
| Lessig is against ZPR (zero-price regulation), which he says prevents structured pricing for how fast a person wants their connection to be. | 12:36:40 |
| i.e.: ZPR goes against non-discriminatory "tiering", which is how we pay for the internets now. | 12:37:04 |
| Lessig: "Architecture that works does not depend on 'trust'." | 12:41:05 |
| Lessig sits down to thunderous applause. :D | 12:41:59 |
| President of the Song Writers Guild of America is now speaking. | 12:42:34 |
| @DarksideHalo[1]: No, it is not Comic Sans. | 12:43:18 |
| Oh, whatever. This guy is going on about piracy and how it's destroyed families and has "destroyed the profession of songwriting". | 12:45:36 |
| Carnes: "For speed and safety, consumers would benefit from services of ISPs to filter unauthorized file-sharing." Um, no. | 12:48:03 |
| Michelle Combs, President of the Christian Coalition of America, is now speaking. This should be good. | 12:49:50 |
| Sorry, Combs is *Vice* President of the CCA. | 12:50:22 |
| Huh. CCA supports net neutrality. I thought this was going to be about child pornography. Color me surprised. | 12:51:27 |
| Combs: "The comments from the cable industry, frankly, offends me. As I respectfully suggest, it ought to offend you." LOL. | 12:53:26 |
| Hah! Comcast was blocking BitTorrent downloads of the King James Bible! Hahaha. That's great. I'm surprised by her comments. | 12:54:05 |
| WHAT THE HELL IS GEORGE OU DOING HERE?!?!?!?! | 12:55:25 |
| Yes, *THAT* GEORGE OU. | 12:55:49 |
| Ou is a poor public speaker. He's reading off a prepared speech, and he's still stumbling. | 12:57:17 |
| Ou: "One user taking up four 'flows' takes up four times more bandwidth." What the hell are 'flows"? | 12:58:37 |
| LOL. Ou says that downloading from webspace that ISPs offer is faster than downloading from BitTorrent. Talk about missing the point. | 13:00:00 |
| Jon Peha, professor at Carnegie Mellon University is now speaking. Thank god Ou is not, anymore. anyway. | 13:02:45 |
| Peha "correcting" other panelists. Comcast does not "delay" P2P, it *blocks* it. | 13:03:28 |
| Peha: comcast practices *are* discriminatory, unless Comcast has been blocking all apps. Comcast *does* degrade P2P. | 13:03:54 |
| LazyTwitter: When was Napster first available to use? | 13:07:50 |
| Jean Prewitt, CEO of Independent Film and Television Alliance, is now speaking. | 13:08:34 |
| Prewitt talks about TV as showing how we need proactive measures to protect independent programming/media. | 13:10:04 |
| Prewitt: "Copyright concerns cannot be an excuse to prevent access to the market." YES. | 13:13:01 |
| James Steyer, CEO of Common Sense Media Founder?, now speaking. | 13:15:36 |
| Steyer (paraphrased): "Blah blah kids blah blah blah kids blah blah kids kids blah." | 13:21:01 |
| Robert Topolski of funchords.com now speaking. Actual victim of TCP resets from Comcast. | 13:23:00 |
| Topolski was the one who first posted about the TCP reset packets from Comcast, and is "probably the igniter of these hearings today." | 13:24:24 |
| Topolski says that TCP reset behavior from Comcast has *not* actually stopped, despite Comcast's protestations to the contrary. | 13:26:18 |
| Topolski: "Comcast interferes 24 hours a day." Evidence against the "congestion" argument that Comcast makes for network management. | 13:26:51 |
| Topolski is a ham radio operator. | 13:27:10 |
| Topolski: Blocking is "still impacting users and still impacting developers." More thunderous applause. | 13:28:04 |
| Topolski argues that network management should be opt-in, not something operated secretly by ISPs. | 13:30:10 |
| Topolski was suffering from an illness, one of the side effects of which was insomnia, which is why he could detect reset packets at 2 AM. | 13:31:25 |
| Topolski used ping to find that typical congestion occurs between 3 and 7:30 PM each weekday when kids come home from school. | 13:32:05 |
| Peha: "The fact that this late in the game, we still don't know what they [Comcast] do, is interesting in itself." | 13:33:07 |
| FCC chairman Martin asking Peha clarification on why Comcast calling its practices "delaying" is incorrect. | 13:34:15 |
| Martin clarifies that Carnes thinks that filtering should happen both for music and video. | 13:35:13 |
| Martin asks Ou why ISPs shouldn't just charge consumers more for more bandwidth usage (airplane model). Ou claims no one wants this. | 13:36:50 |
| Lessig argues that metered access is a good way to effect more infrastructure building. | 13:38:58 |
| Lessig says that he's a Comcast customer, pays for the highest speed, and doesn't actually get what he pays for. | 13:39:16 |
| Lessig argues that regulation should make "playing games" (delaying, blocking) less profitable for ISPs than operating a neutral network. | 13:40:37 |
| @boredzo: I'm pretty sure he at least talked to David Maynor. ;) | 13:40:56 |
| Lessig: "I mean it's not... well, it *is* rocket science." (Referring to finding out the truth of Comcast's network practices.) | 13:42:11 |
| P.S. The audience (including me) overwhelmingly applauds those on the expert panel that support net neutrality. | 13:43:13 |
| There were also some boos after some FCC commissioners spoke when they obviously did *not* support net neutrality. | 13:43:42 |
| Topolski says that there's a form at the FCC website, Form 2000F, which you can use to file complaints against ISPs. | 13:45:24 |
| Commissioner: "Time is of the essence. [...] Companies are deciding the future of the internet." | 13:46:54 |
| Commissioner: Should the FCC wait for internal discussions of net neutrality at ISPs before acting? | 13:47:50 |
| Commissioner: Prewitt's comments are similar to a similar debate regarding media ownership, a subject on which the FCC has been unproductive | 13:49:29 |
| According to the schedule, there should have been a break from 2:15 to 3 PM. It's already 2:52 PM, and we're still in the first of 2 panels | 13:52:35 |
| Prewitt: Content providers are "colonizing the internet to look like television." | 13:53:30 |
| Ou claims that TCP resets are widely used. Points to the gaffe by the Univ of Tennessee's firewall that supposedly used TCP reset packets. | 13:55:49 |
| Re: @simX[1]: UoT's "gaffe" was blaming Comcast instead of the university firewall. Ou claims that 12% of connections get reset. | 13:57:11 |
| Sorry, not University of Tennessee, but the University of Colorado. | 13:57:34 |
| Topolski disagrees with Ou, and says that most routers do *not* support TCP reset packets. | 13:58:06 |
| Topolski says that reset packets are correctly used to deny access to ports to which certain connections are not allowed. | 13:59:23 |
| Peha says the issue is about using TCP reset packets as a *control for network congestion* which is *not* standard. | 14:00:03 |
| Topolski says that Cox Communications also uses TCP reset packets to control network congestion. | 14:01:09 |
| Ou says there's a "background noise" of TCP reset packets. It sounds like this guy doesn't know what he's talking about. | 14:01:32 |
| Ou argues that metered internet pricing would kill P2P. Wait, first he's against P2P (saying that it congests the internet), now he's not. | 14:04:37 |
| Commissioner Tate says that consumers don't have info to know if they get what they're paying for, and so the FCC shouldn't decide on NN yet | 14:08:23 |
| Ou claims ISP advertised speeds are "peak." Lessig shoots him down by saying that they should then advertise average speeds. | 14:09:16 |
| @boredzo: But he's using P2P as support for his argument against metered pricing. If he's not for P2P, then he's disingenuous. | 14:10:56 |
| Prewitt thinks that companies can develop tech to deal with NN. But also says end-users aren't represented in the discussion. | 14:12:14 |
| Commissioner Tate talks about utils to analyze connections. Says there's "something called Switzerland". WTF? | 14:13:15 |
| Lessig originally thought that sufficient competition would be enough to ensure NN. Doesn't believe that now. | 14:14:14 |
| Tate: Majority of P2P traffic is illegal. Topolski: No. P2P started the internet. It wasn't a server-to-client connection originally. | 14:15:17 |
| Carnes asked Topolski if he "licensed" the songs he was sharing. Topolski shoots him down by saying that the copyright had expired. | 14:16:28 |
| 42 minutes left on my battery. Crap. Gotta find a plug for the next panel. | 14:17:09 |
| Commissioner asks if any of the expert panels had been paid by ISPs. Specifically asked Ou. Ou says he personally drove here. | 14:18:28 |
| Apparently you can watch this hearing "at home". Radio, TV (C-Span), internet? Anybody know? | 14:19:38 |
| Topolski uses analogy of gas companies secretly changing formula of gas for Comcast's practices. | 14:20:43 |
| Topolski could upload content via eDonkey, but not gnutella. That was the original impetus for the investigation. | 14:21:33 |
| Topolski mentions a company called Sand Bine (?) which has patented the TCP reset packet "in both directions", as per Comcast's practices. | 14:22:52 |
| Via @anwnn: if you want to listen to the hearing, go to http://www.fcc.gov/realaudio/ . | 14:23:37 |
| Ou is getting laughed at because he has no real-world experience of Comcast's practices as does Topolski. | 14:25:12 |
| @stilist: "Sandvine", that's what I thought. The live CC kept saying "Sand Bine". | 14:25:32 |
| @boredzo: Ah, that sucks. Also, "AFAI'mC"? | 14:29:32 |
| End of first panel. 10 minute break. Second panel coming up. We're way behind schedule. | 14:29:58 |
| On the plus side, I found two power strips along the back wall. Sucking up power for my laptop. More live-tweeting to come. :) | 14:30:33 |
| Currently structuring my comments, in case I get to speak. | 14:32:15 |
| LazyTwitter: When did Napster get shut down? 2001? | 14:32:40 |
| So if I get to speak, I'm first going to counter Carnes' and Ou's characterizations of P2P and BitTorrent, respectively. | 14:45:38 |
| (i.e.: best way to combat piracy is to compete with it, BitTorrent actually helps net congestion by distributing load) | 14:46:08 |
| Then I'm going to mention that it's troubling that Comcast packed the first hearing, and that they didn't show up to this one. | 14:46:46 |
| Then I'm going to make a parallel to ham radio and TV, where independent content has been snuffed out. | 14:47:17 |
| I'm going to mention that self-regulation is an unstable equilibrium; it takes one ISP to start filtering, then they all start doing it. | 14:47:50 |
| I'll conclude with a statement saying that we need to take proactive steps to protect the "anyone can do anything" nature of the 'net. | 14:48:34 |
| @schwa, @steve_holt: Thanks. Will need that for public comments. :) | 14:48:59 |
| @boredzo: Gotcha on the acronym, will do on the weblog post. | 14:49:21 |
| Second panel is about to start. | 14:57:16 |
| @wspr: Yeah, I figured I might piss off a few followers, but I'm glad you're enjoying the coverage. This stuff is super-important. | 14:59:51 |
| Barbara van Schewick, Asst. Professor at Stanford Law School, is introducing the 2nd panel. Has a Ph.D. in CS! | 15:01:10 |
| Schewick: 1) filtering sucks. 2) market will not solve problems even w/disclosure. 3) protect conusmers | 15:01:57 |
| Commissioner Tate sits down at her seat 3 minutes into Schewick's intro. McDowell follows soon after. | 15:03:12 |
| Schewick: "The broadband market is an effective duopoly." ++! | 15:05:02 |
| Schewick: "Service providers prefer quick-fixes" to congestion problem. | 15:05:51 |
| Schewick: Network providers don't use the same criteria as end-users do when choosing what apps to use. | 15:07:50 |
| Schewick: Network management should "affect all applications, not make one application the odd man out." | 15:09:42 |
| Jason Devitt, CEO of SkyDeck, is now speaking. Supposedly helps "people take back their cell phones"? | 15:10:14 |
| Choosing between Comcast and Covat is not a choice, because one doesn't work at the office, one not at home, and Verizon not at Stanford. | 15:11:35 |
| Devitt is annoyed that he can't do what he wants on his cell phone. (i.e.: cell phone has GPS, but only authorized carrier apps can use it) | 15:12:27 |
| Devitt: "PC software market has been distorted by a monopolist." *cough* | 15:12:59 |
| Devitt: "If I were a Dickens book, I would be the ghost of internet's future." | 15:13:26 |
| Devitt: Can't figure out if any traffic shaping tech is active on the phone, because he can't install traffic monitoring software. | 15:14:44 |
| Harold Feld, Senior VP of the Media Access Project, is now speaking. Sheesh he's loud, and he speaks fast. | 15:15:17 |
| Haha, Feld: "It will take 25 or 30 more hearings" for the FCC to force Comcast to stop traffic shaping. | 15:16:06 |
| Feld: Talks about 1999 debate about forcing ISPs to allow access to their pipes by other ISPs, and how we walked away from that debate. | 15:17:37 |
| Feld: Supreme Court says that the internet is a medium diverse of human thought, and 1st Amendment is paramount when debating NN. | 15:18:49 |
| Feld mentions how Jackson's wardrobe malfunction did not stop the FCC from acting, even though the TV networks went into full damage control | 15:20:05 |
| He's speaking really, really fast on various Supreme Court decisions in support of the FCC's jurisdiction over net neutrality. | 15:21:18 |
| Feld: "Not acting, as we did in 1999, carries its own consequences." | 15:22:09 |
| Feld is taking Tate head-on, with her concerns about illegal practices and pornography. | 15:23:19 |
| Of King James Bible downloads via BitTorrent, 276 attempts failed out of 300; but 75.33% of adult porn downloads did not fail once. Hahaha. | 15:24:58 |
| George S. Ford, Chief Economist at the Phoenix Center for Advanced Legal & Economic Public Policy Studies, now speaks. | 15:27:42 |
| Hates calling it "network neutrality", and that it's "analytically void". | 15:28:12 |
| Ford says that every one of the issues can fall under the umbrella of anticompetitive problems. | 15:28:49 |
| Ford thinks that the burden of proof falls on net neutrality advocates. | 15:29:23 |
| Ford says that net neutrality advocates are "using bad math" and "making things up". | 15:29:54 |
| Ford: "Neutrality is not a good thing." Um, no. | 15:30:27 |
| In high concentrated markets, bad practices by companies is common. "Get used to it," he says. But it "doesn't mean things are bad." BOOO | 15:31:48 |
| (He's actually getting verbal boos.) | 15:31:56 |
| Even monopolists have decisions that align with consumers. "It's just not true," that corporations are usually anti-consumer. | 15:33:58 |
| Ford is laughed at. He says he can't comment on Comcast's practices because he's not informed. I shouted, "Well then get informed." | 15:35:10 |
| Brett Glass, CEO of Lariat.net, is speaking now. Finally Ford shut up. | 15:35:55 |
| In 1999, a T1 line cots $6,000/month. | 15:37:26 |
| Lariat.net provides wireless access to the internet outside the bounds of cable/telephone companies. | 15:38:35 |
| Glass says that P2P shifts costs to ISPs, and they disclose that they prohibit P2P on lower tiers. | 15:43:34 |
| Commissioner Martin cuts Glass off. Blake Krikorian, CEO of Sling Media, now speaking. | 15:44:08 |
| Krikorian: Cable companies were threatened by Slingbox. Customers called Sling saying they want to pay more for faster access to video. | 15:46:10 |
| Krikorian: FCC needs to really define the debate, define what "network neutrality" is. Lots of different issues that we're talking about. | 15:47:23 |
| "Honesty, transparency, the facts" — these are things we need in order to create informed decisions. | 15:48:27 |
| Krikorian says the FCC should hold accountable those who don't give the facts. | 15:48:49 |
| Lastly, we need to understand the stakeholders. The panels aren't just big content/business anymore, but they are also a player. | 15:49:09 |
| "Aftermarket", the internet, is critical for movie-makers to recoup $100 million to make a movie. | 15:50:25 |
| Mentions that the VCR *created* the aftermarket, and the MPAA originally fought that tooth and nail. | 15:50:48 |
| Jon Peterson, IETF co-director, speaking now. IETF is volunteer work, he says. | 15:51:18 |
| IETF doesn't make a consensus on public policy. | 15:52:14 |
| VoIP and similar things are not delay-tolerant (they're "inelastic"); they bear the brunt of problems of the changing nature of the 'net. | 15:54:18 |
| IETF simply documents applicability of protocol mechanisms. | 15:54:50 |
| Next up, Gregory Rosston, Deputy Director of the Stanford Institute for Economic Policy Research. | 15:56:13 |
| Rosston tried to download a file during the first panel; it was slow because there're so many laptops on the network at the hearing. | 15:57:23 |
| Metering can be a good solution, but consumers may not actually want that. | 15:57:50 |
| Rosston: "There are times you pay for bandwidth, and times you pay for latency." | 15:59:32 |
| He says that cable companies have incentives to discriminate, but it can also increase efficiency. | 16:00:23 |
| Says that it's ridiculous that the FCC was "disappointed" that a new operator didn't grab the 700 MHz spectrum; they could have enforced it. | 16:01:31 |
| Commission had a chance to do something in 1999, but didn't. Remedies should concentrate on increasing competition. | 16:02:24 |
| Finally, Ben Scott, Policy Director of Free Press is now speaking. | 16:02:38 |
| Scott: "Few choices in the history of the FCC carry as much weight as this one does." | 16:03:23 |
| Scott: "Openness doesn't mean the end to all management. [...] Should promote free speech & commerce in the online market as it always has." | 16:04:07 |
| The question is to apply the policy that the FCC laid out in 2005. | 16:05:05 |
| What brought the FCC to Stanford. Was it Silicon Valley challenging AT&T? "Nope. It was a barber shop quartet [Topolski]." | 16:06:20 |
| The response, by Comcast and cable companies, is because of "the threat of regulation", *not* because of the free market. | 16:07:43 |
| "A duopoly market will not discipline itself. [...] can't expect fans of barber shop quarters riding in like white knights to save the day." | 16:09:49 |
| Scott got the longest and loudest applause and cheers of all panelists. | 16:10:13 |
| Feld: Innovations in the broadband market come because users demand it. That there's no limit to demand is not a problem. | 16:13:15 |
| (Guy came by to say that I can't have my power cord across the walkway. Back on battery, 2.5 hours left.) | 16:14:03 |
| Ford claims that average consumers don't want more bandwidth. | 16:16:17 |
| Peterson of the IETF is wearing a funny, black top hat and a matching black jacket. But he's a good speaker. :) | 16:17:27 |
| IETF has *not* taken a position on TCP Reset packets for managing congestion, according to Schewick. | 16:18:40 |
| Devitt: VC's are reluctant to invest in the market because of the stranglehold wireless carriers have. | 16:24:57 |
| Commissioner Tate wants to know if the panelists agree that consumers have the right to have access to info of what they get. | 16:27:18 |
| Tate wanted to make sure that Glass' company *does* tell consumers that they don't allow P2P access on their network. | 16:28:03 |
| Tate seizes on the fact that the IETF hasn't made a recommendation on NN. But he said they don't make a consensus on public policy! | 16:28:42 |
| Schewick says engineers don't want to go on record saying that TCP Reset packets are bad, for fear of reprisal. | 16:30:25 |
| Schewick: Alternative to metered pricing: volume caps. European ISPs "do this all the time". | 16:31:36 |
| Commissioner McDowell again asks the panel if they're receiving outside consulting fees for participating in the panel. | 16:33:41 |
| Feld says his plane ticket was paid for by Media Democracy (?), Ford says he's paid from a variety of sources. | 16:34:34 |
| Glass: P2P is not a free speech issue, because there are other ways to download content. It's a way of cost-shifting. | 16:37:01 |
| Commissioner McDowell claims that 2 years ago, people raised concerns about forcing consumers to pay more for a faster pipe. Um, what? | 16:39:03 |
| Feld: FCC has jurisdiction to fine not just "outright lying" but also "withholding of information" if ISPs actually have extra capacity. | 16:41:52 |
| Scott says that cable companies allocate only 5% of their bandwidth to high speed internet. | 16:42:23 |
| Public comment time! 90 seconds. Ack! 10 times will be called at a time. | 16:44:10 |
| OOH I GOT CALLED! BYE! | 16:45:19 |
| I had 90 seconds. I focused on competing with piracy, not using network filtering to combat it. Didn't conclude very well, but that's OK. | 17:09:39 |
| Carol Buyee?: Running for Congress on two-piece impeachment platform. FCC has failed to protect public air waves for the public. | 17:12:45 |
| Buyee?: Censorship is the most important issue right now. (Most people are focusing on free speech.) | 17:13:21 |
| George: "What's at stake is our freedom of speech." People are repeating each other; I wish people'd address specific commission concerns. | 17:14:30 |
| Some other guy: All panelists agreed on transparency. Simplest solution to the start of the problem. | 17:15:51 |
| Katherine Sandoval: Teaches antitrust comm. law at SCU. Comcast/BitTorrent agreement is not enough; anticompetitive to use TCP resets. | 17:18:54 |
| Guy from EFF: Developing software to detect network management. Transparency is important. | 17:19:39 |
| Guilermo: Staff writer with Poor News Network. Creates media access to poor migrant workers, wants this media to continue to grow. | 17:20:30 |
| David Harris: Congestion can be solved in other ways than network blocking. e.g.: wireless devices can be smarter. | 17:22:58 |
| Some other guy: Internet as important as printing press. This democracy needs protection. Asks FCC to enforce rules. | 17:24:33 |
| Alex Pulvee (?): Found some people on the internet. (Lol.) Reserves books, etc. on the internet. Internet is critical. | 17:26:45 |
| Guy from American Centrist Party: Small party, can only get word out via the internet. Current players are too large. | 17:28:02 |
| Some guy: Supposedly small # of customers is using up most bandwidth. But most users bring down usage when brought to their attn. | 17:30:04 |
| Some girl: "Pay to play" system favors capitalistic interests. Intellectual curiosity is a benefit of the internet. | 17:31:28 |
| Kathy Cartmell (?): Giving corp.s power to choose who to enter the "town square" (i.e.: internet) is bad. That's the definition of fascism. | 17:32:29 |
| Stephanie Diaz: From Oasis High School. Internet is main form of media to get their word out. Other media is hard to access. | 17:33:37 |
| @bbum: Yep, I read the link. | 17:33:42 |
| Some guy: Used to be able to get DSL/T1 cheaper than the phone companies, not true anymore. Internet is "last bulwark against fascism." | 17:35:11 |
| Eli Edwards: Interned at the Internet Archive. Was a librarian. "Not all packets are alike just because they appear on a P2P network." | 17:37:39 |
| Tian Harner (?): Electrical/software engineer before he became a political activist. Comcast was arbitrary about who they were affecting. | 17:39:05 |
| Some girl: Centerpiece of democracy is freedom of speech. Whole job of companies is to shut people out. | 17:40:50 |
| Some guy from Menlo Park: Real reason to oppose NN is to seize control over others for purposes of profit, advantage, censorship. | 17:42:38 |
| Bruce Allison: Also from Poor Magazine. Why when a poor person gets on the internet, he is censored? | 17:43:15 |
| Some guy: FCC should leave Washington more often. Wants non-profit outfit to provide internet access. | 17:44:21 |
| Some other guy: Cable Coop provided internet to Stanford. At no time was network filtering done. | 17:45:52 |
| Carolyn Brodwell: From Napa; teaches over the 'net w/students from 3 countries. While teaching in China, experienced "selective censorship" | 17:47:18 |
| Some girl: No reason why ACE Hardware should ask what you're going to do with a hammer when you buy it. | 17:48:26 |
| @moksha: Sorry, I wanted it live, and my weblog doesn't support that. Temporarily de-follow me for the day, IYW. | 17:48:57 |
| Daniel Weissman: Anything you say can also be printed in a newspaper. Therefore, blocking P2P *is* a free speech issue. | 17:50:09 |
| Stan Woods: local board of KBFA radio. ISPs corresponding w/companies to spy on union e-mails. "National security" to monitor websites | 17:51:43 |
| Some girl: "The internet is capabale of "leveling the playing field on social, economic, and cultural grounds." | 17:53:35 |
| Anthony Marshall: Producer of current.tv; Loises' Lounge provided forum for up-and-coming content. NN crucial to independent websites. | 17:55:13 |
| Jonas Something: Internet has become useful (first time he used it, thought it was "dull"). Easy to get on, publish info on it. | 17:56:23 |
| @eridius: Yep, @boredzo suggested that, I will do it. | 17:56:41 |
| Gloria (speaking in Spanish): Reporter for Poor News Network. Uses internet for research, inform community. We have a right to info on net | 17:58:19 |
| Audience supports Gloria so that she can get another 90 seconds to speak because her words need to be translated. | 17:59:17 |
| Gloria (cont'd): We don't have enough money for fast 'net access. Truth is what we're reporting, not what people tell us. | 18:00:22 |
| Gloria (cont'd): We are the workers that are making this country fatter, we have a right to the same info. | 18:00:38 |
| Some guy: Using 'net to provide content to K-12 sectors. The cost of limiting the spark of innovation needs to be considered. | 18:02:16 |
| Some guy: Used to have to go to galleries to see art, apply to show art. Internet gives access to galleries all over the world. | 18:03:17 |
| Some guy: Another writer from Poor Magazine. "AT&T, Verizon, and Comcast are digital pimps." Digital boycott if network management cont's. | 18:05:00 |
| Some guy: Could be a matter of life and death (re: deaths in Iraqi Kurdistan). Pentagon's Internet2 plan gives Pentagon centralized control | 18:06:00 |
| Norman Jea (?): "Public trust must be regulated [to prevent the] move towards profits." Build a 'net of inclusion to close economic gap. | 18:08:11 |
| Joanne Moore: Free Speech Radio. Internet was organic entity from the people (not true: from scientists). Internet belongs to people. | 18:10:03 |
| Joanne Moore (cont'd): ISPs were quick to give information to gov't when they were asked to do so. | 18:10:22 |
| Some guy: Info and knowledge are critical to democracy as water is to life. Water was privatized, people rose up against it (really?). | 18:11:51 |
| (Unless otherwise noted, each tweet is a different individual.) | 18:12:05 |
| Some guy: Wants FCC to fine Comcast and use money to enforce. Is gay, surprised to be on same side as Christian Coalition. | 18:13:35 |
| Norma: From Peace and Freedom Party. Socialist party, supports NN. "Capitalism is not a victimless crime." | 18:15:24 |
| Sean Sowell (?): Company sells hardware that works with OSS. Noticed torrents stopped. Wants FCC to help small biz participate in auction | 18:17:53 |
| Lady from Raging Grannies: Supports NN. Pushing people to the slow lane is effectively denial of access. | 18:18:53 |
| James Tiernan: CEO of La Jolla Networks. Principle inventor of MPEG2 transport structure. Didn't get to conclusion. | 18:20:56 |
| Going to 60 sec. per person. Wrapping up by 7:30, hopefully. (That's 10 more min.) | 18:21:24 |
| Joseph: Writer of Poor Magazine. Something about Type !, II, III civilizations? Supports NN. | 18:22:48 |
| Ralph Mueller: Network engineer at Internet Archive. Comcast blocking traffic based on content. Vonage didn't work. Encryption fixed it. | 18:24:12 |
| Max Caine: New small company would be at disadvantage, could distribute software via P2P w/o substantial payment. | 18:25:38 |
| Athena Johnson (?): USF, School of Law. ISPs should not degrade packets based on content. Equal delivery rule. | 18:26:52 |
| Brother Wile (?): From Poor Magazine. Audio/video must stay free. Limiting access to internet akin to limiting highway to Rolls Royces. | 18:27:40 |
| Ruth from Raging Granny: Not for left or right ring, for both and everybody in between. | 18:28:15 |
| Joe Wright (?): Internet has flourished because of openness. | 18:29:23 |
| Richard Tucker: Background in math and CS. "Need business model based on abundance of choice." | 18:30:15 |
| Tracy Rosenberg: From Commedia. Comcast actions have been arbitrary, random, just ones we know about. Should not trust telecoms. | 18:31:46 |
| Bill: Possible to create P2P apps that don't use lots of resources, doesn't infringe. | 18:33:02 |
| Done with public comment. (Phew.) | 18:33:14 |
| Back to FCC Chairman Kevin Martin thanks audience, adjourns hearing. | 18:33:46 |
| PHEW! Done with the live-tweet. I'm hungry, haven't had lunch or dinner. | 18:34:02 |
Overall, I was very heartened by how many citizens showed up to participate in the hearing, by the comments made by most of the panel members, as well as by the willingness of the FCC to listen to the comments of all parties involved. If Comcast packed the original hearing with paid seat-warmers, this hearing was decidedly packed with people who really cared about network neutrality.
I'm not talking about "cared" as in "cared about the issue of network neutrality", but "cared" as in "actively support the principle of network neutrality". Loud cheers of applause almost always punctuated the sentences of supporters of network neutrality on the panel. Active boos were also heard after the statements of a couple of the commissioners who seemed to make it clear that they oppose regulation (network neutrality is a form of regulation), and audible laughing and scoffing at some other assertions by opponents of network neutrality.
During the period of public comment, not one single voice stood out against network neutrality. It was clearly a hearing that was stacked in favor of the views of the general public, not in favor of a particular ISP.
I was also struck by how the panels were also stacked in favor of network neutrality. In the first panel, I counted five panelists staunchly in support, two against, and one that didn't have a well-defined position. The second panel had four staunchly in support, three with ambiguous positions, and two against. Between the panelists and the public, the FCC largely got bombarded with arguments and opinions about why network neutrality regulation should be implemented.
For each panel, one panelist introduced the argument, and the other panelists got to each present a five-or-so-minute opening statement. The commissioners then each got to ask questions of any of the panelists or all of them at once, to clarify things that weren't clear or to get more info on issues that weren't addressed at all. Both panelists who introduced their respective panels were staunchly in support of network neutrality: Lawrence Lessig for the first, and Barbara van Schewick for the second.
Lessig's presentation in particular was excellent. However, I absolutely *hate* his presentation slides: he uses acronyms that nobody ever uses (like "e2e" for "end-to-end" which he claims is equivalent to the term "network neutrality", but I don't understand why he thinks this), and he also uses internet-speak abbreviations for common words like "y" in place of "why". His slides also routinely only contain up to three words from his speech that he presents alongside the presentation. Personally, I just find his slides distracting and unnecessary, but it's possible that others find it compelling and allow them to focus on the words that Lessig wants to emphasize. The content of his speech, though, was easy to understand, to the point, and pretty compelling.
Whereas Lessig's presentation was an excellent opening to the first panel, Ben Scott from Free Press did an excellent opening statement that concluded the formal statements by the second panel. He was very broad in saying that self-regulation has clearly not worked and will not work, and he had some choice quotes, the best of which was "A duopoly market will not discipline itself. [We] can't expect fans of barber shop quartets riding in like white knights to save the day." He was referring to Robb Topolski, who sat on the first panel, and who was the one who originally noticed weird things happening with BitTorrent, investigated the problem, and published his findings on the internet. He was the self-professed (and rightly so) instigator of these FCC hearings.
Two panelists in particular seemed waaay out of touch. And while my bias may show here, both of these panelists were against net neutrality.
The first of these two out-of-touch panelists was, in an ironic, inexplicable twist, George Ou. How anyone thought that George Ou was qualified to sit on the panel at all is laughable. George Ou is the ZDNet columnist who was staunchly in support of David Maynor during the saga of the supposed MacBook Wi-Fi hack. He has already demonstrated that he doesn't have a grasp of technical concepts.
Ou continued to demonstrate this failure to understand during his opening statement in the first panel. He had prepared a statement which he had been reading, and yet he still stumbled over his words. I wouldn't hold that against him, but his statement was just ludicrous. First, he used the word "flows", as in "one user taking up four 'flows' takes up four times more bandwidth." I've never, ever heard this use of the word 'flow', and why not just say that one user might take up four times more bandwidth?
The most ludicrous thing that Ou said was that BitTorrent was unnecessary because he put the same file up on a web server and was able to download it twenty times as fast. Not only did it seem like he only did this test once, but it completely misses the point, anyway. BitTorrent is specifically designed around a paradigm that is not a server-client paradigm. BitTorrent effectively balances network congestion by forcing users who download a file to also serve that file to other users while they are downloading the file themselves. And who is Ou to say what protocol users should be able to use?
Ou was laughed at (by the audience) during the question-and-answer session because Commissioner McDowell asked him where his expertise comes from. When he answered that he had no first-hand technical experience (as does Topolski, who specifically did packet sniffing to investigate Comcast's traffic shaping) and no first-hand policy experience (as does Lessig, who actively looked into legal briefs and decisions on this issue), McDowell basically stopped listening to him. It was excellent to see that even Commissioner McDowell, who seems to be against any form of regulation whatsoever, was still skeptical by Ou's arguments.
The second panelist that seemed out of touch was George Ford on the second panel. He's an economist who basically went on a rant against net neutrality advocates saying that they were using "bad math" and "making things up". I was particularly appalled when he said that in "high concentrated markets" (i.e.: markets in which power is concentrated in only a few players, like the broadband market), it's common for companies to employ bad practices such as Comcast's traffic shaping. "Get used to it," he said. It was pretty incredible. Furthermore, he even said that he can't comment on Comcast's practice because he wasn't informed on exactly what they were doing. I was so incensed that I had to shout out, "Well then get informed!" Ford was also getting audible laughs, scoffs, and boos from the audience.
When the time allotted for public comments finally came around, it was impressive how many people had signed up to speak. Unfortunately, that limited each speaker to 90 seconds each, and later on only 60 seconds each. Almost all of the people who commented made a big deal about how enforcing network neutrality means protecting free speech. I initially thought it was a bit counterproductive, because heart-felt or forceful speeches in favor of free speech is not likely to sway the commissioners who had specific problems with network neutrality. However, by the end, I think that the complete consensus across every single speaker in favor of free speech was compelling.
I signed up to speak myself, and I was called up in the first allotment of 20 people to line up to speak. I was a bit flustered by the 90 second limit, especially because I had prepared structured comments that probably would have lasted 5 minutes. I chose to specifically counter the concerns of Commissioner Tate, who was concerned with the volume of illegal file sharing. I spoke about how Rick Carnes of the Songwriters Guild of America said that P2P was destroying his business, but how there was no legal alternative to P2P file-sharing that consumers could use, and that the appropriate response is not network filtering but to establish legal alternatives (iTunes, Amazon MP3, Hulu.com) which compete with piracy. Unfortunately, I don't think I made clear the relevance of my argument to how network filtering is unnecessary.
The most compelling speaker during the public comment session was Gloria, a reporter for the Poor News Network. She only spoke Spanish, and so another reporter had to translate her comments. It was clear she was passionate about the idea of network neutrality, because she uses the internet for research and to inform the community, and that migrant workers have just as much right to access info on the internet even though they may not have the money to pay for neutral access if network neutrality is not enforced. It was amazing the support she garnered from the audience: when her 90 seconds were up, the audience compelled the moderator to give her another 90 seconds, since her words had to be translated.
As for the commissioners? Commissioner Copps was clearly in support of network neutrality. Commissioners Tate and McDowell made it clear that they tend towards the school of thought that opposes regulation of any kind. Tate in particular was concerned about how network neutrality has the side effect of "protecting" illegal file-sharing, by forcing ISPs to not filter, degrade, or block traffic based on content.
I'm not sure about Commissioner Adelstein, but the chairman, Kevin Martin, seemed to be pretty receptive to network neutrality advocates, and his positions and arguments (especially in support of open access rules for the 700 MHz spectrum) seem to indicate that he might tend towards supporting net neutrality as well. But even Tate and McDowell seemed to be reasonable enough that they can understand the position of net neutrality advocates.
Overall, I was impressed by the hearing. Ordinary people were actively participating and even passionate in support of net neutrality. The panels were both largely in favor of net neutrality, and many of them presented well-reasoned, cogent arguments to which I believe the commissioners were receptive. And perhaps most importantly, I have the feeling that the FCC is going to do the right thing, and decide to enforce net neutrality.
Rants Permalink

Rearranging the MacBook Keyboard Keycaps
lun - marzo 24, 2008, 14:17:44
I've been a Dvorak user for many years now, so whenever I get a new computer or a new keyboard, one of the first things that I do is physically rearrange all the keycaps on the keyboard to match the Dvorak layout.
One of the primary reasons that I do this is because I'm a bilingual typist. It's practically absolutely necessary to know QWERTY if you ever want to use public computer terminals or someone else's computer, so I'd bet that any self-professed Dvorak layout user is also proficient at QWERTY. For me, the problem is that I use the keycaps as a point of reference for what keyboard layout I'm using. When I first sit down to the computer, I take a quick look at the keycaps to remind me which layout I'm using, and then I'm off -- but I don't actually need to look at the keyboard when I'm typing, for both QWERTY and Dvorak.
But when I'm using the QWERTY layout with keycaps that are physically arranged in the Dvorak layout, or vice versa, I get temporarily confused. (This is particularly troublesome for passwords.) Thus, if my main layout is Dvorak, I just like my keycaps to show Dvorak as well.
All desktop keyboards in recent memory on any Mac I've ever used have keycaps that are easily arranged. (Not sure if our ancient Mac IIsi or Mac Plus keyboards were re-arrangeable, though, or even if they had the Dvorak layout installed by default.) Find a tool with a flat edge — I typically use one end of a fingernail clipper, even though a flathead screwdriver would do quite nicely (my bathroom is usually closer than the garage, natch) — wedge it under each keycap, and gently pull up. The keycaps come off easily, rearrange them to the desired layout, and then press down on them. Easy as pie.
Only recently, however, have I started to use a laptop regularly, and rearranging the keycaps on these is significantly more difficult and time-consuming. That's not to say, however, that it's particularly difficult at all; it just seems like it at first, and it seems like you're going to break things, even though you don't.
Earlier MacBooks have keycaps that use a mechanism with a metal bar, and there's already an instructable that shows how to rearrange the keycaps on these MacBooks. It has good pictures and good descriptions, and I was able to follow it to rearrange the keycaps on my older MacBook.
I just (Wednesday) got a newer MacBook, however, and unbeknownst to me, it actually uses a different keycap mechanism. I noticed that the keyboard felt significantly different on this MacBook (they are quieter and a bit more spongy), but I thought that was just because it hadn't been used as much as my older one. However, the aforementioned instructable doesn't work with these new MacBooks — getting a keycap off was much different and produced different results.
In a few Google searches, I couldn't find any step-by-step instructions that show how to rearrange the keycaps on these new MacBooks; this entry is an attempt to rectify that situation. Sorry, I don't have a macro lens on my crappy digital camera, but these photos should be good enough. If some enterprising user with a macro lens and one of these newer MacBooks wants to send me along some higher-quality, less-blurry photos, I'd greatly appreciate it (and would gladly give credit).
The first thing you need to do is, obviously, take off the keycaps. Before you attempt to do this, you need to understand how these keycaps work. Here's a partial picture of the MacBook keyboard, with a few of the keycaps already removed.
Look at the one of the places where a keycap has been removed: you should see two little metal holes on the upper-left and lower-left corners. Now look at one of the keycaps: you can see two concentric, white, plastic, ring-like pieces. This is the plastic scissor mechanism that allows the key to work. Looking at the right-most keycap in this picture, the left side of the mechanism — which is slightly shorter — is going to insert into the aforementioned metal holes.
Look back at the place where a keycap has been removed. On the right side, you can see a small metal flap. The right side of plastic mechanism of the keycap needs to slide under that metal flap to hold it down.
Knowing how the mechanism works reveals how to remove a keycap: you need to first get the plastic mechanism out of the little metal holes. This will allow you to slide it off to the right which will remove the other side of the plastic mechanism from underneath the metal flap. Then you can just lift off the keycap.
Step 1: Remove all of the keycaps from the keyboard. To do this, get a tool with a small, flat end (a jeweler's flathead screwdriver is ideal), and slip it under the lower-left corner of any keycap. You might need to lift up the keycap ever so slightly to see underneath, but you should be able to see the plastic scissor mechanism. Push the scissor mechanism on the lower-left corner so that you push it out of the lower-left metal hole. Once this happens, it should come out of the upper-left hole as well, since the spring back of the lower-left corner pulls the upper-left corner out. Then just slide the keycap off to the right to unhook it from the metal flap, and lift it off.
Step 2: Now you've removed all the keycaps, but the scissor mechanism is still attached to each one. We need to remove each scissor mechanism from each keycap. To do this, simply insert your small tool underneath the shorter end of the scissor mechanism and lift up (see the following photo). It should snap off — don't worry, you haven't broken anything.
Repeat this step for all keycaps, so you should have a set of bare keycaps and bare scissor mechanisms.
Step 3: Physically place the scissor mechanisms back in the holes where the keycaps have been removed. Don't worry about putting the mechanism under the flap or in the holes just yet; for now, worry about the orientation. Note that there is only one orientation in which this scissor mechanism can function. The side of the mechanism facing up should be flat — if it has bumps in it, it's upside-down. The shorter side of the mechanism with the two plastic bars should also go on the left side.
The following photo shows the orientation in which the scissor mechanism should be placed. The scissor mechanisms in the left three keycap holes are placed correctly; the right-most scissor mechanism is placed with the bottom side facing up instead of down.
Repeat this step for each scissor mechanism.
Step 4: Slip the right side of the scissor mechanism under the metal flap on the right side of each keycap hole. Only the inner plastic ring piece will slip under the metal flap; the outer ring will not. The top row of scissor mechanisms in the following photo have been slipped under the metal flap.
Repeat for each scissor mechanism.
Step 5: Slip the scissor mechanism into the metal holes on the left hand side. You should easily be able to place one of the plastic bars into one of the holes — the top one is your best bet, here. Then, with your tool, you need to bend the lower-left part of the scissor mechanism so that it, too, can slip into the other metal hole. (This is very similar to what you had to do in order to get the keycap off in the first place.)
The three scissor mechanisms in the bottom row of the previous photo have been placed in the metal holes as well, so they're completely in place.
Repeat for each scissor mechanism.
Step 6: You've passed the hard part. This last step is easy. Just place the keycaps in their positions, and press down hard. You should hear a few clicks. Press down in different places of the keycap to make sure that all parts snapped.
The only tricky part of this step is to remember that each keycap can only go in one orientation. Some keys, like the 'z', 'n', and 's' keys look similar when they're upside-down or right-side up — flip these ones upside-down and you should easily be able to















