tag:blogger.com,1999:blog-68257312018641783092024-03-05T12:55:41.295-05:00crdloa place for my code, thoughts, and other boring stuffcrdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.comBlogger45125tag:blogger.com,1999:blog-6825731201864178309.post-7458760920816459122021-06-12T10:21:00.001-04:002021-06-12T10:21:00.228-04:00handy makefile script<p>I frequently find myself looking for default make rules, and inevitably how to print their values. Here's a script to help.</p><p>Adapted from <a href="https://blog.melski.net/2010/11/30/makefile-hacks-print-the-value-of-any-variable/">https://blog.melski.net/2010/11/30/makefile-hacks-print-the-value-of-any-variable/</a></p>
<pre class="brush: bash">$ cat ~/bin/make-vars
#!/bin/bash
_vars=
for v in $@; do
_vars="${_vars} print-${v}"
done
make -f- ${_vars} <<'EOF'
print-%:
@echo '$*=$($*)'
@echo ' origin = $(origin $*)'
@echo ' flavor = $(flavor $*)'
@echo ' value = $(value $*)'
EOF
</pre>
<p>Here it is in use</p>
<pre class="brush: bash">
$ make-vars LINK.cc
LINK.cc=c++
origin = default
flavor = recursive
value = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
</pre>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-30242894360729990712021-06-04T00:51:00.001-04:002021-06-04T13:56:47.379-04:00New home for joinery<p>As of version 1.10, joinery is now hosted in the <a href="https://search.maven.org/search?q=joinery">central repo</a> using the sh.joinery groupId.</p><p>As part of the move to central, joinery also has a shiny new domain <a href="https://joinery.sh">https://joinery.sh</a>.<br /></p>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-91988404867578739092015-07-10T10:26:00.000-04:002015-07-10T10:29:43.680-04:00pipelines and functional java<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://martinfowler.com/articles/refactoring-pipelines.html">Mr. Fowler</a> has written a nice series on using pipelines instead of iteration for processing collections.<br />
<br />
On a similar note, I recently came across <a href="http://www.slideshare.net/tkowalcz/33rd-degree-reactive-java">this presentation on reactive programming</a> in Java which also notes the benefits of composing operations as pipelines (though with a particular focus on processing sequences of observable events since this is reactive java after all). If you read through the deck to the last slide, you'll notice a humorous meme which represents more concisely Fowler's main point.<br />
<br />
I'm so glad <a href="http://flatmapthatshit.com/">this</a> exists.<br />
<br />
Obviously, as shown in my <a href="http://github.com/cardillo/joinery">Joinery</a> project, I'm a big fan of this programming style. It provides a powerful mechanism for expressing the kinds of operations that are required when operating on large amounts of data while yielding a very high signal:noise ratio when reading the code.</div>
crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-78515532428283768552012-09-21T18:46:00.000-04:002012-09-21T18:46:03.021-04:00apache zookeeper status with bash<div dir="ltr" style="text-align: left;" trbidi="on">
Most <a href="http://zookeeper.apache.org/">Apache ZooKeeper</a> users are familiar with ZooKeeper's four letter words.
And many bash users know that recent versions of the popular shell can redirect to network ports.
But I've yet to see the two used together. The other day I found myself without netcat and looking for a quick way to get stats out of ZooKeeper. A short bash function later and I can easily check on ZooKeeper from any shell (so much quicker than spinning up a JVM).
<br />
<pre class="brush: bash">zk4 ()
{
echo "${2-localhost}:${3-2181}> ${1-ruok}"
exec 3<> /dev/tcp/${2-localhost}/${3-2181}
echo ${1-ruok} 1>&3
cat 0<&3
[[ ${1-ruok} == "ruok" ]] && echo
}
</pre>
Usage is simple, by default it will issue the <span style="font-family: "Courier New",Courier,monospace;">ruok</span> command to <span style="font-family: "Courier New",Courier,monospace;">localhost</span> on the default port <span style="font-family: "Courier New",Courier,monospace;">2181</span>. But you can specify alternate values for each of the host, port, and command parameters.
<br />
<pre class="brush: bash">zk4 stat
zk4 srvr
zk4 ruok zk-server1.myco.com 20181
</pre>
</div>
crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-13716485327159184732011-03-01T20:31:00.000-05:002011-05-30T16:32:04.986-04:00sweet ironyNo matter which political side you take on the HBGary story, you have to admit... the irony could not be more sweet.<br />
<br />
<a href="http://arstechnica.com/tech-policy/news/2011/02/anonymous-speaks-the-inside-story-of-the-hbgary-hack.ars">http://arstechnica.com/tech-policy/news/2011/02/anonymous-speaks-the-inside-story-of-the-hbgary-hack.ars</a>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-74073017047887813042011-02-21T20:11:00.002-05:002011-02-21T20:13:13.081-05:00a quick reviewIn lieu of actual new content... a quick recap of some good posts from several of my favourite sources:<br />
<br />
1. Steve Yegge's excellent post on code, code base size, and perhaps a reason to use <a href="http://www.mozilla.org/rhino/">rhino</a> - <a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html">http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html</a><br />
<br />
2. Reginald Braithwaite's writings on code style and why clarity is king - <a href="http://weblog.raganwald.com/2007/12/golf-is-good-program-spoiled.html">http://weblog.raganwald.com/2007/12/golf-is-good-program-spoiled.html</a><br />
<br />
3. Hamlet D'Arcy's humorous article on the detriments of new found functional programming knowledge - <a href="http://hamletdarcy.blogspot.com/2009/08/how-to-tell-your-co-workers-have.html">http://hamletdarcy.blogspot.com/2009/08/how-to-tell-your-co-workers-have.html</a><br />
<br />
There you have it, just in case you missed 'em the first time around.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-43936312646846612732010-08-14T09:58:00.004-04:002010-08-14T10:34:09.514-04:00getting reacquainted with javascriptOk, I'm admittedly a little late to the party here. Lots of people are doing really, really cool things with javascript these days.<br />
<br />
So, I've been using rhino to whip together my java experiments lately. Setup is trivial, you just need <tt>java</tt> and <tt>js.jar</tt>.<br />
<br />
<ol><li><a href="https://developer.mozilla.org/en/RhinoDownload">download rhino</a> </li>
<li>extract js.jar (at least)</li>
<li>for an interactive shell, run <tt>java -jar js.jar</tt></li>
<li>or run a script using <tt>java -jar js.jar some-javascript-file.js</tt></li>
</ol><br />
Once you have rhino, all sorts of java-ish things can be whipped up as quick hacks.<br />
A quick http server, for example, goes something like this:<br />
<br />
<pre class="brush: javascript">function main() {
var s = new java.net.ServerSocket(8080)
while (true) {
var client = s.accept()
var sc = new java.util.Scanner(client.getInputStream())
var method = sc.next()
var path = '.' + sc.next()
var out = new java.io.PrintWriter(
new java.io.OutputStreamWriter(client.getOutputStream()))
try {
var f = new java.io.FileInputStream(path)
out.println("HTTP/1.1 200 Success")
out.println("Content-Type: text/html")
out.println()
for (var c = f.read(); c != -1; c = f.read())
out.write(c)
} catch (e if e.javaException
instanceof java.io.FileNotFoundException) {
out.println("HTTP/1.1 404 File not found")
out.println("Content-Type: text/html")
out.println()
out.println("<html><body>")
out.println("<h1>File not found</h1>")
out.println("</body></html>")
}
out.flush()
out.close()
}
}
main()
</pre><br />
Wait, what about a threaded server you say? Try this on for size.<br />
<br />
<pre class="brush: javascript">function main() {
var s = new java.net.ServerSocket(8080)
while (true) {
var client = s.accept()
var t = java.lang.Thread(function() {
var sc = new java.util.Scanner(client.getInputStream())
var method = sc.next()
var path = '.' + sc.next()
var out = new java.io.PrintWriter(
new java.io.OutputStreamWriter(client.getOutputStream()))
try {
var f = new java.io.FileInputStream(path)
out.println("HTTP/1.1 200 Success")
out.println("Content-Type: text/html")
out.println()
for (var c = f.read(); c != -1; c = f.read())
out.write(c)
} catch (e if e.javaException
instanceof java.io.FileNotFoundException) {
out.println("HTTP/1.1 404 File not found")
out.println("Content-Type: text/html")
out.println()
out.println("<html><body>")
out.println("<h1>File not found</h1>")
out.println("</body></html>")
}
out.flush()
out.close()
}
)
t.start()
}
}
main()
</pre><br />
For more reading about rhino and javascript including how to structure, organize, and manage your code for larger projects, try these great posts.<br />
<br />
<a href="http://steve-yegge.blogspot.com/2008/06/rhinos-and-tigers.html">http://steve-yegge.blogspot.com/2008/06/rhinos-and-tigers.html</a><br />
<a href="http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth">http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth</a><br />
<a href="http://peter.michaux.ca/articles/javascript-widgets-without-this">http://peter.michaux.ca/articles/javascript-widgets-without-this</a><br />
<a href="http://www.jspatterns.com/">http://www.jspatterns.com/</a>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-79572955280667804402010-08-08T22:17:00.003-04:002010-09-22T20:22:38.989-04:00reading files in javaJust came across this aging, but still surprisingly relevant analysis of <a href="http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly">reading files in java</a>. Basically compares the relative performance of several common (and some newer, lesser known) file reading methods... quite interesting.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-13910727671767281612010-08-08T16:27:00.000-04:002010-08-08T16:27:33.429-04:00emergency lispKeep this <a href="http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html">excellent lisp post</a> handy. It is perhaps a little dated, but only in terms of the actual date of the post. It provides a good introduction to lisp programming, especially when transitioning from another, less functional language. Even though it deals specifically with emacs lisp, the concepts are close enough. Definitely useful the next time a co-worker needs convincing using <a href="http://clojure.org/">clojure</a>.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-36096855558848425352010-08-04T08:13:00.002-04:002010-09-21T17:22:26.322-04:00your test suite is brokenTake the quiz and fess up if <a href="http://blogs.perl.org/users/ovid/2010/08/your-test-suite-is-broken.html">your test suite is broken</a>. Remember, test suites are software too, and as software, they need maintenance and upkeep just like the rest of the code your write.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-83441018670916394652010-08-03T08:34:00.000-04:002010-08-03T08:34:35.450-04:00looking forward to 2.6.35Based on the <a href="http://lkml.org/lkml/2010/8/1/188">changelog</a> and <a href="http://kernelnewbies.org/Linux_2_6_35">this writeup</a>, the latest linux kernel release appears to be pretty power-packed. I'm particularly looking forward to the performance improvements around spreading network load across cpu cores.<br />
<br />
On a slightly related note, I find the whole kernel code shepherding process amazing. How many managers have the ability to rattle off the number of post-release-candidate commits (with averages and comparisons against previous release candidates)? Never mind the whole staging and merging process. I think many software teams could learn quite a bit about managing the development process across distributed teams by letting go of centralized source control and watching the linux kernel developers.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-64388093433541251072010-08-02T20:22:00.002-04:002010-08-03T08:23:33.456-04:00nice perl tipI just came across <a href="http://blogs.perl.org/users/david_cantrell/2010/02/while-im-on-the-subject-of-shell-scripting.html">this excellent perl tip</a>. I'm not sure I'd use it exactly as written, but the idea of being able to open perl modules by module name instead of file name is certainly appealing. Now, to figure out how to apply this to other languages too.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-72495705504262009272010-08-01T12:30:00.001-04:002010-08-01T14:06:04.543-04:00autonomous agents for software testingI've been thinking about software testing quite a bit lately. I've been thinking about the artificial intelligence/algorithms used in game programming too. And so naturally, at some point it occurred to me that the same algorithms used to make all those characters, monsters, cars, or whatever meander in and out of the background scenery of our favorite games might be useful in software testing scenarios.<br />
<br />
Imagine you need to test a particularly hard-to-pin down bug - one that only happens during periods of high usage. It seems to me that you have a couple of options. You can force your users to pitch in and help with testing (not likely, and certainly not popular). You can beg your fellow programmers to do their best to mimic users (also not likely or popular). Or lastly (wishful thinking) you could fire up some program which will spawn an army of autonomous agents to meander through common use cases and behave as normal users creating the necessary "background traffic" needed for testing.<br />
<br />
This is currently just an idea in its infancy, I don't know of any actual implementations. But it does seem like an interesting area for some research and coding. One could imagine initial versions would need lists of steps that could be invoked at random intervals and sequences by many agents through some programming interface. However, far off future versions might know how to inspect user interfaces for menus, buttons, and dialog boxes - simulating mouse clicks and keyboard entry (valid or invalid) until something happens in response.<br />
<br />
Although I haven't found anything this sophisticated yet, it occurs to me that areas of security research might already have made progress on similar tools. Black-box penetration testing usually involves sending random (or perhaps not so random) payloads in an attempt to illicit an unexpected error or otherwise interesting response.<br />
<br />
So, any takers want to whip something like this up for me?crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-39770117321299028742010-07-22T21:53:00.000-04:002010-07-22T21:53:49.130-04:00simple overrides for quick mocking in perlA more concrete example (and one I use too frequently) of overriding for testing similar to what is described by <a href="http://blogs.perl.org/users/sawyer_x/2010/07/simple-symbol-overriding-for-tests.html">Sawyer X at blogs.perl.org: Simple symbol overriding for tests</a>. Of course, my example uses inheritance and re-blessing rather than symbol overriding, but the result is basically the same. I like to use the snippet below to test mail sending functionality by simply printing the resulting mail to stdout.<br />
<br />
<pre class="brush: perl">my $smtp = Net::SMTP->new($mailhost);
...
if ($i_dont_want_to_send_mail) {
package Mock::SMTP;
our @ISA = qw(Net::SMTP);
no strict qw(refs);
for (qw(mail to data dataend quit)) {
*$_ = sub { };
}
for (qw(datasend)) {
*$_ = sub { shift; print @_, "\n" }
}
# re-bless my Net::SMTP reference to a Mock reference
$smtp = bless $smtp || {};
}
</pre>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-10924877032046488752010-07-16T23:13:00.000-04:002010-07-16T23:13:19.767-04:00screen for cluster managementAfter my <a href="http://blog.crdlo.com/2010/07/parallel-ssh-tool-roundup.html">parallel ssh roundup</a> and <a href="http://blog.crdlo.com/2010/07/broadcast-ssh-my-entry-into-world-of.html">hacking my own solution</a>...<br />
<br />
I just realized <a href="http://www.gnu.org/software/screen/">screen</a> can do this too using "at" and "stuff". Here's how:<br />
<br />
<ol><li>open a bunch of screens and ssh to various hosts</li>
<li>get to a screen command prompt (control key followed by colon, ^C-a <b>:</b> )</li>
<li>at the prompt, enter the command "at \#", this tells screen to run command that follows on all windows (yes, include the backslash and don't press enter yet)</li>
<li>continue with the command "stuff", which tells screen to quite literally stuff whatever follows it into the input of a screen terminal (don't press enter quite yet)</li>
<li>follow stuff with the command you want to run, you'll need to put it in quotes if the command has arguments (not yet)</li>
<li>lastly, you need to end the line with a return so the shell(s) will run the command, so end the line with "\012" which is octal for a newline character</li>
</ol><br />
Now, press enter and what your command get run across all of your screen sessions. This is particular cool for long running commands where you can switch back and forth between screen windows and check on the progress of many machines or also useful if you have a couple of quick maintenance task to run on a bunch of hosts.<br />
<br />
So, putting it all together, the whole sequence looks like this:<br />
<br />
<pre class="brush: shell">^C-a : at \# stuff ls \012
^C-a : at \# stuff 'ls -alR' \012
</pre>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-80361589793773851642010-07-12T21:14:00.001-04:002010-07-12T21:20:55.597-04:00a survey of web visualization toolkitsI'm always on the lookout for new tools to create graphs, charts, and other visualizations. It is an obsession that dates back to my days slaving over <a href="http://www.gnuplot.info/">gnuplot</a> and <a href="http://www.r-project.org/">R</a> scripts (or even *gasp* <a href="http://www.tug.org/metapost.html">metapost</a>). Here are some more modern toolkits I've come across which lend themselves to visualizations for the web.<br />
<br />
<ul><li><a href="http://processing.org/">Processing</a> has to be one of my favorites, probably because I've been using it the longest.</li>
<li>And if Processing isn't web-2.0-enough for you, there is always <a href="http://processingjs.org/">the Javascript implementation</a>.</li>
<li><a href="http://vis.stanford.edu/protovis/">Protovis</a> - any visualization toolkit that can be used to create an interactive version of <a href="http://vis.stanford.edu/protovis/ex/napoleon.html">Minard’s Napoleon</a> has to get good marks.</li>
<li>Google has <a href="http://code.google.com/apis/charttools/index.html">Chart Tools</a>.</li>
<li><a href="http://www.degrafa.org/">Degrafa</a> has been used to create some beautiful visualizations.</li>
<li>Or there is the slightly higher-level <a href="http://www.axiis.org/">Axiis</a> if you prefer (which is built on top of Degrafa).</li>
<li>Should you be religiously opposed to flash, you might like <a href="http://www.danvk.org/dygraphs/">dygraphs</a></li>
<li><a href="http://prefuse.org/">Prefuse</a> is another Java toolkit with some great graph and chart types</li>
<li>And <a href="http://flare.prefuse.org/">Flare</a> (also from the Prefuse guys) you post those interactive visualizations to the web in flash.</li>
</ul>Ok everyone, which ones haven't I seen yet? <br />
<ul></ul>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-62097844164302087992010-07-11T22:24:00.000-04:002010-07-12T09:35:39.182-04:00broadcast ssh - my entry into the world of parallel or cluster ssh toolsI threatened before when writing up my review of the parallel or cluster ssh tools out there that I would write my own. And after a quick review of <a href="http://www.lag.net/paramiko/">paramiko</a>, especially the demo scripts included, this turned out to be a pretty quick hack.<br />
<br />
The basics of my ssh client are this:<br />
<ul><li>prompt for username and password - ssh keys not required (although I would like to add support for using them if available in the future)</li>
<li>interactive use - I often want to look at things, which leads me to want to look at other things; in other words, I don't want to be constrained by having a list of commands to execute up front</li>
<li>parallel - I have a bunch of commands and a bunch of machines, a simple loop executing each command on each machine isn't going to cut it </li>
</ul>Those last two together make things a little tricky, the interactive bit means you have two choices. You can be line oriented, prompt for a command and send it to each host or you can be completely interactive and send each character.<br />
<br />
I started with the former, but soon found that if you only send commands, you have practically no environment setup (that is all done in the shell, remember...). So, despite the difficulties in dealing with the terminal, that is what this implementation does.<br />
<br />
A terminal based solution has its own issues, the line buffering of output from each host has to be dealt with to avoid interleaved garbage as the results of each command. But in the end that wasn't too hard.<br />
<br />
In the end, usage is simple, cut-n-paste the code, save it as bssh.py and run something like:<br />
<pre class="brush: bash">./bssh.py host1 host2 host3 host4</pre>Enter a username and password at the prompts, and away you go, just enter commands as you would with any other shell. You will of course need paramiko and its dependency <a href="http://pycrypto.org/">pycrypto</a> installed and available.<br />
<br />
<a name='more'></a><br />
<br />
<pre class="brush: python">#!/usr/bin/env python
import sys, getpass, paramiko, socket, tty, termios, traceback
from select import select
user=raw_input('Username: ') or getpass.getuser()
password=getpass.getpass()
port=22
def main(hosts):
clients = {}
try:
for h in hosts:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
print 'connecting to', h, 'as', user
client.connect(h, port, user, password)
print 'invoking shell on', h
clients[h] = {
'client': client,
'channel': client.invoke_shell(),
'output': ''
}
oldtty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
for h in clients:
clients[h]['channel'].settimeout(0.0)
while clients:
channels = [clients[h]['channel'] for h in clients]
rd, wr, err = select([sys.stdin] + channels, [], [])
closed = []
for h in clients:
ch = clients[h]['channel']
if ch in rd:
try:
x = ch.recv(1024)
if len(x) == 0:
ch.close()
clients[h]['client'].close()
closed.append(h)
else:
x = clients[h]['output'] + x
lines = x.splitlines()
if x.endswith('\n'):
clients[h]['output'] = ''
else:
clients[h]['output'] = lines[-1]
del lines[-1]
for line in lines:
sys.stdout.write('%s> %s\n\r' % (h, line))
sys.stdout.flush()
except socket.timeout:
pass
for h in closed:
del clients[h]
if sys.stdin in rd:
x = sys.stdin.read(1)
for h in clients:
clients[h]['channel'].send(x)
sys.stdout.write(x)
sys.stdout.flush()
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
except:
traceback.print_exc()
for h in clients:
try:
clients[h]['channel'].close()
except:
pass
try:
clients[h]['client'].close()
except:
pass
if __name__ == '__main__':
main(sys.argv[1:])
</pre><br />
Of course, the hundred (or so) lines above could use some work, things like using different usernames and passwords for various hosts, ssh key (or other) authentication, better (or maybe just shorter) labels to prefix each output line, and I'm sure there are more. But for now, it's a workable solution that has payed dividends already in my productivity.<br />
<br />
The bottom line here is: paramiko rocks. From the demos to the shear flexibility of being able to program ssh sessions at the protocol level, I'm sure this is going to be an oft-used addition to my toolbox.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-76177676123935775912010-07-11T12:05:00.001-04:002010-07-11T12:06:16.734-04:00dnode - javascript remote invocation<a href="http://simonwillison.net/2010/Jul/11/dnode/">dnode</a> is just the latest in a serious of cool things people are doing with javascript that I find amazing. <a href="http://processingjs.org/">processingjs</a> is another (albeit not very new anymore).crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-73197840027881544212010-07-11T11:52:00.001-04:002010-07-11T12:03:15.650-04:00on lunch and bike shedsToday, Seth Godin hits on a pet peeve of mine, <a href="http://sethgodin.typepad.com/seths_blog/2010/07/so-easy-to-talk-about-lunch.html">arguing about unimportant things</a>. Although he casts the problem as a discussion from the perspective of deciding on lunch, I like the programmers version better.<br />
<br />
We all know the type, whether sitting in a code review or discussing a database schema, there is always one person willing to spend hours discussing minutia. Either it is the indentation style of a particular comment instead of the correctness of the algorithm. Or it is the virtues of camel case names for database objects as opposed to the performance trade off of complete normalization.<br />
<br />
<a name='more'></a><br />
In the programming community, we know this as the <a href="http://bikeshed.com/">bike shed</a> problem. It has been written about elsewhere, see <a href="http://blog.bryanbibat.com/2009/07/15/color-of-the-bikeshed/">http://blog.bryanbibat.com/2009/07/15/color-of-the-bikeshed/</a> and <a href="http://softwaremaven.innerbrane.com/2010/03/why-you-care-about-color-of-bike-shed.html">http://softwaremaven.innerbrane.com/2010/03/why-you-care-about-color-of-bike-shed.html</a>, and you will ultimately find the original source on the matter: <a href="http://en.wikipedia.org/wiki/Parkinson%27s_Law_of_Triviality">Parkinson's Law of Triviality</a> (no, not Wikipedia, Parkinson). I believe the bike shed analogy can be attributed to Feynmann.<br />
<br />
So, if you are here and not familiar with this issue -- please read up and lets all try to avoid this type of thing in the future.<br />
<br />
As a post script, I'm not advocating a view in which small details get overlooked, coding style and naming things are very important -- and I really like blue bikesheds. But at some point, you simply decide on a coding style (or naming standards, or whatever) and stop debating - after that point you simply use it. Then you move on to discussing the more important aspects of the problem at hand.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-53967102402892043682010-07-10T16:05:00.001-04:002010-07-11T10:51:27.543-04:00operator brings semantics to firefoxI just came across <a href="http://kaply.com/weblog/operator/">operator</a>, a firefox add-on for recognizing <a href="http://microformats.org/">microformats</a> and I have to say I'm impressed. I think this is a pretty big step in the right direction for the semantic web.<br />
<br />
As far as the semantic web goes, I've always been kind of on-the-fence regarding the human annotation versus automated statistical approaches. I'm still not convinced either will win out. It seems unlikely that every web author will annotate all their pages -- and yet, I'm not sure machine learning approaches will ever be able to accurately annotate things automatically.<br />
<br />
But with all of the generated pages out there, having just a few of the big ones support microformats, and browser support for recognizing those pages is a really big step. For example, <a href="http://linkedin.com">linkedin</a> already returns profile pages in hresume format. With operator, you can extract names, phone numbers, addresses, and event information easily.<br />
<br />
Update: operator doesn't seem to work in firefox 4 beta, but I think we can forgive that for now.<br />
<br />
<span style="display: none">FDA52EB2TTEK</span>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-45953075360259579772010-07-09T22:22:00.003-04:002010-07-10T15:44:55.549-04:00normals - a processing experiment<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij8GNmlnNDlXuJdVFwRVjVJG9ZJMLnOjMd8bNL7LnXTy-NETlqNCw4ADJsjswYHgYVbrolJdgGZ9Qq5mip3OXgr-YNF6m-ex5_5o8WAECLOp6BofmFF8S9Y2qnIfxQkdtCpn3NgdvnDy8/s1600/normals.png" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" rw="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij8GNmlnNDlXuJdVFwRVjVJG9ZJMLnOjMd8bNL7LnXTy-NETlqNCw4ADJsjswYHgYVbrolJdgGZ9Qq5mip3OXgr-YNF6m-ex5_5o8WAECLOp6BofmFF8S9Y2qnIfxQkdtCpn3NgdvnDy8/s200/normals.png" width="192" /></a></div><p>As part of a visualization I'm attempting to create, I was doing some experiments in <a href="http://processing.org/">processing</a>. One of the experiments involved distributing points randomly on a sphere, and drawing the normal vectors for those points. Add in a trackball for rotating, panning, and zooming and it ended up being a pretty cool interactive toy by itself.</p><a name='more'></a><br />
<p>I've been hoping to post the applet, but unsuccessful at getting it into blogger... so until I can do that, I'm just posting this screenshot instead. Hopefully, I'll be able to follow up with the applet itself soon.</p><br />
<p>As a quick preview of what I'm trying to create - I want to be able to visualize simulated cluster communications as peers join, participate, leave, or drop out of a peer to peer network. In my mind, each peer will be one of those points on the sphere, with new peers popping up and peers disappearing or leaving from time to time. Their communications during network discovery and regular network usage will be represented visually by lines between the points. The interesting part will be when I can animate the networks over time and watch how different p2p algorithms appear. But I still have a fair amount of coding to get all that working.</p>crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-10634336553118038852010-07-09T21:34:00.000-04:002010-07-11T10:48:54.177-04:00my tracks for android<a href="http://mytracks.appspot.com/">my tracks for android</a>... I've been threatening to write something like this for years... glad to see Google finally beat me to it. Now, I just need an android phone.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-63313171452329641752010-07-06T21:59:00.003-04:002010-07-07T08:05:58.318-04:00firefox 4 first impressionsAfter only a few short hours online with the new beta release of <a href="http://www.mozilla.com/en-US/firefox/beta/">firefox 4</a>, I can already tell I'm going to like it. I have yet to find any issues, and it loads pages lighting fast. I highly recommend anyone thinking of testing the waters with this preview release to go for it.<br />
<br />
<a name='more'></a> I did have to install the <a href="https://addons.mozilla.org/en-US/firefox/addon/15003/">compatibility reporter</a> addon to get things like firebug, yslow, and operator to work. But I think it is fair to expect addon developers to need some time to catch up when running a beta release.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-42250278113400903572010-07-06T21:47:00.025-04:002010-07-06T21:47:00.625-04:00playing poker during classWhat should the punishment be for students playing poker during class? Well, for my recent "Foundations of Object Oriented Programming" class, there was no punishment -- rather, playing poker was required.<br />
<br />
<a name='more'></a><br />
Each time I teach this class, I let the students select their final programming project. Of course, I give them suggestions and reserve the final decision for myself, but I think overall this works well since they get to work on something that matters to them.<br />
<br />
One requirement of the project is that it must be divisible into groups and the groups must be able to work independently. Since this is an object oriented class, this usually involves interfaces and mock objects, etc. In my most recent class, we designed an interface for poker playing and each group was required to implement a "poker bot".<br />
<br />
Once all was said and done, we had a tournament and it was a lot of fun. Below is a video of (the rudimentary graphical interface I made of) one instance of our playoff.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='480' height='300' src='https://www.blogger.com/video.g?token=AD6v5dxABkHuyOF1I8GyyJwHdPmZTRtyR3rh83dwqYq8nBx4ICmVYk3KZ_trI_g8skix5ff_8SNL8UNaHjjK3IXVrQ' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div><br />
There are quite a few reasons I think this makes an especially good project for this class. For one, the students are introduced to a number of important programming principles. All of their submissions must conform to the interface we design over the course of our discussions about the project (which usually span the entire second half of the semester). Second, the way our implementation was designed introduced students to event driven programming since basically each action by any player generates an event to all the other player bots. Also, given the nature of the problem, students are given a crash course in machine learning (if only to make it painfully clear that teaching computers to make "think" like humans is difficult).<br />
<br />
Lastly, congratulations to everyone who participated in this project, I know it was a lot of work and all your bots competed admirably.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0tag:blogger.com,1999:blog-6825731201864178309.post-1937931095576782782010-07-05T20:09:00.002-04:002010-07-05T20:26:07.178-04:00plasmodium protein interaction network visualizationI was recently finishing my write-up about using <a href="http://processing.org">processing</a> to create interactive art. In that article I wanted to mention the animation and physics processing libraries by Jeff Traer Bernstein and while looking up the references I was reminded of this <a href="http://www.cs.princeton.edu/~traer/plasmodium/">visualization</a>. It has always been one of my favorites, so I'm finally getting around to sharing it.crdlohttp://www.blogger.com/profile/12125558929574686676noreply@blogger.com0