<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4024934086395647348</id><updated>2012-01-26T16:17:44.050-06:00</updated><category term='premature optimization'/><category term='pulse'/><category term='puma in a box'/><category term='arensito'/><category term='adam'/><category term='sam'/><category term='being a shot-caller'/><category term='unnecessarily long blog posts'/><category term='hackjam'/><category term='arc'/><category term='frp'/><category term='modem'/><category term='daydreaming about bathing in beer'/><category term='minutes'/><category term='eight'/><category term='screen capture'/><category term='language'/><category term='etc'/><category term='jws'/><category term='nlp'/><category term='shell'/><category term='haskell'/><category term='livescribe'/><category term='calling shots'/><category term='avr piano gcc atmega brandon'/><category term='frame masks'/><category term='postscript'/><category term='jungles'/><category term='rambling'/><category term='brandon mythtv dvr linux'/><category term='movie guis'/><title type='text'>Hack Jam Log Book</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>40</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-7094626210603091219</id><published>2011-08-01T07:50:00.002-05:00</published><updated>2011-08-01T08:05:41.767-05:00</updated><title type='text'>7/28</title><content type='html'>Hackjam was pretty fun &lt;span style="text-decoration: line-through;"&gt;this&lt;/span&gt; last week. I expressed some disdain for Lisp's single single quote quoting syntax, born mostly in my ignorance, and got some good feedback from the Lispers about how it is used and what it does. The "close" for the single single quote quote is whitespace which I had previously assumed but there are so many flavors it was hard to be certain.&lt;br /&gt;&lt;br /&gt;We also played with &lt;a href="http://www.movsd.com/thegun.htm"&gt;TheGun.exe&lt;/a&gt; which brings me no end of delight -- it does not have a config file, but its standalone configurator modifies the exe so that next time it runs the settings you configured are "default". "Played with" included loading it in Notepad.exe as well as vim and attempting to change some strings and observing it to fail loading, both in Windows 7 and Wine 1.32. Under Wine, at least, TheGun.exe would not save modifications to the very executable image responsible for the running process, but you could save them to a different file at least and run that, or attempt to. I suspect you probably just couldn't write to the exe of any running process. Near the top of the file there were some mentions of TheGun and I changed one to Horse and it would not load, sadly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-7094626210603091219?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/7094626210603091219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=7094626210603091219&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7094626210603091219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7094626210603091219'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2011/08/728.html' title='7/28'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-3151413212574277156</id><published>2011-07-01T18:48:00.007-05:00</published><updated>2011-07-07T00:58:16.943-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='movie guis'/><title type='text'>Movie GUIs</title><content type='html'>I went to Hackjam the first time in who knows how long and it was nice to see everyone again.&lt;br /&gt;&lt;br /&gt;I found accessmaincomputerfile.net the other day and was inspired to try my hand at some immersive or attention-grabbing GUI components. Movie GUIs are overkill and extreme and make "real" GUIs look like the 20th century -- the ones I get excited about anyhow. The other ones I get excited about are the ones that are too real such as Trinity+nmap  or SunOS in the new Tron movie. These aren't very exciting to see on your normal computer though since, well, they already are on your normal computer.&lt;br /&gt;&lt;br /&gt;My first step is to  implement a clock applet resembling the &lt;a href="http://accessmaincomputerfile.net/photo/1280/1601273791/1/tumblr_lc0q3jfgng1qdhhtj"&gt;screenshot from Darkstar&lt;/a&gt;. I am running XFCE4 in Arch right now so I am going to target this environment. Adam was very helpful to me in gathering some information and getting started on setting up the build environment and sharing his perspective on how it might work. I have successfully compiled the original clock applet now. There are five options, each of which is based from a .c file in the xfce4-panel source tree, so my intent is to add clock-darkstar.c as an important part of finagling a sixth option into the mix.&lt;br /&gt;&lt;br /&gt;After doing all this hard work I decided making a XFCE plugin did not really further my goals and it would probably be more fun and tasty to pursue another avenue that did not necessarily require XFCE for example.&lt;br /&gt;&lt;br /&gt;I already have some experience with SDL so I am going to bark up that tree.&lt;br /&gt;&lt;br /&gt;As much as I want to learn new things, what I really want is to have a sweet new Darkstar (1974) clock applet. Now I am abusing the term "clock" and "applet" since this beastmaster can be so much more! A clock for starters, but the view implies so many fiddly knobs! Every text field is completely configurable in a number of ways. Good grief I am already in over my head before I even hit the water!&lt;br /&gt;&lt;br /&gt;I am going to nuke my copy of the xfce4-panel out of spite and also to make sure I have a lot of headache to go through in case I forget that I am doing this with SDL and not making a xfce4 plugin.&lt;br /&gt;&lt;br /&gt;I am also listening to Voltaire right now. Background music, not advice.&lt;br /&gt;&lt;br /&gt;Cheers!&lt;br /&gt;&lt;br /&gt;EDIT: here is a great link to what I have accomplished thus far &lt;a href="https://jonathanstone.homeip.net/darkstar.tgz"&gt;https://jonathanstone.homeip.net/darkstar.tgz&lt;/a&gt;. &lt;https: net="" tgz=""&gt; Please kindly disregard the certificate error, thanks. You can build it with some normal command such as "make". Also you need to put a 639x359 darkstar_1974.bmp in the folder at runtime since I am NOT distributing that. I got mine from accessmaincomputerfile.net as linked above and converted it to bmp with such a command: "convert darkstar_1974.jpg darkstar_1974.bmp". The 20ms delay is necessary to make the thing not nom down on all the cycles. Experimenting with higher values resulted in even lower (&amp;lt;1%) CPU utilization but then I couldn't close the window because the events occuring during the wait cycle are not processed.&lt;br /&gt;&lt;/https:&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-3151413212574277156?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/3151413212574277156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=3151413212574277156&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3151413212574277156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3151413212574277156'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2011/07/movie-guis.html' title='Movie GUIs'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-8065496917393093437</id><published>2010-12-12T13:34:00.003-06:00</published><updated>2010-12-12T15:04:33.310-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jungles'/><category scheme='http://www.blogger.com/atom/ns#' term='jws'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>silly shell tricks</title><content type='html'>You can use 'tac' to implement a stack.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Red comes from stdin, black is stdout:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instead of doing `factor`:&lt;/div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;factor&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;33&lt;/span&gt;&lt;/div&gt;&lt;div&gt;33: 3 11&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;19&lt;/span&gt;&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;27&lt;/span&gt;&lt;/div&gt;&lt;div&gt;27: 3 3 3&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;^D&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can do this:&lt;/div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;tac | factor&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;394&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;87&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;19&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;666&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;^D&lt;/span&gt;&lt;/div&gt;&lt;div&gt;666: 2 3 3 37&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;87: 3 29&lt;/div&gt;&lt;div&gt;394: 2 197&lt;/div&gt;&lt;div&gt;$&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What was reversed was the order of inputs sent to factor, not the output generated by factor. The effect is of course haveable a number of different ways:&lt;/div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;echo "394 87 19 666" | factor | tac&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;666: 2 3 3 37&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;87: 3 29&lt;/div&gt;&lt;div&gt;394: 2 197&lt;/div&gt;&lt;div style="color: rgb(255, 0, 0); "&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;and this is the same procedure however factor sees them in the order you typed them, not in their stack-reversed order. I think I can use this to my advantage someday, when I want a filter to see reversed input.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can also flip the output over the logical y = -x line using both tac and rev; this is also mostly JFF (just for fun):&lt;/div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;echo "394 87 19 666" | factor | tac | rev&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;73 3 3 2 :666&lt;/div&gt;&lt;div&gt;91 :91&lt;/div&gt;&lt;div&gt;92 3 :78&lt;/div&gt;&lt;div&gt;791 2 :493&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Clearly nonsensical. These filters are transitive however!&lt;/div&gt;&lt;div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;echo "394 87 19 666" | factor | tac | rev | tac | rev&lt;/span&gt;&lt;/div&gt;&lt;div&gt;394: 2 197&lt;/div&gt;&lt;div&gt;87: 3 29&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;666: 2 3 3 37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;echo "394 87 19 666" | factor | tac | rev | rev | tac&lt;/span&gt;&lt;/div&gt;&lt;div&gt;394: 2 197&lt;/div&gt;&lt;div&gt;87: 3 29&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;666: 2 3 3 37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;echo "394 87 19 666" | factor | tac | tac | rev | rev&lt;/span&gt;&lt;/div&gt;&lt;div&gt;394: 2 197&lt;/div&gt;&lt;div&gt;87: 3 29&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;666: 2 3 3 37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;echo "394 87 19 666" | factor | rev | tac | tac | rev&lt;/span&gt;&lt;/div&gt;&lt;div&gt;394: 2 197&lt;/div&gt;&lt;div&gt;87: 3 29&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;666: 2 3 3 37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;$ &lt;span class="Apple-style-span" &gt;echo "394 87 19 666" | factor | rev | rev | tac | tac&lt;/span&gt;&lt;/div&gt;&lt;div&gt;394: 2 197&lt;/div&gt;&lt;div&gt;87: 3 29&lt;/div&gt;&lt;div&gt;19: 19&lt;/div&gt;&lt;div&gt;666: 2 3 3 37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While I did not exhaust the combinations of two tacs and two revs, I feel confident knowing their properties that my conjecture holds, and I would even go so far as to say that any finite stream for which their exists sufficient RAM to process is preserved through arbitrary linear combinations of even counts of tacs and even counts of revs. A number of assumptions are of course depended upon: tac should require no more space than the streamed lines actually occupy and rev's space is constant in the number of lines and per-line, linear in the length. With clever stream pointer manipulation, both of these tools should not require to allocate additional space however.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have decided to run into a dense jungle banging on a drum and screaming DEATH TO MONKEYS!!! Here is a map of my progress: &lt;a href="http://piratejon.com:8080/mirror"&gt;http://piratejon.com:8080/mirror&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-8065496917393093437?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/8065496917393093437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=8065496917393093437&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/8065496917393093437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/8065496917393093437'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2010/12/silly-shell-tricks.html' title='silly shell tricks'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-1422564239633980397</id><published>2010-10-10T12:00:00.003-05:00</published><updated>2010-10-10T12:19:42.017-05:00</updated><title type='text'>sockets</title><content type='html'>Hack Jam Log Book deserves a new post.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have not been to hackjam in a while due to a great personal inconvenience in the tradeoff between space and time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This has not limited my hacking however.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This weekend I made a great sockets program in C. It has the following features: if you run it with a certain set of flags it attempts to initiate a TCP connection with a specified host on the specified port. If you run it with a different set of flags it listens for a connection attempt on the specified port. These behaviors are meant to be used in a complementary way though you can do whatever you want with them really. After a connection is established, a message loop enters which polls both stdin and the established socket connection. Since my terminal is in some kind of cooked buffered line mode, it sucks when you are typing and the remote host sends a message, but fortunately nothing is lost except maybe the user.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is no protocol.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is not a lot different from telnet however it has even fewer features and capabilities.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It does however illustrate basic blocking sockets and select() in C.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It does not currently compile in Windows (maybe cygwin?) though it will soon enough -- a little WSAStartup() here and maybe some WSACleanup() there and some other smidgens and #ifdefs and we'll have it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Code at &lt;a href="http://jonathanstone.homeip.net:8080/chat"&gt;http://jonathanstone.homeip.net:8080/chat&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Direction: ncurses to solve dumb text entry problems, full Win32 support, and openssl for point-to-point encryption.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-1422564239633980397?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://jonathanstone.homeip.net:8080/chat' title='sockets'/><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/1422564239633980397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=1422564239633980397&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1422564239633980397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1422564239633980397'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2010/10/sockets.html' title='sockets'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-5666048545522080888</id><published>2010-03-29T17:54:00.002-05:00</published><updated>2010-03-29T17:54:59.137-05:00</updated><title type='text'>A Painted Blog</title><content type='html'>I'm trying a little experiment; it's a blog that's painted on a 4'x8' piece of plywood; each new post is painted right on top of the last one, building up a visual history in layers of paint. Check it out at http://diiq.org/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-5666048545522080888?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://diiq.org' title='A Painted Blog'/><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/5666048545522080888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=5666048545522080888&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5666048545522080888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5666048545522080888'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2010/03/painted-blog.html' title='A Painted Blog'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-1160289926083714138</id><published>2009-08-09T09:31:00.004-05:00</published><updated>2009-08-09T13:03:24.220-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arensito'/><title type='text'>xkb and xmodmap: a big mess</title><content type='html'>So I've convinced myself to try a new keyboard mapping; arensito is currently the only word that I can type quickly and accurately.&lt;br /&gt;&lt;br /&gt;I thought that I would take a moment to write down the steps that it took to get a mapping with an extensive and unusual Alt-gr map up and running (on Linux). What is available online is exceedingly unhelpfull.&lt;br /&gt;&lt;br /&gt;1. I used Mod_switch rather than ISO_level3_Shift.  ISO is the 'correct' choice, but by default  N and J cannot be level shifted; fixing that requires xkb, and xkb is evilly difficult to use.&lt;br /&gt;&lt;br /&gt;2. Speaking of xkb and evil,  Mod_switch won't always work unless xkb is off. So in xorg.conf:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Section "InputDevice"&lt;br /&gt;Identifier  "Keyboard0"&lt;br /&gt;Driver      "keyboard"&lt;br /&gt;Option      "CoreKeyboard"&lt;br /&gt;Option      "XkbDisable" "true"&lt;br /&gt;#    Option        "XkbRules" "xorg"&lt;br /&gt;#    Option        "XkbModel" "latitude"&lt;br /&gt;#    Option        "XkbLayout" "us"&lt;br /&gt;EndSection&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Make sure to comment out all the xkb rules. In .xsession or .xinitrc or wherever you put scripts that run before your X session starts:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;export XKB_DISABLE=1&lt;/pre&gt;&lt;br /&gt;3. Edit .Xmodmap:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;keycode 44 = j J plus&lt;br /&gt;keycode 0x41 = Mode_switch&lt;br /&gt;clear mod3&lt;br /&gt;add mod3 = Mode_switch&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(note that I use the spacebar as my Mode_switch; chances are you want someting different)&lt;br /&gt;&lt;br /&gt;Mode_switch uses the third and fourth keysyms; 'j' and 'J' are the first and second, 'plus' is the third. space+j will return '+'.&lt;br /&gt;&lt;br /&gt;Please understand that this is the wrong way to do this; the 'right' way is to use xkb. However, rolling your own xkb mapping is a major undertaking, while xmodmap is reasonably simple. Disabling xkb as I have done here is not reccomended generally, and can apparently cause problems if you use compositing. Nevertheless, this solution works for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-1160289926083714138?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/1160289926083714138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=1160289926083714138&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1160289926083714138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1160289926083714138'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2009/08/xkb-and-xmodmap-big-mess.html' title='xkb and xmodmap: a big mess'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-3944895924364579862</id><published>2009-08-08T11:17:00.005-05:00</published><updated>2009-08-08T11:36:37.723-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eight'/><title type='text'>a  lisp</title><content type='html'>I'm working on designing a programming language. I am doing so because I want to do more of what I enjoy about programming. Boilerplate code does nothing for me. It is the beautiful code, the obvious-once-you-see-it-but-what-were-you-smoking-when-you-saw-it code, that makes me enjoy programming. I want a language that maximizes my experience of the numinous, a language that comes as close to the platonic program in my head as it can.&lt;br /&gt;&lt;br /&gt;I don't want a super-efficient language, or a minimal language, or a super-readable language. I want a language that is &lt;span style="font-style: italic;"&gt;fun.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The most controversial way I can put it is probably also the best: there is a quote.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." – Brian W. Kernighan&lt;/blockquote&gt;&lt;br /&gt;My design philosophy is this: I want a language in which I can code as cleverly as possible. Because I enjoy it. To hell with anything else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-3944895924364579862?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/3944895924364579862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=3944895924364579862&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3944895924364579862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3944895924364579862'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2009/08/lisp.html' title='a  lisp'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-755264428199710737</id><published>2009-06-25T15:57:00.003-05:00</published><updated>2009-07-15T19:25:41.110-05:00</updated><title type='text'>Clone of Existing Game with 3D Enhancement</title><content type='html'>I have spent the past three HackJam sessions cloning the super-fun Flash game &lt;a href="http://www.k2xl.com/games/boomshine/"&gt;Boomshine&lt;/a&gt;, in C. The reason for doing this is because I would like to add a 3D extension to this game. I want the third dimension to be time. Right now the balls bounce about on a flat plane, and the progression of time from present to more present results essentially in a visual overwrite of the balls at their new space coordinates. Well, by using perspective, I want to draw a 3D representation of the balls so that you can see in a single glance where the ball started and where the ball will be after many units of time have passed and, up to pixellation, where the ball will be at every moment in between. To describe this further, let me explain that while the balls are just bouncing about on their original 2D plane, the 3D view will be essentially static because the balls' velocities are fixed. The 3D view can only change after the player drops his ball with the mouse, and the outcomes of the original balls interact with that which was not there before.&lt;br /&gt;&lt;br /&gt;I got the idea to do this from a discussion with Montana about "solving" the game -- i.e. figuring out where you could place your ball to ensure that you "won". He suggested something about Einstein's light cones and thus this idea was born.&lt;br /&gt;&lt;br /&gt;I have never done 3D graphics before except in QBasic like ten years ago so this will be challenging and interesting.&lt;br /&gt;&lt;br /&gt;Right now I have successfully cloned the behavior of the original game. The balls bounce, collide, grow, shrink and die predictably, and all parameters (initial size, color, growth rate, target growth size, waiting duration, shrink rate, and number of balls) are completely customizable within reasonable limits i.e. no negative radii.&lt;br /&gt;&lt;br /&gt;With regard to shininess, I hope to do some transparency/alpha blending so the balls don't just overlap, also when bouncing off the edges the sprites flicker because the collision logic is funky however they ultimately careen off at the correct angle and stop flickering when they get away from the edge. Also maybe sound at some point? However these are all ancillary to my chief interest, which is representing the time dimension spatially.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-755264428199710737?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/755264428199710737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=755264428199710737&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/755264428199710737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/755264428199710737'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2009/06/clone-of-existing-game-with-3d.html' title='Clone of Existing Game with 3D Enhancement'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-5155639552291240915</id><published>2009-02-24T23:07:00.004-06:00</published><updated>2009-02-24T23:36:06.900-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='frp'/><category scheme='http://www.blogger.com/atom/ns#' term='arc'/><title type='text'>Haskell -&gt; Arc</title><content type='html'>Lately, Haskell's type system, powerful as it is, has been tending to get in my way.   It worked fine when implementing chunks of natural language parsers, but when I went back to revise my design, I was having a horrible time.   More recent toy projects such as the RSS reader or a simple graphical game have similarly made me grumpy.&lt;br /&gt;&lt;br /&gt;At the same time, compile time type checking has probably detected more than it's share of bugs in my code.   It's a tradeoff.  Whether it's a net win or loss is hard for me to say; I've done very little functional programming without strong typing.   I don't like Java style strong typing, but the ML type system is a different beast.  Having spent the better part of a year working in Haskell, I'm due to try a new programming language, so I'm going to move to Lisp for a while.&lt;br /&gt;&lt;br /&gt;Unfortunately for me, the essays that convinced me to finally a Lisp were on Arc, an arguably incomplete dialect.  It has almost nothing in the way of libraries.   After looking at Arc, though, Common Lisp looks warty and Scheme's lack of unhygenic macros is disturbing for a power language.   So I'll start with Arc, though I may well have to move to Common Lisp if I get frustrated with what I can't do (though I do have something of a backup plan in the works for that; more on that later, if it comes to pass).&lt;br /&gt;&lt;br /&gt;Picking up on loose ends, blogwise, my tron lightbike FRP game fell apart when I had trouble working out a definition of the behavior of the walls trailing behind the players.   I couldn't find a way to define a behavior that was a list of snapshots of another behavior at points dictated by a third behavior, and I couldn't help feeling that it was more natural to define it procedurally (though that may just be what I'm more used to).  I ended up being frustrated enough that I put it down and never came back to it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-5155639552291240915?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/5155639552291240915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=5155639552291240915&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5155639552291240915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5155639552291240915'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2009/02/haskell-arc.html' title='Haskell -&gt; Arc'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-5981230772067339293</id><published>2009-01-15T17:24:00.002-06:00</published><updated>2009-01-15T17:33:45.172-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='calling shots'/><category scheme='http://www.blogger.com/atom/ns#' term='puma in a box'/><title type='text'>Settling Down</title><content type='html'>I haven't posted in a while because I've been all over the map lately.  Shiny objects that have occupied me include kernels, compilers, HTML engines, procedurally generated game content, PJ's scrapture program, &lt;a href="http://yudkowsky.net/singularity/aibox"&gt;the AI Box game&lt;/a&gt; (careful with that box, son, there's a puma inside), writing a small RSS reader, and now, Functional Reactive Programming.  &lt;a href="http://www.haskell.org/haskellwiki/Functional_Reactive_Programming"&gt;FRP&lt;/a&gt; seems to be to event-driven programming what functional programming is to imperative programming.  I'll talk more about that once I'm more confident that I've got my head around it.&lt;br /&gt;&lt;br /&gt;I'm dropping in to call a shot.  For next week I'll have a simple FRP implementation of the Tron Lightbike game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-5981230772067339293?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/5981230772067339293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=5981230772067339293&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5981230772067339293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5981230772067339293'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2009/01/settling-down.html' title='Settling Down'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-2326502162512196402</id><published>2008-12-27T00:55:00.009-06:00</published><updated>2008-12-31T16:18:37.596-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frame masks'/><category scheme='http://www.blogger.com/atom/ns#' term='etc'/><category scheme='http://www.blogger.com/atom/ns#' term='unnecessarily long blog posts'/><category scheme='http://www.blogger.com/atom/ns#' term='daydreaming about bathing in beer'/><category scheme='http://www.blogger.com/atom/ns#' term='rambling'/><category scheme='http://www.blogger.com/atom/ns#' term='jws'/><category scheme='http://www.blogger.com/atom/ns#' term='premature optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='screen capture'/><title type='text'>Merry Holidays, and Screen Capture Update</title><content type='html'>&lt;div&gt;The Screen Capture dealio described in my last post is coming along. It presently displays two adjacent colored boxes: one solid foreground colored, and one mostly background colored but flickering to foreground color at a customizable rate of once per n frames; the foreground and background colors are also customizable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The least n for which the results are meaningful is, of course, 2, which means that during every 2nd frame the box is painted foreground colored while during all other frames the box is background colored. At this rate my naked, unaided eye can infer the foreground color with ease, though it's hard to say whether that is affected by the adjacent solid box -- this will have to be eliminated during future double-blind tests. Unfortunately the rapid cycling introduced some horizontal lines which were very unpleasant to look at and which will have to be dealt with effectively before useful conclusions can be drawn.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Adam and Sam gave helpful insights on what was causing the unpleasant horizontal lines and how to cope with it. Presently the main drawing loop merely increments the frame index counter, wraps it to zero if necessary, and throws up the appropriate frame for the flickering side, and does this as quickly as possible. The horizontal line problem arises when the program writes to the colored box's memory location while that location is being read and updated by the display hardware. In order to get around this it is necessary to interrupt the flow of things and patiently wait for the vertical refresh to complete and then resume.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A vertical refresh of 60Hz means, that 60 times per second the screen will be redrawn, and a higher FPS than that should make it always invisible. I think that because there is no computation or rendering or any complicated graphical processing, only blitting a small square that's already in memory, that it should not be hard to get better than 60 FPS, thereby making the refresh rate, and horizontal lines, appear invisible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Is this possible? The SDL trick of creating a double-buffered hardware surface and calling SDL_Flip() in the draw loop does not seem to have helped the horizontal line problem. So I'm looking into OpenGL to see if that will afford me the degree of control necessary to eliminate this problem. Sam suggested that because of various factors which I don't recall in their entirety, including but not limited to some things having to do with what the eye can keep together and how quickly the monitor updates, I would only be able to split it into about four frames before the image did not appear whole. Makes sense, if the images are too far apart (in time) then the eye may not unify them. This will of course be tested.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next up will be separating the target display image into nonoverlapping (and not necessarily continous) chunks, one on each frame. There are combinatorially many ways of splitting a fixed number of pixels onto a fixed number of frames. A few of the ways I'll be looking at are:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;random pixels: approximately (width*height)/n pixels will be pseudorandomly selected from the image and recorded to a frame with no repetition. Or some repetition but not in every frame? These are variables that will have to be examined for best output.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"checkerboard": the image will be divided checkerboard style into alternate squares, so that individual frames will appear as checkerboards, alternating background with foreground.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"radially chopping", or "pi cutting": from the center of the image outwardly drawn radii at regular (or irregular) angular intervals will determine where one region ends and the next begins. Again, one or more nonadjacent regions to a frame. No/some repetition?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The more I think about this, the more I think that the clearest aggregate image with the least information about the whole picture contained in a single frame will be had with random pixels and some repetition spread evenly enough so that most pixels that repeat do not appear next to other repeating pixels very often. For specific definitions of "most" and "very often" and "next to" and "evenly enough" and such.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Jumping right ahead to implementation details ... assuming there to be an arbitrary upper limit on the number of frames that an image can be split into, and assuming that arbitrary upper limit may just happen to be equal to the size in bits of a single data register in the processor on the machine I've been doing all the development for this project on, and assuming that I want to implement several different ways of splitting images up into frames and that given this last assumption that I certainly do not want to duplicate a whole lot of code doing so but would much rather, say, pass an image to any one of several image-to-frames splitting routines which may exist at any point in time and to have those routines all return an efficient description of how that image should be split among any desired number of frames upto the arbitrary limit, I think that I can do this: create a "frame mask" of dimensions equal to that of the image whose elements are 32-bit integers, with bit 0 indicating whether the pixel should be present in frame 0, and bit &lt;span class="Apple-style-span" style="font-style: italic;"&gt;n&lt;/span&gt; indicating whether the pixel should be present in frame &lt;span class="Apple-style-span" style="font-style: italic;"&gt;n&lt;/span&gt;. The splitting routines would all be able to write this format quite easily, and the post-splitting frame-generating routine would have no trouble reading it at all. This also makes it easy to save particular random splittings that turn out to be favorable for later analysis or just to show your friends.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, I'm done rambling. Sometime this year (2008) I'll get git setup on dreamhost and post the code for all to see. It's not pasted here because, frankly, in its current state, it's not very interesting :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;UPDATE: repository'd: &lt;a href="http://piratejon.com/git?p=scrapture.git"&gt;http://piratejon.com/git?p=scrapture.git&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-2326502162512196402?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/2326502162512196402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=2326502162512196402&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/2326502162512196402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/2326502162512196402'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/12/merry-holidays-and-screen-capture.html' title='Merry Holidays, and Screen Capture Update'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-6858261168763020426</id><published>2008-12-09T22:04:00.004-06:00</published><updated>2008-12-09T22:15:08.874-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hackjam'/><title type='text'>Hack Jam: 3.12.08</title><content type='html'>Topics of discussion: AI, NLP, Cantaloupe, Primes, and the possibility of being 4/9ths Asian.&lt;br /&gt;&lt;br /&gt;Just thought I'd dash out a quick note on what went on last week. PJ pulled off several examples of the ever-impressive trick: hacking with cat. That is to say, he wrote compilable c programs using cat, without re-writing. &lt;br /&gt;&lt;br /&gt;Those of us who use interpreted languages were perhaps nonplussed. He showed a clear and utter disregard for the fact that coding is supposed to be hard.&lt;br /&gt;&lt;br /&gt;However, I took back my own when the time came to sum an infinite series --- Lisp's native support for calculation with rational numbers allowed me thousands of digits accuracy without writing a bignum summer, making my solution only one line long.&lt;br /&gt;&lt;br /&gt;This brought to mind an interesting challenge --- writing code with write-or-die...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-6858261168763020426?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/6858261168763020426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=6858261168763020426&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6858261168763020426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6858261168763020426'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/12/hack-jam-12308.html' title='Hack Jam: 3.12.08'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-5819583084840432922</id><published>2008-12-01T02:10:00.004-06:00</published><updated>2008-12-01T03:07:17.834-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jws'/><category scheme='http://www.blogger.com/atom/ns#' term='being a shot-caller'/><category scheme='http://www.blogger.com/atom/ns#' term='screen capture'/><title type='text'>Breaking Screen Captures</title><content type='html'>&lt;div&gt;So my homie Nick had an interesting idea that I thought I would spend a bit of time exploring. The idea is to break the screen-capturability of an image by replacing it with several rapidly refreshing frames that appeared to the naked eye over time as a coherent image but which individually conveyed no useful information and rather appeared scrambled. So that under screen capture you get a single unrecognizable frame. If you take a digital video (i.e. rapid series of screen captures) you may still be able to view the image by playing the video. But you should not be able to extract the image by itself without some eyemulating algorithm, which we hope would be extremely difficult to compute.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think it would be quite possible to simply fraction the image into distinct geometric regions and display only part of the whole per frame, however it would be even easier to reassemble these than it was to separate them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, this week I'll begin by writing some stuff that blits an array of same-size bitmaps in order to the same region of the screen. Then I'll experiment with colors -- what does a solid red region look like, and what does a "red emulated" region look like, side-by-side, even? Does the number and difference/sameness between frames needed to convey a solid color depend on the color being conveyed? Is it easier or harder to emulate two different colors simultaneously -- that is to say, does color A being adjacent to color B change the requirement for number and quality of frames needed to achieve emulation? How about dithering A and B, and with different sizes of blocks? Hopefully the answers to these questions will suggest a formula for easily deconstructing an image into frames that are not easily reconstructible except by the natural power of the unaided (or lens-aided) human eye. At first I will treat color. Next will come shape, and how different shapes in different colors can be contrived to emulate a target image. Finally I hope to make an arbitrary jpeg unscreencapturable without hiding it in a hardware buffer -- this is in the long-term of course.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One application for this sort of technology is for controlling the shareability of images through websites or other software. In the past schemes have been implemented to disable mouse access of an image via Javascript or by otherwise manipulating the user-agent to act rather as the "content-provider-agent". I find this usage to be mostly heinous, but it is interesting nevertheless. More useful would be in CAPTCHA technology, where an algorithm might struggle to decode a series of frames that a human eye could read easily -- this may even lead to CAPTCHAs that are easier to read for humans but that bots could not reassemble into a coherent image, much less find the text in. This usage would be much less heinous, though it is still solving a problem that shouldn't exist. I think the most useful usage for this will be in elucidating characteristics of the human eye. And making fun of my colorblind friend Bob.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-5819583084840432922?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/5819583084840432922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=5819583084840432922&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5819583084840432922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/5819583084840432922'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/12/breaking-screen-captures.html' title='Breaking Screen Captures'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-4371374866560848126</id><published>2008-11-28T16:16:00.002-06:00</published><updated>2008-11-28T16:24:06.436-06:00</updated><title type='text'>Write or Die: Now on Emacs!</title><content type='html'>For those of you that write, or wish you wrote, or otherwise procrastinate while performing text-based activities, try out &lt;a href="http://lab.drwicked.com/writeordie.html"&gt;write-or-die&lt;/a&gt;.  It is a nice cattle prod; if you don't write for several seconds, it will punish you. I find that the Kamikaze mode is most effective --- the punishment is that it will delete words, bit by bit, until you begin to write again.&lt;br /&gt;&lt;br /&gt;However, I use emacs; and switching from my carefully-tuned text-editor extraordinaire to a javascript-based text-box is a bit of a disappointment. That's why I threw together this emacs version of write-or-die.&lt;br /&gt;&lt;br /&gt;Just paste the following into your init.el, and when the time comes, &lt;span style="font-style: italic;"&gt;M-x write-or-die&lt;/span&gt;. When you have accomplished your goal, &lt;span style="font-style: italic;"&gt;M-x no-more-die,&lt;/span&gt; and you're set.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(let ( (write-or-die-time ())&lt;br /&gt;      (write-or-die-init ()) )&lt;br /&gt;&lt;br /&gt;(defun write-or-die ()&lt;br /&gt; (interactive)&lt;br /&gt; (setf write-or-die-init (run-with-idle-timer 3 t 'w-or-die)))&lt;br /&gt;&lt;br /&gt;(defun w-or-die ()&lt;br /&gt; (interactive)&lt;br /&gt; (kill-region (point-max) (- (point-max) 10))&lt;br /&gt; (setf write-or-die-time (run-with-idle-timer&lt;br /&gt;            (time-add (current-idle-time)&lt;br /&gt;         (seconds-to-time 3))&lt;br /&gt;            ()&lt;br /&gt;      'w-or-die)))&lt;br /&gt;&lt;br /&gt;(defun no-more-die ()&lt;br /&gt;      (interactive)   &lt;br /&gt;      (cancel-timer write-or-die-init) &lt;br /&gt;      (cancel-timer write-or-die-time))&lt;br /&gt;&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Possible improvements --- flashing colors, like the web-version has, to warn you of the time limit; word-by-word deletion, rather than 10 characters at a time; variable time limit; etc. But those can wait. Right now I need to write another 10,000 words.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-4371374866560848126?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/4371374866560848126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=4371374866560848126&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/4371374866560848126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/4371374866560848126'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/write-or-die-now-on-emacs.html' title='Write or Die: Now on Emacs!'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-3576583135205438418</id><published>2008-11-26T20:19:00.002-06:00</published><updated>2008-11-26T20:55:54.493-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='brandon mythtv dvr linux'/><title type='text'>MythTV</title><content type='html'>For a quick breather away from the piano, I decided to set up a MythTV box.&lt;br /&gt;&lt;br /&gt;For those of you who are unfamiliar, &lt;a href="http://mythtv.org/"&gt;MythTV&lt;/a&gt; is the Linux DVR project.  It also has a lot of optional plug-ins (installed seperately) for things like Weather, News, NetFlix queuing, etc.  Not having a digital capture card makes my success thus far limited, but allow me to tell you what I have learned.&lt;br /&gt;&lt;br /&gt;First of all, for those who are interested in different types of cards out there, here are the different terms that get thrown around:&lt;br /&gt;&lt;br /&gt;* NTSC [in terms of broadcast] = analog/"your grandmother's television".  Think the TV with two knobs, the first one you turn to "U" to make the second knob work.&lt;br /&gt;* ATSC = new, hip digital broadcast TV [officially taking off Feb 2009]&lt;br /&gt;* Clear QAM = The "free" broadcast channels your local cable provider gives out.  Usually includes the ATSC channels in your area.  For those who are interested, my research shows that Cox Cable has a whopping 6 Clear QAM channels available in Norman, OK.&lt;br /&gt;* DVB = Digital Video Broadcast.  DVB-T is terrestial, DVB-C is cable, DVB-S is satellite.&lt;br /&gt;&lt;br /&gt;With the basic terminology out of the way, have fun looking for good cards.  Reviews are limited.  You might enjoy these handy posts for tutorials on installing MythTV and selecting cards:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mythtv.org/docs/mythtv-HOWTO.html#toc5"&gt;http://www.mythtv.org/docs/mythtv-HOWTO.html#toc5&lt;/a&gt; [Installing MythTV]&lt;br /&gt;&lt;a href="http://www.mythtv.org/wiki/index.php/Category:Video_capture_cards"&gt;http://www.mythtv.org/wiki/index.php/Category:Video_capture_cards&lt;/a&gt; [Capture Cards]&lt;br /&gt;&lt;br /&gt;There are a lot of pre-requisites, including some that aren't listed.  The big one is of "&lt;a href="http://rpmfind.net/linux/rpm2html/search.php?query=qt3-MySQL"&gt;Qt3MySQL&lt;/a&gt;" [why they don't list it as an actual pre-req, I don't know].  The ones listed in the tutorial include:&lt;br /&gt;mysql, gcc, freetype2-devel, xorg-xserver-devel, qt-devel and lame.&lt;br /&gt;Also required:&lt;br /&gt;qmake, Xv, QT3MySQL, mplayer, ffmpeg, transcode, many others&lt;br /&gt;&lt;br /&gt;Pro Tip!&lt;br /&gt;If while making a program you get lines that show...&lt;br /&gt;&lt;strong&gt;/usr/bin/ld: cannot find -lMERPMERP&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;collect2: ld returned 1 exit status&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Do a search in your package manager for MERPMERP.  Many times, that will resolve it and you can resume MAKEing your program.&lt;br /&gt;&lt;br /&gt;Anyway, when you go to MAKE the program, assuming you have everything, it will take about 30+ minutes to compile with a pretty decent CPU, so I recommend a good lunch.  &lt;br /&gt;&lt;br /&gt;Once everything is installed, run mythfilldatabase to populate your SQL backend with channel data from your card.  If you don't like something you've done during the initial setup, don't worry... you can always run mythtv-setup again.&lt;br /&gt;&lt;br /&gt;As a last note, MythPlugins is worth installing at least for MythArchive.  Unless you want to purchase a &lt;a href="http://www.dell.com/content/products/productdetails.aspx/pvaul_md1000?c=us&amp;amp;l=en&amp;amp;s=bsd&amp;amp;cs=04"&gt;nice JBOD system &lt;/a&gt;for harddrives, install it and play around with the "Archive" [burns recorded shows to DVD]!&lt;br /&gt;&lt;br /&gt;As I hear more about cards, plug-ins and more, I'll keep you posted.&lt;br /&gt;&lt;br /&gt;Regards,&lt;br /&gt;&lt;br /&gt;Brandon&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-3576583135205438418?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/3576583135205438418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=3576583135205438418&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3576583135205438418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3576583135205438418'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/mythtv.html' title='MythTV'/><author><name>Brandon Bagwell</name><uri>http://www.blogger.com/profile/07241811394960939097</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-364633012563737439</id><published>2008-11-21T14:56:00.004-06:00</published><updated>2008-11-26T19:51:16.429-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jws'/><category scheme='http://www.blogger.com/atom/ns#' term='postscript'/><title type='text'>Postscript Posters</title><content type='html'>One of the more exciting things you can do with Postscript is to make a poster -- vector graphics are sexy and you can easily make them as large or small as you want while the plotter or viewing device faithfully retains the original image's sharpness and definition. And bigger is always better: Why make a Rhode Island-sized poster when you can have Texas for the cost of a scaling factor?&lt;br /&gt;&lt;br /&gt;I set out to make a poster and found that although it was ultimately a straightforward task, I had to figure a few things out to get it to work.&lt;br /&gt;&lt;br /&gt;First, it was necessary for me to write the whole poster on a single 8.5x11 sheet. Apparently it is very hard to change the page size in postscript, so sticking with the default and specifying an appropriate bounding box worked best for me. The bounding box is done up by writing near the top of the file&lt;br /&gt;&lt;span style="font-family:courier;"&gt;%%BoundingBox: x1 y1 x2 y2&lt;/span&gt;&lt;br /&gt;So, you specify the lower-left and upper-right corners of the smallest rectangle that includes everything you want to be in the image.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On my first try I simply drew my graphics at the intended poster size on the page -- all that was visible to me was the bottom corner of the page, while the majority of the graphics were plotted at coordinates not within the page size.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once I had everything looking the way I wanted it to I just had to issue the scale commands at the beginning of the file:&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:courier;"&gt;.15 .15 scale&lt;/span&gt;&lt;/div&gt;&lt;div&gt;caused the graphics to follow to be drawn at the fifteen percent required to get them on the page.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At that point I used the "poster" utility with a scaling factor of the inverse of the one I supplied to postscript -- here, 6.667 -- and piped the output to a new ps file. The new ps file went to ps2pdf, and the final product was the poster at the size I needed split over 40 8.5x11 pages. Cool beans!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ultimately I decided that what I did want was a whole poster and they are not that expensive so I will take the downscaled pdf to Kinko's and have them upscale it to poster size and print it for me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Making posters is pretty cool and I think you should try it too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-364633012563737439?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/364633012563737439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=364633012563737439&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/364633012563737439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/364633012563737439'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/postscript-posters.html' title='Postscript Posters'/><author><name>Jonathan Wesley Stone</name><uri>http://www.blogger.com/profile/11821543582142009054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-6213098092595937374</id><published>2008-11-18T19:58:00.004-06:00</published><updated>2008-11-20T22:58:41.654-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='livescribe'/><category scheme='http://www.blogger.com/atom/ns#' term='sam'/><category scheme='http://www.blogger.com/atom/ns#' term='pulse'/><title type='text'>Livescribe Pulse Hacking: The buisness already!</title><content type='html'>Blah, blah, blah. Those of you who were up to date on your Fourier transform are now bored out of your mind --- and those of you who weren't are still wondering why I'm talking so much about it rather than about the pen.&lt;br /&gt;&lt;br /&gt;So now, it happens! Data is sent from the pen to my laptop, running Linux, via &lt;span style="font-style: italic;"&gt;vibrating air!&lt;/span&gt; Doesn't it just put you at the edge of your seat?&lt;br /&gt;&lt;br /&gt;The good news: "Hello, World!" did get from my pen to my desktop. The bad news: it did so at something like 8bps --- that's 8 &lt;span style="font-style: italic;"&gt;bits&lt;/span&gt; per second, mind you. So it took something like a quarter of a minute just to send those two words.&lt;br /&gt;&lt;br /&gt;Are improvements possible? Absolutely. I can increase my sampling rate (currently 8kHz, could easily be 16). I can increase the number of different frequencies to increase the per-unit-bandwidth.&lt;br /&gt;&lt;br /&gt;But what is currently killing me is (I believe) the period &lt;span style="font-style: italic;"&gt;between &lt;/span&gt;tones; not the tones themselves.    There are two dangerous things that happen during the transition. One is that the Fourier analysis for time-bins which contain a frequency change have two peaks; this makes classifying those bins far more challenging, even classifying them as worthless and ignoring them.&lt;br /&gt;&lt;br /&gt;Second, and a little more worrying, is on the pen: the amount of time that passes between the current sound clip ending after I request that the next sound play, and the next sound actually &lt;span style="font-style: italic;"&gt;playing&lt;/span&gt;.  It is, uh ... not zero. And that of course makes the the whole in-between-tone period even HARDER to identify and cope with.&lt;br /&gt;&lt;br /&gt;Short note. Hopefully have more time next week to discuss possible fixes for all these faults.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-6213098092595937374?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/6213098092595937374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=6213098092595937374&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6213098092595937374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6213098092595937374'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/livescribe-pulse-hacking-buisness.html' title='Livescribe Pulse Hacking: The buisness already!'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-1969170378797385647</id><published>2008-11-17T00:19:00.004-06:00</published><updated>2008-11-17T00:29:34.957-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='calling shots'/><category scheme='http://www.blogger.com/atom/ns#' term='nlp'/><category scheme='http://www.blogger.com/atom/ns#' term='adam'/><category scheme='http://www.blogger.com/atom/ns#' term='language'/><title type='text'>Word Mangling, Verb Conjugation, Concepts</title><content type='html'>I've been busy with mundane parts of the nlp system recently.  In the past week, I rewrote about 90 percent of the word recognizer and grammar parser.  The new word recognition allows extended forms of words (eg. run -&gt; runner -&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;runneresque&lt;/span&gt;) and irregular verbs (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;eg&lt;/span&gt;. go, went, gone).  Of course, just because the system can recognize words like &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;filelike&lt;/span&gt; doesn't mean it can assign meaning to them, aside from the rather &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;vague&lt;/span&gt; "has some properties a file has."  Of course, that's all you or I get as well; it's an evocative word, used to convey a starting point rather than to nail down specific properties.  Computationally, perhaps it could be used for something like linking a new concept to nod in an existing conceptual graph.  I'll see how that can work as I continue to research and/or reinvent and/or borrow wheels.&lt;br /&gt;&lt;br /&gt;The upgrade to the grammar parser now recognizes as many different tenses, aspects, voices, and persons as I've found to exist so far, including some I'm somewhat dubious about.  Is future perfect continuous passive ("will have been being eaten") for real?  It may just be PageRank, but &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;google's&lt;/span&gt; only showing grammar sites for at least the first 50 hits for "&lt;a href="http://www.google.com/search?q=%22will+have+been+being%22"&gt;will have been being&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;So now I'm back to where I thought I was two weeks ago, ready to start working on a new knowledge representation.  And that brings me to this sentence:&lt;br /&gt;&lt;br /&gt;"Alice believed Bob lied."&lt;br /&gt;&lt;br /&gt;Pulling this apart, there's at least 6 concepts introduced here, each &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;pronounable&lt;/span&gt; in the next sentence:&lt;br /&gt;&lt;br /&gt;C1: the act of lying.  "It's something we've all done."&lt;br /&gt;C2: Bob.  "He's been known to prevaricate."&lt;br /&gt;C3: the event of Bob lying, in the past.  "It's happened before."&lt;br /&gt;C4: the act of (or quality of) belief in C3.  "It's true of Eve as well."&lt;br /&gt;C5: Alice.  "She's not quick to trust."&lt;br /&gt;C6: Alice holding a belief in C3.  "It's because of their past."&lt;br /&gt;&lt;br /&gt;This has been bugging me for the past week and a half or so.  How many of those are &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;conceived&lt;/span&gt; on first reading?  C1 and C4 specifically: they're the hardest to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;pronounize&lt;/span&gt; in a non awkward way.  Do the pronouns force a reevaluation of the sentence when the other four don't fit the pronoun?&lt;br /&gt;&lt;br /&gt;I've been cowardly and not calling shots for a while, so nothing to report there outside of the progress mentioned above.  I've got just one called shot for the next week: research in the area of knowledge representation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-1969170378797385647?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/1969170378797385647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=1969170378797385647&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1969170378797385647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1969170378797385647'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/word-mangling-verb-conjugation-concepts.html' title='Word Mangling, Verb Conjugation, Concepts'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-4250661048318830926</id><published>2008-11-13T01:14:00.003-06:00</published><updated>2008-11-13T01:28:38.138-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='avr piano gcc atmega brandon'/><title type='text'>Makefile , Blink , and Software Controlled Buttons</title><content type='html'>As promised, another update on the glorious piano project.&lt;br /&gt;&lt;br /&gt;This week has mostly been about getting a good solid foundation for development.  After some time, I managed to make my first Makefile specifically for the Atmega16 and my avr-toolchain.  I also managed to test it both on my JTAG programmer, as well as Sam's STK500v2 which I'm still in possession of. &lt;br /&gt;&lt;br /&gt;Additionally, I spent a good deal of time trying to get a software controlled switch to work.  Getting the code to compile and upload to the Atmega was simplified with my Makefile, for sure, but for some reason the silly microcontroller was resetting on me.  The data sheet didn't seem to provide much help [I went through all of the RESETs listed, to no avail].  Sam suggested I research the internal pull-up resistors, but they seemed to hold the current around +3V, and also produce the same intermittent reset problem.  I finally said enough was enough and decided to do external pull-up resistors.  If you are interested, here is a site which shows the basic diagram of how to put a switch into a Microcontroller:  http://www.micahcarrick.com/05-15-2006/avr-tutorial-switch-debounce.html  . &lt;br /&gt;&lt;br /&gt;I've uploaded my sample code onto my website for now.  You can find all of the available warez under http://brandon.bagwellonline.com/piano  .  Currently, you will find a simple "blink" program, a "swbutton" [which has a software-controlled button listed], the Makefile, and eventually an image of my JTAG programming breadboard.  Hopefully, I will add more interesting pics as they become available, but with were the project is at the moment, all the fun will exist in the world of C, Assembly, and my head.&lt;br /&gt;&lt;br /&gt;Updates will be coming, though they will be slower since the end of the year is a busy time for me at work [everyone else is burning their vacation time].  Besides, I'm still catching up on Doctor Who and Business Week. &lt;br /&gt;&lt;br /&gt;More next time,&lt;br /&gt;&lt;br /&gt;Brandon&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-4250661048318830926?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/4250661048318830926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=4250661048318830926&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/4250661048318830926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/4250661048318830926'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/makefile-blink-and-software-controlled.html' title='Makefile , Blink , and Software Controlled Buttons'/><author><name>Brandon Bagwell</name><uri>http://www.blogger.com/profile/07241811394960939097</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-8561050581613701904</id><published>2008-11-12T15:30:00.005-06:00</published><updated>2008-11-12T17:47:05.675-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='livescribe'/><category scheme='http://www.blogger.com/atom/ns#' term='modem'/><category scheme='http://www.blogger.com/atom/ns#' term='sam'/><category scheme='http://www.blogger.com/atom/ns#' term='pulse'/><title type='text'>Livescribe Pulse Modem Hack: The Fourier Transform</title><content type='html'>So we have a rough idea what the frequency domain looks like; now we need some way of actually transforming data in the time domain (raw from the microphone)  into frequency domain data. We'll do that through the creative application of &lt;span style="font-style: italic;"&gt;interference.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For this trick to work, we must remember that the average value of a sinusoid is zero --- half the wave is positive, half the wave is negative, and it all cancels out nicely.&lt;br /&gt;&lt;br /&gt;The other thing we need to know is how sinusoids multiply. So imagine a sinusoid, plodding along; a nice, slow wave with a long wavelength. Now imagine a fast, short wave sinusoid right on top of it. For each point along the x-axis of our imaginary graph, multiply the value of the slow wave with the value of the fast wave; and take care --- I said &lt;span style="font-style: italic;"&gt;multiply&lt;/span&gt;, not add.&lt;br /&gt;&lt;br /&gt;If your imagination is in smooth working order, you might piece together that the result is a periodic, oscillating wave. If your imagination is exceptionally  good, you might even be able to notice that this curve is made up of two summed sinusoidal components. Truth be told, my imagination didn't hold up to the strain --- now I've got to find a new one. I recommend &lt;a href="http://www.e-tutor.com/et2/graphing"&gt;this&lt;/a&gt; for when your function imagination breaks down.&lt;br /&gt;&lt;br /&gt;(In the meantime, we can &lt;a href="http://crca.ucsd.edu/%7Emsp/techniques/latest/book-html/node77.html"&gt;examine a little math &lt;/a&gt;and discover that the two components are, in fact, sine waves whose frequencies are the sum of our original two sine waves and their difference, respectively.)&lt;br /&gt;&lt;br /&gt;But regardless of what the components are, they are sinusoidal --- and we already said that the average value of a sine is zero.&lt;br /&gt;&lt;br /&gt;What happens, though, if we take two &lt;span style="font-style: italic;"&gt;identical&lt;/span&gt; sine waves, and multiply them? Every place that one is positive, the other is positive as well; a positive times a positive is another positive... and every place one is negative, the other is as well; negative times negative is also positive.&lt;br /&gt;&lt;br /&gt;All of a sudden the average value &lt;span style="font-style: italic;"&gt;is no longer zero!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;More exciting still, the trick still works even when we use a sum of multiple sinusoids for our first wave --- if the sinusoid we're multiplying by is exactly the same frequency as one of the components of our first wave, then the average value of the product is non-zero --- and that value is proportional to the amplitude of the component wave. We've found a way to pick a single sine wave out of a sum of them! Our transform! Right?&lt;br /&gt;&lt;br /&gt;There's an insidious evil lurking behind this joy.&lt;br /&gt;&lt;br /&gt;Notice what happens when our two waves fall ninety degrees out of phase, so that the peaks of one wave occur simultaneous to the zeros of the other. When we multiply, BAM. another simple sine wave. That's no help --- its average is still zero. As it turns out, the average value of the product of same-frequency sines is not simply proportional to the amplitude of the original wave; it's proportional to the amplitude &lt;span style="font-style: italic;"&gt;and phase shift&lt;/span&gt;. Shoot.&lt;br /&gt;&lt;br /&gt;There is one hope, however: cosine. Cosine's &lt;span style="font-style: italic;"&gt;already &lt;/span&gt;ninety degrees out of phase with sine, right?  So whenever multiplying by a sine wave results in a false negative, multiplying by a cosine will get a full-strength output.&lt;br /&gt;&lt;br /&gt;And sure enough, in combination, multiplying by sine, separately multiplying by cosine, and then adding the two results, negates the phase-based part of the new wave. Loverly. Here, we've invented the full form of the Fourier Transform (for that is indeed what it is): The amplitude of a given frequency component of a wave is equal to the average of the sum of a unit cosine at the given frequency times the original wave  times a unit sine at the given frequency times the original wave.&lt;br /&gt;&lt;br /&gt;That's it --- easy as pie, right?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;Well, no, actually. Nowadays, no one uses that kind of notation --- we transform everything into the complex domain before we even begin. Even worse, there are huge pitfalls as soon as you make the whole thing digital --- when you no longer have smooth curves but individual samples the whole mess gets much more involved, plus there's the issue of efficiency; the method we used is about as fast as a mole on a paddleboat. It can't even reach the pedals, poor thing.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The practical application of all this comes right back to the Livescribe pulse. You remember that, right? All this has been about that. What we have now is a way to determine which frequency dominates a given audio sample. By making the pen play individual, pre-chosen frequencies, we can send data from the pen's speaker, through the PC microphone, and then decode the sounds back into labeled frequencies. Peachy. Now all we need is a way to encode data as a list of frequencies, and we're all set!&lt;br /&gt;&lt;br /&gt;That will be the topic of my next post, where, with luck, I will be able to declare success in sending data from the pen to my PC &lt;span style="font-style: italic;"&gt;without&lt;/span&gt; the use of Livescribe's desktop software.&lt;br /&gt;&lt;br /&gt;So stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-8561050581613701904?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/8561050581613701904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=8561050581613701904&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/8561050581613701904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/8561050581613701904'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/livescribe-pulse-modem-hack-fourier.html' title='Livescribe Pulse Modem Hack: The Fourier Transform'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-9100110878370561324</id><published>2008-11-06T23:20:00.003-06:00</published><updated>2008-11-12T17:34:24.239-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='minutes'/><category scheme='http://www.blogger.com/atom/ns#' term='hackjam'/><title type='text'>No Hackjam 11.5.08</title><content type='html'>No 11.5 hack jam; physical conditions were unfavorable (torrential rain).&lt;br /&gt;&lt;br /&gt;I succeeded in all my calls for last week.&lt;br /&gt;&lt;br /&gt;This week:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;a post explaining the fourier transform, and how to use it.&lt;/li&gt;&lt;li&gt;the first bit actually transmitted from pen to computer by sound&lt;/li&gt;&lt;li&gt;another 10000 words of novel&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-9100110878370561324?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/9100110878370561324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=9100110878370561324&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/9100110878370561324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/9100110878370561324'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/no-hackjam-11508.html' title='No Hackjam 11.5.08'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-3542342933194138647</id><published>2008-11-03T23:34:00.003-06:00</published><updated>2008-11-12T17:34:46.149-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nlp'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='adam'/><title type='text'>NLP: Extracting Meaning from Noun Phrases</title><content type='html'>Today we'll look at one way to build up a representation of noun phrases as logical statements (see the &lt;a href="http://hackjam.blogspot.com/2008/10/im-going-to-start-series-of-detailed.html"&gt;first post&lt;/a&gt; for an introduction to the problem space we're working in).  Once again, I'll be using Haskell code derived from my current project to demonstrate exactly what I mean.  One thing that has become more and more apparent to me as I progress is that this kind of representation of the meaning of sentences is the wrong way to go.  As I describe the structure I've been using, we'll take a look at some concepts that are difficult to represent in ways that don't depend on the english meaning of predicates themselves.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; module HackJamNLP2 where&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;First, we need to revisit and expand our grammar somewhat.  This is still a simplified grammar relative to English taken as a whole.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data NounPhrase     = ANoun Word&lt;br /&gt;&gt;                     | APronoun Word&lt;br /&gt;&gt;                     | Name Word&lt;br /&gt;&gt;                     | AdjectivesNoun [Word] Word&lt;br /&gt;&gt;                     | NPRelClause NounPhrase RelativeClause&lt;br /&gt;&lt;br /&gt;&gt; data RelativeClause = RelativeClause Word VerbPhrase&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A quick grammar refresher.  Relative clauses are a kind of extra, descriptive, verb phrase.  In the sentence, "He who smelt it, dealt it," the relative clause "who smelt it" modifies he.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data PartOfSpeech = Noun | Verb | Adjective | Article | Pronoun&lt;br /&gt;&gt;                   | Adverb | QueryWord | Unknown&lt;br /&gt;&gt;                     deriving Eq&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We're going to classify the words who what where why when and how as query words.  In this naive system, the presense of a query word is going to set off the whole sentence as a question.  So this system will flag "That's not how you do it," as a query.  This is not a fatal flaw, but requires a bit of analysis to get around.&lt;br /&gt;&lt;br /&gt;Now let's update our logical notation.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data LogicSentence = Atom ID [Term]&lt;br /&gt;&gt;                    | And LogicSentence LogicSentence&lt;br /&gt;&gt;                    | Implies LogicSentence LogicSentence&lt;br /&gt;&gt;                    | ForAll Term LogicSentence&lt;br /&gt;&gt;                    | Exists Term LogicSentence&lt;br /&gt;&gt;                    | MemberOf Term Term&lt;br /&gt;&gt;                      deriving Show&lt;br /&gt;&gt;&lt;br /&gt;&gt; data Term = Variable ID&lt;br /&gt;&gt;           | Set [Term]&lt;br /&gt;&gt;           | HigherOrder LogicSentence&lt;br /&gt;&gt;             deriving Show&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;From the definitions we used last time, we're adding some elements of higher order logic: sets and higher order terms.  (Sets were in the last post but not used.)  A number of concepts are much more natural to express in sets, and higher order terms are used sparingly to store meta information to pass on to a higher module, rather than passing around an extra structure to store intent, etc.&lt;br /&gt;&lt;br /&gt;One more thing before we get into the meat of this post.  Let's define a couple shorthand notations for patterns that will show up a couple of times.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; x                   = Variable "x"&lt;br /&gt;&gt; inContext           = Atom "in-context" [x]&lt;br /&gt;&lt;br /&gt;&gt; aSetWhere sent      = let s = Variable "s" in&lt;br /&gt;&gt;                       Exists s (ForAll x ((x `MemberOf` s) `Implies` sent))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;aSetWhere defines a set where all it's members satisfy a given sentence.&lt;br /&gt;&lt;br /&gt;Throughout convertNounPhrase, which we are about to (re)define, the variable "x" will represent the current noun phrase.  We can avoid clashes by being carefull to substitute variables whenever we add two noun phrases together.  We'll do that in combineNVSents, another function from last time that we'll expand in just a bit, and we'll use that function in a general way anytime we're combining sentences.&lt;br /&gt;&lt;br /&gt;The first important change is that our convertNounPhrase will now return a list of LogicSentences, each representing a /possible/ interpretation of the given grammar parse.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase     :: NounPhrase -&gt; [LogicSentence]&lt;br /&gt;&gt; convertNounPhrase (Name name)&lt;br /&gt;&gt;                       = [Exists x (Atom ("called-" ++ wordString name) [x])]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The conversion of Names is unchanged from last time, except for wrapping the result inside a list.  Something I didn't point out last time was the awkwardness here in mapping, say, "Bob" to "Ex called-Bob(x)".  What this does is put information inside the name of the object /inside/ the name of the predicate.  Unfortunately, there's no where else to put it.  My first system used a Const type of Term, but that doesn't scale to any system where two different objects have the same name.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase (ANoun n)&lt;br /&gt;&gt;       | partOfSpeech n == QueryWord&lt;br /&gt;&gt;                       = [Atom "speaker-asking"&lt;br /&gt;&gt;                               [HigherOrder (ForAll x baseSentence)]]&lt;br /&gt;&gt;       | isPlural n    = [ForAll x baseSentence, aSetWhere baseSentence]&lt;br /&gt;&gt;       | otherwise     = [Exists x baseSentence,&lt;br /&gt;&gt;                          ForAll x baseSentence,&lt;br /&gt;&gt;                          aSetWhere baseSentence]&lt;br /&gt;&gt;   where baseSentence  = Atom (wordString n) [x]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's the big reason why Higher order terms were added; it's much more elegant to state the meaning of a question to be "speaker-asking(q)" where q is a sentence describing what the question should answer, Jeopardy style, than to avoid higher oder terms and pass another parameter around all the functions.&lt;br /&gt;&lt;br /&gt;The case of a plural noun brings up our first ambiguous meaning.  So what does a word like "potatoes" refer to?  All potates, or some?  Compare the sentences "Potatoes come from the ground," and "Bob had potatoes for breakfast."  It's impossible to tell the meaning of "potatoes" without context, so all we can do here is shrug and let something downstream try to disambiguate the meanings.&lt;br /&gt;&lt;br /&gt;The last case is a bit odd.  I haven't been able to come up with any sentence where it makes sense to use a sigular noun without an article outside of gems like "I can has cheeseburger?"  Hopefully our parser throws out parses with this form when more correct parses are available, but if we are asked to convert the NounPhrase, we should do our best.  Unfortunately in this case, our best is to throw all the possibilities out there.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase (APronoun n)&lt;br /&gt;&gt;                       = case wordString n of&lt;br /&gt;&gt;                               "I"       -&gt; [Exists x (Atom "speaker" [x])]&lt;br /&gt;&gt;                               "you"     -&gt; [Exists x (Atom "audience" [x])]&lt;br /&gt;&gt;                               otherwise -&gt; [Exists x inContext]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pronouns are the same as last time, just wrapped in lists.  I'm still truncating this for brevity, but you can see here a good case for adding the meaning of at least some words into the Word type itself.  We could define a "meaningOf" field for the Word type and use that instead of all these Atom clauses.  This also allows an agent to modify the results it gets from this module by modifying its dictionary, rather than having to rewrite meanings built in here.&lt;br /&gt;&lt;br /&gt;And if we extend our definition of words to include the occasional phrase like "on fire", we can easily have the meanings of "on fire" and "aflame" be the same without any special cases.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase (AdjectivesNoun (adj:adjs) noun)&lt;br /&gt;&gt;       | isThe adj &amp;amp;&amp;amp; isPlural noun&lt;br /&gt;&gt;                       = [ForAll x (inContext `And` (baseSentence adjs noun)),&lt;br /&gt;&gt;                          aSetWhere (inContext `And` (baseSentence adjs noun))]&lt;br /&gt;&gt;       | isA adj &amp;amp;&amp;amp; isPlural noun&lt;br /&gt;&gt;                       = []&lt;br /&gt;&gt;       | isPlural noun = [ForAll x (baseSentence (adj:adjs) noun),&lt;br /&gt;&gt;                          aSetWhere (baseSentence (adj:adjs) noun)]&lt;br /&gt;&gt;       | isThe adj     = [Exists x (inContext `And` (baseSentence adjs noun))]&lt;br /&gt;&gt;       | isA adj       = [ForAll x (baseSentence adjs noun),&lt;br /&gt;&gt;                          Exists x (baseSentence adjs noun)]&lt;br /&gt;&gt;       | otherwise     = [Exists x (baseSentence (adj:adjs) noun)]&lt;br /&gt;&gt;   where&lt;br /&gt;&gt;       isThe adj       = wordString adj == "the"&lt;br /&gt;&gt;       isA adj         = wordString adj == "a" || wordString adj == "an"&lt;br /&gt;&gt;       baseSentence [] n&lt;br /&gt;&gt;                       = Atom (wordString n) [x]&lt;br /&gt;&gt;       baseSentence (adj:adjs) n&lt;br /&gt;&gt;                       = Atom (wordString adj) [x] `And` (baseSentence adjs n)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I've broken an adjective phrase into six different cases based on the article, if any, it begins with and the plurality of the noun.  You can see that we ignore phrases like "a potatoes."  Above I argued that we should try to find a meaning for anything we get, but here we've got contradictory indicators about the plurality of the term rather than some grammar abuse.&lt;br /&gt;&lt;br /&gt;One other part that was suprising to me was the seemingly contradictory interpretations of singular nouns preceeded by a or an.  The first case is a sentence like "A book is written by an author," where the intent is to refer to all books through the idea of a book-ness.  The second case is the intuitive one: "A book is misssing."&lt;br /&gt;&lt;br /&gt;You can also see that adjectives are treated the same way as nouns: as atomic sentences.  "A big ant" becomes "big(x) &amp;amp; ant(x)," which is problematic.  Through And-Elimination, we get "big(x)"; this ant is no longer big for an ant, it is just /big/.  We could introduce big-relative-to-ants(x), or possibly "Ey average-ant(y) &amp;amp; big-relative-to(x, y)," neither of which is particularly appealing.  It gets worse however.  From the &lt;a href="http://www.ics.mq.edu.au/%7Eelena/AkhmDrasALTA07.pdf"&gt;Akhmatova&lt;/a&gt; paper I mentioned in my last progress posting: take the sentence "The gastronomic capital of France is Lyon."  And-Elimination (and a proper interpretation of the rest of the sentence) will leave you with "The capital of France is Lyon."  So adjectives are difficult to shoehorn in to logic like this, regardless of whether they are limiting or modifying the base noun.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase (NPRelClause np (RelativeClause word vp))&lt;br /&gt;&gt;                       = [combineNVSents nSent (vSent (subjectOf nSent))&lt;br /&gt;&gt;                                       | nSent &lt;- convertNounPhrase np, &gt;                                         vSent &lt;- convertVerbPhrase vp] &lt;/pre&gt;&lt;br /&gt;Moving on, the conversion of relative clauses is fairly straightforward, funny notation notwithstanding.  This funny looking structure is the one bit of Haskell I decided to sneak in here.  It's a list comprehension, and it's best explained via a contrived example.  Let's say you wanted a list of strings that consisted of all possible combinations of a set of prefixes and suffixes.  In Haskell, you could say:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; contrived           = [ prefix ++ suffix | prefix &lt;- ["un", "im", "non"], &gt;                                            suffix &lt;- ["bad", "good", "ugly"] ] &lt;/pre&gt;&lt;br /&gt;This creates a list of nine strings.  Now compare that with definition for relative clauses above, and you can see that we are making all possible combinations of noun and verb phrases we can muster.  (The definition of convertVerbPhrase from the last post returned only a single LogicSentence; here we're using one modified to return a list of Sentences.)&lt;br /&gt;&lt;br /&gt;That's it for this post.  There are, of course, more types of noun phrases, but the pattern is the same for them: determine the proper representation in your scheme and add a case to convertNounPhrase to handle it.  Verb phrases are trickier, and I hope to get to them soon.&lt;br /&gt;&lt;br /&gt;I'm including below the handful of defintions that were reused from last time, in case you want to refer to them (it also makes this post compile as well!). This includes the modified convertVerbPhrase and a new convertSentence that deals with convertNounPhrase and convertVerbPhrase returning lists.  It should look familiar after the last example.&lt;br /&gt;&lt;br /&gt;=====&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data VerbPhrase = AVerb Word&lt;br /&gt;&lt;br /&gt;&gt; data Word = Word {&lt;br /&gt;&gt;               wordString    :: String,&lt;br /&gt;&gt;               partOfSpeech  :: PartOfSpeech,&lt;br /&gt;&gt;               isPlural      :: Bool&lt;br /&gt;&gt;             }&lt;br /&gt;&lt;br /&gt;&gt;&lt;br /&gt;&gt; type ID = String&lt;br /&gt;&lt;br /&gt;&gt; convertVerbPhrase     :: VerbPhrase -&gt; [Term -&gt; LogicSentence]&lt;br /&gt;&gt; convertVerbPhrase (AVerb v) = [\subject -&gt; Atom (wordString v) [subject]]&lt;br /&gt;&lt;br /&gt;&gt; subjectOf             :: LogicSentence -&gt; Term&lt;br /&gt;&gt; subjectOf (ForAll t _) = t&lt;br /&gt;&gt; subjectOf (Exists t _) = t&lt;br /&gt;&lt;br /&gt;&gt; combineNVSents        :: LogicSentence -&gt; LogicSentence -&gt; LogicSentence&lt;br /&gt;&gt; combineNVSents (ForAll t npDescription) vpDescription&lt;br /&gt;&gt;                    = ForAll t (npDescription `Implies` vpDescription)&lt;br /&gt;&gt; combineNVSents (Exists t npDescription) vpDescription&lt;br /&gt;&gt;                    = Exists t (npDescription `And` vpDescription)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-3542342933194138647?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/3542342933194138647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=3542342933194138647&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3542342933194138647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3542342933194138647'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/11/nlp-extracting-meaning-from-noun.html' title='NLP: Extracting Meaning from Noun Phrases'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-3387279054704338151</id><published>2008-10-31T22:54:00.002-05:00</published><updated>2008-10-31T23:26:50.448-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='avr piano gcc atmega brandon'/><title type='text'>Greetings</title><content type='html'>This is my first blog post to this, or any other blog... so please bear with me as I gather up steam and learn the new format.&lt;br /&gt;&lt;br /&gt;For those of you who don't know me, I'm Brandon.  Hello!  I know there isn't much listed on my current project, so here is generally the gist... we got an old upright Lexington-brand piano free from some nice people who were cleaning their basement.  The guys here were interested in getting a piano for the foyer, but didn't want to spend a lot [read "any"] money.  As such, the piano is what you expect from a free piano.  The word "totaled" comes to mind [and that of the piano tuner I had take a look at it].&lt;br /&gt;&lt;br /&gt;To make a long story short, being the group full of steam-punk, tinkering, tech heads that only the readers of this blog might enjoy, we decided to turn this 1940's upright piano into an electric keyboard.  Perfect! Keeps a tune forever and maybe does other nice nifty things as well.&lt;br /&gt;&lt;br /&gt;Having never messed with embedded systems [or electronics even], it made process somewhat scary.  However, it still had to be easier [and cheaper] than rebuilding normally.  I got together with Sam [who is Fantastic in only ways Dr. Who can describe] and plotted the course.  We purchased the following items:&lt;br /&gt;&lt;br /&gt;* 100 x Small Raised Tactile Switches&lt;br /&gt;* 3 x Atmega16 Microcontrollers&lt;br /&gt;* 3 x 5 Volt VRMs&lt;br /&gt;* 1 x JTAG-ICE-MKI programmer for said Atmegas&lt;br /&gt;* 1 x "magical" breakout board from Sparkfun [SKU: BOB-00718 ] to turn signals into computer based serial.&lt;br /&gt;* 1 x Jumperkit, including Capacitors, resistors, and some breadboards... various other sundry electronic components        [Total cost so far, &lt; $150 US].&lt;br /&gt;&lt;br /&gt;The general goal is to have the microcontroller interpret the incoming signals from the various buttons, encode them into a long byte stream, send it over to a laptop running ALSA hidden in the piano cabinent and PRESTO! Electronic piano!&lt;br /&gt;&lt;br /&gt;As to installing the AVR Toolkit, I know that Sam mentioned how frustrating some things were.  I am running Mandriva Linux 2008 on my devel-machine and installed the following packages to get everything working AOK:&lt;br /&gt;&lt;br /&gt;avrdude&lt;br /&gt;avr-libc-1.6.2&lt;br /&gt;binutils-2.19.50&lt;br /&gt;ddd [graphical gdb front-end, kinda nice since I'm not used to gdb]&lt;br /&gt;gcc-4.3.2 for the AVR [you'll use --target=avr]&lt;br /&gt;gdb-6.8 [for handyness]&lt;br /&gt;gmp-4.2.2&lt;br /&gt;mpfr-2.3.0&lt;br /&gt;simulavr-0.1.2.5&lt;br /&gt;&lt;br /&gt;Those are all of the packages that you truly need [plus their sub-dependencies, such as a YACC or a BISON... also a neat one called "m4" for gcc.&lt;br /&gt;&lt;br /&gt;With those installed, you should be good to go.  However, I do want to draw this post to a close as otherwise it will be so long you might loose interest.&lt;br /&gt;&lt;br /&gt;I will post my Makefile and other "piano-warez" on my website or this blog for those who are interested. The Makefile is very basic, so remember, just because you graduate with a BS in CS does not make you a programmer.  &lt;br /&gt;&lt;br /&gt;I will also post on some of my other projects as they happen. &lt;br /&gt;&lt;br /&gt;Regards,&lt;br /&gt;&lt;br /&gt;Brandon Bagwell&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-3387279054704338151?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/3387279054704338151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=3387279054704338151&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3387279054704338151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3387279054704338151'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/greetings.html' title='Greetings'/><author><name>Brandon Bagwell</name><uri>http://www.blogger.com/profile/07241811394960939097</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-7866664286872718282</id><published>2008-10-31T20:50:00.004-05:00</published><updated>2008-11-12T17:35:07.589-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nlp'/><category scheme='http://www.blogger.com/atom/ns#' term='adam'/><title type='text'>Words about Language</title><content type='html'>I've had a pretty productive week with regards to my NLP project; I added an implementation of backward chaining inference, so now I can start playing with interpreting context and unifying concepts.  With that built, I'm more or less back up to where I was with my first system, only with a code base that still has room to grow.  I can ask simple questions, and so long as the knowledge base is in the right state, get yes or I-don't-know answers.  Unfortunately, my approach right now is so general that if I mention two facts about a specific thing, say, emacs, the system won't make the assumption that I'm not talking about two different things, both called emacs.&lt;br /&gt;&lt;br /&gt;Which brings me to my next target, context and pronouns.  Pronouns are obviously a problem for computers; if I say "Bob threw a brick at the window, and it shattered," what shattered?  It's easy for us to say that the window shattered, but we get that from our knowledge of the world, not from any particular structure in the sentence.  I could also say "Bob threw a vase at the wall, and it shattered," and this time, with the same structure, "it" now refers to the object being thrown, the vase.&lt;br /&gt;&lt;br /&gt;We know this from one of two ways, and I'm not sure which.  We either know that a vase or window can shatter, whereas a brick or wall is not likely to, or we visualize the event and our internal model predicts which object shatters.  Neither is particularly easy for a computer; the latter has obvious computational problems, the former requires a search through potentially large amounts of data.&lt;br /&gt;&lt;br /&gt;For my first crack at it, I'll be keeping a list of 'things' that have been in context, attempting to unify objects referred to by pronouns until I don't end up with a conflict.  I'm planning on limiting the domain of 'things' that can be discussed to something small, like the nature of files, programs, and directories, in what I'm sure will be a vain attempt to limit the size of the knowledge base that this approach will require.&lt;br /&gt;&lt;br /&gt;In other news, my posts on the comprehension module are still coming, but writing them keeps taking longer than I expect.  Just when I get into the flow of writing, I notice something I'm doing wrong and have to go fix it.&lt;br /&gt;&lt;br /&gt;I've read two papers in the past week.   &lt;a href="http://nlp.stanford.edu/pubs/natlog-coling08.pdf"&gt;Modeling Semantic Containment and Exclusion in Natural Language Inference, MacCartney and Manning&lt;/a&gt; covers using natural logic for modeling the semantics of language, and the successes and problems they've found there.  &lt;a href="http://www.ics.mq.edu.au/%7Eelena/AkhmDrasALTA07.pdf"&gt;Recognizing Textual Entailment Via Atomic Propositions, Akhmatova and Molla &lt;/a&gt;describes an approach using traditional logic (like you saw in my Haskell-laden post).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-7866664286872718282?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/7866664286872718282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=7866664286872718282&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7866664286872718282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7866664286872718282'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/ive-had-pretty-productive-week-with.html' title='Words about Language'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-2385475487644152164</id><published>2008-10-31T00:21:00.010-05:00</published><updated>2008-11-12T17:35:36.343-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='livescribe'/><category scheme='http://www.blogger.com/atom/ns#' term='modem'/><category scheme='http://www.blogger.com/atom/ns#' term='sam'/><category scheme='http://www.blogger.com/atom/ns#' term='pulse'/><title type='text'>Livescribe Pulse Hacking I: The Frequency Domain</title><content type='html'>One of the frustrating things about the exciting &lt;a href="http://livescribe.com/"&gt;livescribe pulse&lt;/a&gt; is it's inability to communicate with linux. Even through virtualization of a windows machine, you'll be lucky to get a working system.&lt;br /&gt;&lt;br /&gt;Another is the fact that, while programs build with the livescribe pre-release SDK can save files to the pen, they cannot send those files to the desktop machine --- the only way to interact with program data is through the pen.&lt;br /&gt;&lt;br /&gt;Well, I say pooh to that: "Pooh!"&lt;br /&gt;&lt;br /&gt;Since I was first able to program my livescribe pulse (in a rude rendition of 'hello, world'),  I've been scheming on how to communicate with the pen through hackish means. While reverse engineering the livescribe communications protocol would have been the correct way to do it, I feared it was, and is, beyond my means and motivation.  I concentrated instead on the &lt;span style="font-style: italic;"&gt;other&lt;/span&gt; two ways the pen has of communicating: the screen and the speaker.&lt;br /&gt;&lt;br /&gt;My original plan had been to use light sensors, an AVR, and a program that would flash the pen's OLED display in order to send data back to the desktop computer. While this is plausible, the narrow bandwidth of the light produced by the OLED display makes it difficult to sense --- and the communication would always be one way. Besides, special hardware would be necessary, and that would  make the potential user base tiny: linux-using livescribe owners who have the knowledge and hardware to program microcontrollers.&lt;br /&gt;&lt;br /&gt;No, there must be a better way; so we turn to the speaker. Most computer owners have a microphone on hand; and communicating via tones is a tried and true method. My path is clear: create a livescribe modem!&lt;br /&gt;&lt;br /&gt;In order to recieve information, the computer must be able not just to record the sounds coming from the pen, but to &lt;span style="font-style: italic;"&gt;analyze &lt;/span&gt;them. To write software that can do that, we must have a firm understanding of the &lt;span style="font-style: italic;"&gt;frequency domain&lt;/span&gt;. (Prerequisites note: If you don't have a firm understanding of the concepts &lt;span style="font-style: italic;"&gt;frequency, wavelength,&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;sinusoidal &lt;/span&gt;graphs, it's time for a trip to &lt;a href="http://wikipedia.com/"&gt;wikipedia&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The central nugget of the matter goes like this: any continuous, periodic function can be represented as an infinite sum of sines and cosines.&lt;br /&gt;&lt;br /&gt;Give that a minute to sink in; &lt;span style="font-style: italic;"&gt;any&lt;/span&gt; function that is continuous --- not differentiable, just continuous --- and periodic --- but the length of the period can be as long as you like  --- will do. Square waves, sawtooths, Bart Simpson's hair;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt; &lt;/span&gt;any &lt;/span&gt;arbitrary waveform can be represented by a simple sum of sines and cosines.&lt;br /&gt;&lt;br /&gt;Wow.&lt;br /&gt;&lt;br /&gt;You may be worried about that word 'infinite' up there. Luckily, it turns out that we can approximate our function with some finite number&lt;span style="font-weight: bold;"&gt; k&lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt; &lt;/span&gt;sines and cosines; and that each time we increase&lt;span style="font-weight: bold;"&gt; k&lt;/span&gt;, the approximation becomes more accurate.&lt;br /&gt;&lt;br /&gt;Now let's take a moment to remember what the &lt;span style="font-style: italic;"&gt;time domain&lt;/span&gt;, looks like. Imagine a signal coming from your microphone. It is a long string of numbers, and each number indicates a magnitude of sound at a single point in time (which is to say, the difference in pressure on the front and rear surfaces of the microphone pickup). If we were to graph the sound of someone whistling by using the time as the independent variable, and magnitude as the dependent, we'd see a lovely sine wave --- the archetypal image of sound, in the time domain.&lt;br /&gt;&lt;br /&gt;But there is another way of plotting the same sound. We said that any curve --- no matter how complex our time domain curve might be --- can be represented by a sum of sines and cosines, right?&lt;br /&gt;&lt;br /&gt;And, hold on to your hats, we only need 2 numbers to define a sine wave: the frequency of the wave, and the amplitude.  So we have lots of data points enumerated by two real numbers? &lt;span style="font-style: italic;"&gt;That&lt;/span&gt; sounds like a graph. And indeed it is. If we graph frequency as the independent variable and amplitude as the dependent, we have arrived at a graph of our sound in the frequency domain.&lt;br /&gt;&lt;br /&gt;For those of you still having a little trouble visualizing, here's what the sound of me whistling looks like in the time domain:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_OKQBL_J5AsU/SRCADpYcJuI/AAAAAAAAADo/GSuG7Vi0xL0/s1600-h/time.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 112px;" src="http://1.bp.blogspot.com/_OKQBL_J5AsU/SRCADpYcJuI/AAAAAAAAADo/GSuG7Vi0xL0/s400/time.png" alt="" id="BLOGGER_PHOTO_ID_5264848764532434658" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And here's what it looks like in the frequency domain:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_OKQBL_J5AsU/SRCBLlDqvbI/AAAAAAAAADw/tmXecdSAzHc/s1600-h/freq.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 266px;" src="http://3.bp.blogspot.com/_OKQBL_J5AsU/SRCBLlDqvbI/AAAAAAAAADw/tmXecdSAzHc/s400/freq.png" alt="" id="BLOGGER_PHOTO_ID_5264850000322149810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;See that big sharp spike there around 800Hz? That is the primary frequency of the whistle (772Hz: a G5 that's a little flat). All the other stuff is the shower, the refrigerator, the computer fan, the traffic outside, the wind, and so on; but remember we're measuring in decibels, so they are whole orders of magnitude less in amplitude than the whistle.&lt;br /&gt;&lt;br /&gt;Most of you are probably yelling at the screen by now, asking me how on earth we're supposed to &lt;span style="font-style: italic;"&gt;find&lt;/span&gt; these numbers. Where do we get this sum of sinusoids if all we're given is the time domain information? The empty-words answer is "The fourier transform." To &lt;span style="font-style: italic;"&gt;understand&lt;/span&gt; that answer, we're going to have to go in a journey --- one that I'll leave to my next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-2385475487644152164?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/2385475487644152164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=2385475487644152164&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/2385475487644152164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/2385475487644152164'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/livescribe-pulse-hacking-i-frequency.html' title='Livescribe Pulse Hacking I: The Frequency Domain'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_OKQBL_J5AsU/SRCADpYcJuI/AAAAAAAAADo/GSuG7Vi0xL0/s72-c/time.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-2098360787715895733</id><published>2008-10-30T18:03:00.005-05:00</published><updated>2008-11-12T17:36:07.683-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='minutes'/><category scheme='http://www.blogger.com/atom/ns#' term='hackjam'/><title type='text'>Hack Jam: 10.29.08</title><content type='html'>,Topics of discussion: AVR, NLP, and MLB.&lt;br /&gt;&lt;br /&gt;Brandon finally received all the parts for his electric piano conversion, so we set about getting his AVR toolchain and  JTAG programmer working. We had a discussion of how messy the current binutils/avr-gcc/avr-libc combination is --- it was one of the worst source builds I have have ever had to perform. It took me more than a day on my machine --- and Brandon sped through the process in just 6 hours on his.&lt;br /&gt;&lt;br /&gt;For those of you out there that are receiving that relished error "illegal opcode movw for mcu avr3", there is hope! My recommendations are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Remove all traces of avr-binutils. Kill them dead. Remnants of the latest release of binutils will wreak havoc when you try to work either with bleeding edge snapshots or older versions.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Forget the latest releases --- go back several stable versions of both gcc and binutils, to at least January 2008, or even back into 2007. (Your other option is to get bleeding edge snapshots, but I did not have any more success with these than with the latest releases.)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Download all the avr-gcc and binutils patches you can find from the date of release of binutils and gcc that you downloaded to the date of the next stable version; attempt to apply all of them. Don't worry if some fail --- just push ahead.&lt;/li&gt;&lt;li&gt;For the actual configuring, I recommend reading &lt;a href="http://www.nongnu.org/avr-libc/user-manual/install_tools.html"&gt;this page&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Make and install binutils.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Make and install gcc (fingers crossed!)&lt;/li&gt;&lt;li&gt;Only upon the successful completion of avr-gcc's install should you even worry about avr-libc.&lt;/li&gt;&lt;/ul&gt;Note that these are only hints. I am not attempting to give a full overview of what works --- but you'll save many headaches if you start with these steps.&lt;br /&gt;&lt;br /&gt;On calling my shots:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You may have noticed the lack of posts. Surprise! I failed to meet both drawing post calls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I did program my livescribe. &lt;a href="http://penlets.com/"&gt;penlets.com &lt;/a&gt;was a major help&lt;/li&gt;&lt;li&gt;I did get a relatively detailed outline ready for nanowrimo&lt;/li&gt;&lt;/ul&gt;Score: 2/4.&lt;br /&gt;&lt;br /&gt;For next week:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A post on my evil plans for communicating with linux from my livescribe pulse.&lt;/li&gt;&lt;li&gt;The beginning of a nano novel. Huzzah!&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-2098360787715895733?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/2098360787715895733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=2098360787715895733&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/2098360787715895733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/2098360787715895733'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/hack-jam-102708.html' title='Hack Jam: 10.29.08'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-275001421121800635</id><published>2008-10-25T11:36:00.002-05:00</published><updated>2008-11-12T17:36:28.374-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nlp'/><category scheme='http://www.blogger.com/atom/ns#' term='adam'/><title type='text'>Pluralities and Progress</title><content type='html'>I've been wondering for a while about how to deal with the meaning of plural nouns.  In my last post I treated them as referring to all things of a type, as in "The rm program deletes files".  But they can also refer to a set of things of a type, as in "Bob deleted files."  There's an implied "some" in that second sentence; we know that Bob didn't delete all files everywhere.  The tense of the sentence or passage helps quite a bit for determining which interpretation is more probable, but that approach is not ironclad.  Contrast "Bob deleted files," with "Bob deleted his files."  "His files" is a smaller set of things, one that Bob could conceivably delete all of.  Unfortunately, the knowledge of files, the act of deleting, and Bob that we can use to differentiate the two situations come from prior knowledge.  I'm hoping to use logical inference for disambiguation like this, but at the moment, I'm not optimistic about the size of the knowledge base that will be necessary.&lt;br /&gt;&lt;br /&gt;In other news, I've been working on this long enough now that I'm going to start reading the literature.  I'm probably way overdue on this step, having so far only read through what Russell and Norvig had to say about this in their &lt;a href="http://aima.cs.berkeley.edu/"&gt;book&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I met both of my goals for last week, though my recognition of plurality is a bit crude.  I'm intending to revisit how I'm representing my dictionary soon, so I'll make it less crude then.&lt;br /&gt;&lt;br /&gt;For this week, my goals are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Build a simple logical inference framework&lt;/li&gt;&lt;li&gt;Read two papers on AI&lt;/li&gt;&lt;li&gt;Continue the NLP series with interpretation of verb phrases.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-275001421121800635?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/275001421121800635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=275001421121800635&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/275001421121800635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/275001421121800635'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/pluralities-and-progress.html' title='Pluralities and Progress'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-7584590963863981611</id><published>2008-10-23T12:29:00.003-05:00</published><updated>2008-11-12T17:36:41.810-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='minutes'/><category scheme='http://www.blogger.com/atom/ns#' term='hackjam'/><title type='text'>Hackjam 10.22.08</title><content type='html'>Discussion topics: puzzles, communication, form/content interrelationships, the livescribe pulse, Steven Wright, logic puzzles, cellular automata.&lt;br /&gt;&lt;br /&gt;We had a lengthy conversation on how art and communication can work together, and how they can work against each other. We came to no conclusions, but I thought it might be interesting to talk a little about how I think about the form/content interrelationship, and why it's so important to me in art critique and analysis. I'll do it a bit jesuitically, because I think art criticism is too often left &lt;span style="font-style: italic;"&gt;too &lt;/span&gt;&lt;span&gt;open to opinion --- let's all share the same language, shall we?&lt;br /&gt;&lt;br /&gt;For the sake of brevity and generality, I will refer to a work of art as an &lt;span style="font-style: italic;"&gt;artifact&lt;/span&gt;. The artifact is the actual painting, sculpture, poem, novel... even performance art leaves behind a temporal artifact, which is the primary means of the audience experiencing the piece.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;audience&lt;/span&gt; is anyone who comes in contact with the artifact. Note that this is distinguished from the intended audience, which are the people the artist &lt;span style="font-style: italic;"&gt;expects&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;desires&lt;/span&gt; to come in contact with the artifact.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;content&lt;/span&gt; is &lt;span style="font-style: italic;"&gt;the change in the audience caused by contact with the artifact.&lt;/span&gt; That is a trickier definition than is often put forward. This definition does not discriminate based on what the content is --- only where it comes from. What is worth taking away from this definition is that content can with a single thought  be cleaved from&lt;span style="font-style: italic;"&gt; intended&lt;/span&gt; content, just as audience and intended audience are distinct.  As critics we are as much, if not much more, concerned with the content as with the intended content.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;Finally, the hardest one. &lt;span style="font-style: italic;"&gt;Form&lt;/span&gt; is the &lt;span style="font-style: italic;"&gt;thingness&lt;/span&gt; of a thing. The form of a painting is the color, line, texture, surface, and technique used to paint it. The form of a poem is the prosody, the rhyme, the aural, temporal, and visual texture of the artifact. The context of the work (where, when, and how the audience comes in contact with it) is also a formal aspect. &lt;span style="font-style: italic;"&gt;&lt;/span&gt;When we say "That's &lt;span style="font-style: italic;"&gt;well made&lt;/span&gt;" we're discussing the form.&lt;br /&gt;&lt;br /&gt;The relationship between from and content is of the utmost importance to the creation of a successful artifact. To understand why, we need to look even closer at what content is --- and more importantly &lt;span style="font-style: italic;"&gt;where &lt;/span&gt;content is. "[...] &lt;/span&gt;&lt;span&gt;&lt;span style="font-style: italic;"&gt;content&lt;/span&gt; is &lt;span style="font-style: italic;"&gt;the change in the audience caused by contact with the artifact&lt;/span&gt;." &lt;/span&gt;Content only exists when the artifact comes in contact with the audience. Without an audience, content cannot exist. How does the audience know what to do? How do they know how they are supposed to change in order to create the proper content? There is no "audience instruction manual," is there? How can the artist tell the audience what to do when they don't even know who the audience is?&lt;br /&gt;&lt;br /&gt;There is only one way for the artist to communicate with the audience --- through the artifact itself; through it's form.&lt;br /&gt;&lt;span&gt;&lt;a href="http://images.google.com/images?q=guernica"&gt;&lt;br /&gt;Guernica&lt;/a&gt; communicates the anguish of the bombing through line, shape, color, size, and context. Without performing a complete critique of the work (which you could find by doing &lt;a href="http://www.google.com/search?q=guernica"&gt;this&lt;/a&gt;), we can see why the form is so important by performing a heavy-handed thought experiment. Can you imagine a photorealistic color image of an unhappy horse, that was, say, 8" by 10"? Compare that to the screaming animal in the center of Guernica (keeping in mind that the whole painting is more than 25 feet long). Would the content be the same? Or does the rough and broken line of the mother and child, the broken and offset curve of the bull's horns, the impossible jagged edge of the fallen sword, do they accomplish something that a different form could not, despite having the same intended content?&lt;br /&gt;&lt;br /&gt;The relationship between form and content is impossible difficult, almost invisible, and it is what makes art art.&lt;br /&gt;&lt;br /&gt;On calling my shots:&lt;br /&gt;&lt;br /&gt;Last week I did get a post for makerfaire, I did not complete my post on drawing, but I did get some work on it done. It will go up this week. Score: 1/2.&lt;br /&gt;&lt;br /&gt;This week I call:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Successfully programming the livescribe pulse with my own program&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Completing my rough nanowrimo outline&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Completing last weeks drawing post and adding another&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-7584590963863981611?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/7584590963863981611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=7584590963863981611&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7584590963863981611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7584590963863981611'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/hackjam-102208.html' title='Hackjam 10.22.08'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-7720388215370363532</id><published>2008-10-22T17:36:00.004-05:00</published><updated>2008-10-22T18:27:12.409-05:00</updated><title type='text'>NLP: Grammar Trees to Logical Statements</title><content type='html'>I'm going to start a series of detailed posts about the comprehension module.  This is the section that translates a grammar tree into a logical statement.  For this discussion, we'll be looking at a simplified version of my simplified version of English grammar.  We'll expand our grammar in future posts.  Since I've started this post, I've improved my approach in this area as well, so you'll be seeing the evolution of this code, with a couple weeks lag time.&lt;br /&gt;&lt;br /&gt;It also gives me an opportunity to introduce a bit of Haskell.  I'll introduce you to Haskell just enough to understand what I'm doing.  If you want to learn it well enough to use it, I suggest one of these &lt;a href="http://learnyouahaskell.com"&gt;fine&lt;/a&gt; &lt;a href="http://en.wikibooks.org/wiki/Haskell/YAHT"&gt;tutorials&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; module HackjamNLP where&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This post is written in literate Haskell.  The lines begining with "&gt;" are source lines, everything else is a comment.  You can copy this post to a file and load it into an interpreter if you like.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data Sentence = Declarative NounPhrase VerbPhrase&lt;br /&gt;&gt;&lt;br /&gt;&gt; data NounPhrase = ANoun Word&lt;br /&gt;&gt;                 | APronoun Word&lt;br /&gt;&gt;                 | Name Word&lt;br /&gt;&gt;&lt;br /&gt;&gt; data VerbPhrase = AVerb Word&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What I'm doing here is defining three new types, Sentence, NounPhrase, and VerbPhrase, each with one or more type constructors.  So a Sentence can be constructed with Declarative, a NounPhrase with ANoun, AProunoun, or Name, and VerbPhrase with Verb.  Everything after the type constructor's name are the types each constructor requires to build a value of that type.  In other code, here's a rough equivalent to Sentence's Declarative constructor in a bastard Java-like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;: Sentence Declarative(NounPhrase np, VerbPhrase vp) { ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So type constructors are like functions that return values of a given type (but more useful, as we'll see later).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data Word = Word {&lt;br /&gt;&gt;               wordString    :: String,&lt;br /&gt;&gt;               partOfSpeech  :: PartOfSpeech,&lt;br /&gt;&gt;               isPlural      :: Bool&lt;br /&gt;&gt;             }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here we see another syntax for declaring a data type.  It is common to name the constructor for a type the same thing as the type itself when there is only one constructor for that type.  The :: can be read as "has type", so we can reason that a Word is made of wordString of type String, a partOfSpeech of type PartOfSpeech, and isPlural of type Bool.  Each of these identifiers is a function that can be applied to a Word to get it's corresponding field.&lt;br /&gt;&lt;br /&gt;You've probably noticed that Haskell is case sensitive.  Actually, the upper/lower case convention I'm using isn't convention at all; It's required by syntax.  All types and type constructors (and names of modules, but I'm not going there) are required to be uppercase, everything else is must be lowercase.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data PartOfSpeech = Noun | Verb | Adjective | Article | Pronoun&lt;br /&gt;&gt;                   | Adverb | Unknown&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;One last definition.  Here I'm enumerating the types of speech that I'm using.  This is the same syntax as before, except none of these have any parameters, and I compacted the formatting.&lt;br /&gt;&lt;br /&gt;Now I can build Sentences out of Strings, PartOfSpeeches, and Bools.  As a quick example, let's quickly build a Sentence representing "I win.":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; iWin = Declarative (APronoun (Word "I" Pronoun False))&lt;br /&gt;&gt;                    (AVerb (Word "win" Verb False))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Tada.&lt;br /&gt;&lt;br /&gt;Again, we're going to take for granted that some other nice module has generated these grammatical trees for us.  We should only be concerned with converting them to logical statements.  First, we define a representation of logical statements.  This representation won't describe all logical statements; I've left out constructors that I won't be using here to keep things simple.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; data LogicSentence = Atom ID [Term]&lt;br /&gt;&gt;                    | And LogicSentence LogicSentence&lt;br /&gt;&gt;                    | Implies LogicSentence LogicSentence&lt;br /&gt;&gt;                    | ForAll Term LogicSentence&lt;br /&gt;&gt;                    | Exists Term LogicSentence&lt;br /&gt;&gt;                      deriving Show&lt;br /&gt;&gt;&lt;br /&gt;&gt; data Term = Variable ID&lt;br /&gt;&gt;           | Set [Term]&lt;br /&gt;&gt;             deriving Show&lt;br /&gt;&gt;&lt;br /&gt;&gt; type ID = String&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The [] brackets in [Term] indicate a list of that type, and the last line defines ID to be a type equivilant to a String.&lt;br /&gt;&lt;br /&gt;The deriving statements for Term and LogicSentence tell the compiler to generate a default implementation of a class.  In this case, we want these types to be instances of the Show class so we can convert them to strings and display them on our terminals.  This default necessarily be pretty, as we'll see later.  We could also have it derive other classes like Read (to convert strings to the type), Eq (equality), and Ord (ordering, i.e. less than, greater than).  Think of derive as saying "You're so smart, Mr Compiler, I'm sure you can figure out this on your own."&lt;br /&gt;&lt;br /&gt;Now we can start building LogicSentences.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; x = Variable "x"&lt;br /&gt;&gt; iWinLogic = Exists x ((Atom "speaker" [x]) `And` (Atom "win" [x]))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here I've put And inside backticks to change it from a prefix operator (like "f" in "f(x,y)") to an infix operator (like "+" in "x + y").  The braces are back, and again they denote lists.  [x] creates the list with x as it's only element.&lt;br /&gt;&lt;br /&gt;We've arrived at the point where we can work on what we came here to do.  We'll tackle a bit at a time, starting with converting just the noun phrase to a logical sentence.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase     :: NounPhrase -&gt; LogicSentence&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here I've declared the type of something I'm calling convertNounPhrase.  All this says is that it's a function that takes a NounPhrase and returns a list of LogicSentece.  The compiler is smart enough that it could infer the type of the function on it's own, but it's common practice to specify it explicitly.  There are two reasons for this.  First, it serves to improve readability and provides documentation for the author.  Second, it helps to locate compile errors by making sure the compiler arrived at the same type the author intended&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase (Name name)&lt;br /&gt;&gt;                       = Exists x (Atom ("called-" ++ wordString name) [x])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Haskell is nice and lets us define functions in parts.  Here we define the convertNounPhrase function when given a NounPhrase built with the Name constructor.  This is called pattern matching, and it's &lt;span style="font-style: italic;"&gt;wonderful&lt;/span&gt; for building functions like this cleanly.  Haskell will try each definition of convertNounPhrase in the order defined until a match is found (if none are found, it throws an exception).  Note that name here doesn't refer to the NounPhrase built with Name, but the word used to build Name with.&lt;br /&gt;&lt;br /&gt;A name, by itself, indicates that there is something that is called by that name.  In other words, our representation of "Adam" is: there exists some x such that called-Adam(x) is True.  (++ is the concatenation operator, and strings are just lists of Chars, so that ("called-" ++ wordString n) buisness builds strings like "called-Adam".)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase (ANoun n)&lt;br /&gt;&gt;       | isPlural n    = ForAll x (Atom (wordString n) [x])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Besides specifying the manner in which a parameter is constructed, we can also place /guards/ in our pattern matches.  This definition only matches Nouns built with a Word that satisfy isPlural.  For the moment, we'll assume that no non-plural nouns without articles (the, a, an) are passed by the grammar tree builder.&lt;br /&gt;&lt;br /&gt;The case statement draws near!&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertNounPhrase (APronoun n)&lt;br /&gt;&gt;                       = case wordString n of&lt;br /&gt;&gt;                               "I"       -&gt; Exists x (Atom "speaker" [x])&lt;br /&gt;&gt;                               "you"     -&gt; Exists x (Atom "audience" [x])&lt;br /&gt;&gt;                               otherwise -&gt; Exists x (Atom "in-context" [x])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I won't go into the syntax of case; I'm sure you can figure out how it works.&lt;br /&gt;&lt;br /&gt;Note I'm leaving out a number of possibile pronouns here in the name of brevity.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertVerbPhrase     :: VerbPhrase -&gt; (Term -&gt; LogicSentence)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We're getting trickier here.  convertVerbPhrase is a function that takes a VerbPhrase and returns a list of &lt;span style="font-style: italic;"&gt;functions&lt;/span&gt;.  These functions each take a Term and return a LogicSentence.  In Haskell, all functions are curried, so I could remove the parentheses from this type definition if I wanted to.  I'm leaving them in for readability.&lt;br /&gt;&lt;br /&gt;Why do we want to return a function here?  A verb phrase describes an action or relation.  It needs the subject of the sentence to complete it's meaning.  If I say "dances a jig.", it's not a complete sentence; there is an immediate question of "Who?".  It needs the who for the full meaning.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertVerbPhrase (AVerb v) = (\subject -&gt; Atom (wordString v) [subject])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We'll expand verb phrases soon, but for now, we'll just deal with a single verb.  This definition shows the syntax for a lambda function: (\x -&gt; ... ).  When we apply a term to the result of convertVerbPhrase, that term will be used in place of subject.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertSentence       :: Sentence -&gt; LogicSentence&lt;br /&gt;&gt; convertSentence (Declarative np vp)&lt;br /&gt;&gt;                       = let nounSentence = convertNounPhrase np&lt;br /&gt;&gt;                             subject = subjectOf nounSentence&lt;br /&gt;&gt;                             action = convertVerbPhrase vp&lt;br /&gt;&gt;                         in combineNVSents nounSentence (action subject)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally, the goal of the post.  This demonstrates a let block.  Those equal signs don't mean what they do in imperative programming.  That is to say, we aren't evaluating convertNounPhrase np and storing the result as nounSentence, we are declaring that nounSentence is equivalent to convertNounPhrase np.  We could have wrote this function as&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; convertSentence2 (Declarative np vp)&lt;br /&gt;&gt;       = combineNVSents (convertNounPhrase np)&lt;br /&gt;&gt;                        (convertVerbPhrase vp&lt;br /&gt;&gt;                                           (subjectOf (convertNounPhrase np)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So now we need to define subjectOf and combineNVSents, and we'll be done for now.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; subjectOf             :: LogicSentence -&gt; Term&lt;br /&gt;&gt; subjectOf (ForAll t _) = t&lt;br /&gt;&gt; subjectOf (Exists t _) = t&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Another feature of Haskell's pattern matching: we can tell the compiler that we don't care about some terms.  "_" is a wildcard.  It will match anything for that term.&lt;br /&gt;&lt;br /&gt;Note that we don't have to define subjectOf for all possible Sentences.  We'll accept a Exception if it's called for a Sentence it's not defined for.  We're careful above to have convertNounPhrase only return these two types of sentences, precisely so this funtion will work.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; combineNVSents        :: LogicSentence -&gt; LogicSentence -&gt; LogicSentence&lt;br /&gt;&gt; combineNVSents (ForAll t npDescription) vpDescription&lt;br /&gt;&gt;                    = ForAll t (npDescription `Implies` vpDescription)&lt;br /&gt;&gt; combineNVSents (Exists t npDescription) vpDescription&lt;br /&gt;&gt;                    = Exists t (npDescription `And` vpDescription)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nothing new here.&lt;br /&gt;&lt;br /&gt;Now we can load this post into a Haskell interpreter (I'm using ghci) and try it out:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ghci&gt; convertSentence iWin&lt;br /&gt;Exists (Variable "x") (And (Atom "speaker" [Variable "x"]) (Atom "win" [Variable "x"]))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I win.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-7720388215370363532?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/7720388215370363532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=7720388215370363532&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7720388215370363532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7720388215370363532'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/im-going-to-start-series-of-detailed.html' title='NLP: Grammar Trees to Logical Statements'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-6473883465373165522</id><published>2008-10-22T15:54:00.006-05:00</published><updated>2008-10-22T17:04:56.229-05:00</updated><title type='text'>On Makerfaire</title><content type='html'>Well, we a-traveled to Austin this past weekend to take part in &lt;a href="http://www.makerfaire.com/"&gt;MakerFaire&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Rather than show you photos of what was there, I thought I'd scan in some gestures from my sketchbook. Gesture drawing is something that we'll be coming to (eventually) in the how-to-draw posts, but for the moment, suffice it to say that gestural drawing is a way to capture a person or thing as quickly as possible; important in these circumstances because everyone was a-movin' and a-shakin'.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;img style="border: 2px solid rgb(0, 0, 0); margin: 0em 2em 1em 1em; float: left;" src="http://3.bp.blogspot.com/_OKQBL_J5AsU/SP-YRdTsSfI/AAAAAAAAADY/iE0BoWxPZoY/s400/pa200451.jpg" alt="" id="BLOGGER_PHOTO_ID_5260090315484449266" border="0" /&gt;It's not a terribly long drive to Austin from here, but long enough that we drove well past sunset Friday night. I drew things in the dark. This is one place and time when your blind contour drawing is more than just an exercise. I particularly like this one, because it was drawn as we passed the truck; you can see I drew clockwise from the right, and by the time I got back around to the wheels, they were beside us instead of in front.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;br /&gt;&lt;img style="border: 2px solid rgb(0, 0, 0); margin: 0em 1em 1em 2em; float: right;" src="http://4.bp.blogspot.com/_OKQBL_J5AsU/SP-YHSstC-I/AAAAAAAAACg/4CW40ANHCnA/s400/pa200436.jpg" alt="" id="BLOGGER_PHOTO_ID_5260090140837874658" border="0" /&gt;&lt;br /&gt;The next morning we grabbed coffee before heading out to the Faire; the fairground opened at 10:00, so we had plenty of time. Lisa had some trouble getting a truly dry cappuccino, but the wait staff was eager to remedy the problem. Scarily chipper. Really.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;br /&gt;&lt;img style="border: 2px solid rgb(0, 0, 0); margin: 0em 2em 1em 1em; float: left;" src="http://1.bp.blogspot.com/_OKQBL_J5AsU/SP-YHvrBCpI/AAAAAAAAACo/rjXZ0Q-vcOs/s400/pa200437.jpg" alt="" id="BLOGGER_PHOTO_ID_5260090148615424658" border="0" /&gt;&lt;br /&gt;The human-sized mousetrap was impressive --- I got a front-row seat to the first run. This was just before the actual performance; the young man was about to make his stage debut as the strongest boy in the world. He did a fine job.&lt;br /&gt;&lt;br /&gt;It was an interesting point, though, that very, very few of the performers at the faire were particularly good showmen. All the tech and engineering was excellent --- really neat --- but if you didn't already know how it worked and why it was so impressive, the presentation would have been a bit off-putting. Several performances had everything right and were just missing a P.T. Barnum to turn it into a real piece of buskering.&lt;br /&gt;&lt;br /&gt;When hats were passed, I am sure that they suffered because of that.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;br /&gt;&lt;br /&gt;There was a lot to see, and much of it is recorded elsewhere. I'm hoping more to capture the spirit of the place than give an exact recounting of what we saw. The highlights for me were the Mice Pace Maze --- a maze made entirely out of sound. I wished it had been much bigger; the concept is really lovely to me. Hats off the them. Cyclecide's guitar/bike machine was also much fun. I think my favorite part, though, was just wandering and listening to people talking, exchanging ideas, learning new skills, and building community. Many of my sketches were just people talking.&lt;br /&gt;&lt;br /&gt;It's my hope that next year, that sense of community-building is enhanced. Many of the booth-persons stuck to such a rigid script that it was hard to get into a real conversation. The times when that shell cracked were far more exciting. A lot of time was spend chatting with the people willing to chat.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;br /&gt;&lt;img style="border: 2px solid rgb(0, 0, 0); margin: 0em 1em 1em 2em; float: right;" src="http://4.bp.blogspot.com/_OKQBL_J5AsU/SP-YIKCaZSI/AAAAAAAAAC4/bFv5ZlyppiQ/s400/pa200440.jpg" alt="" id="BLOGGER_PHOTO_ID_5260090155692877090" border="0" /&gt;&lt;br /&gt;After Makerfaire on Saturday, we drove up to Dallas, where some of the group went clubbing. I wasn't that well aquainted with downtown Dallas, so I went for a walk. We agreed to meet back at a cafe where this man was on the wait staff.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;br /&gt;&lt;img style="border: 2px solid rgb(0, 0, 0); margin: 0em 2em 1em 1em; float: left;" src="http://3.bp.blogspot.com/_OKQBL_J5AsU/SP-YIe9YS1I/AAAAAAAAADA/eppBEkWX6bw/s400/pa200442.jpg" alt="" id="BLOGGER_PHOTO_ID_5260090161308912466" border="0" /&gt;&lt;br /&gt;&lt;/div&gt;It was pretty late. While I walked I spent some time thinking on what I had seen at makerfaire, and about the nerdy community in general. It has always been striking to me that only some people are interested in how things work, and that only some are interested in how they express themselves. Ti seems to me that whatever our occupations and whatever our interests, we should understand what we are doing, and do it with a practiced body and a focused mind. Even if you make washers in a nut-bolt-and-washer factory, you ought to make washer-making into an art. Make masterpieces of your life.&lt;br /&gt;&lt;br /&gt;When I got tired of walking, I sat under an overpass for a while. Then it was time to head back to the cafe for hot chocolate.&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;br /&gt;&lt;img style="border: 2px solid rgb(0, 0, 0); margin: 0em 1em 1em 2em; float: right;" src="http://1.bp.blogspot.com/_OKQBL_J5AsU/SP-YRMrDJgI/AAAAAAAAADI/l_Zo7bSjU7s/s400/pa200444.jpg" alt="" id="BLOGGER_PHOTO_ID_5260090311019013634" border="0" /&gt;&lt;br /&gt;&lt;/div&gt; After Dallas we did the Modern and the Kimbell in Fort worth. I might write another post about what we saw and said there, but I think I've said enough.&lt;br /&gt;&lt;br /&gt;This was drawn while getting still more coffee, and wondering at how many people are apparently fueled entirely by the stuff.&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;br /&gt;I don't know whether I discovered anything new this weekend; but time will tell. As a church sign told me at 2:00AM, "This is a test, Joe Clifford."&lt;br /&gt;&lt;br /&gt;&lt;img style="border: 2px solid rgb(0, 0, 0); margin: auto;" src="http://2.bp.blogspot.com/_OKQBL_J5AsU/SP-YRGnMjVI/AAAAAAAAADQ/5_60as_lwKY/s400/pa200447.jpg" alt="" id="BLOGGER_PHOTO_ID_5260090309392239954" border="0" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-6473883465373165522?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/6473883465373165522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=6473883465373165522&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6473883465373165522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6473883465373165522'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/on-makerfaire.html' title='On Makerfaire'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_OKQBL_J5AsU/SP-YRdTsSfI/AAAAAAAAADY/iE0BoWxPZoY/s72-c/pa200451.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-3140429528114860171</id><published>2008-10-21T23:48:00.017-05:00</published><updated>2008-10-22T01:28:59.033-05:00</updated><title type='text'>More 10/15/08 Progress</title><content type='html'>A decent week, if unnecessarily loaded down with homework...  Also, it has become apparent that my neighbors expect life to stop for football games.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Motor Drivers:&lt;/span&gt;&lt;br /&gt;I have become irritated with the motor driver offerings to the hobby community (and the educational community for that matter).  Your choices?  Realistically Pololu and IFI.  This is &lt;span style="font-weight: bold;"&gt;unacceptable&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;In response I have started designing motor drivers.  Everything from the 10A range to 100-300A.  Parts are on the way, samples have been shipped, and donations have been collected from friends.  I hope to have at least one finished before the Spring semester.  Units will be sold at a minimal markup; software and schematics will be made open source.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Underwater ROV:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Poured float from urethane foam to allow for near-neutral buoyancy and minimum compression at depth.&lt;/li&gt;&lt;li&gt;Finished modifications to propeller hubs and mounted fourth motor.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Linear Accelerator:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;New coil tested. 3.5" long coil, 3 layers, 14awg tried as 1st stage.  Resulting velocities were significantly less than the previous coil(4 layers, approx 2.5" long 14awg) which had achieved 6.5J Kinetic Energy at over 20m/s.&lt;/li&gt;&lt;li&gt;I must finish construction of a "V-switch" using 2 SCR banks.  Held up by tight budget and lack of high current IGBT drive optoisolators.&lt;/li&gt;&lt;li&gt;Got the idea of expanding the V switch out to multiple legs and using either a longer coil or additional coils on the same stage(if that makes sense).&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Centaur:&lt;/span&gt;&lt;br /&gt;A late night wiring "correction" bypassed a voltage regulator, putting ~10VDC unregulated to the 5VDC "regulated" power bus.  Casualties included two MaxSonar's. As a result, I will include a zener diode + fuse with any power bus containing valuable electronics on future projects.  It was fortunate my GPS was not wired during the incident and the more than a dozen Dynamixel servos are rated to over 12VDC.&lt;br /&gt;&lt;br /&gt;I made progress on a few other projects not deserving of their own section(at this time).  My Matlab simulation of obstacle avoidance using RL is working with only 4 bit numbers.  Prepare for a RL robot running no code. "Hard-wired for learning?" you ask... that's right.   Also, I re-attached my other walker's(cricket?) head because it looked very depressing laying on the ground, connected only by its "spinal cord".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-3140429528114860171?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/3140429528114860171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=3140429528114860171&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3140429528114860171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3140429528114860171'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/oct-15-progress.html' title='More 10/15/08 Progress'/><author><name>Joshua Southerland</name><uri>http://www.blogger.com/profile/00796539322974281778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-1874510112440661657</id><published>2008-10-16T21:02:00.004-05:00</published><updated>2008-10-16T21:12:19.529-05:00</updated><title type='text'>Calling Shots for 10/15</title><content type='html'>My grade for last week's called shots: B-.&lt;br /&gt;&lt;br /&gt;I did get them both, just not as thoroughly as I wanted.  My post on "where I'm at" became part I, and I had some errors with generated parses.  On the other hand, I did get some fodder for an upcoming post entitled "Computers say the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;darndest&lt;/span&gt; things."&lt;br /&gt;&lt;br /&gt;For this week:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Subject Verb agreement.  I'll be completely removing results for now where the subject and verb don't agree.  I'll be bringing them back later on when I introduce scoring for results, because sometimes a person speak bad.  In the meantime, I'm hoping to work with smaller, more &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;manageable&lt;/span&gt; sets of parses while I work with other problems like relevance and context.&lt;/li&gt;&lt;li&gt;Further word shenanigans.  Nouns can be adjectives: "clown car," "text file," and "blog post."  Words can also be built from existing words as well: "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;bloggy&lt;/span&gt;," "blogger," and "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;bloggily&lt;/span&gt;" all communicate meaning, even if we've just invented the word "blog.&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;NLP&lt;/span&gt;, Part II&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-1874510112440661657?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/1874510112440661657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=1874510112440661657&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1874510112440661657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1874510112440661657'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/calling-shots-for-1015.html' title='Calling Shots for 10/15'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-6611462865788186607</id><published>2008-10-15T23:42:00.002-05:00</published><updated>2008-10-15T23:53:30.407-05:00</updated><title type='text'>10.15.08 Hackjam</title><content type='html'>Discussed physics, &lt;a href="http://www.nanowrimo.org"&gt;nanowrimo&lt;/a&gt;, a little haskell and a little C.&lt;br /&gt;&lt;br /&gt;By discussing physics I mean I introduced the group  to &lt;a href="http://www.fantasticcontraption.com"&gt;Fantastic Contraption,&lt;/a&gt; and very little got done ;). If you haven't played fantastic contraption, you ought to give it a try; it is a nice pure example of what engineering is. It's certainly better than forcing your kids to build yet &lt;span style="font-style: italic;"&gt;another&lt;/span&gt; bridge --- there is other engineering in the world than bridge building!&lt;br /&gt;&lt;br /&gt;We also got a few more heads interested in nanowrimo --- National Novel Writing Month. The goal is to write 50,000 words in the 30 days of November. It is an incredibly beneficial excersize. We talked about methods of writing --- whether to plan out each scene, or write as you fancy at the moment. I have written with very little planning the past three years, but failed to finish the past two. I'm going to try some more extensive planning this year and we'll see what happens.&lt;br /&gt;&lt;br /&gt;This weekend: Makerfaire. I'll do my best to write a few posts from there.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On calling shots:&lt;br /&gt;&lt;br /&gt;I made two of three of my shots for this week, and that ain't bad.&lt;br /&gt;&lt;br /&gt;For next week:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Post on Makerfaire&lt;/li&gt;&lt;li&gt;Post another drawing excersize&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;And now off to bed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-6611462865788186607?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/6611462865788186607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=6611462865788186607&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6611462865788186607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/6611462865788186607'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/101508-hackjam.html' title='10.15.08 Hackjam'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-4918445106133800770</id><published>2008-10-15T11:49:00.005-05:00</published><updated>2008-10-15T12:48:55.541-05:00</updated><title type='text'>On the Livescribe Pulse</title><content type='html'>&lt;span style="font-weight: bold;"&gt;The Pitch&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.livescribe.com/"&gt;Livescribe Pulse &lt;/a&gt;is an e-pen; it allows you to take notes while recording simultaneous audio, and then uplaod both the notes and the audio to your computer.&lt;br /&gt;&lt;br /&gt;For instance, you're sitting in a hackjam, and someone says "Oh, a Lagrangian inverted hapgood might be able to solve that problem." You're scribbling math in your notebook as best you can, but you've never heard of a Lagrangian inverted hapgood (for &lt;a href="http://www.google.com/search?hl=en&amp;amp;client=firefox-a&amp;amp;rls=org.mozilla%3Aen-US%3Aunofficial&amp;amp;hs=sq9&amp;amp;q=%22lagrangian+inverted+hapgood%22&amp;amp;btnG=Search"&gt;good reason&lt;/a&gt;) --- so you make a little note: "soln?" and keep working.&lt;br /&gt;&lt;br /&gt;Later, when you get back home, you tap "soln?" with the tip of your pen, and the disembodied voice of your friend repeats "Oh, a Lagrangian inverted hapgood might be able to solve that problem." You happily google the phrase and discover what you needed to know.&lt;br /&gt;&lt;br /&gt;Much sillier, but also more fun, is the built in piano. With a few strokes of the livescribe, you can draw a single octave piano --- and then play it with the tip of the pen!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Product:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The pen comes in a nice box of a reasonable size;  inside is the pen, a simple manual (a single folded page), a carrying case for the pen, headphones, a lanyard for the pen, replacement ink cartridges, and a spiral-bound notebook.&lt;br /&gt;&lt;br /&gt;The pen has only one button, which the manual explains should be pushed. The pen came charged, and turned on after about two seconds boot time.&lt;br /&gt;&lt;br /&gt;Setting the date, and time is an amusing experience --- in the cover of the notebook is a page printed with a calculator and various function keys --- including a left/right handed switch to control the direction of the display (hooray!). The time and date are set by tapping the appropriate 'buttons' on this printed page.&lt;br /&gt;&lt;br /&gt;A reasonable tutorial walks you through how to use the pen. At the bottom of each page of the notebook, there is a set of printed controls --- record, pause, stop, time, speed, and volume. Tapping on record begins recording, and anything you write (on any page of the notebook) is tied to what you record as you record. If you want to hear something again, just tap on the note (down to the individual stroke) and listen to exactly what was happening when you drew that line. Or, if you like, turn on the optional latency, and hear what happened starting 5 seconds before you put ink there.&lt;br /&gt;&lt;br /&gt;The pen can perform calculator functions in two ways --- by using the scientific(ish) calculator in the front cover of the notebook, or by accessing the calculator function by drawing a 'nav plus' (a big + sign) anywhere in the notebook, starting the calculator, and then &lt;span style="font-style: italic;"&gt;writing&lt;/span&gt; simple arithmetic: write "24*36=" and the pen's display will alert you that the answer is 864.&lt;br /&gt;&lt;br /&gt;The handwriting recognition is quite good; I had no trouble with incorrect readings in the limited vocabulary that the pen currently uses.&lt;br /&gt;&lt;br /&gt;The desktop application is another matter. It works only in windows (still no luck with virtualization for me, though some claim that VMWare does the trick). While one &lt;span style="font-style: italic;"&gt;can &lt;/span&gt;export pages as PDFs, there is little opportunity to take the images or the sound out of the Livescribe program and &lt;span style="font-style: italic;"&gt;use&lt;/span&gt; them.  The search ability (which uses handwriting recognition to search a whole notebook of notes for key words) works fine --- not brilliantly, but just fine.&lt;br /&gt;&lt;br /&gt;There is an online portion of the Livescribe application of which I cannot speak --- my native windows machine is not on the interwebs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How it Works&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;The pen's workings are rather clever. The pen contains an ARM9 processor, a OLED display, a pressure sensor, and an tiny infrared camera which points at the tip of the pen. Each page of each notebook (you can use as many as four at once) is printed with a pattern of tiny (.3mm) dots called the anoto pattern. Any five by five section of the anoto pattern (about 3mm^2) is uniquely identified by the pattern of dots. Capturing the pattern with the camera allows the pen to identify its location on a sub-mm level.&lt;br /&gt;&lt;br /&gt;Everything else is just clever programming.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Pros:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It does exactly what it says it does&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Excellent&lt;/span&gt; on-pen interface.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;HIGH wow factor&lt;/li&gt;&lt;li&gt;Large capacity (1 or 2 GB)&lt;/li&gt;&lt;li&gt;Audio is clear&lt;/li&gt;&lt;li&gt;Notes are legible&lt;/li&gt;&lt;li&gt;An on-pen application development suite is coming -- and is in pre-release now. &lt;--- VERY exciting. Why I bought the pen.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;The Cons:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Windows only&lt;/li&gt;&lt;li&gt;Desktop application is nearly useless. Good only for archiving notebooks you're replacing&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Cost: $150-200 US&lt;/li&gt;&lt;li&gt;Battery life: 1-2days. Charge time: 1-2 hours.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;What I Think Should Change&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;I'd love to see .svg, jpg, and .png export of pages, and SOME kind of export of audio.&lt;br /&gt;&lt;br /&gt;The pen is completely round. It rolls off of everything.&lt;br /&gt;&lt;br /&gt;The pen has no cap --- only a full carrying case.&lt;br /&gt;&lt;br /&gt;Livescribe is making a lot of vauge promises about applications (Spanish translation, full handwriting recognition) and coming-soon features (the ability to print your own paper --- notebooks are $5 apiece and up). From what I can tell, livescribe expects the Pulse to be able to heal the sick and expel daemons by the end of this year. &lt;span style="font-style: italic;"&gt;But they have not released a timeline. &lt;/span&gt;Lots of big talk, but they won't say when it'll all actually be done. That's worrying me a lot guys. I'm happy enough to wait even a year for some of those abilities; just tell me that it's gonna take that long. Don't vaguely suggest that it might be done by this December.&lt;br /&gt;&lt;br /&gt;There you have it. The Livescribe Pulse. Available online and at Target for ~$150 and $200, depending on memory capacity. Notebooks are 4 for $20.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-4918445106133800770?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/4918445106133800770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=4918445106133800770&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/4918445106133800770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/4918445106133800770'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/on-livescribe-pulse.html' title='On the Livescribe Pulse'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-7454820716580023227</id><published>2008-10-14T22:20:00.001-05:00</published><updated>2008-10-14T22:20:54.893-05:00</updated><title type='text'>Natural Language Processing - Part I</title><content type='html'>I went to see Iron Man back in May when it came out. It was a fun movie and it definitely satisfied my inner comic nerd but the first words out of my mouth when we left the theater were, "I have some software to write." Since then, I've been working on a small portion of that software: a natural language interface for a computer, a sort of natural language shell.&lt;br /&gt;&lt;br /&gt;The first stab was a naive one. It worked in a subset of english where every word had only one meaning and every sentence had only one possible parse. I thought I knew how bad of a limitation I had placed on myself, but I wanted to start building an approximate solution and get experience in the problem space. It turned out that I underestimated the limitations I was working under and had to abandon that approach sooner than I had hoped. Before I stopped, however, I had a system that I could make statements to, ask questions of, and even tell to launch programs, provided I was careful in my wordings.&lt;br /&gt;&lt;br /&gt;One sentence would be read in at a time, parsed according to a BNF grammar, and classified as declarative, imperative, or inquisitive. Declarative sentences would be added to the knowledge base (KB). There was no validation on what was added; the system could be fed two inconsistent statements and it'd take both as gospel. Answering questions involved a search of the KB for an answer. Yes/no questions did a backward substituion search for satisfiability and "what is" questions searched for facts in the KB that answer the question. So given: "All men are mortal", and "Socrates was a man", it could answer the question "Was Socrates a mortal?" with "Yes." and "Who was Socrates?" with "A man." Imperative sentences were recognized, and if the verb of the sentence was "run" and the object a constant (names like "emacs" that weren't in the dictionary were treated as constants), it would try to run a program with that constant's name in the background.&lt;br /&gt;&lt;br /&gt;Just over two months ago, I started from scratch. (I had been learning Haskell as I wrote the first system, so even the code that had reusable functionality was a mess.) Through the magic of Monads, the new parsing code is about 40% smaller and returns a set of all the interpretations for a sentence it can come up with. This set gets much larger than I expected. Just introducing the ability to interpret any word as a name explodes the number of possible responses. The program shows the sentence "Emacs is a program that opens text files" as having 23 unique parses. Now, there's a lot of those 23 that can be discarded through checking some form of subject verb agreement. What's left can even be ignored given a parse that assumes less names, so it looks like there's still a workable solution there. In the worst cases, the system will have to deal with a nondeterministic KB until either more context is available to make the sentence clearer, or the system can ask questions.&lt;br /&gt;&lt;br /&gt;This is an interesting problem in a lot of ways. More next week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-7454820716580023227?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/7454820716580023227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=7454820716580023227&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7454820716580023227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/7454820716580023227'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/natural-language-processing-part-i.html' title='Natural Language Processing - Part I'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-166029809760000848</id><published>2008-10-11T12:22:00.002-05:00</published><updated>2008-10-11T12:31:30.891-05:00</updated><title type='text'>More from 10/8/08</title><content type='html'>Montana's still working on his grid evaluation computing thing.  I've long forgotten what he calls it.  From what I understand, he's got functions that evaluate constants, but realizes he needs functions that can evaluate references.  It seems like he's making progress lately, so I'm hoping we can get him to post what he's up to.&lt;br /&gt;&lt;br /&gt;So I'm working on a font based on my handwriting.  It's something I've wanted for a while as a novelty item, but I've been pleased with how well it's working out.  It's nice to have a font that my brain associates with drafts, notes to myself, and unfinished stuff.  I'm hoping to have it in a usable state for the start of Nanowrimo so I can put it into an extended test.&lt;br /&gt;&lt;br /&gt;I did not quite make my shot for the week.  I made progress in the form of a couple of design breakthroughs, but not much in the form of code aside from recognizing plural forms of nouns, and even that was crude.  I've got a three day weekend here, so I should do better this week.&lt;br /&gt;&lt;br /&gt;My called shots for this week:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Most sentences converted to a (possibly large) set of possible logical meanings&lt;/li&gt;&lt;li&gt;A post describing where I'm at with this thing.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-166029809760000848?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/166029809760000848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=166029809760000848&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/166029809760000848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/166029809760000848'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/more-from-10808.html' title='More from 10/8/08'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-1388990427025275607</id><published>2008-10-11T10:46:00.007-05:00</published><updated>2008-10-11T14:03:23.247-05:00</updated><title type='text'>Drawing exersize</title><content type='html'>I tried writing a few paragraphs about why I think people should learn to draw --- communicating ideas, self expression, recording memories --- and it seemed like so much fluff. It comes down to this: I bet you've said, "I wish I could draw."&lt;br /&gt;&lt;br /&gt;Gaining the ability to draw realistically (and even &lt;a href="http://arminmersmann.artroof.com/"&gt;photorealistically&lt;/a&gt;) is not hard ; you will need to devote some time to it, however. For this first exersize, you'll need to set aside 20-30 minutes of quiet time alone. I don't recommend music, and if there will be other people, avoid conversation. Alone is best.&lt;br /&gt;&lt;br /&gt;You will also need a pen --- ballpoint is fine --- and a nice big piece of paper. You &lt;span style="font-style: italic;"&gt;can&lt;/span&gt; do this on 8.5x11, but it's much more rewarding on big paper. I'll be doing my example on a page that's nearly 2'x3'.&lt;br /&gt;&lt;br /&gt;Set up a comfortable place to sit; you'll want to be able to sit up pretty straight, and be able to reach your paper easily.&lt;br /&gt;&lt;br /&gt;Enough preparation, eh? Read all the instructions first:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Place your pen in your writing hand and lightly touch the tip to the center of your paper.&lt;/li&gt;&lt;li&gt;Sit so that you face away from your paper, but your drawing hand can still comfortably reach the page. You should not be able to see it at all.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;With your non-writing hand, make a nice relaxed shape; curl your fingers as if you're holding something, or pointing lightly. Just keep it very relaxed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now &lt;span style="font-style: italic;"&gt;without looking at the paper&lt;/span&gt;, begin to draw your hand. Let your eye trace along the exterior outline, very slowly, taking in each bump and curve. As your eye moves, try and move your pen in the same way --- copying each little bump. When you've done the outline, then start working on the little grooves and interior lines.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Take the full 20-30 minutes and try and record every little detail. NO PEEKING. Please, I beg of you, resist the urge to look. Just let the pen move unobserved, and don't worry about the result. Chances are you'll be bored silly after about 10 minutes. Resist the urge to stop --- this is exersize! Keep pushing yourself to find new lines, new curves. Never stop drawing --- if you must, redraw the lines you've already done.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Go ahead. Do it! Reading what you were supposed to learn without doing the exercise is futile --- come back and read the rest when you're done.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Done? Good! Here's mine:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_OKQBL_J5AsU/SPDvuTPlb0I/AAAAAAAAACY/aZ1dY2E6Z3s/s1600-h/blind_contour.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_OKQBL_J5AsU/SPDvuTPlb0I/AAAAAAAAACY/aZ1dY2E6Z3s/s400/blind_contour.png" alt="" id="BLOGGER_PHOTO_ID_5255964343860031298" border="0" /&gt;&lt;/a&gt;A masterwork, no? If yours looks as little like a hand as mine does, I congratulate you --- you didn't peek even once! (Note that for clarity, after my 20 minutes were up I traced directly over the primary contours again --- the ones around my hand.) Right now you're probably despairing eve being able to draw --- and yelling at me about unreasonable constraints, ridiculous time limits, and difficult subject matters.&lt;br /&gt;&lt;br /&gt;Tough beans.&lt;br /&gt;&lt;br /&gt;There were several purposes to this exersize. None of those purposes was to make you look like Leonardo. Here are some reasons why I made you suffer through that:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Hand-eye coordination. If you can write, you have enough hand-eye coordination to draw. But learning to sync your hand to your eye when they are not pointed in the same direction is a little like patting your stomach and rubbing you head: not hard once you get the hang of it, but it takes a bit of time. You just spent 20 minutes forcing your hand to follow your eye.&lt;/li&gt;&lt;li&gt;Observation NOT classification. One of the greatest roadblocks to realistic drawing is labeling. As long as you continue to see a hand as four fingers and a thumb, you'll never draw it accurately. Blind contour drawing (which is what you just did) forces you to think in terms of lines and curves; you can't tell whether you're drawing a finger because you can't see what you're drawing. You can only concentrate on what the pen is doing &lt;span style="font-style: italic;"&gt;right now.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Confidence.&lt;span style="font-style: italic;"&gt; &lt;/span&gt;I know that that might seem paradoxical, to say you gained confidence from making such a godawful rendition of a hand --- but  think of the last time you drew something. Did you use pencil? Did you erase much? How frustrated were you during the process --- and with the result? Now think about how you felt and thought during this drawing. You spent 20 minutes drawing a hand. I hope you felt relaxed during the process --- even meditative. You didn't erase once, because you were using pen, and you couldn't see what you were doing anyway. And you should feel good about your result, too. You drew in pen. You drew &lt;span style="font-style: italic;"&gt;blind.&lt;/span&gt; And I bet there are recognizable bits in there, aren't there?&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Try doing one of these a day for a few days. Don't worry about improvement --- just notice the calm, trance-like state that prolonged observation creates; during later exercises, you'll want to remember what that feels like.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[Note: for those of you who are looking up "blind contour" --- this exersize is a modified blind contour, because we are including many interior lines, which are not technically contours. Doing a pure blind contour is also worth a try, and is much faster. Do just what we did here, but only draw the outline --- no interior curves at all. It should only take a few minutes at most.]&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-1388990427025275607?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/1388990427025275607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=1388990427025275607&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1388990427025275607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/1388990427025275607'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/drawing-exersize.html' title='Drawing exersize'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_OKQBL_J5AsU/SPDvuTPlb0I/AAAAAAAAACY/aZ1dY2E6Z3s/s72-c/blind_contour.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-704155595884141434</id><published>2008-10-09T11:59:00.003-05:00</published><updated>2008-10-22T17:28:03.749-05:00</updated><title type='text'>Hack Jam: 10.8.08</title><content type='html'>Discussion: typography, drawing, and the &lt;a href="http://www.wired.com/techbiz/people/magazine/16-10/ff_walker?currentPage=all"&gt;library of our dreams.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Font was on the table because Adam's been working on a font for the coming &lt;a href="http://www.nanowrimo.org"&gt;nanowrimo&lt;/a&gt;; for tasks of that nature, several of us use &lt;a href="http://fontforge.sourceforge.net/"&gt;FontForge. &lt;/a&gt;Fontforge has a miserable interface; it's highly unintuitive, uses multiple windows that cannot be docked, and is all around a hassle to use.  However, it is open source software -- and is pretty much the ONLY free or even reasonably cheap software that will allow you to make the most of what the TrueType and OpenType standard have to offer in terms of kerning pairs, ligatures, and hinting. Powerful but not agile or intuitive? The story of open source.&lt;br /&gt;&lt;br /&gt;We also talked about how unfortunate it was that so few pieces of software allow for the use of these features even when they are included in a font; Adobe products remain nearly the only bastion of font flexibility --- outside, of course, the ever miraculous Latex.&lt;br /&gt;&lt;br /&gt;I mentioned that I had offended an art student by mentioning that I thought it was worth any artist's time to learn to draw. In my opinion, the ability to communicate visually, to see objects with a draftsman's eyes, is enough excuse. But still further, it is expected of you --- if you say you're an artist, lay people assume that means you can draw. As Adam put it: "When someone asks 'Can you draw that?', 'No' is  the boring answer." I brought up Betty Edwards' &lt;span style="font-style: italic;"&gt;Drawing on the Right Side of the Brain &lt;/span&gt;which is a book of exersizes  based on a neuro-psychological understanding of how draftsmen draw; I recommended her methods as pedagogical breakthroughs which ought to be applied but, at least in my experience, have not been.&lt;br /&gt;&lt;br /&gt;On calling my shots:&lt;br /&gt;I did not get the Livescribe working with virtualization; I did get the pen working on a native windows system, and it is recognized by a VirtualBox machine, but the LiveScribe Desktop installer throws an unrecoverable error when attempting to communicate with the pen. Will try VMPlayer.&lt;br /&gt;&lt;br /&gt;This week I call several small things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A post reviewing the Livescribe.&lt;/li&gt;&lt;li&gt;A post with a right-brained drawing excersize you can do at home&lt;/li&gt;&lt;li&gt;Screen-print a t-shirt for Maker faire.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-704155595884141434?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/704155595884141434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=704155595884141434&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/704155595884141434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/704155595884141434'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/hack-jam-81008.html' title='Hack Jam: 10.8.08'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-8005626604649709797</id><published>2008-10-03T23:41:00.005-05:00</published><updated>2008-10-04T02:29:39.681-05:00</updated><title type='text'>Fastbootin' Linux</title><content type='html'>A couple of links are in order regarding recent progress made in booting a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;linux&lt;/span&gt; system faster.  Linux developers &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Arjan&lt;/span&gt; van &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;de&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Ven&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Auke&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Kok&lt;/span&gt; gave a presentation at the recent Linux Plumbers conference on booting an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Asus&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;eee&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;pc&lt;/span&gt; in 5 seconds (&lt;a href="http://www.youtube.com/watch?v=s7NxCM8ryF8"&gt;video&lt;/a&gt;).  That's five seconds to usable desktop with processor and disk idle, but no, that doesn't include bios posting.  I'm not sure how long that is on a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;eee&lt;/span&gt;.  &lt;a href="http://lwn.net/Articles/299483/"&gt;Here's&lt;/a&gt; the most detailed article covering the presentation, and &lt;a href="http://www.fenrus.org/plumbers_fastboot.ppt"&gt;here's&lt;/a&gt; the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;ppt&lt;/span&gt; itself.&lt;br /&gt;&lt;br /&gt;I've been playing around with some of the techniques they used this week.  I had pruned my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;init&lt;/span&gt; scripts sometime last year to get a 15 second boot time, though that had climbed up to the 25 second range with my new laptop and new hardware.  I've gotten it back down below 20 seconds by applying the available kernel patches in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Arjan's&lt;/span&gt; &lt;a href="http://lwn.net/Articles/299591/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;fastboot&lt;/span&gt; .git tree&lt;/a&gt; and modularizing the non-critical part of my kernel.  There's three major avenues to pursue to remove more time on my box.  I still want to understand why there's a 3 second pause in the kernel loading process that wasn't there on my old laptop.  There's a new X.org server that should improve &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;startup&lt;/span&gt; time somewhat.  I should be able to use &lt;a href="http://www.moblin.org/projects/fast-boot"&gt;super &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;readahead&lt;/span&gt;&lt;/a&gt; to improve IO throughput in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;bootup&lt;/span&gt; (and possibly &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;preload&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;firefox&lt;/span&gt; as well?).&lt;br /&gt;&lt;br /&gt;The presentation was done from systems installed with Fedora and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;Moblin&lt;/span&gt;. From what I read, these improvements will end up in most other distributions as well.  The kernel patches may make it into 2.6.28 (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;earlyish&lt;/span&gt; 2009), the improvements made to X should make it into the next release of X.org.&lt;br /&gt;&lt;br /&gt;I'm putting this all aside for a little while and get back to working on English language processing this weekend; I'll write up more about exactly what I'm doing with that soon.  As a target for &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_21"&gt;Wednesday&lt;/span&gt;, I'll commit to making &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_22"&gt;significant&lt;/span&gt; progress, but I'm in an exploring stage, so I'm won't committing to what that will entail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-8005626604649709797?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/8005626604649709797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=8005626604649709797&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/8005626604649709797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/8005626604649709797'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/fastbootin-linux.html' title='Fastbootin&apos; Linux'/><author><name>Adam Heck</name><uri>http://www.blogger.com/profile/00716800125148427529</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4024934086395647348.post-3107327282416806419</id><published>2008-10-02T00:34:00.005-05:00</published><updated>2008-10-02T19:25:14.424-05:00</updated><title type='text'>Hack Jam: 1.10.08</title><content type='html'>Topics of discussion: the &lt;a href="http://en.wikipedia.org/wiki/Two_envelopes_problem"&gt;two envelope problem, &lt;/a&gt;the livescribe Pulse, slackware bootup times.&lt;br /&gt;&lt;br /&gt;Adam brought up a neat examination of a mircocosm within the two envelopes problem:&lt;br /&gt;&lt;br /&gt;Select a random number from the positive reals. Now select another. What are the chances that the second is greater than the first?&lt;br /&gt;&lt;br /&gt;(Note that what follows is from my mouth -- it is not necessarily Adam's opinion or intention with this example.)&lt;br /&gt;&lt;br /&gt;I see several resolutions to this problem. The first cheats, so we'll start there.&lt;br /&gt;&lt;br /&gt;Make your first pick; call that number A. Due to the uncountably infinite nature of the reals, there are as many real numbers between zero and a as there are between A and the infinite (think of a function with a vertical asymptote, like tangent --- tan(x) for x from 0 to pi/4 maps to y from 0 to infinity). Therefore, it is equally likely that your next selection will be greater as it will be less --- any A divides R+ into two equal parts, so the answer to our original question is 1/2.&lt;br /&gt;&lt;br /&gt;Why does this result cheat? Because the paradox returns if we change from R, the reals, to the natural numbers (1, 2, 3...).  Then the infinity trick fails; there is only one number between 0 and 2, and still an infinite number between 2 and infinity.&lt;br /&gt;&lt;br /&gt;We can also employ a different cheat --- redefining probability. Mathematicians that subscribe to "frequency probability" define probability as  the number of occurances divided by the number of trials. If you flip a coin 100 times, and it comes up heads 57 times, then the probability of it coming up heads is .57. As the number of trials (flips) approaches infinite, then the frequency definition equates to the classical definition of probability. Using the frequency definition solves one big part of the paradox: the expected value of a  random selection  between one and  infinity.&lt;br /&gt;&lt;br /&gt;That expected value is infinite --- but no matter how many times you make the selection, your actual return will be a finite number --- 0% of your expected value. Even if you take billions of trials and average them, your actual return will never be infinite. It helps here to keep in mind that 'infinity' is not a number, it is a limit. Our random selection will not return 'infinity' no matter what;  just very large numbers.&lt;br /&gt;&lt;br /&gt;So how does frequency probability dissolve that paradox? By rejecting the problem definition. If you were able to to 10 trials of selecting a random natural (or real) number between zero and infinity, one of those selections would be the highest. As far as frequency probability is concerned, that number is the maximum possible value. The infinite never enters the equation; and if you change the infinity in the original problem to some number, the answer becomes easily 1/2.&lt;br /&gt;&lt;br /&gt;This leads me to believe that the entire paradox stems from the even simpler problem: select a random positive natural number. Such a thing is certainly physically impossible, but I don't want to reject it just for that. But untli the paradox of expected value versus average return is resolved, I think that the original envelopes paradox is contained in many respects in this (admittedly more abstract) simpler question.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My updates:&lt;br /&gt;&lt;br /&gt;In the last week I got Hack Jam Log Book up and running.&lt;br /&gt;&lt;br /&gt;For next Wednesday, I call getting a livescribe Pulse running via virtualization on a linux box.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4024934086395647348-3107327282416806419?l=hackjam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hackjam.blogspot.com/feeds/3107327282416806419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4024934086395647348&amp;postID=3107327282416806419&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3107327282416806419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4024934086395647348/posts/default/3107327282416806419'/><link rel='alternate' type='text/html' href='http://hackjam.blogspot.com/2008/10/hack-jam-11008.html' title='Hack Jam: 1.10.08'/><author><name>Sam Bleckley</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_OKQBL_J5AsU/Sh3IxQkIc1I/AAAAAAAAAD8/fXIxBkJie5Q/S220/SB_ornament.jpg'/></author><thr:total>2</thr:total></entry></feed>
