<?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-6461387352629250590</id><updated>2012-01-31T02:55:03.692-08:00</updated><category term='install'/><category term='flash'/><category term='processing'/><category term='keyboard shortcuts'/><category term='synergy'/><category term='seq24'/><category term='SQL'/><category term='system beep'/><category term='clojure'/><category term='bugs'/><category term='pseudocode'/><category term='C'/><category term='memoization'/><category term='latex'/><category term='soa'/><category term='WAR'/><category term='UI'/><category term='line count'/><category term='parsing'/><category term='ontology'/><category term='algorithms'/><category term='brightness'/><category term='aplications'/><category term='batch rename'/><category term='sed'/><category term='OpenStreetMap'/><category term='ip'/><category term='owl'/><category term='firefox'/><category term='code formatting'/><category term='cylinder'/><category term='grails'/><category term='audio'/><category term='tar.gz'/><category term='collision detection'/><category term='linear algebra'/><category term='rss'/><category term='environment variables'/><category term='puredata'/><category term='email'/><category term='Flex'/><category term='frustration'/><category term='glut'/><category term='vim'/><category term='eclipse'/><category term='dual screen'/><category term='dual head'/><category term='laptop'/><category term='dual computer'/><category term='password protect'/><category term='Rserve'/><category term='jack'/><category term='MySQL'/><category term='cuda'/><category term='RDF'/><category term='java'/><category term='linux sound'/><category term='semantic web'/><category term='example'/><category term='nvidia-glx-new'/><category term='graphics'/><category term='envyng'/><category term='gpgpu'/><category term='networking'/><category term='gui'/><category term='Groovy'/><category term='kde4'/><category term='batch'/><category term='audio sampling'/><category term='flash plugin'/><category term='interpreter'/><category term='parallelization'/><category term='desktop background'/><category term='gedit'/><category term='drivers'/><category term='math parser'/><category term='html'/><category term='synthesizer'/><category term='file management'/><category term='atom'/><category term='design'/><category term='regular expressions'/><category term='kile'/><category term='dhcp'/><category term='string replace'/><category term='ubuntu'/><category term='eclispe'/><category term='notification'/><category term='nvidia'/><category term='svn'/><category term='openjdk'/><category term='feeds'/><category term='lines of code'/><category term='WebServices'/><category term='JAVA_HOME'/><category term='SPARQL'/><category term='introduction'/><category term='JOGL'/><category term='MVC'/><category term='quadrics'/><category term='sounds'/><category term='autostart'/><category term='recursive'/><category term='xargs'/><category term='skype'/><category term='tomcat'/><category term='midi'/><category term='error reporting'/><category term='sun java'/><category term='gnome'/><category term='floating point'/><category term='C++'/><category term='find'/><category term='protege'/><category term='cmake'/><category term='Jetty'/><category term='glew'/><category term='opengl'/><category term='sdk'/><category term='python'/><category term='DBPedia'/><category term='background'/><category term='code'/><category term='compiz'/><category term='trigonometry'/><category term='feedparser'/><category term='flex builder'/><category term='okular'/><category term='pipes'/><category term='linux'/><category term='rendering'/><category term='instrument'/><category term='math'/><category term='emacs'/><category term='research'/><category term='word count'/><category term='login'/><category term='wallpaper'/><category term='fluxbox'/><category term='sockets'/><category term='WordPress'/><category term='tutorial'/><category term='rename'/><category term='music'/><category term='lisp'/><category term='syntax highlighting'/><category term='principles'/><category term='sphere'/><category term='CSV'/><category term='website'/><category term='subclipse'/><category term='inside test'/><category term='blog'/><category term='kde'/><category term='tar'/><category term='replace'/><category term='redirection'/><category term='cdt'/><category term='camel case'/><category term='muparser'/><category term='expression parser'/><category term='unix'/><category term='drum machine'/><category term='ip address'/><category term='qt'/><category term='g++'/><category term='Glassfish'/><category term='password'/><category term='multitouch'/><category term='Axis2'/><category term='dual monitor'/><category term='zip'/><category term='R'/><title type='text'>Life of a Programmer Geek</title><subtitle type='html'>Technical journeys into the unknown!</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default?start-index=101&amp;max-results=100'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>110</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5393286463477653378</id><published>2010-12-25T17:50:00.001-08:00</published><updated>2010-12-25T17:52:10.570-08:00</updated><title type='text'>Merry Christmas World!</title><content type='html'>Today I released a lot of my code as open source &lt;a href="https://github.com/curran"&gt;here&lt;/a&gt;. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5393286463477653378?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5393286463477653378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5393286463477653378' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5393286463477653378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5393286463477653378'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/12/merry-christmas-world.html' title='Merry Christmas World!'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2484828080204980223</id><published>2010-12-08T21:04:00.001-08:00</published><updated>2010-12-23T19:52:27.272-08:00</updated><title type='text'>This site has moved</title><content type='html'>to &lt;a href="http://curransoft.com/code/"&gt;http://curransoft.com/code/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2484828080204980223?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2484828080204980223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2484828080204980223' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2484828080204980223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2484828080204980223'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/12/this-site-has-moved.html' title='This site has moved'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3297803570256475595</id><published>2010-12-06T18:50:00.001-08:00</published><updated>2010-12-06T21:19:20.418-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SPARQL'/><category scheme='http://www.blogger.com/atom/ns#' term='semantic web'/><category scheme='http://www.blogger.com/atom/ns#' term='DBPedia'/><category scheme='http://www.blogger.com/atom/ns#' term='RDF'/><title type='text'>Querying the Semantic Web</title><content type='html'>&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Supposedly the Semantic Web contains lots of information, but what information? What is in there? Show me the money! I want to ask Wikipedia "What are all universities in the world and their student populations?" and I thought, what better test query for the Semantic Web?&lt;br /&gt;&lt;br /&gt;I began &lt;span class="Apple-style-span"&gt;my search by looking at various example queries through the &lt;a href="http://dbpedia.neofonie.de/"&gt;DBPedia faceted browser&lt;/a&gt;:&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;[links from &lt;a href="http://wiki.dbpedia.org/FacetedSearch?v=17jm"&gt;this page&lt;/a&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); line-height: 24px; "&gt;&lt;ul style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.75em; margin-left: 2em; "&gt;&lt;li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;a href="http://dbpedia.neofonie.de/browse/rdf-type:River/River-mouth:Rhine/Place-length~:50000~/?fc=30" target="_blank" title="Outgoing link (in new window)" class="outerlink" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: blue; text-decoration: none; font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Rivers that flow into the Rhine and are longer than 50 kilometers&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;a href="http://dbpedia.neofonie.de/browse/MusicalWork-artist:The%20Beach%20Boys/Work-releaseDate-year~:1980~1990/rdf-type:Album/" target="_blank" title="Outgoing link (in new window)" class="outerlink" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: blue; text-decoration: none; font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Albums from the Beach Boys that were released between 1980 and 1990&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;a href="http://dbpedia.neofonie.de/browse/rdf-type:Scientist/Person-birthPlace:France/Person-birthDate-year~:1800~1900/" target="_blank" title="Outgoing link (in new window)" class="outerlink" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: blue; text-decoration: none; font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;French scientists who were born in the 19th century&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;a href="http://dbpedia.neofonie.de/browse/rdf-type:Skyscraper/Building-floorCount~:50~/Building-buildingEndDate-year~:~1999/Place-location:China/?fc=18" target="_blank" title="Outgoing link (in new window)" class="outerlink" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: blue; text-decoration: none; font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Skyscrapers in China that have been constructed before 2000 and have more than 50 floors&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;a href="http://dbpedia.neofonie.de/browse/rdf-type:Actor/TelevisionShow-starring-of:Lost%20%28TV%20series%29/Person-birthPlace:England/?fc=12" target="_blank" title="Outgoing link (in new window)" class="outerlink" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: blue; text-decoration: none; font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Actors of the American TV-series Lost that were born in England&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;a href="http://dbpedia.neofonie.de/browse/rdf-type:Mammal/Species-conservationStatus:EN/Species-order:Primate/" target="_blank" title="Outgoing link (in new window)" class="outerlink" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: blue; text-decoration: none; font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Endangered Primates&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 24px;"&gt;&lt;span class="Apple-style-span"&gt;That's pretty cool, I can manage to &lt;/span&gt;&lt;a href="http://dbpedia.neofonie.de/browse/rdf-type:University/"&gt;&lt;span class="Apple-style-span"&gt;list all un&lt;/span&gt;iversities&lt;/a&gt;, but how to display their student populations? I see no way of doing this with this faceted browser tool, which is really a &lt;a href="http://en.wikipedia.org/wiki/Faceted_search"&gt;faceted search&lt;/a&gt; tool, because all it allows one to do is filter the listing based on various parameters, not to specify which parameters are shown.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 24px;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 24px;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;I think we'll need to learn some &lt;a href="http://en.wikipedia.org/wiki/SPARQL"&gt;SPARQL&lt;/a&gt; to get at the student populations. I came across a &lt;a href="http://www.xml.com/pub/a/2005/11/16/introducing-sparql-querying-semantic-web-tutorial.html?page=1"&gt;nice SPARQL tutorial from XML.com&lt;/a&gt; and began following it. It seems like &lt;a href="http://dbpedia.org/snorql/?query=PREFIX+dbo%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2F%3E%0D%0A%0D%0ASELECT+%3Fname+%3Fbirth+%3Fdeath+%3Fperson+WHERE+{%0D%0A+++++%3Fperson+dbpedia2%3AbirthPlace+%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FBerlin%3E+.%0D%0A+++++%3Fperson+dbo%3AbirthDate+%3Fbirth+.%0D%0A+++++%3Fperson+foaf%3Aname+%3Fname+.%0D%0A+++++%3Fperson+dbo%3AdeathDate+%3Fdeath%0D%0A+++++FILTER+(%3Fbirth+%3C+%221900-01-01%22^^xsd%3Adate)+.%0D%0A}"&gt;SNORQL&lt;/a&gt; is a widely used query interface for DBPedia. The &lt;a href="http://dbpedia.org/snorql/?query=PREFIX+dbo%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2F%3E%0D%0A%0D%0ASELECT+%3Fname+%3Fbirth+%3Fdeath+%3Fperson+WHERE+{%0D%0A+++++%3Fperson+dbpedia2%3AbirthPlace+%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FBerlin%3E+.%0D%0A+++++%3Fperson+dbo%3AbirthDate+%3Fbirth+.%0D%0A+++++%3Fperson+foaf%3Aname+%3Fname+.%0D%0A+++++%3Fperson+dbo%3AdeathDate+%3Fdeath%0D%0A+++++FILTER+(%3Fbirth+%3C+%221900-01-01%22^^xsd%3Adate)+.%0D%0A}"&gt;SNORQL link&lt;/a&gt; from the &lt;a href="http://wiki.dbpedia.org/Applications"&gt;DBPedia Applications page&lt;/a&gt; presents an example query executed on the DBPedia knowledge base: "List all names, birth dates and death dates for all people born in Berlin before 1900."&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style="color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(153, 153, 153); border-right-color: rgb(153, 153, 153); border-bottom-color: rgb(153, 153, 153); border-left-color: rgb(153, 153, 153); line-height: 14px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; overflow-x: auto; overflow-y: auto; width: 100%; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; "&gt;&lt;code&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;PREFIX dbo: &amp;lt;http://dbpedia.org/ontology/&amp;gt;&lt;br /&gt;&lt;br /&gt;SELECT ?name ?birth ?death ?person WHERE {&lt;br /&gt;?person dbpedia2:birthPlace &amp;lt;http://dbpedia.org/resource/Berlin&amp;gt; .&lt;br /&gt;?person dbo:birthDate ?birth .&lt;br /&gt;?person foaf:name ?name .&lt;br /&gt;?person dbo:deathDate ?death&lt;br /&gt;FILTER (?birth &amp;lt; "1900-01-01"^^xsd:date) .&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 24px;"&gt;&lt;a href="http://dbpedia.org/snorql/?query=PREFIX+dbo%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2F%3E%0D%0A%0D%0ASELECT+%3Fname+%3Fbirth+%3Fdeath+%3Fperson+WHERE+{%0D%0A+++++%3Fperson+dbpedia2%3AbirthPlace+%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FBerlin%3E+.%0D%0A+++++%3Fperson+dbo%3AbirthDate+%3Fbirth+.%0D%0A+++++%3Fperson+foaf%3Aname+%3Fname+.%0D%0A+++++%3Fperson+dbo%3AdeathDate+%3Fdeath%0D%0A+++++FILTER+(%3Fbirth+%3C+%221900-01-01%22^^xsd%3Adate)+.%0D%0A}"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Click here&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; to see the result in the &lt;a href="https://github.com/kurtjx/SNORQL"&gt;SNORQL Query Browser (GitHub page)&lt;/a&gt;, a project by&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; &lt;a href="http://richard.cyganiak.de/"&gt;Richard Cyganaik&lt;/a&gt; for the &lt;a href="http://www4.wiwiss.fu-berlin.de/bizer/d2r-server/"&gt;D2R server project&lt;/a&gt;. Notice how nowhere in the query is "Person" specified - that is assumed given the fact that the resource has a "birth date".&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 24px; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;I discovered something I had been wondering how to do: a query listing all the outgoing edges from a given resource, in other words listing all RDF (subject-predicate-object) triples which have a given resource as the subject. Here's a query which lists all the triples with Konraz Zuse (a listing in the previous result) as the subject:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style="color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(153, 153, 153); border-right-color: rgb(153, 153, 153); border-bottom-color: rgb(153, 153, 153); border-left-color: rgb(153, 153, 153); line-height: 14px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; overflow-x: auto; overflow-y: auto; width: 100%; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; "&gt;&lt;code&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;SELECT ?property ?hasValue&lt;br /&gt;WHERE {&lt;br /&gt;{ &amp;lt;http://dbpedia.org/resource/Konrad_Zuse&amp;gt; ?property ?hasValue }&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 24px;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;See the results by clicking &lt;a href="http://dbpedia.org/snorql/?query=SELECT+%3Fproperty+%3FhasValue%0D%0AWHERE+{%0D%0A++{+%3Chttp://dbpedia.org/resource/Konrad_Zuse%3E+%3Fproperty+%3FhasValue+}%0D%0A}"&gt;here&lt;/a&gt;. Here are some triples returned:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 24px;"&gt;&lt;table class="sparql" border="2"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;th&gt;property&lt;/th&gt;     &lt;th&gt;hasValue&lt;/th&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://xmlns.com/foaf/0.1/Person&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/Scientist110560637&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/ComputerPioneers&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://www.w3.org/2002/07/owl#Thing&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/ComputerDesigners&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/ProgrammingLanguageDesigners&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/Werner-von-Siemens-RingLaureates&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/GermanInventors&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/ComputerHardwareEngineers&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/GermanCivilEngineers&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/class/yago/GermanComputerScientists&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/ontology/Person&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/td&gt;     &lt;td&gt;http://dbpedia.org/ontology/Scientist&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2002/07/owl#sameAs&lt;/td&gt;     &lt;td&gt;http://umbel.org/umbel/ne/wikipedia/Konrad_Zuse&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2002/07/owl#sameAs&lt;/td&gt;     &lt;td&gt;http://www4.wiwiss.fu-berlin.de/dblp/resource/person/120373&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2002/07/owl#sameAs&lt;/td&gt;     &lt;td&gt;http://rdf.freebase.com/ns/guid.9202a8c04000641f8000000000022414&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2000/01/rdf-schema#comment&lt;/td&gt;     &lt;td&gt;Konrad Ernst Otto Zuse war ein deutscher Bauingenieur, Erfinder und Unternehmer. Mit seiner Entwicklung des Z3 im Jahre 1941 baute er den ersten universellen Computer der Welt.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2000/01/rdf-schema#comment&lt;/td&gt;     &lt;td&gt;コンラート・ツーゼ（Konrad Zuse、1910年6月22日 - 1995年12月18日）は、ドイツの技術者である。彼の最も重要な業績は、1941年に世界初の完全動作するプログラム制御式コンピュータ Zuse Z3 を完成させたことである（プログラムはテープに格納）。1998年、Z3 はチューリング完全であることが証明された。 何が世界初のコンピュータかという問題はコンピュータの定義に依存するが、Z3 は後のマシンと比較したときに汎用性に問題がある。ツーゼは高級プログラミング言語 プランカルキュール を1945年に設計したが、これは理論的な部分での業績であり、彼の生きている間には実装されることもなく後のプログラミング言語にも直接的な影響を与えることはなかった。 技術的な業績だけでなく、ツーゼは1946年に世界初のコンピュータ企業を設立した。この会社は世界初の商用コンピュータZ4を開発し、1950年にチューリッヒ工科大学にリースしている。第二次世界大戦の影響で、ツーゼの業績の大部分はイギリスやアメリカ合衆国では気づかれなかった。アメリカの企業で彼の影響が見られたのは 1946年にIBMがツーゼに特許使用許諾を得たのが最初である。1960年代後半になると、ツーゼは計算する宇宙（計算によって成り立つ宇宙）の概念を提唱した。 Z4とZ3の複製品がミュンヘンのドイツ博物館にある。 ベルリンの Deutsches Technikmuseum Berlin はコンラート・ツーゼおよび彼の作品に関する特別展示をしている。再現されたZ1を含む12台の彼のマシン、オリジナルの文書、いくつかのツーゼの描いた絵などが展示されている。&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2000/01/rdf-schema#comment&lt;/td&gt;     &lt;td&gt;Konrad Zuse var en tysk pioneer innenfor informatikk. Hans største bragd var konstruksjonen av den første funksjonelle datamaskin med programmer lagret på tape, kalt Z3, i 1941.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2000/01/rdf-schema#comment&lt;/td&gt;     &lt;td&gt;Конрад Цузе — немецкий инженер, пионер компьютеростроения. Наиболее известен как создатель первого действительно работающего программируемого компьютера и первого языка программирования высокого уровня.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;http://www.w3.org/2000/01/rdf-schema#comment&lt;/td&gt;     &lt;td&gt;Konrad Zuse was a German engineer and computer pioneer who collaborated with the German government during World War 2, which helped finance his projects. His greatest achievement was the world's first functional program-controlled Turing-complete computer, the Z3, in 1941 (the program was stored on a punched tape). He received the Werner-von-Siemens-Ring in 1964 for the Z3.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 24px; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 24px; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Wow. We get to know all the "kinds of person" he is known to be - a German inventor, scientist and computer pioneer - and summaries in many languages, and many more results not shown. Thats pretty impressive.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 24px; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="line-height: 24px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 24px; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;I played with the query a bit and remembered seeing the "DISTINCT" keyword in some SPARQL queries. Here's a variation on the above query that gives you a list of all unique property types which are applied to Konrad Zuse:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style="color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(153, 153, 153); border-right-color: rgb(153, 153, 153); border-bottom-color: rgb(153, 153, 153); border-left-color: rgb(153, 153, 153); line-height: 14px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; overflow-x: auto; overflow-y: auto; width: 100%; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; "&gt;&lt;code&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;SELECT DISTINCT ?property&lt;br /&gt;WHERE {&lt;br /&gt;{ &amp;lt;http://dbpedia.org/resource/Konrad_Zuse&amp;gt; ?property ?hasValue }&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Amazingly, the example queries from the XML.com tutorial &lt;a href="http://dbpedia.org/snorql/?query=PREFIX+table:+%3Chttp://www.daml.org/2003/01/periodictable/PeriodicTable%23%3E%0D%0A%0D%0ASELECT+%3Fname%0D%0AFROM+%3Chttp://www.daml.org/2003/01/periodictable/PeriodicTable.owl%3E%0D%0A%0D%0AWHERE+{+%3Felement+table:name+%3Fname.+}"&gt;actually execute through the DBPedia Snorql instance&lt;/a&gt;!&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Very nice! Now we have some example queries for listing of some property values, a key ingredient in our "What are all universities in the world and their student populations?" puzzle. I see that the queries work, but how do I find out what vocabulary I can use? Google "DBPedia Ontology" and you're there in a few clicks. &lt;a href="http://wiki.dbpedia.org/Ontology"&gt;The DBPedia Ontology page&lt;/a&gt; contains many useful links. &lt;a href="http://mappings.dbpedia.org/server/ontology/classes"&gt;Here&lt;/a&gt; is the DBPedia ontology (class hierarchy) in text form. From that page there is a link to the &lt;a href="http://mappings.dbpedia.org/server/ontology/classes/University"&gt;University ontology class&lt;/a&gt;, which in turn lists all of its properties, including "&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;numberOfStudents".&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;How can we use these things in a SPARQL query? We need URIs, not unqualified strings like "&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;numberOfStudents". I noticed that in the result of a previous query, [Konraz Zuse, rdf:type dbpedia:ontology/Person] was a triple. If you expand the object into its full URI (&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(85, 85, 85); white-space: pre; font-family: monospace; "&gt;PREFIX dbpedia: &lt;http: org=""&gt;&lt;/http:&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;) you get&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;a href="http://dbpedia.org/ontology/Person"&gt; http://dbpedia.org/&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;a href="http://dbpedia.org/ontology/Person"&gt;ontology/Person&lt;/a&gt;, which when accessed in a browser gives you a Linked Data interface to DBPedia. Just to see, I replaced Person with University, and sure enough, here is the Linked Data description of the DBPedia University class:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; "&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;a href="http://dbpedia.org/ontology/University"&gt;http://dbpedia.org/&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;a href="http://dbpedia.org/ontology/University"&gt;ontology/University&lt;/a&gt;, which reveals that University is the domain of the owl:Property &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://dbpedia.org/ontology/numberOfStudents"&gt;http://dbpedia.org/ontology/numberOfStudents&lt;/a&gt;, which we can use in our query.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Here's the query that returns a listing of 10 universities from DBPedia:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style="color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(153, 153, 153); border-right-color: rgb(153, 153, 153); border-bottom-color: rgb(153, 153, 153); border-left-color: rgb(153, 153, 153); line-height: 14px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; overflow-x: auto; overflow-y: auto; width: 100%; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; "&gt;&lt;code&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;PREFIX dbo: &amp;lt;http://dbpedia.org/ontology/&amp;gt;&lt;br /&gt;SELECT ?university WHERE {&lt;br /&gt;?university rdf:type dbo:University.&lt;br /&gt;} LIMIT 10&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;So, Wikipedia, what are all universities in the world and their student populations?&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;...translates to...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style="background-color: rgb(238, 238, 238); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(153, 153, 153); border-right-color: rgb(153, 153, 153); border-bottom-color: rgb(153, 153, 153); border-left-color: rgb(153, 153, 153); padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; overflow-x: auto; overflow-y: auto; width: 100%; "&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 14px; font-size: medium;"&gt;PREFIX dbo: &lt;http: org="" ontology=""&gt; SELECT ?name ?students WHERE {      ?university rdf:type dbo:University.      ?university foaf:name ?name.      ?university dbo:numberOfStudents ?students } ORDER BY DESC(?students) LIMIT 50&lt;/http:&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;See the results &lt;a href="http://dbpedia.org/snorql/?query=PREFIX+dbo:+%3Chttp://dbpedia.org/ontology/%3E%0D%0ASELECT+%3Fname+%3Fstudents+WHERE+{%0D%0A+++++%3Funiversity+rdf:type+dbo:University.%0D%0A+++++%3Funiversity+foaf:name+%3Fname.%0D%0A+++++%3Funiversity+dbo:numberOfStudents+%3Fstudents%0D%0A}+ORDER+BY+DESC(%3Fstudents)%0D%0ALIMIT+50"&gt;here&lt;/a&gt;! Here are the top 50, formatted from RDF into HTML via the &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;cd=5&amp;amp;ved=0CEgQFjAE&amp;amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FXSLT&amp;amp;ei=K7z9TJ31JoG0lQeg0-y1CA&amp;amp;usg=AFQjCNHdV2LfojcHFC70RiakUSLLXH9UlA"&gt;XSLT&lt;/a&gt; transformation provided with Snorql:&lt;/span&gt;&lt;div&gt;&lt;table class="sparql" border="1" style="font-family: 'Times New Roman'; "&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;name&lt;/th&gt;&lt;th&gt;students&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Indira Gandhi National Open University&lt;/td&gt;&lt;td&gt;3000000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;California Community Colleges System&lt;/td&gt;&lt;td&gt;2900000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;The Open University of China&lt;/td&gt;&lt;td&gt;2700000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Church Educational System&lt;/td&gt;&lt;td&gt;1200000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Florida College System&lt;/td&gt;&lt;td&gt;800000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universitas Terbuka&lt;/td&gt;&lt;td&gt;580458&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;အဝေးသင် တက္ကသိုလ် (ရန်ကုန်)&lt;/td&gt;&lt;td&gt;560000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;มหาวิทยาลัยรามคำแหง&lt;/td&gt;&lt;td&gt;525000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;City University of New York&lt;/td&gt;&lt;td&gt;483000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;The University System of Ohio&lt;/td&gt;&lt;td&gt;478367&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;State University of New York&lt;/td&gt;&lt;td&gt;438361&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;State University of New York&lt;/td&gt;&lt;td&gt;438361&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Bangladesh Open University&lt;/td&gt;&lt;td&gt;432767&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;বাংলাদেশ উন্মূক্ত বিশ্ববিদ্যালয়&lt;/td&gt;&lt;td&gt;432767&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;California State University&lt;/td&gt;&lt;td&gt;417112&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chicago Public Schools&lt;/td&gt;&lt;td&gt;407955&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Yashwantrao Chavan Maharashtra University&lt;/td&gt;&lt;td&gt;400000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Community College of the Air Force&lt;/td&gt;&lt;td&gt;351715&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Centre national d'enseignement à distance&lt;/td&gt;&lt;td&gt;350000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;University of Buenos Aires&lt;/td&gt;&lt;td&gt;308594&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universidad de Buenos Aires&lt;/td&gt;&lt;td&gt;308594&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;National Autonomous University of Mexico&lt;/td&gt;&lt;td&gt;305969&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universidad Nacional Autónoma de México&lt;/td&gt;&lt;td&gt;305969&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Oklahoma State System of Higher Education&lt;/td&gt;&lt;td&gt;236000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;University of Delhi&lt;/td&gt;&lt;td&gt;220000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DU&lt;/td&gt;&lt;td&gt;220000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;दिल्ली विश्वविद्यालय&lt;/td&gt;&lt;td&gt;220000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Cairo University&lt;/td&gt;&lt;td&gt;200000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Gāmaʿat al-Qāhirah&lt;/td&gt;&lt;td&gt;200000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;جامعة القاهرة&lt;/td&gt;&lt;td&gt;200000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;University of Guadalajara&lt;/td&gt;&lt;td&gt;195071&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;University of North Carolina&lt;/td&gt;&lt;td&gt;183000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Korea National Open University&lt;/td&gt;&lt;td&gt;182859&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universidad Bolivariana de Venezuela&lt;/td&gt;&lt;td&gt;180000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universidad Nacional de Educación a Distancia&lt;/td&gt;&lt;td&gt;180000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;National University for Distance Education&lt;/td&gt;&lt;td&gt;180000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;The Open University&lt;/td&gt;&lt;td&gt;168850&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universidad Autónoma de Santo Domingo&lt;/td&gt;&lt;td&gt;167533&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UASD&lt;/td&gt;&lt;td&gt;167533&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sharks&lt;/td&gt;&lt;td&gt;161668&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Miami Dade College&lt;/td&gt;&lt;td&gt;161668&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Studium Urbis&lt;/td&gt;&lt;td&gt;147000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sapienza – Università di Roma&lt;/td&gt;&lt;td&gt;147000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Modern University for the Humanities&lt;/td&gt;&lt;td&gt;140000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;University of Bikaner&lt;/td&gt;&lt;td&gt;140000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;University of London&lt;/td&gt;&lt;td&gt;135090&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universitas Londiniensis&lt;/td&gt;&lt;td&gt;135090&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universidade Norte do Paraná&lt;/td&gt;&lt;td&gt;130000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Norte do Paraná University&lt;/td&gt;&lt;td&gt;130000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Universidad Autónoma de Nuevo León&lt;/td&gt;&lt;td&gt;129341&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;http: org="" 2003="" 01="" geo="" lat=""&gt;&lt;http: org="" 2003="" 01="" geo="" long=""&gt;&lt;a href="http://dbpedia.org/snorql/?query=PREFIX+dbo:+%3Chttp://dbpedia.org/ontology/%3E%0D%0ASELECT+%3Fname+%3Fstudents+%3Flat+%3Flong+WHERE+{%0D%0A+++++%3Funiversity+rdf:type+dbo:University.%0D%0A+++++%3Funiversity+foaf:name+%3Fname.%0D%0A+++++%3Funiversity+dbo:numberOfStudents+%3Fstudents.%0D%0A+++++%3Funiversity+%3Chttp://www.w3.org/2003/01/geo/wgs84_pos%23lat%3E+%3Flat.%0D%0A+++++%3Funiversity+%3Chttp://www.w3.org/2003/01/geo/wgs84_pos%23long%3E+%3Flong%0D%0A}+ORDER+BY+DESC(%3Fstudents)%0D%0ALIMIT+50"&gt;Here&lt;/a&gt;&lt;/http:&gt;&lt;/http:&gt;'s a version that gives you (lat,long) coordinates too.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Mission accomplished. It looks like the Semantic Web is quite promising after all. I look forward to seeing a user interface which would allow me to construct that query and view the results visually within one browser window - including all vocabulary researching.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;What an incredible time to be alive - the collective body of human common knowledge is finally available for machines to process. I wonder what will come next.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3297803570256475595?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3297803570256475595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3297803570256475595' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3297803570256475595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3297803570256475595'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/12/querying-semantic-web.html' title='Querying the Semantic Web'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4580051659709688386</id><published>2010-11-29T17:00:00.000-08:00</published><updated>2010-11-29T15:13:36.701-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='gpgpu'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='kde4'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='cuda'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Hello!</title><content type='html'>Greetings! This blog is a collection of guides and technical notes for doing various things, mostly in &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/11/ubuntu-linux.html"&gt;Ubuntu Linux&lt;/a&gt;. Here is a list the entries I find myself going back to often:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;If you appreciate this site and want to support it, go for it!&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;form action="https://www.paypal.com/cgi-bin/webscr" method="post"&gt;&lt;input type="hidden" name="cmd" value="_s-xclick"&gt;&lt;input type="hidden" name="hosted_button_id" value="F3GQANSJMPBFS"&gt;&lt;input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"&gt;&lt;img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /&gt;&lt;/form&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;b&gt;Ubuntu&lt;/b&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/11/ubuntu-linux.html"&gt;Ubuntu Introduction&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/06/installation-scripts.html"&gt;Installation scripts&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Editors&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/04/eclipse-java-development-in-ubuntu.html"&gt;Installing Eclipse&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/03/learning-clojure-and-emacs.html"&gt;Emacs (and SLIME with Clojure)&lt;/a&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/05/rediscovering-emacs.html"&gt;Emacs Keystroke Reference&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/using-vim.html"&gt;Vim&lt;/a&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/03/flex-in-gedit.html"&gt;Flex in Gedit&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Java&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/01/installing-glassfish.html"&gt;Installing Glassfish&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/06/installing-jetty.html"&gt;Installing Jetty&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/06/deploying-war-in-jetty.html"&gt;Deploying a WAR file in Jetty&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/02/getting-started-with-jpa.html"&gt;Getting Started with Java Persistence API&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/11/interfacing-to-r-from-java.html"&gt;R and Java&lt;/a&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/03/grails.html"&gt;Getting started with Grails&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SQL:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/03/everyday-sql.html"&gt;Day to day SQL reference&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Flex&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/09/starting-to-learn-flash.html"&gt;Learning Flex&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/08/flex-builder-in-linux.html"&gt;Flexbuilder in Linux&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/01/flex-webservices-glassfish-eclipse.html"&gt;Flex, WebServices, Glassfish, Eclipse&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/03/using-open-source-flex-sdk.html"&gt;Using the Open Source Flex SDK&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Clojure&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/03/learning-clojure-and-emacs.html"&gt;Learning Clojure (and Emacs with SLIME)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/05/model-view-controller-gui-in-clojure.html"&gt;MVC in Clojure&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/04/opengl-in-clojure.html"&gt;OpenGL in Clojure&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/05/3d-grapher-in-clojure.html"&gt;3D Grapher in Clojure (using OpenGL)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;LaTeX&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/latex.html"&gt;Getting Started with LaTeX&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/10/algorithms-in-latex.html"&gt;Pseudocode&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/09/using-vim-for-latex.html"&gt;LaTeX in VIM&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/07/sweet-latex-development-setup.html"&gt;LaTeX in Emacs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Graphics&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/ways-to-install-nvidia-drivers-in.html"&gt;Installing Nvidia Drivers&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/06/opengl-glut-and-glew-in-eclipse.html"&gt;OpenGL in Eclipse&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/opengl-example-rendering-cylinders.html"&gt;OpenGL Cylinders and Spheres with inside test&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/05/cuda-development-in-ubuntu.html"&gt;Getting Started with CUDA in Ubuntu&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/using-vim-for-cuda.html"&gt;CUDA in VIM&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/using-eclipse-for-cuda-development.html"&gt;CUDA in Eclipse&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Wordpress&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/09/installing-wordpress-blog.html"&gt;Installing Wordpress&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/10/wordpress-email-notifications.html"&gt;Set up Email notifications&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Unix&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/11/recursive-word-count.html"&gt;Recursive word count&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/05/unix-magic-text-search-across-files.html"&gt;Text search across files&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/11/global-string-replace-in-all-php-files.html"&gt;String replacement across many files&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/batch-rename.html"&gt;batch rename&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/09/remove-files-by-type-in-unix.html"&gt;delete all but a given type of file&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/07/remove-all-svn-directories.html"&gt;remove all .svn directories&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/07/unix-redirection-to-black-hole.html"&gt;Redirect all output to a black hole&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Utilities&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/zipping-files-from-command-line.html"&gt;zipping and unzipping&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/06/command-line-svn-client.html"&gt;using SVN (version control) command line client&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/09/setting-background-with-command.html"&gt;Set the desktop background from the command line&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/09/setting-up-synergy.html"&gt;Setting Up Synergy&lt;/a&gt; (cross-computer keyboard and mouse sharing)&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/05/ubuntu-nvidia-dual-screen-setup.html"&gt;NVidia Dual Monitor setup&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/ubuntu-annoyances.html"&gt;Turn off the system beep and ALL system sounds&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/code-to-html.html"&gt;Code to HTML&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Projects&lt;/b&gt;:&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/03/sine-wave-instrument-with-puredata-and.html"&gt;Musical Instrument using Processing and PureData&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/03/frequency-modulation-pad-with-puredata.html"&gt;Frequency Modulation Pad with PureData and Processing&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/12/writing-synthesizer.html"&gt;Simple Synthesizer using JACK and QT&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/12/fretboard.html"&gt;Keyboard as Guitar Fretboard to Midi using JACK and QT&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/05/3d-grapher-in-clojure.html"&gt;3D Grapher using Clojure and OpenGL&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/04/tree-draws-well.html"&gt;Tiny Lisp Parser and Abstract Syntax Tree Visualizer in Java&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/03/sine-wave-instrument-with-puredata-and.html"&gt;&lt;/a&gt;&lt;br /&gt;All code and text on this blog is in the public domain, free to use and modify with no restrictions whatsoever.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;--&lt;a href="http://www.curransoft.com/"&gt;Curran&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4580051659709688386?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4580051659709688386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4580051659709688386' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4580051659709688386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4580051659709688386'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/06/hello.html' title='Hello!'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8183113402621210988</id><published>2010-11-23T13:50:00.000-08:00</published><updated>2010-11-23T14:19:30.639-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='principles'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><title type='text'>Design Axioms</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Axioms for Human Computer Interaction Design&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;An executive summary of the excellent article by &lt;a href="http://www.mit.edu/~juhan/"&gt;Juhan Sonin&lt;/a&gt; found at&lt;br /&gt;&lt;a href="http://www.mit.edu/~juhan/design_axioms.html"&gt;http://www.mit.edu/~juhan/design_axioms.html&lt;/a&gt;&lt;div&gt;&lt;a href="http://www.mit.edu/~juhan/design_axioms.html"&gt;&lt;/a&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Let data scream&lt;/b&gt; (screen real estate: 85% data, 15% UI)&lt;/li&gt;&lt;li&gt;Always &lt;b&gt;use real data&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Prototype&lt;/b&gt; like crazy (fast development iterations)&lt;/li&gt;&lt;li&gt;Address&lt;b&gt; layout, color, and interaction design&lt;/b&gt; from the start&lt;/li&gt;&lt;li&gt;&lt;b&gt;Allow users to bitch&lt;/b&gt; about your service quickly (1-click feedback)&lt;/li&gt;&lt;li&gt;&lt;b&gt;Dogfood&lt;/b&gt; your services&lt;/li&gt;&lt;li&gt;Ask for forgiveness rather than permission (&lt;b&gt;just&lt;/b&gt; &lt;b&gt;do&lt;/b&gt;)&lt;/li&gt;&lt;li&gt;Get &lt;b&gt;continual feedback&lt;/b&gt; in the &lt;b&gt;domain vernacular&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Use grid hierarchies&lt;/b&gt; and basic information layouts&lt;/li&gt;&lt;li&gt;When in doubt, &lt;b&gt;bang left&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Pay attention to &lt;b&gt;good typography practice&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Use less than 5 type treatments of only 1 type face&lt;/li&gt;&lt;li&gt;Use &lt;b&gt;better words and less of them&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Color carefully&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;The document&lt;/b&gt; should be center stage, &lt;b&gt;not the paint&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;What interface?&lt;/b&gt; Great interfaces disappear and have low cognitive overhead&lt;/li&gt;&lt;li&gt;People should be &lt;b&gt;engaging directly with the content&lt;/b&gt; (e.g. iPhone photo app)&lt;/li&gt;&lt;li&gt;&lt;b&gt;Manipulate the data&lt;/b&gt;, not the interface&lt;/li&gt;&lt;li&gt;Over time as you use a service or product, the &lt;b&gt;interface melts into the background&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Design first for the &lt;b&gt;repeat user&lt;/b&gt; (jedi), &lt;b&gt;then&lt;/b&gt; &lt;b&gt;novice&lt;/b&gt;, then the &lt;b&gt;infrequent/inexperienced&lt;/b&gt; user.&lt;/li&gt;&lt;li&gt;Experience breeds familiarity, and in interface design &lt;b&gt;familiarity promotes usability&lt;/b&gt;. &lt;/li&gt;&lt;li&gt;&lt;b&gt;Cognitive heat sink&lt;/b&gt;: I get it, feels right, go here... instead of oh yeah, I remember where that was&lt;/li&gt;&lt;li&gt;&lt;b&gt;Use keyboard shortcuts&lt;/b&gt; to supplement intuitive actions (enabling ninja speed)&lt;/li&gt;&lt;li&gt;&lt;b&gt;Design every second&lt;/b&gt; of the experience&lt;/li&gt;&lt;li&gt;&lt;b&gt;Performance&lt;/b&gt; ("snappiness") counts.&lt;/li&gt;&lt;li&gt;Products thrive (or wither) based on the &lt;b&gt;users’ experience&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-8183113402621210988?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8183113402621210988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8183113402621210988' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8183113402621210988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8183113402621210988'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/11/design-axioms.html' title='Design Axioms'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2557292581422904898</id><published>2010-08-27T16:43:00.001-07:00</published><updated>2010-08-29T17:55:39.361-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenStreetMap'/><title type='text'>Editing OpenStreetMap</title><content type='html'>Mapping a region and adding it to OpenStreetMap is a gratifying experience.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Today I thought I'd try out the &lt;a href="http://code.google.com/p/osmtracker-android/"&gt;OSMTracker Android app&lt;/a&gt;. I used it to record GPS traces of an unmapped area in Paxton, MA - walking trails near a small lake called Turkey Hill Pond. I rode my bike through the trails while the app was running. At the end I had these "GPX" files which I opened up in &lt;a href="http://josm.openstreetmap.de/"&gt;JOSM&lt;/a&gt; and used as the basis for adding new paths.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I noticed that the entire lake was missing so I installed the wms plugin for JOSM and used the Yahoo satellite images to trace out the lake. Tagging was straightforward once I found the &lt;a href="http://wiki.openstreetmap.org/wiki/Map_Features"&gt;tag definition page&lt;/a&gt;. I created an OSM account and uploaded the data, and within a few hours the image tiles were updated.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Here is a before and after screen capture of the OSM map:&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4933508370/" title="turkey hill pond edits by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4121/4933508370_d4bbf230c4.jpg" width="299" height="398" alt="turkey hill pond edits" /&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How cool! Its a great feeling to know I've contributed something, and that anyone who looks at this region in OSM in the future will see these trails.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next I'd like to map the Lowell state forest - there is no good map for all those trails.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2557292581422904898?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2557292581422904898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2557292581422904898' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2557292581422904898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2557292581422904898'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/08/editing-openstreetmap.html' title='Editing OpenStreetMap'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4121/4933508370_d4bbf230c4_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5194686271076702823</id><published>2010-08-24T09:04:00.000-07:00</published><updated>2010-08-24T12:59:27.506-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='flex builder'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Flex Builder in Linux</title><content type='html'>Here is how to get Flexbuilder working in Linux.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Set up the Flex 3.5 SDK:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd ~/opt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mkdir flex_sdk_3.5&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd flex_sdk_3.5&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://fpdownload.adobe.com/pub/flex/sdk/builds/flex3/flex_sdk_3.5.0.12683.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unzip flex_sdk_3.5.0.12683.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm flex_sdk_3.5.0.12683.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "PATH=\$PATH:\$HOME/opt/flex_sdk_3.5/bin" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Install Flexbuilder&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd ~/opt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mkdir flexbuilder&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd flexbuilder&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://download.macromedia.com/pub/labs/flex/flexbuilder_linux/flexbuilder_linux_install_a5_112409.bin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod +x flexbuilder_linux_install_a5_112409.bin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;./flexbuilder_linux_install_a5_112409.bin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now open Eclipse and add the Flex 3.5 SDK in Properties -&gt; Flex Compiler -&gt; Configure Flex SDKs -&gt; add -&gt; choose the folder ~/opt/flex_sdk_3.5 -&gt; ok -&gt; choose to use the "Flex 3.5" SDK.&lt;br /&gt;&lt;br /&gt;Theoretically that should do it, but at the time I did this (8/24/10) some additional steps were required. First I got the error&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;java.lang.IllegalArgumentException: "The attribute value type is  com.adobe.flexbuilder.project.compiler.internal.ProblemManager and  expected is one of java.lang.String, Boolean, Integer" &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;which is a result of &lt;a href="http://bugs.adobe.com/jira/browse/FB-21284"&gt;this bug&lt;/a&gt;. To fix this, follow the instructions &lt;a href="http://www.jamesward.com/2009/09/29/flex-builder-3-on-eclipse-3-5/"&gt;here&lt;/a&gt;. The instructions were not clear on this point: you need to copy the class file &lt;span style="font-style: italic;"&gt;into the inside of the jar&lt;/span&gt; file.&lt;br /&gt;&lt;br /&gt;The next error I had trouble with was the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;configuration variable 'target-player' must only be set once&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This persisted even after I went into Properties -&gt; Flex Compiler and unchecked the box that says "Require Flash Player version". It turns out that the player version is defined in the SDK in&lt;br /&gt;&lt;br /&gt;flex_sdk_3.5/frameworks/flex-config.xml&lt;br /&gt;&lt;br /&gt;I edited that file and commented out the line with the required player version. Even after this the error is still there for me... until I applied the patch described &lt;a href="http://blog.danyul.id.au/?p=68"&gt;here&lt;/a&gt;. Now FlexBuilder in Linux is working! Woo hoo!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5194686271076702823?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5194686271076702823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5194686271076702823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5194686271076702823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5194686271076702823'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/08/flex-builder-in-linux.html' title='Flex Builder in Linux'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3818659466942298164</id><published>2010-08-23T15:30:00.000-07:00</published><updated>2010-08-27T15:29:35.764-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drum machine'/><category scheme='http://www.blogger.com/atom/ns#' term='puredata'/><category scheme='http://www.blogger.com/atom/ns#' term='audio sampling'/><category scheme='http://www.blogger.com/atom/ns#' term='processing'/><title type='text'>RhythmSample</title><content type='html'>Here is a small project I did which lets you play several samples at several frequencies - quarter notes, eighth notes and sixteenth notes. The GUI is written in Java using Processing as a library. The audio generation is done using PureData, driven by messages sent from the Java GUI over a socket.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.curransoft.com/archive/RhythmSample-code.zip"&gt;Here&lt;/a&gt; is the code. To run it, first open the PureData patch (you can use the startPd.sh script for this or do it manually), then run the Java program. The Java code communicates to the PureData patch over a socket.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4932766373/" title="rhythmSample_pd by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4135/4932766373_5d009aa5b9.jpg" width="500" height="317" alt="rhythmSample_pd" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4921203553/" title="rhythmSample_window by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4100/4921203553_cc0cb0287c.jpg" width="398" height="426" alt="rhythmSample_window" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/archive/rhythmSample-sound.mp3"&gt;Here&lt;/a&gt; is how it sounds when played:&lt;br /&gt;&lt;object height="81" width="100%"&gt; &lt;param name="movie" value="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Fcurran%2Frhythmsample-sound&amp;amp;secret_url=false"&gt; &lt;param name="allowscriptaccess" value="always"&gt; &lt;embed allowscriptaccess="always" height="81" src="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Fcurran%2Frhythmsample-sound&amp;amp;secret_url=false" type="application/x-shockwave-flash" width="100%"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;span&gt;&lt;a href="http://soundcloud.com/curran/rhythmsample-sound"&gt;RhythmSample-sound&lt;/a&gt; by &lt;a href="http://soundcloud.com/curran"&gt;curran&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3818659466942298164?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3818659466942298164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3818659466942298164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3818659466942298164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3818659466942298164'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/08/rhythmsample.html' title='RhythmSample'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4135/4932766373_5d009aa5b9_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5871075597906184808</id><published>2010-06-17T07:44:00.000-07:00</published><updated>2010-06-17T11:33:27.342-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='error reporting'/><category scheme='http://www.blogger.com/atom/ns#' term='camel case'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='regular expressions'/><title type='text'>Slick Grails Error Reporting</title><content type='html'>Here's a slick way of nicely reporting errors using Grails' built-in validation machinery:&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package adminprototype&lt;br /&gt;class AdminController {&lt;br /&gt;  def index = { }&lt;br /&gt;  def createDatabaseConnection = {&lt;br /&gt;    render Utils.saveAndReport(&lt;br /&gt;      new DatabaseConnection(params))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;package adminprototype&lt;br /&gt;class Utils {&lt;br /&gt;  static String saveAndReport(Object o){&lt;br /&gt;    return o.save()?&amp;quot;success&amp;quot;:reportErrors(o)&lt;br /&gt;  }&lt;br /&gt;  static String reportErrors(Object o){&lt;br /&gt;    def error = o.errors.getFieldError()&lt;br /&gt;    String field = error.getField().toString()&lt;br /&gt;    field = field.replaceAll(&amp;quot;\\B([A-Z])&amp;quot;, &amp;quot; \$1&amp;quot;)&lt;br /&gt;    field = field.toLowerCase()&lt;br /&gt;    String bogus = error.getRejectedValue()&lt;br /&gt;    return &amp;quot;The &amp;quot;+field+&amp;quot; cannot be &amp;quot;+(bogus?bogus:&amp;quot;blank&amp;quot;)+&amp;quot;.&amp;quot;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Now if I leave out the field "databaseName" in a request like this:&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;http://localhost:8080/AdminPrototype/admin/createDatabaseConnection?port=1234&lt;/span&gt;&lt;br /&gt;I get a really nice error message with the camel case field name converted into a space delimited name:&lt;br /&gt;The database name cannot be blank.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5871075597906184808?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5871075597906184808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5871075597906184808' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5871075597906184808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5871075597906184808'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/06/slick-grails-error-reporting.html' title='Slick Grails Error Reporting'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8956086853527186284</id><published>2010-06-16T07:10:00.000-07:00</published><updated>2010-06-16T09:15:05.087-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetty'/><title type='text'>Installing Jetty</title><content type='html'>Unfortunately the Jetty Ubuntu package doesn't include what is needed for JNDI, namely the "jetty-plus" stuff. Here's how to install Jetty manually:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;mkdir ~/opt&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;cd ~/opt&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;wget http://download.eclipse.org/jetty/7.1.4.v20100610/dist/jetty-distribution-7.1.4.v20100610.zip&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;unzip jetty-distribution-7.1.4.v20100610.zip&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;mv jetty-distribution-7.1.4.v20100610 jetty&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;cd jetty&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0); "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0); "&gt;echo "&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;div&gt;export JETTY_HOME=`pwd`&lt;/div&gt;&lt;div&gt;export PATH=\$PATH:`pwd`/bin" &gt;&gt; ~/.bashrc&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;restart your terminal&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;One way to start Jetty is:&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0); "&gt;java -jar start.jar&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Now go to &lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;a href="http://localhost:8080/"&gt;http://localhost:8080/&lt;/a&gt; to test it.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Ctrl+c will stop this.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0); "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Jetty comes with a command line utility for starting and stopping Jetty as a service, here's how to use it:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;jetty.sh start&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;jetty.sh stop&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Links&lt;/div&gt;&lt;div&gt;&lt;a href="http://download.eclipse.org/jetty/"&gt;Jetty Download Page&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://wiki.eclipse.org/Jetty/Howto/Run_Jetty"&gt;Running Jetty&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/6461387352629250590-8956086853527186284?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8956086853527186284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8956086853527186284' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8956086853527186284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8956086853527186284'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/06/installing-jetty.html' title='Installing Jetty'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-9221796016495149921</id><published>2010-06-15T07:46:00.000-07:00</published><updated>2010-06-15T12:44:29.857-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WAR'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetty'/><title type='text'>Deploying a WAR in Jetty</title><content type='html'>&lt;b&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Here's how to deploy a WAR file in Jetty using the Ubuntu Jetty package:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;Install Jetty:&lt;/b&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;sudo apt-get install jetty -y&lt;/span&gt;&lt;/div&gt;&lt;div&gt;edit /etc/default/jetty so the 4th line reads&lt;/div&gt;&lt;div&gt;NO_START=0&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;To start Jetty:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;sudo /etc/init.d/jetty start&lt;/span&gt;&lt;/div&gt;&lt;div&gt;go to &lt;a href="http://localhost:8080/"&gt;http://localhost:8080/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To stop Jetty:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0); "&gt;sudo /etc/init.d/jetty stop&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0); "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;To list all commands:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;/etc/init.d/jetty6 help&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To deploy a WAR file, copy it into &lt;/div&gt;&lt;div&gt;/usr/share/jetty/webapps&lt;/div&gt;&lt;div&gt;and restart the server. The root URL of the web app will be http://localhost:8080/warfilename/ where warfilename is the name of your war file.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Links:&lt;/div&gt;&lt;div&gt;&lt;a href="http://docs.codehaus.org/display/JETTY/Newbie+Guide+to+Jetty"&gt;Newbie Guide to Jetty&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://docs.codehaus.org/display/JETTY/Debian+Packages"&gt;Jetty Debian package documentation&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://docs.codehaus.org/display/JETTY/DataSource+Examples"&gt;JNDI in Jetty&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/6461387352629250590-9221796016495149921?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/9221796016495149921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=9221796016495149921' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/9221796016495149921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/9221796016495149921'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/06/deploying-war-in-jetty.html' title='Deploying a WAR in Jetty'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1389545177379446894</id><published>2010-05-25T12:46:00.000-07:00</published><updated>2010-05-25T12:48:16.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><title type='text'>Unix Magic: text search across files</title><content type='html'>This command will find all occurrences of "table.sqlTable" across all files within the current directory and all subdirectories recursively (-r) and will give you line numbers (-n)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;grep -r -n "table.sqlTable" ./*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;oh yeah.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1389545177379446894?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1389545177379446894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1389545177379446894' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1389545177379446894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1389545177379446894'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/05/unix-magic-text-search-across-files.html' title='Unix Magic: text search across files'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1843509612777056537</id><published>2010-05-16T21:00:00.000-07:00</published><updated>2010-05-17T18:43:45.419-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='keyboard shortcuts'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Rediscovering Emacs</title><content type='html'>I get the idea that Emacs is all about power and efficiency, but somehow I fell out of using it because I would forget all those darn keystrokes and I had to USE the text editor RIGHT AWAY to get stuff done.&lt;br /&gt;&lt;br /&gt;But now my curiosity is again piqued. Is it really possible to do all code editing operations while keeping my hands in the standard position - no arrow keys and no mouse? That would be sweet, and worth the learning time.&lt;br /&gt;&lt;br /&gt;So here goes - a comprehensive documentary of relearning Emacs:&lt;br /&gt;&lt;br /&gt;To open Emacs and have it stay in the terminal, use&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;emacs -nw&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Basic Operations &lt;/span&gt;(C = ctrl, M = alt)&lt;br /&gt;C-x C-c = close Emacs&lt;br /&gt;C-x C-s = save file&lt;br /&gt;C-x s ! = save all open files&lt;br /&gt;&lt;div&gt;C-x C-f = open file&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cursor Navigation&lt;/span&gt;&lt;br /&gt;C-v = pg down&lt;br /&gt;M-v = pg up&lt;br /&gt;C-l = center on cursor text&lt;br /&gt;C-l C-l = cursor text to top&lt;br /&gt;C-l C-l C-l = cursor text to bottom&lt;br /&gt;C-p = up arrow&lt;br /&gt;C-n = down arrow&lt;br /&gt;C-f = right arrow&lt;br /&gt;C-b = left arrow&lt;br /&gt;M-f = forward a word&lt;br /&gt;M-b = back a word&lt;br /&gt;C-a = home (cursor to beginning of line)&lt;br /&gt;C-e = end (cursor to end of line)&lt;br /&gt;M-a = forward a sentence&lt;br /&gt;M-e = back a sentence&lt;br /&gt;M-&lt; = cursor to beginning of document M-&gt; = cursor to end of document&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Undo Redo&lt;/b&gt;&lt;/div&gt;&lt;div&gt;C-/ = Undo&lt;/div&gt;&lt;div&gt;C-/ [do stuff] C-/ = Redo (undoing previous undos)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Editing Text&lt;/b&gt;&lt;/div&gt;&lt;div&gt;? = backspace&lt;/div&gt;&lt;div&gt;C-d = delete&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;div&gt;&lt;b&gt;Essentials for Coding&lt;/b&gt;&lt;/div&gt;&lt;div&gt;C-j = intelligent newline (accounts for indentation)&lt;/div&gt;&lt;div&gt;Mark a region (for example M-&gt; M-&lt;&gt;&lt;div&gt;C-M-\ = auto-indent region &lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;div style="display: inline ! important;"&gt;(auto-indent, auto-format)&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;M-g g = go to line&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;M-/ = autocomplete word&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;&lt;b&gt;Search and Replace&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;C-s = search forward&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;C-r = search backward&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;C-M-s = regex search&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;M-% = incremental search and replace&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline ! important;"&gt;M-x replace-string = global search and replace&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;Selecting, Copying, Pasting, and Marking&lt;/span&gt;&lt;br /&gt;C-spacebar = set mark on cursor&lt;br /&gt;Shift+(any cursor navigation) = set mark on cursor&lt;/div&gt;&lt;div&gt;C-x C-x = swap mark and cursor&lt;/div&gt;&lt;div&gt;C-u C-SPC = cycle through mark ring (previous 16 marks)&lt;/div&gt;&lt;div&gt;region = the text between the last set mark and the cursor&lt;br /&gt;M-w = copy region&lt;br /&gt;C-w = cut region&lt;/div&gt;&lt;div&gt;C-k = cut from cursor to end of line&lt;br /&gt;C-y = paste&lt;/div&gt;&lt;div&gt;M-y = replace pasted text with previously copied text (scrolls through copy history)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Arguments&lt;/span&gt;&lt;br /&gt;Arguments can be passed to any text editing or navigation operation:&lt;br /&gt;C-u 123 = give '123' or whatever number you type as an argument to the operation you are about to do.&lt;br /&gt;M-123 = the same thing. For example,&lt;br /&gt;C-u 100 * = M-100 * = type 100 '*' characters&lt;br /&gt;C-u 8 C-v = M-8 C-v = scroll up 8 lines&lt;br /&gt;M-x z = repeat command&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cancel&lt;/span&gt;&lt;br /&gt;C-g = cancel anything (scrap arguments, or cancel pending operation)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Macros&lt;/span&gt;&lt;br /&gt;You can record a sequence of operations and then play it back repeatedly:&lt;/div&gt;&lt;div&gt;F3 = start recording macro (stuff you do is recorded)&lt;/div&gt;&lt;div&gt;F4 = stop recording macro&lt;/div&gt;&lt;div&gt;F4 = execute recorded macro&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;div&gt;&lt;b&gt;Buffers&lt;/b&gt;&lt;/div&gt;&lt;div&gt;When you have multiple files open, they are in "buffers".&lt;/div&gt;&lt;div&gt;C-x C-b = list buffers&lt;/div&gt;&lt;div&gt;C-x b = switch to buffer&lt;/div&gt;&lt;div&gt;C-x k = close buffer&lt;/div&gt;&lt;div&gt;C-x rightArrow = next buffer&lt;/div&gt;&lt;div&gt;C-x leftArrow = previous buffer&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Windows&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;You can have many files open at once, either in their own "window" (screen partition) or in offscreen "buffers" (like tabs).&lt;br /&gt;C-x 2 = split window vertically&lt;br /&gt;C-x 3 = split window horizontally&lt;br /&gt;C-x o (letter o)= move cursor between windows&lt;br /&gt;C-x 0 (number zero) = close window&lt;br /&gt;C-x } = expand window horizontally&lt;br /&gt;C-x { = contract window horizontally&lt;br /&gt;M-x z = repeat command (useful with C-x } and C-x {)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Variables&lt;/b&gt;&lt;/div&gt;&lt;div&gt;C-h v var RET = view variable value and documentation&lt;/div&gt;&lt;div&gt;M-x set-variable RET var RET value RET = set variable value&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;File Browsing and Manipulation&lt;/b&gt;&lt;/div&gt;&lt;div&gt;M-x dired = DIRectory EDitor (see &lt;a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Dired.html"&gt;manual&lt;/a&gt;)&lt;/div&gt;&lt;div&gt;...once in dired...&lt;br /&gt;C-x C-q =  make dired writable, so editing names as text renames actual files.&lt;/div&gt;&lt;div&gt;f = go into directory&lt;/div&gt;&lt;div&gt;^ = go up out of current directory&lt;/div&gt;&lt;div&gt;To &lt;a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Dired-Deletion.html#Dired-Deletion"&gt;delete files&lt;/a&gt;:&lt;br /&gt;&lt;div&gt;d = flag file for deletion&lt;/div&gt;&lt;div&gt;u = unflag file for deletion&lt;/div&gt;&lt;div&gt;x = delete files flagged for deletion&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Diff&lt;/b&gt;&lt;/div&gt;&lt;div&gt;M-x ediff&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Case&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://jamesthornton.com/emacs/node/emacs_244.html"&gt;http://jamesthornton.com/emacs/node/emacs_244.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Miscellaneous Linux Keyboard Tips&lt;/span&gt;&lt;br /&gt;M-Tab = switch between windows&lt;br /&gt;C-M-rightArrow = switch desktop right&lt;br /&gt;C-M-leftArrow = switch desktop left&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Version Control&lt;/b&gt;&lt;/div&gt;&lt;div&gt;see &lt;a href="http://www.gnu.org/software/emacs/tour/"&gt;http://www.gnu.org/software/emacs/tour/&lt;/a&gt; search for "Version Control"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Groovy in Emacs&lt;/span&gt;&lt;br /&gt;Download groovy-mode:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo wget http://svn.groovy.codehaus.org/browse/~raw,r=HEAD/groovy/trunk/groovy/ide/emacs/groovy-mode.el -O /usr/share/emacs23/site-lisp/groovy-mode.el&lt;/span&gt;&lt;br /&gt;You might need to replace 23 with your version number.&lt;br /&gt;&lt;br /&gt;Put this in ~/.emacs:&lt;br /&gt;&lt;pre class="code-java"&gt;;;; turn on syntax hilighting&lt;br /&gt;(global-font-lock-mode 1)&lt;br /&gt;&lt;br /&gt;;;; use groovy-mode when file ends in .groovy or has #!/bin/groovy at start&lt;br /&gt;(autoload 'groovy-mode &lt;span class="code-quote"&gt;"groovy-mode"&lt;/span&gt; &lt;span class="code-quote"&gt;"Groovy editing mode."&lt;/span&gt; t)&lt;br /&gt;(add-to-list 'auto-mode-alist '(&lt;span class="code-quote"&gt;"\.groovy$"&lt;/span&gt; . groovy-mode))&lt;br /&gt;(add-to-list 'interpreter-mode-alist '(&lt;span class="code-quote"&gt;"groovy"&lt;/span&gt; . groovy-mode))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/Emacs+Plugin"&gt;Groovy mode&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Dired.html"&gt;Dired manual&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://lpn.rnbhq.org/tools/xemacs/emacs_ref.html"&gt;Emacs Commands List&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.gnu.org/software/emacs/tour/"&gt;Guided tour of emacs&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1843509612777056537?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1843509612777056537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1843509612777056537' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1843509612777056537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1843509612777056537'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/05/rediscovering-emacs.html' title='Rediscovering Emacs'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4747195132159262769</id><published>2010-04-18T13:15:00.000-07:00</published><updated>2010-06-11T05:58:03.551-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='protege'/><category scheme='http://www.blogger.com/atom/ns#' term='ontology'/><category scheme='http://www.blogger.com/atom/ns#' term='semantic web'/><category scheme='http://www.blogger.com/atom/ns#' term='owl'/><title type='text'>Installing Protege</title><content type='html'>Here's how to install the &lt;a href="http://protege.stanford.edu/"&gt;Protege&lt;/a&gt; ontology editor in Ubuntu Linux:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Download Protege&lt;/b&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;wget http://protege.stanford.edu/download/protege/4.1/installanywhere/InstData/Linux/NoVM/install_protege_4.1.bin&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;b&gt;Run the Installer&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;sh ./install_protege_4.1.bin&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This will pop up a GUI installer. &lt;/div&gt;&lt;div&gt;I chose as my install directory "~/opt/Protege_4.1/", but anywhere will work.&lt;/div&gt;&lt;div&gt;Click through until you are done.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Run Protege&lt;/b&gt;&lt;/div&gt;&lt;div&gt;To run Protege, execute&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;/home/curran/opt/Protege_4.1/Protege&lt;/span&gt;&lt;/div&gt;&lt;div&gt;replacing &lt;span class="Apple-style-span"  style="color:#006600;"&gt;/home/curran/opt&lt;/span&gt; with your Protege location.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Set up Protege as a command:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;To set up "Protege" as a command, add the Protege directory to your PATH environment variable as follows:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;echo "&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;export PATH=\$PATH:\$HOME/&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;opt/Protege_4.1/" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;replacing the details with the location you chose. Restart your terminal and now run the command (note upper case P)&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;Protege&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Enjoy!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4747195132159262769?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4747195132159262769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4747195132159262769' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4747195132159262769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4747195132159262769'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/04/installing-protege.html' title='Installing Protege'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3450616045262476972</id><published>2010-04-10T17:17:00.000-07:00</published><updated>2010-04-10T17:22:04.611-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gedit'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails in Gedit</title><content type='html'>To install Grails plugin for Gedit:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd ~/opt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;git clone git://github.com/aeischeid/gedit-grails-bundle.git&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd gedit-grails-bundle/grails-gedit/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; sudo ./install.sh&lt;/span&gt;&lt;br /&gt;Restart Gedit and woo hoo!&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://www.grails.org/Gedit"&gt;Grails Gedit page on Grails site&lt;/a&gt;&lt;br /&gt;&lt;a href="http://github.com/aeischeid/gedit-grails-bundle"&gt;gedit-grails-bundle in GitHub&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3450616045262476972?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3450616045262476972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3450616045262476972' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3450616045262476972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3450616045262476972'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/04/grails-in-gedit.html' title='Grails in Gedit'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3362358876779227351</id><published>2010-03-30T19:09:00.000-07:00</published><updated>2010-04-25T09:30:33.637-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gedit'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Flex in Gedit</title><content type='html'>Man I really do like coding in simple environments - it's like walking barefoot on the beach. So, I figured, why not get acquainted with Flex not through sluggish autocompletions and feigned build magic, but rather by relying only on solid tooling, a simple text editor, and documentation.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4477468137/" title="codeswamp by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2789/4477468137_71bf46c381.jpg" alt="codeswamp" border="0" width="500" height="322" /&gt;&lt;/a&gt;&lt;br /&gt;The mxml is legible and colorful, while the actionscript demands a more focused eye and takes longer to digest. This is the default syntax highlighting of mxml in Gedit - as XML. There is no built-in support for mxml and actionscript.&lt;br /&gt;&lt;br /&gt;Luckily, &lt;a href="http://conic.se/blog/posts/8/"&gt;someone has created mxml and as3 language definitions&lt;/a&gt; compatible with Gedit. Here's how to install them:&lt;br /&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;cd /usr/share/gtksourceview-2.0/language-specs&lt;br /&gt;sudo wget http://conic.se/static/blog/code/Langfiles/actionscript.lang&lt;br /&gt;sudo wget http://conic.se/static/blog/code/Langfiles/MXML.lang&lt;br /&gt;sudo update-mime-database /usr/share/mime&lt;/span&gt;&lt;br /&gt;restart Gedit, and voila!&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4478190848/" title="balance by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4006/4478190848_5549183bf9.jpg" alt="balance" width="500" height="350" /&gt;&lt;/a&gt;&lt;br /&gt;Balance. Much improved legibility.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;In Windows&lt;/span&gt;&lt;br /&gt;The parallel to&lt;br /&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;/usr/share/gtksourceview-2.0/language-specs&lt;/span&gt;&lt;br /&gt;in a Windows Gedit installation is&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;C:\Program Files\gedit\share\gtksourceview-2.0\language-specs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Put the MXML.lang file there and restart Gedit.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A Fix for fx:Script and mx:Script&lt;/span&gt;&lt;br /&gt;Initially, the MXML.lang file does not handle the new fx:Script tag, which makes it impossible to use with Flex 4 code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4550799839/" title="gedit_ugly_fx_script by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4024/4550799839_61f49d7a32.jpg" alt="gedit_ugly_fx_script" width="500" height="271" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A partial solution is to replace all occurences of "mx:" with "fx:" in &lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);"&gt;MXML.lang. This will make fx:Script work, but will break mx:Script.&lt;br /&gt;&lt;br /&gt;I was able to get Gedit to recognize both the mx:Script and fx:Script tags by editing the MXML.lang file:&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;sudo gedit &lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;/usr/share/gtksourceview-2.0/language-specs/MXML.lang&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);"&gt;and &lt;span style="color: rgb(0, 153, 0);"&gt;adding&lt;/span&gt; the following code&lt;br /&gt;&lt;pre   style="color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;lt;context id="actionscriptfx"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;start&amp;gt;&amp;amp;lt;fx:Script&amp;amp;gt;&amp;lt;/start&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;end&amp;gt;&amp;amp;lt;/fx:Script&amp;amp;gt;&amp;lt;/end&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;  &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;include&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;context sub-pattern="0" where="start" style-ref="element-name"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;context sub-pattern="0" where="end" style-ref="element-name"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;context ref="element-name"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;context id="actionscript-codefx" extend-parent="false"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       &amp;lt;start&amp;gt;&amp;amp;lt;!\[CDATA\[&amp;lt;/start&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       &amp;lt;end&amp;gt;\]\]&amp;amp;gt;&amp;lt;/end&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       &amp;lt;include&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;           &amp;lt;context sub-pattern="0" where="start" style-ref="cdata-delim"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;           &amp;lt;context sub-pattern="0" where="end" style-ref="cdata-delim"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;           &amp;lt;context ref="actionscript:actionscript"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       &amp;lt;/include&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;/context&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   &amp;lt;/include&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;lt;/context&amp;gt;&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;context id="mxml"&amp;gt;&lt;br /&gt;&amp;lt;include&amp;gt;&lt;br /&gt;&amp;lt;context ref="comment"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="doctype"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="actionscript"/&amp;gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;context ref="actionscriptfx"&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;context ref="cdata"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="prolog"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="processing-instruction"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="start-tag"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="end-tag"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="entity"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="character-reference"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="unallowed-chars"/&amp;gt;&lt;br /&gt;&amp;lt;context ref="close-tag-outside-tag"/&amp;gt;&lt;br /&gt;&amp;lt;/include&amp;gt;&lt;br /&gt;&amp;lt;/context&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Then run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;sudo update-mime-database /usr/share/mime&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;and restart Gedit.&lt;br /&gt;&lt;br /&gt;Update: After all that work I found out there is an up to date version here:&lt;br /&gt;http://github.com/julien/gedit_flex&lt;br /&gt;will update this post once I try it out.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3362358876779227351?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3362358876779227351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3362358876779227351' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3362358876779227351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3362358876779227351'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/03/flex-in-gedit.html' title='Flex in Gedit'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2789/4477468137_71bf46c381_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3435244480589045475</id><published>2010-03-27T20:23:00.000-07:00</published><updated>2010-03-30T19:45:04.065-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sdk'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Using the Open Source Flex SDK</title><content type='html'>I'd like to do some Flex development without Flexbuilder. Here's how I got the open source SDK working in Ubuntu Linux:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Installing:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Download the SDK from the &lt;a href="http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex4sdk"&gt;download page&lt;/a&gt;. Unzip its contents to ~/opt/flex as follows:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;cd ~/Downloads&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;unzip flex_sdk_4.zip -d ~/opt/flex&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Add the Flex bin directory to your PATH:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;echo "PATH=\$PATH:\$HOME/opt/flex/bin" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;restart your terminal. Now you should have the mxmlc command and other Flex command line tools available:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Writing Hello World:&lt;/div&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;body {&lt;br /&gt;height: 100%;&lt;br /&gt;width: 100%;&lt;br /&gt;margin: 0;&lt;br /&gt;}&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;object width="550" height="400"&amp;gt;&lt;br /&gt;&amp;lt;param name="movie" value="hello.swf"&amp;gt;&lt;br /&gt;&amp;lt;embed src="hello.swf" width="100%" height="100%"&amp;gt;&lt;br /&gt;&amp;lt;/embed&amp;gt;&lt;br /&gt;&amp;lt;/object&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Here we have a typical HTML page for displaying a .swf file. And below is a "Hello World" mxml file.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&amp;gt;&lt;br /&gt;   &amp;lt;mx:Label text="Hello World!"/&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;You can download, compile, and run these files as follows:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.curransoft.com/code/hello/hello.mxml http://www.curransoft.com/code/hello/hello.html&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mxmlc hello.mxml&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;firefox hello.html&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There you go!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3435244480589045475?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3435244480589045475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3435244480589045475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3435244480589045475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3435244480589045475'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/03/using-open-source-flex-sdk.html' title='Using the Open Source Flex SDK'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5914585936399721685</id><published>2010-03-26T21:46:00.000-07:00</published><updated>2010-03-27T10:13:19.446-07:00</updated><title type='text'>Hilarious</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;I find this set of instructions very funny, from the kind folks at &lt;a href="http://www.itis.gov/downloads/"&gt;ITIS&lt;/a&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;3. Installation instructions.&lt;br /&gt;&lt;br /&gt; Windows Instructions&lt;br /&gt;&lt;br /&gt;   After downloading the ITIS MySQL zip file, that&lt;br /&gt;   file "itisMySQL111908.zip" will now reside on your&lt;br /&gt;   system as a Compressed (zipped) Folder.&lt;br /&gt;&lt;br /&gt;   Use WinZip or some other software to extract the&lt;br /&gt;   following 4 files from your downloaded ITIS zip file:&lt;br /&gt;     installdb.bat createdb.sql ITIS.sql ReadmeMySQL.txt&lt;br /&gt;&lt;br /&gt;   Use "My Computer" to go to where you have&lt;br /&gt;   extracted those 4 files.&lt;br /&gt;&lt;br /&gt;   On your Windows system, make sure that&lt;br /&gt;   you can run the MySQL software as the&lt;br /&gt;   MySQL user root on your PC.&lt;br /&gt;&lt;br /&gt;   If you can't run MySQL as the MySQL user root&lt;br /&gt;   on your PC then edit file "installdb.bat"&lt;br /&gt;   and replace root with your chosen MySQL user name.&lt;br /&gt;&lt;br /&gt;   Make sure that the MySQL Server is running on&lt;br /&gt;   your PC prior to double clicking on the icon.&lt;br /&gt;&lt;br /&gt;   Caution:  When you install this new ITIS database&lt;br /&gt;   in MySQL on your PC, the SQL command to drop any&lt;br /&gt;   preexisting database called "itis" is first executed&lt;br /&gt;   before creating and loading the new "itis" database.&lt;br /&gt;&lt;br /&gt;   To install the ITIS database onto MySQL on your PC,&lt;br /&gt;   double click on the icon:&lt;br /&gt;      installdb.bat&lt;br /&gt;&lt;br /&gt;   Note: You will be prompted for your MySQL password after&lt;br /&gt;   clicking on the icon.&lt;br /&gt;   Be patient when waiting for the data to load into MySQL.&lt;br /&gt;   The loading of the data may take 2 minutes or more.&lt;br /&gt;&lt;br /&gt; Linux Instructions&lt;br /&gt;&lt;br /&gt;   On Linux, execute the following command:&lt;br /&gt;     mysql -uroot -p &amp;lt; createdb.sql&lt;br /&gt;&lt;br /&gt;   Note: You may use a different MySQL user name other than root.&lt;br /&gt;&lt;br /&gt; Mac OS X Instructions&lt;br /&gt;&lt;br /&gt;   On Mac OS X, execute the following command:&lt;br /&gt;     mysql -uroot -p &amp;lt; createdb.sql&lt;br /&gt;&lt;br /&gt;   Note: Again, you may use a different MySQL user name other than root.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5914585936399721685?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5914585936399721685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5914585936399721685' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5914585936399721685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5914585936399721685'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/03/hilarious.html' title='Hilarious'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5627506787887269094</id><published>2010-03-26T09:22:00.001-07:00</published><updated>2010-03-26T13:08:28.828-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='CSV'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Everyday SQL</title><content type='html'>I have been using SQL from time to time with no formal database education, and find myself looking up the same stuff over and over, so I thought I'd collect solutions for such common things here for reference.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Setting up:&lt;/span&gt;&lt;br /&gt;I'm using Ubuntu and MySQL. To install MySQL:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install mysql-server mysql-client -y&lt;/span&gt;&lt;br /&gt;This installer will prompt you for a root password.&lt;br /&gt;To run the command line SQL client as the SQL root user:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql -u root -p&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;-u&lt;/span&gt; means user, &lt;span style="color: rgb(0, 102, 0);"&gt;-p&lt;/span&gt; means it will prompt for a password. Now you should be at an SQL terminal that looks like this:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; &lt;/span&gt;&lt;br /&gt;To list databases:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; SHOW DATABASES;&lt;/span&gt;&lt;br /&gt;To "use" a database (which is akin to "cd" in Unix), for example the "information_schema" database built into MySQL:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; USE information_schema;&lt;/span&gt;&lt;br /&gt;To list tables:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; SHOW TABLES;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;By the way, the convention for SQL is to use upper case, but it is case insensitive, so&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; show tables;&lt;br /&gt;&lt;/span&gt;would work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creating a Database:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; CREATE DATABASE test;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; USE test;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creating a table:&lt;/span&gt;&lt;br /&gt;with column "foo" of type string with max length 5 and column "bar" of type int:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;CREATE TABLE test (foo VARCHAR(5),bar INTEGER);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Inserting values (adding rows):&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; INSERT INTO test VALUES ("A",1);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; INSERT INTO test VALUES ("B",2);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; INSERT INTO test VALUES ("C",3);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Querying for everything:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; SELECT * FROM test;&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;+------+------+&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| foo  | bar  |&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;+------+------+&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| A    |    1 | &lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| B    |    2 | &lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| C    |    3 | &lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;+------+------+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;3 rows in set (0.00 sec)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Querying for a specific field:&lt;/span&gt;&lt;br /&gt;backticks are used for quoting but are not necessary for column names without spaces.&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;SELECT `foo` FROM test;&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;+------+&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| foo  |&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;+------+&lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| A    | &lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| B    | &lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;| C    | &lt;/span&gt;&lt;br /&gt;&lt;span style=" color: rgb(0, 102, 0);font-family:courier new;"&gt;+------+&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Querying with a filter:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; SELECT * FROM test WHERE foo='B' or foo='C';&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-family:courier new;"&gt;+------+------+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-family:courier new;"&gt;| foo  | bar  |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-family:courier new;"&gt;+------+------+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-family:courier new;"&gt;| B    |    2 | &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-family:courier new;"&gt;| C    |    3 | &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-family:courier new;"&gt;+------+------+&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Deleting specific records:&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; DELETE FROM test WHERE foo='B' or foo='C';&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Deleting a table:&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; DROP TABLE test;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Deleting a database&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; DROP DATABSE test;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Exiting:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; exit&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;Bye&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Reading a CSV file:&lt;/span&gt;&lt;br /&gt;From a unix shell, I'll download a sample CSV file:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.curransoft.com/data/iris.csv&lt;/span&gt;&lt;br /&gt;Go into the SQL shell:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql -u root -p&lt;/span&gt;&lt;br /&gt;Create an empty table with column names and types mirroring the CSV:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; USE test;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; CREATE TABLE `iris` (`SepalLength` float,`SepalWidth` float,`PetalLength` float,`PetalWidth` float,`Class` varchar(20));&lt;/span&gt;&lt;br /&gt;Load in the CSV file with the following SQL:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;LOAD DATA LOCAL INFILE 'iris.csv'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;INTO TABLE iris&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;FIELDS TERMINATED BY ','&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ENCLOSED BY '"'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;LINES TERMINATED BY '\n'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;(`SepalLength`,`SepalWidth`,`PetalLength`,`PetalWidth`,`Class`);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The delimiter is specified by &lt;span style="color: rgb(0, 102, 0);"&gt;FIELDS TERMINATED BY&lt;br /&gt;&lt;/span&gt;The quote symbol is specified by &lt;span style="color: rgb(0, 102, 0);"&gt;ENCLOSED BY&lt;br /&gt;&lt;/span&gt;The newline symbol is specified by &lt;span style="color: rgb(0, 102, 0);"&gt;LINES TERMINATED BY&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;/span&gt;The rest specifies which columns to map the CSV columns to.&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Dumping a table to a SQL script file:&lt;/span&gt;&lt;br /&gt;The mysqldump utility generates a SQL script for recreating a given table. It outputs to stdout, so its output must be redirected to a file. From a unix shell, here's how to output the iris table into iris.sql:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysqldump test iris -u root -p &gt; iris.sql&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;Loading a SQL script (backup file):&lt;/span&gt;&lt;br /&gt;This will load the generated iris.sql file, which creates and populates the iris table on the currently used database.&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; source iris.sql;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Giving access to the outside:&lt;/span&gt;&lt;br /&gt;To open your MySQL instance to the outside world, you first need to modify my.cnf:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo gedit /etc/mysql/my.cnf&lt;/span&gt;&lt;br /&gt;such that&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;bind-address = your_ip&lt;/span&gt;&lt;br /&gt;where your_ip is the "inet addr" field of the output of the command&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;ifconfig&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The second thing you need to do is grant access to a specific user name and password for a specific computer:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; GRANT ALL ON database_name.table_name to 'username'@'client_ip' identified by 'password';&lt;/span&gt;&lt;br /&gt;for example:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; GRANT ALL ON test.* to 'fred'@'192.168.45.32' identified by 'fred123';&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;div&gt;&lt;b&gt;Start/Stop/Restart the MySQL server:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;sudo /etc/init.d/mysql start&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;sudo /etc/init.d/mysql stop&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;sudo /etc/init.d/mysql restart&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Enjoy!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5627506787887269094?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5627506787887269094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5627506787887269094' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5627506787887269094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5627506787887269094'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/03/everyday-sql.html' title='Everyday SQL'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-7660398999595453554</id><published>2010-03-25T13:20:00.000-07:00</published><updated>2010-06-18T02:16:38.836-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='environment variables'/><category scheme='http://www.blogger.com/atom/ns#' term='JAVA_HOME'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails</title><content type='html'>I decided to try out Grails in Ubuntu. Here's what I did to get Grails up and running:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Installation:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Download the Grails binary from the &lt;a href="http://www.grails.org/Download"&gt;Grails download page&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;Unzip it into ~/opt, so everything will end up in ~/opt/grails-1.3.0 or whatever version you get. This directory will be GRAILS_HOME.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We will also need to set JAVA_HOME. You can see a list of installed JDKs (DO NOT use a JRE for JAVA_HOME) by executing&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;sudo update-alternatives --config javac&lt;/span&gt;&lt;/div&gt;&lt;div&gt;My machine shows only one: /usr/lib/jvm/java-6-openjdk/bin/javac, which I'll use as JAVA_HOME, minus the /bin/javac.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To set JAVA_HOME, GRAILS_HOME, and append the Grails bin directory to PATH, execute the following as a single command in a terminal (shift+insert to paste) with your correct paths substituted (this command appends the text to the end of .bashrc, which is executed every time a shell starts):&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;echo "&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;export JAVA_HOME=/usr/lib/jvm/java-6-openjdk&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;export GRAILS_HOME=\$HOME/opt/grails-1.3.0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;export PATH=\$PATH:\$HOME/opt/grails-1.3.0/bin" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Restart the terminal.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Quick Start:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Now lets run through the &lt;a href="http://www.grails.org/Quick+Start"&gt;quick start&lt;/a&gt;:&lt;/div&gt;&lt;div&gt;grails create-app takes the name of the project as an argument, for which it creates a project directory. I'm going to make a project in ~/grailsCode/book as follows:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;cd ~/&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;mkdir grailsCode&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;cd grailsCode&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;grails create-app book&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This creates the directory book with a bunch of stuff in it.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;cd book&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;grails create-domain-class book&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This creates a directory structure and groovy file for a "book" domain class. Edit this file:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/domain/book/Book.groovy&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;such that it contains&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package book&lt;br /&gt;&lt;br /&gt;class Book {&lt;br /&gt;String title&lt;br /&gt;String author&lt;br /&gt;static constraints = {&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now add some test data by editing this file&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/conf/BootStrap.groovy&lt;/span&gt;&lt;/div&gt;&lt;div&gt;such that it contains&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;import book.*&lt;br /&gt;class BootStrap {&lt;br /&gt;&lt;br /&gt;def init = { servletContext -&amp;gt;&lt;br /&gt;// Create some test data&lt;br /&gt;new Book(author:"Stephen King",title:"The Shining").save()&lt;br /&gt;new Book(author:"James Patterson",title:"Along Came a Spider").save()&lt;br /&gt;}&lt;br /&gt;def destroy = {&lt;br /&gt;}&lt;br /&gt;} &lt;/code&gt;&lt;/pre&gt;&lt;div&gt;"import book.*" is not in the original quick start. I think at some point in the past Grails did not use packages for its domain classes, and the quick start has not been updated? Now it does use packages, so the class name "Book" is not recognized without importing "book.Book" or "book.*".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Now create a controller:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;grails create-controller book&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Now edit the file&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/controllers/book/BookController.groovy&lt;/span&gt;&lt;/div&gt;&lt;div&gt;such that is contains&lt;/div&gt;&lt;div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package book&lt;br /&gt;&lt;br /&gt;class BookController {&lt;br /&gt;&lt;br /&gt;def scaffold = Book&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;(yes, you must remove "def index = { }", otherwise it will not work)&lt;/div&gt;&lt;div&gt;Now run&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;grails run-app&lt;/span&gt;&lt;/div&gt;&lt;div&gt;You should eventually see "Server running. Browse to http://localhost:8080/book"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I first ran this, I got the error &lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Error executing script RunApp: : Error starting Sun's native2ascii:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;This was because my JAVA_HOME was pointing to a JRE instead of a JDK. I changed it to point to a JDK (and updated the instructions above) and it worked!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So at http://localhost:8080/book I find a sweet autogenerated GUI for creating, removing, and listing Books!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4467517164/" title="Grails-book-list-Screenshot by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2788/4467517164_663a533df0_o.png" alt="Grails-book-list-Screenshot" height="246" width="394" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is so much magic happening I am a bit overwhelmed. What is responsible for that GUI? Where is the data stored? How can I change the home page display? Lots of questions, but at least I'm up and running.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Using MySQL:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;A Grails project uses an in-memory HSQLDB database by default, which is wiped out every time you change the code or restart. I'd like to configure it to use a local MySQL instance, and to not delete the data on restart. Here's how to do this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Create the database to use and grant access to a "grails" user:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;mysql -u root -p&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;mysql&gt; CREATE DATABASE book;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;mysql&gt; GRANT ALL ON book.* TO 'grails'@'localhost' IDENTIFIED BY 'g123';&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Edit the file&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/conf/DataSource.groovy&lt;/span&gt;&lt;/div&gt;&lt;div&gt;such that it contains&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;...leave the rest of the file the same...&lt;br /&gt;environments {&lt;br /&gt;development {&lt;br /&gt;dataSource {&lt;br /&gt;pooled = true&lt;br /&gt;dbCreate = "update"&lt;br /&gt;url = "jdbc:mysql://localhost/book"&lt;br /&gt;driverClassName = "com.mysql.jdbc.Driver"&lt;br /&gt;username = "grails"&lt;br /&gt;password = "g123"&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Now we need the MySQL Connector jar, which we could go download and stick in the lib directory, but there is a better way. We can instead add the jar as a dependency using Grails' built-in dependency management system built on &lt;a href="http://ant.apache.org/ivy/"&gt;Apache Ivy&lt;/a&gt; using the Maven central repository as follows (the build system will download the jar for you - how sweet is that!):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Edit the file&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/conf/BuildConfig.groovy &lt;/span&gt;&lt;/div&gt;uncomment the lines containing&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;mavenCentral()&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;and&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;runtime 'mysql:mysql-connector-java:5.1.5'&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;so you get&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;...&lt;br /&gt;repositories {&lt;br /&gt;grailsPlugins()&lt;br /&gt;grailsHome()&lt;br /&gt;mavenCentral()&lt;br /&gt;}&lt;br /&gt;dependencies {&lt;br /&gt;runtime 'mysql:mysql-connector-java:5.1.5'&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;then run&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;grails run-app&lt;/span&gt;&lt;/div&gt;&lt;div&gt;It works! It took a while on the "Resolving dependencies..." step as it downloaded the MySQL connector jar. Now if you create a new book and stop the server, the new book will still be there the next time you start it (this behavior is specified by the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;dbCreate = "update"&lt;/span&gt; setting).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last gotcha is to remove the automatic adding of books from the bootstrap file. As it stands, that code will persist new copies of those preset books upon every restart. Edit the file&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/conf/BootStrap.groovy&lt;/span&gt;&lt;/div&gt;&lt;div&gt;such that the "init" closure is empty:&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;def init = { servletContext -&amp;gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Now you'll have no more books automatically added.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Domain Object Relationships:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;So far all we have seen is Grails magic - I still don't know how to actually write a webapp. Lets add tags to our books to get more familiar with Grails. This process is inspired by the Bookmarks example from the Definitive Guide to Grails by Graeme Rocher, the creator of Grails.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lets create the Tag class:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;grails create-domain-class tag&lt;/span&gt;&lt;/div&gt;&lt;div&gt;now to add its relationship to Book, edit the file&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/domain/book/Tag.groovy&lt;/span&gt;&lt;/div&gt;&lt;div&gt;such that it contains&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package book&lt;br /&gt;class Tag {&lt;br /&gt;static belongsTo = Book&lt;br /&gt;Book book&lt;br /&gt;String name&lt;br /&gt;static constraints = {}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;The line&lt;/div&gt;&lt;div&gt;&lt;pre style="font-family: 'Andale Mono','Lucida Console',Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 682px;"&gt;&lt;code&gt;static belongsTo = Book&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;signals to the object relational mapping system of Grails (called GORM, built on Hibernate) that in the database, a Tag is owned by its corresponding Book. This means that when a Book is deleted (from the books database table), all its tags are also deleted (from the tags database table), and not the other way around.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now we need to tell GORM that there is a one-to-many relationship between Books and Tags. Edit the Book class&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;gedit grails-app/domain/book/Book.groovy&lt;/span&gt;&lt;/div&gt;&lt;div&gt;such that it contains&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package book&lt;br /&gt;class Book {&lt;br /&gt;static hasMany = [tags:Tag]&lt;br /&gt;String title&lt;br /&gt;String author&lt;br /&gt;static constraints = {&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;Tag doesn't yet have a controller, create one with&lt;/div&gt;&lt;div&gt;grails create-controller tag&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package book&lt;br /&gt;class TagController {&lt;br /&gt;def scaffold = Tag&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;now when you run&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 102, 0);"&gt;grails run-app&lt;/span&gt;&lt;/div&gt;&lt;div&gt;you will have a gui for CRUD operations on both Books and Tags, which has the correct delete behavior.&lt;/div&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4468050505/" title="Screenshot-Create Tag by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2707/4468050505_6b7cc4ccce_o.png" alt="Screenshot-Create Tag" height="259" width="268" /&gt;&lt;/a&gt;&lt;div&gt;Customizing toString and adding validation constraints:&lt;/div&gt;&lt;div&gt;We can see from the listing of books in the tag selection GUI that a book is represented as "book.Book : $id". We can easily change this by overriding the toString method of the Book class as follows:&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package book&lt;br /&gt;class Book {&lt;br /&gt;static hasMany = [tags:Tag]&lt;br /&gt;String title&lt;br /&gt;String author&lt;br /&gt;static constraints = {&lt;br /&gt;   title(blank:false)&lt;br /&gt;   author(blank:false)&lt;br /&gt;}&lt;br /&gt;String toString(){"$title by $author"}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;In Grails, quoted strings are in fact "GStrings" and support string interpolation - so you can access variables in scope and even write inline Groovy code using the $ escape character (use ${...code...} for more elaborate Groovy code)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I also added the constraints that the author and title fields cannot be blank. GORM automatically validates the instance using these constraints right before persisting to the database, in the call to save(). Lets add a constraint to the Tag class as well:&lt;/div&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;package book&lt;br /&gt;class Tag {&lt;br /&gt;static belongsTo = Book&lt;br /&gt;Book book&lt;br /&gt;String name&lt;br /&gt;static constraints = {name(blank:false)}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;Now, when we try to make a new Tag whose name is blank, an error with corresponding GUI results:&lt;/div&gt;&lt;a href="http://www.flickr.com/photos/10604632@N02/4468167007/" title="Screenshot-Create-Tag-with-constraint by curran.kelleher, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2695/4468167007_ccb9be76ce_o.png" alt="Screenshot-Create-Tag-with-constraint" height="296" width="389" /&gt;&lt;/a&gt;&lt;div&gt;We can also see that our string interpolation worked correctly: "$title by $author" evaluated to "The Shining by Stephen King".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enjoy!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Links:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.grails.org/Installation"&gt;Grails Installation instructions&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.grails.org/Quick+Start"&gt;Grails Quick-Start&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="https://help.ubuntu.com/community/EnvironmentVariables"&gt;Ubuntu page on environment variables&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.grails.org/doc/latest/guide/3.%20Configuration.html#3.7%20Dependency%20Resolution"&gt;Grails dependency resolution&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-7660398999595453554?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/7660398999595453554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=7660398999595453554' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7660398999595453554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7660398999595453554'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/03/grails.html' title='Grails'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5325709580269149622</id><published>2010-03-13T21:53:00.000-08:00</published><updated>2010-08-27T16:00:21.684-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='puredata'/><category scheme='http://www.blogger.com/atom/ns#' term='multitouch'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='instrument'/><category scheme='http://www.blogger.com/atom/ns#' term='processing'/><title type='text'>Sine wave Instrument with PureData and Processing</title><content type='html'>&lt;div style="text-align: left;"&gt;So I've made some progress toward a usable touch screen based musical instrument using PureData and Processing. So far it has:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;An XY pad with 8 strips corresponding to 8 notes of a scale (with the root at the topmost and bottommost strips).&lt;/li&gt;&lt;li&gt;The left-right direction controls the note pitch.&lt;/li&gt;&lt;li&gt;The up-down direction adds vibrato.&lt;/li&gt;&lt;li&gt;The key, octave, and scale (diatonic mode),  can be chosen from menus.&lt;/li&gt;&lt;/ul&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_c8St2I7onXQ/S5x63RiO4vI/AAAAAAAAAJA/lfGqNk-OSAA/s1600-h/InstrumentPad.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 398px;" src="http://2.bp.blogspot.com/_c8St2I7onXQ/S5x63RiO4vI/AAAAAAAAAJA/lfGqNk-OSAA/s400/InstrumentPad.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5448364739229836018" /&gt;&lt;/a&gt;These menus are not your ordinary menus - they are lists that take up the entire screen while the mouse is held down on one of the menus. The goal with this is to optimize interaction for a touch screen. This setup takes only one gesture (press on menu and release on chosen menu item) to choose something, rather than the two clicks needed for traditional menus (click to open, click to choose). Also, navigating to a large menu button area on a touch screen is much easier, faster, and more reliable than using traditional small menus (which are great when using a mouse but sketchy on a touch screen). Here's a screenshot of the scale menu:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_c8St2I7onXQ/S5x8ZAXBxjI/AAAAAAAAAJI/Isoc06IGY4I/s1600-h/ScaleSelection.png"&gt;&lt;img src="http://4.bp.blogspot.com/_c8St2I7onXQ/S5x8ZAXBxjI/AAAAAAAAAJI/Isoc06IGY4I/s400/ScaleSelection.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5448366418246616626" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 397px; height: 400px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Drag events are associated with the component upon which the corresponding press event fired. In other words, when one presses on a component and drags beyond its borders, drag events are still routed to the original component. This behavior is desirable, because the semantics of the drag are often well defined and useful for these extended drags. For example, the range of pitches for an XY pad controlling an instrument is extended upwards and downwards by this behavior).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The audio is generated by a PureData patch which accepts control messages from the GUI Java program over a socket. I figured out a really neat way of distributing messages in PureData that I haven't seen on the web anywhere - taking the message from a netreceive object, splitting it into a list, and using its two elements to generate a live message, which routes values automatically to their correct receiver (abbreviated "r") objects. This way you don't need to set up a big routing tree of "route", "send" and "receive" objects. Here is the PureData patch:&lt;/div&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_c8St2I7onXQ/S5yAkq9vmnI/AAAAAAAAAJQ/t5gsLMPgvYI/s1600-h/pdCode.png"&gt;&lt;img src="http://4.bp.blogspot.com/_c8St2I7onXQ/S5yAkq9vmnI/AAAAAAAAAJQ/t5gsLMPgvYI/s400/pdCode.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5448371016708364914" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 382px; height: 387px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The GUI program sends a bunch of messages to set initial values when it starts up. This is necessary because PureData patches don't remember their number settings.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The synth part now uses an ADSR amplitude envelope, which fixes that clicking effect that I originally had and gives the sine wave some kick on the attack. I hope to build out the oscillator into an all out synthesizer, and have instruments definable by synth configurations. Then I could add an "Instrument" menu, which would be nice.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was also thinking that maybe a grid or radial configuration might be better for the menus than the current list format ... I'm not sure.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway I hope you enjoy this! &lt;a href="http://www.curransoft.com/code/PDMusic.zip"&gt;Here&lt;/a&gt; is the full source code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.curransoft.com/archive/scalepad.mp3"&gt;Here&lt;/a&gt; is how it sounds:&lt;/div&gt;&lt;div&gt;&lt;object height="81" width="100%"&gt; &lt;param name="movie" value="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Fcurran%2Fscalepad&amp;amp;secret_url=false"&gt; &lt;param name="allowscriptaccess" value="always"&gt; &lt;embed allowscriptaccess="always" height="81" src="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Fcurran%2Fscalepad&amp;amp;secret_url=false" type="application/x-shockwave-flash" width="100%"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;span&gt;&lt;a href="http://soundcloud.com/curran/scalepad"&gt;Scalepad&lt;/a&gt; by &lt;a href="http://soundcloud.com/curran"&gt;curran&lt;/a&gt;&lt;/span&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5325709580269149622?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5325709580269149622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5325709580269149622' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5325709580269149622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5325709580269149622'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/03/sine-wave-instrument-with-puredata-and.html' title='Sine wave Instrument with PureData and Processing'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_c8St2I7onXQ/S5x63RiO4vI/AAAAAAAAAJA/lfGqNk-OSAA/s72-c/InstrumentPad.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-838883155580825468</id><published>2010-03-01T21:36:00.002-08:00</published><updated>2010-08-27T15:40:28.516-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='synthesizer'/><category scheme='http://www.blogger.com/atom/ns#' term='ip'/><category scheme='http://www.blogger.com/atom/ns#' term='puredata'/><category scheme='http://www.blogger.com/atom/ns#' term='sockets'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='processing'/><title type='text'>Frequency Modulation Pad with PureData and Processing</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_c8St2I7onXQ/S4ynIAuP3ZI/AAAAAAAAAIY/TUHY8ruHsdA/s1600-h/xyfreqmod.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 325px;" src="http://2.bp.blogspot.com/_c8St2I7onXQ/S4ynIAuP3ZI/AAAAAAAAAIY/TUHY8ruHsdA/s400/xyfreqmod.png" alt="" id="BLOGGER_PHOTO_ID_5443909805658856850" border="0" /&gt;&lt;/a&gt;All the code fits in the screenshot! I was surprised at how easy this was to do - very impressed by both the Processing and PureData socket APIs. The Processing GUI drives a PureData frequency modulator synth over IP. X controls carrier frequency, Y controls modulation frequency. There is also a delay on the sound - again I'm blown away at how easy this was to add (granted, I just ripped it from an example).&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;I'd like to eventually expand this into an all out music machine (think Kaossilator+KaossPad) with a multitouch interface.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/archive/xyfreqmod.zip"&gt;Here&lt;/a&gt; is the source code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/archive/xyfreqmod.mp3"&gt;Here&lt;/a&gt; is an example of how it sounds.&lt;/div&gt;&lt;br /&gt;&lt;object height="81" width="100%"&gt; &lt;param name="movie" value="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Fcurran%2Fxyfreqmod&amp;amp;secret_url=false"&gt; &lt;param name="allowscriptaccess" value="always"&gt; &lt;embed allowscriptaccess="always" height="81" src="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Fcurran%2Fxyfreqmod&amp;amp;secret_url=false" type="application/x-shockwave-flash" width="100%"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;span&gt;&lt;a href="http://soundcloud.com/curran/xyfreqmod"&gt;Xyfreqmod&lt;/a&gt; by &lt;a href="http://soundcloud.com/curran"&gt;curran&lt;/a&gt;&lt;/span&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enjoy!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-838883155580825468?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/838883155580825468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=838883155580825468' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/838883155580825468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/838883155580825468'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/03/frequency-modulation-pad-with-puredata.html' title='Frequency Modulation Pad with PureData and Processing'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_c8St2I7onXQ/S4ynIAuP3ZI/AAAAAAAAAIY/TUHY8ruHsdA/s72-c/xyfreqmod.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8772566485716849808</id><published>2010-02-05T07:37:00.000-08:00</published><updated>2010-02-09T12:48:35.707-08:00</updated><title type='text'>ProcessingJS Mouse Problems</title><content type='html'>ProcessingJS is awesome, but does not handle the sentics of mouse events the same as Processing does. Here are some problems I ran into, and sample code that demonstrates them:&lt;br /&gt;&lt;br /&gt;- mouseDragged and mouseMoved BOTH get invoked on mouse move even when a mouse button is pressed. This case should invoke mouseDragged ONLY and not mouseMoved.&lt;br /&gt;- mouseClicked gets invoked even after a drag. mouseClicked should only be invoked when the cursor has not moved between the press and the release.&lt;br /&gt;&lt;br /&gt;Here is a sample program that demonstrates the issues:&lt;br /&gt;&lt;br /&gt;Zip file of working HTML+pjs code here (code text also included below):&lt;br /&gt;&lt;a href="http://www.curransoft.com/archive/mouseSemantics.zip" target="_blank" style="color: rgb(42, 93, 176); "&gt;http://www.curransoft.com/&lt;wbr&gt;archive/mouseSemantics.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is an image of the code running in Processing and ProcessingJS, showing very different results. The image shows a run in Chrome, I also get the same results in Firefox.&lt;br /&gt;&lt;img src="http://www.curransoft.com/archive/processingjs_mouse_problems.png" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's how to interpret the image: Blue means that only mouseMoved was&lt;br /&gt;fired, green means that only mouseDragged was fired, red means that&lt;br /&gt;both mouseMoved and mouseDragged were fired, and the larger purple&lt;br /&gt;circle means that mouseClicked was fired. This is what happened with&lt;br /&gt;the following set of mouse interactions: move the mouse in from the&lt;br /&gt;upper left (blue in both: OK), drag a bit towards the lower right&lt;br /&gt;(green in Processing: OK, red in ProcessingJS: NOT OK), release after&lt;br /&gt;the drag (no mouseClicked invocation in Processing: OK, mouseClicked&lt;br /&gt;invocation in ProcessingJS: NOT OK), move a bit more (blue in&lt;br /&gt;both:OK), click (mouseClicked invocation in both:OK) move off the&lt;br /&gt;screen(blue in both:OK).&lt;br /&gt;&lt;br /&gt;I would imagine that these problems would not be too hard to fix.&lt;br /&gt;Thoughts anyone?&lt;br /&gt;&lt;br /&gt;The code:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;boolean moved = false;&lt;br /&gt;boolean dragged = false;&lt;br /&gt;boolean clicked = false;&lt;br /&gt;&lt;br /&gt;void setup()&lt;br /&gt;{&lt;br /&gt;size(200, 200);&lt;br /&gt;frameRate(15);&lt;br /&gt;noStroke();&lt;br /&gt;background(255);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void draw()&lt;br /&gt;{&lt;br /&gt;if(moved &amp;amp;&amp;amp; !dragged)&lt;br /&gt;  fill(0,0,255);&lt;br /&gt;if(!moved &amp;amp;&amp;amp; dragged)&lt;br /&gt;  fill(0,255,0);&lt;br /&gt;if(moved &amp;amp;&amp;amp; dragged)&lt;br /&gt;  fill(255,0,0);&lt;br /&gt;if(moved || dragged)&lt;br /&gt;  ellipse(mouseX,mouseY,10,10);&lt;br /&gt;if(clicked){&lt;br /&gt;  fill(200,0,200);&lt;br /&gt;  ellipse(mouseX,mouseY,30,30);&lt;br /&gt;}&lt;br /&gt;moved = false;&lt;br /&gt;dragged = false;&lt;br /&gt;clicked = false;&lt;br /&gt;}&lt;br /&gt;void mouseMoved(){&lt;br /&gt;moved = true;&lt;br /&gt;}&lt;br /&gt;void mouseDragged(){&lt;br /&gt;dragged = true;&lt;br /&gt;}&lt;br /&gt;void mouseClicked(){&lt;br /&gt;clicked = true;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;UPDATE 2/9&lt;br /&gt;&lt;br /&gt;The bug was &lt;a href="http://github.com/annasob/processing-js/commit/81c42e33817232dec6d75f568b59fc39a7de1bc6"&gt;fixed&lt;/a&gt; by Corban Brook 4 days after the &lt;a href="https://processing-js.lighthouseapp.com/projects/41284-processingjs/tickets/283-inconsistent-mouse-event-semantics#ticket-283-4"&gt;report&lt;/a&gt; was filed. Amazing! It's so great to see that these online communities really work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-8772566485716849808?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8772566485716849808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8772566485716849808' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8772566485716849808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8772566485716849808'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2010/02/processingjs-mouse-problems.html' title='ProcessingJS Mouse Problems'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3023513544650269441</id><published>2009-12-20T11:02:00.000-08:00</published><updated>2009-12-20T12:39:37.034-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='synthesizer'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='midi'/><category scheme='http://www.blogger.com/atom/ns#' term='jack'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Writing a Synthesizer</title><content type='html'>I've been working on writing a synthesizer, and thought people might be interested in the things I've encountered in its development. Thus far I've got a nicely working, single sine oscillator, polyphonic, ADSR enveloped synthesizer for &lt;a href="http://jackaudio.org/"&gt;Jack&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Getting started:&lt;/span&gt;&lt;br /&gt;I used &lt;a href="http://doc.trolltech.com/4.3/tutorial.html"&gt;this QT Tutorial&lt;/a&gt; and the Jack "midisine.c" example client that comes with the &lt;a href="http://jackaudio.org/download"&gt;Jack source code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When I got the midisine code working, I saw that it was sometimes losing notes. The reason was that it was coded such that when more than one midi event has the same time location, only the first one is taken. This can be solved by checking if the next event has the same time as the previous one, and if so processing the event immediately instead of incrementing the time index and moving on regardless.&lt;br /&gt;&lt;br /&gt;In the process callback, when the note is on, the code is just doing (for every sample "i"):&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;ramp += note_frequency;&lt;br /&gt;ramp = (ramp &amp;gt; 1.0) ? ramp - 2.0 : ramp;&lt;br /&gt;out[i] = note_velocity*sin(2*PI*ramp);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;So, "ramp" ends up being a saw wave which goes from -1 to 1 smoothly then jumps back to around -1 every cycle. This "ramp" is the input used to calculate the sine wave value. Pretty neat!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Adding Polyphony:&lt;/span&gt;&lt;br /&gt;I had originally used sdt::list&lt;note&gt; to keep track of notes, which meant that in the Jack process callback I was creating NEW OBJECTS and putting them on the list, then using an iterator to loop through the list when generating sine waves.&lt;br /&gt;&lt;br /&gt;I realized that this could be done much more efficiently in a way which created no new Note instances or iterators in the process callback. This was to have a fixed size array which always contained a set number (polyphony) of notes. These notes are then turned on and off, but never created or destroyed, in the process callback. In this scheme, when a note on event is encountered, the list of notes is iterated through until a note which is "off" is encountered, then that note object is mutated to contain the new parameters, and is set to "on."&lt;br /&gt;&lt;br /&gt;Furthermore, I realized that this list need not be fully iterated when reading existing notes, so I implemented an optimization which keeps track of the highest index at which a note is stored. This index is maintained by the two functions which turn notes on and off. With this modification, the process callback only iterates over notes which are actually on, not all "polyphony" of them (with the exception of when fragmentation happens, i.e. "a on", "b on", "a off" - in which case "a" will be iterated over (but ignored) even though it is off).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Adding an amplitude envelope:&lt;/span&gt;&lt;br /&gt;The ADSR (attack, decay, sustain, release) envelope was trickier than I had anticipated. &lt;/note&gt;I adopted the "ramp" idea to the envelope stages, and computed the amplitude for each stage as a function of the stage and the ramp value. I realized later that this can be made much more efficient by just using computing an amplitude increment value when stages change, and simply incrementing the amplitude by that every sample rather than performing the amplitude computation as a function of the stage and ramp value. This turned out to makes the envelope implementation both simpler (it is now a fairly simple state machine) and more efficient (only additions must be performed for each sample).&lt;br /&gt;&lt;br /&gt;Now it becomes a bit complex. When a note off event is encountered, the note should not actually be turned off, it should be set to be in its release stage, and turned off when it is done releasing. Because this could happen at any one of the A, D, or S stages, and we don't want discontinuities in the sound wave, the initial amplitude of the release stage must be the previous amplitude, not the sustain amplitude. Therefore the release increment must be a function of the existing amplitude.&lt;br /&gt;&lt;br /&gt;So now imagine that one plays all the piano notes in a swoop of the hand. The max polyphony is reached pretty soon if the release time is long, because all those notes that are releasing are not actually turned off until their release phase has finished. To avoid losing the new note events, I made the modification to the note on handler that if all notes ("polyphony" of them)  are on, it should see if there are any notes in the release phase, and if so, use the one that is farthest along (whose envelope ramp is highest), effectively cutting it off and replacing it with the newly on note. This seems to work pretty well.&lt;br /&gt;&lt;br /&gt;A few things are still not quite right. As it is, the release time is fixed and the release rate depends on the initial amplitude (when the release phase is triggered). The case &lt;span style="font-style: italic;"&gt;should&lt;/span&gt; be that the release rate is fixed and the release time is not. This is an easy fix.&lt;br /&gt;&lt;br /&gt;Another nice feature that was easy to add was automatically connecting the audio output to the Jack "system out," so you don't need to manually connect it every time you run it:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;jack_connect (client,jack_port_name(output_port),"system:playback_1");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;So now we have a cleanly running, single sine oscillator, polyphonic, ADSR enveloped synthesizer. A version of the code at this point can be found &lt;a href="http://curransoft.com/code/simpleSynth.zip"&gt;here&lt;/a&gt;. Feel free to use for any purpose.&lt;br /&gt;&lt;note&gt;&lt;br /&gt;More to come.&lt;br /&gt;&lt;br /&gt;&lt;/note&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3023513544650269441?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3023513544650269441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3023513544650269441' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3023513544650269441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3023513544650269441'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/12/writing-synthesizer.html' title='Writing a Synthesizer'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5058285283703707383</id><published>2009-12-18T18:58:00.000-08:00</published><updated>2009-12-18T19:10:15.484-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='jack'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Fretboard</title><content type='html'>I've been playing around with Linux audio stuff, and decided to learn a bit by writing a program that allows me to play the keyboard as though it were a guitar. I learned a lot about C++, QT, and Jack, and eventually I got it working and &lt;a href="http://github.com/curran/Fretboard"&gt;published it&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://farm3.static.flickr.com/2599/4195817101_8905a70337_o.png" height="128" width="447" /&gt;&lt;br /&gt;Features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fretboard is a Jack client which outputs midi notes.&lt;/li&gt;&lt;li&gt;Pressing a key on the keyboard causes the the corresponding fret in the GUI to display a circle, and the corresponding midi note is emitted.&lt;/li&gt;&lt;li&gt;Preset instrument mappings include guitar, bass, cello, and violin.&lt;/li&gt;&lt;li&gt;Hold - when the spacebar is held down, notes are held (not turned off when you release the key), and playing a note that's already on toggles it on and off.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Custom mappings are supported - you can change to the base (lowest open string) midi note (60 is middle C) and the offsets (in half-steps) for each string.&lt;/li&gt;&lt;li&gt;GPL license.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt; Dependencies: QT 4, Jack&lt;br /&gt;&lt;/p&gt;#To download, use GIT:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install git -y&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;git clone git://github.com/curran/Fretboard.git&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; cd Fretboard&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#To make and run:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install libqt4-dev libjack-dev -y&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;qmake&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; make&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; ./fretboard&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5058285283703707383?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5058285283703707383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5058285283703707383' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5058285283703707383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5058285283703707383'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/12/fretboard.html' title='Fretboard'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-520300120989561031</id><published>2009-07-28T15:05:00.000-07:00</published><updated>2009-07-28T15:06:50.651-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Remove all .svn directories</title><content type='html'>Recursively removes all those pesky .svn directories in your tree:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;find|grep [.]svn$|xargs rm -r -f&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-520300120989561031?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/520300120989561031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=520300120989561031' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/520300120989561031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/520300120989561031'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/07/remove-all-svn-directories.html' title='Remove all .svn directories'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-501113898284676323</id><published>2009-07-28T10:42:00.001-07:00</published><updated>2009-07-28T11:05:39.406-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='okular'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Sweet LaTeX development setup</title><content type='html'>Here's how I like to work with LaTeX these days: Linux terminal, Emacs, and Okular.&lt;br /&gt;&lt;br /&gt;Open terminal, go to directory with .tex file (here I'll use all.tex as a sample file).&lt;br /&gt;&lt;br /&gt;#create all.dvi&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;latex all&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#open an auto-updating viewer in the background with messages stifled&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;okular all.dvi &amp;amp;&gt; /dev/null &amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#use Emacs as the editor&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;emacs -nw all.tex&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#ctrl-z to put Emacs in background, then&lt;br /&gt;#compile latex, and already open Okular automatically refreshes&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;latex all&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#put emacs in foreground to edit further&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;fg&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#from now on, to compile and view:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;edit&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ctrl+x s ! - save all in Emacs&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ctrl+z - hide emacs&lt;/li&gt;&lt;li&gt;up arrow twice, enter - compile latex (execute latex all)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;alt+tab - focus to Okular for viewing&lt;br /&gt;&lt;/li&gt;&lt;li&gt;alt+tab - focus to terminal&lt;/li&gt;&lt;li&gt;fg - show emacs&lt;/li&gt;&lt;li&gt;repeat&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;It gets really fast with a few repetitions.&lt;br /&gt;&lt;br /&gt;Alternatively, one could map the compile command to a keystroke in Emacs, but I prefer a regular old terminal because of the great interactive error messages from LaTeX.&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://www.nongnu.org/emacsdoc-fr/manuel/shell.html"&gt;Running Shell Commands from Emacs&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-501113898284676323?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/501113898284676323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=501113898284676323' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/501113898284676323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/501113898284676323'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/07/sweet-latex-development-setup.html' title='Sweet LaTeX development setup'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5990982331966733638</id><published>2009-07-28T10:37:00.000-07:00</published><updated>2009-07-28T10:42:23.813-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='redirection'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><title type='text'>Unix redirection to black hole</title><content type='html'>I wanted to stifle Okular's annoying messages, so I learned how to redirect to a black hole:&lt;br /&gt;&lt;br /&gt;okular &gt; /dev/null&lt;br /&gt;&lt;br /&gt;..but that only redirects stdout, and stderr still goes to the terminal. So, I learned how to redirect stderr to a black hole:&lt;br /&gt;&lt;br /&gt;okular &gt;&amp; /dev/null&lt;br /&gt;&lt;br /&gt;..but not stdout still goes to the terminal. Here's how to redirect both at once:&lt;br /&gt;&lt;br /&gt;okular &gt;&amp; /dev/null&lt;br /&gt;&lt;br /&gt;and put the application in the background:&lt;br /&gt;&lt;br /&gt;okular &gt;&amp; /dev/null &amp;&lt;br /&gt;&lt;br /&gt;Another short but sweet unix success story.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5990982331966733638?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5990982331966733638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5990982331966733638' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5990982331966733638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5990982331966733638'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/07/unix-redirection-to-black-hole.html' title='Unix redirection to black hole'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-962580847821126504</id><published>2009-06-08T13:03:00.000-07:00</published><updated>2009-06-09T14:27:38.537-07:00</updated><title type='text'>Installation Scripts</title><content type='html'>I have organized some scripts for automating installation and configuration of things I end up doing every time I install Ubuntu. I use a &lt;a href="http://bitbucket.org/curran/ubuntuautomation/"&gt;BitBucket repository&lt;/a&gt; to store the scripts. Here they are:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;#Common Things&lt;/span&gt;:&lt;br /&gt;#install LaTeX, SVN&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install texlive subversion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#install and configure emacs and vim, kill the system beep&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://bitbucket.org/curran/ubuntuautomation/raw/c896a3c66d2f/fix_ubuntu.sh &amp;amp;&amp;amp; sh ./fix_ubuntu.sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#install eclipse&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://bitbucket.org/curran/ubuntuautomation/raw/c896a3c66d2f/install_eclipse.sh &amp;amp;&amp;amp; ./install_eclipse.sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#install Clojure and Clojure-SLIME&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://bitbucket.org/curran/ubuntuautomation/raw/1b06abf276e6/install_clojure.sh &amp;amp;&amp;amp; sh ./install_clojure.sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;#Not-so-common Things&lt;/span&gt;:&lt;br /&gt;#install glassfish&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://bitbucket.org/curran/ubuntuautomation/raw/c896a3c66d2f/install_glassfish_v2_1.sh &amp;amp;&amp;amp; sh ./install_glassfish_v2_1.sh&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;To install everything at once:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://bitbucket.org/curran/ubuntuautomation/raw/abb8f7116cbd/install_all.sh&lt;/span&gt;&lt;br /&gt;#perhaps remove the things you don't want from the script...&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sh ./install_all.sh&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-962580847821126504?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/962580847821126504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=962580847821126504' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/962580847821126504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/962580847821126504'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/06/installation-scripts.html' title='Installation Scripts'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4587682368750073161</id><published>2009-06-03T13:06:00.000-07:00</published><updated>2010-04-08T15:22:10.024-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Command Line SVN Client</title><content type='html'>I've decided to learn the svn command line client. It turns out the svn command line is not that bad and complicated after all. Here are what I've gathered as the essentials:&lt;br /&gt;&lt;br /&gt;to &lt;span style="font-weight: bold;"&gt;check out&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn checkout&lt;/span&gt; [svn url]&lt;br /&gt;&lt;br /&gt;to &lt;span style="font-weight: bold;"&gt;add a file &lt;/span&gt;to the repository (this is NOT comitting, so after "add"ing a file, it's not actually copied into the repository, it's just marked for inclusion in the next commit):&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn add&lt;/span&gt; [filename]&lt;br /&gt;&lt;br /&gt;In SVN, when you add a new file, you need to "add" it to SVN, then "commit" it - two separate steps. It becomes tedious and error prone to find which files have been newly created and execute "svn add ..." for each one. Here's how you can&lt;span style="font-weight: bold;"&gt; ensure that all new files under the current directory are added&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn add * --force&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;to &lt;span style="font-weight: bold;"&gt;commit&lt;/span&gt; all changed files in the current directory (to actually submit them to the repository or update them - note that the files must first be "add"ed):&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn commit -m "your comment here"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To &lt;span style="font-weight: bold;"&gt;remove a file&lt;/span&gt; from the repository, first delete it on your system, then execute:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn delete&lt;/span&gt; [filename]&lt;br /&gt;&lt;br /&gt;The comments you (and anyone else) add with -m "your comment here" are recorded in the SVN commit history. To &lt;span style="font-weight: bold;"&gt;view the comment history&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn log | head -n 30&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This uses the "head" unix utility to show only the first 30 lines of the output of "svn log", which shows the most recent 7 or 8 comments. "svn log" alone will spew out all comments ever written.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Daily use:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#update from the repository&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn up&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#if you have local changes you want to discard, do the following:&lt;br /&gt;#revert all, recursively, to the last update&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn revert -R ./&lt;/span&gt;&lt;br /&gt;#do a fresh update&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn up&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#to add a new file to svn&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn add newfile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#to add recursively&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn add dir/* --force&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(oddly,&lt;span style="color: rgb(0, 102, 0);"&gt; svn add dir/*&lt;/span&gt; is NOT recursive)&lt;br /&gt;&lt;br /&gt;#to remove a file&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn rm oldfile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#to move a file&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn mv oldfile newfile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#to commit&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;svn commit -m "your comment here"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.abbeyworkshop.com/howto/misc/svn01/"&gt;SVN Cheat Sheet&lt;/a&gt;&lt;br /&gt;&lt;a href="http://agaric.com/note/subversion-client-ubuntu-anything-tortoisesvn"&gt;Subversion client for Ubuntu: anything like TortoiseSVN?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://svnbook.red-bean.com/en/1.0/ch03s06.html"&gt;SVN: Examining History&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4587682368750073161?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4587682368750073161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4587682368750073161' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4587682368750073161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4587682368750073161'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/06/command-line-svn-client.html' title='Command Line SVN Client'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8744463410378763994</id><published>2009-05-20T08:37:00.000-07:00</published><updated>2009-05-20T09:12:57.143-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='okular'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='seq24'/><category scheme='http://www.blogger.com/atom/ns#' term='kile'/><title type='text'>Linux Frustrations</title><content type='html'>I've been getting frustrated lately by Linux, I'm going to vent.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Seq24 (the sequencer) sucks&lt;/span&gt;&lt;br /&gt;Seq24, a sequencing program, is broken out of the box in Ubuntu Studio. Why is this? Do the Ubuntu Studio folks to any testing before they release? I ranted with error messages on &lt;a href="http://ubuntuforums.org/showthread.php?t=1136015&amp;amp;page=2"&gt;this forum&lt;/a&gt; and &lt;a href="https://bugs.launchpad.net/ubuntu/+source/seq24/+bug/346277"&gt;this bug report&lt;/a&gt; about seq24 - the package is broken, the web site download page is out of date, and the real latest code also crashes and doesn't connect to JACK, the audio server used by many Linux DAWs and synths.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Kile (the LaTeX IDE) sucks&lt;/span&gt;&lt;br /&gt;Now I am trying to use Kile for LaTeX editing. It's totally hosed, completely crap compared to older versions. Here are the problems:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;By default the lines don't wrap. Whats up with this? Doesn't just about EVERY SINGLE PERSON editing a LaTeX document want word wrap? Word wrap should definitely be on by default. Why not?&lt;/li&gt;&lt;li&gt;The menus Compile, Convert, View, and Other (under Build) - the ones used to BUILD AND VIEW LATEX, which is the WHOLE POINT of using the program - are empty, even though I have LaTeX and Okular etc. installed and can compile and view LaTeX from the command line just fine.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Okular (the KDE PDF/document viewer) sucks&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;When I open a pdf in Okular, it has these two huge ass panels on the right, one with "Bookmarks", "Reviews", "Thumbnails" and "Contents" (which is blanked out, why is that even there? that makes no sense whatsoever and should be taken away unless it is needed for SOMETHING)&lt;/li&gt;&lt;li&gt;So, I go to get rid of this ridiculous huge panel thing that should be hidden by default because it makes my document too small to read the text - which is the WHOLE POINT OF MY OPENING THE DOCUMENT IN THE FIRST PLACE - and I look in the "View" menu, because the panel thing - which I have no idea what it's even called, because it's not labeled - is definitely something I am viewing right now. Well, it turns out to be under Settings -&gt; Show Navigation Panel, who'd have guessed.&lt;/li&gt;&lt;/ul&gt;Conclusions and recommendations to people who work with the stuff:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Seq24&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;@Ubuntu: Update the Ubuntu package to the latest version&lt;/li&gt;&lt;li&gt;@seq24: fix the crash when I click "tools" and have it connect to Jack out of the box&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Kile&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;@Kile: Word wrap should be on by default.&lt;/li&gt;&lt;li&gt;@Kile: Kile should be able to build and view LaTeX documents out of the box.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;@&lt;/span&gt;Ubuntu: The Kile package should be tested before releasing&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Okular&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;@KDE/Okular: The navigation panel should be hidden by default - I can scroll just fine, thanks, without it.&lt;/li&gt;&lt;li&gt;@KDE/Okular: The navigation panel should be labeled "Navigation Panel" so I know what to look for when I want to close it.&lt;/li&gt;&lt;li&gt;@KDE/Okular: Better yet, it should have a little X in the upper right corner so I could just close it, the real estate lost wouldn't hurt anybody.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Thanks for listening. I'd appreciate it if anyone told me which specific procedures to go through to get these changes made, or if some specific log files or error details would be useful (I'll post them here).&lt;br /&gt;&lt;br /&gt;If I have some time I'd like to help in fixing these annoyances. They give Linux a bad name.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-8744463410378763994?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8744463410378763994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8744463410378763994' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8744463410378763994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8744463410378763994'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/05/linux-frustrations.html' title='Linux Frustrations'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8530608583053039376</id><published>2009-05-14T13:58:00.000-07:00</published><updated>2009-06-09T14:30:04.592-07:00</updated><title type='text'>3D Grapher in Clojure</title><content type='html'>&lt;h1 class="pagetitle"&gt;LiquidMath&lt;/h1&gt; &lt;!--PageText--&gt;  &lt;p&gt;&lt;strong&gt;&lt;a href="http://github.com/curran/LiquidMath/tree/master"&gt;GitHub repository&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Curran Kelleher&lt;/strong&gt;&lt;br /&gt;May 13, 2009 &lt;/p&gt; &lt;h2&gt;Overview&lt;/h2&gt; &lt;p&gt;&lt;span class="wikiword"&gt;LiquidMath&lt;/span&gt; is a 3D graphing calculator. It graphs implicit parametric equations, where (x,y,z) = f(u,v). Functions are input as Lisp code in the text box, and the surface is displayed as a freely rotatable 3D object. There is much room for improvement, I plan to continue developing this project.&lt;br /&gt;&lt;/p&gt; &lt;h2&gt;Screenshot&lt;/h2&gt; &lt;div&gt;&lt;img src="http://www.cs.uml.edu/ecg/pub/uploads/OPLspr09/ck-screenshot.png" alt="" title="" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Technology&lt;/h2&gt; &lt;p&gt;&lt;span class="wikiword"&gt;LiquidMath&lt;/span&gt; is written in Clojure, a modern Lisp variant which compiles to Java bytecode. Java's Swing API is used for the GUI. &lt;span class="wikiword"&gt;OpenGL&lt;/span&gt; is used for 3D rendering, accessed via the Java &lt;span class="wikiword"&gt;OpenGL&lt;/span&gt; (JOGL) library. &lt;span class="wikiword"&gt;OpenGL&lt;/span&gt; Display Lists are used to achieve smooth rotation interaction. &lt;/p&gt; &lt;h2&gt;Innovation&lt;/h2&gt; &lt;p&gt;&lt;span class="wikiword"&gt;LiquidMath&lt;/span&gt; combines the dynamic nature of Lisp, the beauty of math, and the interactivity of modern graphics to deliver an effective educational tool for gaining insight into the nature of parametric surfaces. Conventionally, courses which explore 3D surfaces such as calculus III use only static diagrams. &lt;span class="wikiword"&gt;LiquidMath&lt;/span&gt; could be used by instructors during class, or by students when doing assignments. &lt;/p&gt; &lt;h2&gt;Technology Used Block Diagram&lt;/h2&gt; &lt;p&gt;&lt;span class="wikiword"&gt;LiquidMath&lt;/span&gt; is designed around the model-view-controller pattern, in which the model is the data representing salient application state, the view is the gui definition, and the controller sets up communication between the view and model. The view contains the text box and graphics panel. The text box updates the model via a listener added by the controller. The graphics panel is responsible for responding to changes in the model by generating and compiling code from the newly entered function string, then re-rendering the surface into the display list. &lt;/p&gt; &lt;div&gt;&lt;img src="http://www.cs.uml.edu/ecg/pub/uploads/OPLspr09/ck-block.png" alt="" title="" /&gt;&lt;/div&gt; &lt;h2&gt;Additional Remarks&lt;/h2&gt; &lt;p&gt;The full source code is posted &lt;a href="http://github.com/curran/LiquidMath/tree/master"&gt;here &lt;/a&gt;(public domain, feel free to use, copy, etc): &lt;/p&gt; &lt;p class="vspace"&gt;Here are some additional works that came out of this project: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a class="urllink" href="http://lifeofaprogrammergeek.blogspot.com/2009/03/learning-clojure-and-emacs.html" rel="nofollow"&gt;A tutorial on Clojure, Emacs, and SLIME&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a class="urllink" href="http://lifeofaprogrammergeek.blogspot.com/2009/04/opengl-in-clojure.html" rel="nofollow"&gt;JOGL example from Wikipedia ported to Clojure&lt;/a&gt; (and the refactored Java version was &lt;a class="urllink" href="http://en.wikipedia.org/wiki/Jogl" rel="nofollow"&gt;contributed back to Wikipedia&lt;/a&gt;) &lt;/li&gt;&lt;li&gt;&lt;a class="urllink" href="http://lifeofaprogrammergeek.blogspot.com/2009/05/model-view-controller-gui-in-clojure.html" rel="nofollow"&gt;Blog post about a model-view-controller skeleton&lt;/a&gt; &lt;/li&gt;&lt;li&gt;An intermediate stage was a &lt;a class="urllink" href="http://curransoft.com/code/clj-grapher-20090511.zip" rel="nofollow"&gt;2D animated grapher&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The following are discussions on the Clojure mailing list: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a class="urllink" href="http://groups.google.com/group/clojure/browse_thread/thread/f42f2cf463719a3/936947c63d496e58#936947c63d496e58" rel="nofollow"&gt;fresh clojure tutorial&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a class="urllink" href="http://groups.google.com/group/clojure/browse_thread/thread/c2830dc6441620a/51cecc6c6003e785#51cecc6c6003e785" rel="nofollow"&gt;the game loop ... the clojure way?&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a class="urllink" href="http://groups.google.com/group/clojure/browse_thread/thread/db6e52e83c587419/c4d1fb03fc38b679#c4d1fb03fc38b679" rel="nofollow"&gt;Yet Another Swing Example&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a class="urllink" href="http://groups.google.com/group/clojure/browse_thread/thread/8678ecb6cad60356/437176152332c199#437176152332c199" rel="nofollow"&gt;Documentation Flaw for "binding"&lt;/a&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/6461387352629250590-8530608583053039376?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8530608583053039376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8530608583053039376' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8530608583053039376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8530608583053039376'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/05/3d-grapher-in-clojure.html' title='3D Grapher in Clojure'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1766491966625186138</id><published>2009-05-09T11:04:00.001-07:00</published><updated>2009-05-09T12:02:04.227-07:00</updated><title type='text'>Visualization System Ideas</title><content type='html'>I just had an ! idea ! for a web-based visualization system architecture which would support selection across visualizations, collaborative visualization, and massive data sets.&lt;br /&gt;&lt;br /&gt;The idea is that a url-accessible entity will contain a stateful resource which can be interacted with OpenGL-style via bunches of function calls (in URL requests). Some of the functions would be as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Give me a session ID&lt;br /&gt;arguments:&lt;br /&gt;return value: sessionID&lt;br /&gt;side effect: initialize the session on the server side, make it usable&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Load a data set into my session&lt;br /&gt;arguments: sessionID, pointer to distributed data set resource&lt;br /&gt;return value:&lt;br /&gt;side effect: loads the given data set pointer into the session, makes it usable&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create a visualization&lt;br /&gt;arguments: sessionID, visualization type&lt;br /&gt;return value: visualizationID&lt;br /&gt;side effect: load a visualization instance of the specified type, which uses the currently loaded data set, and can be referred to by the returned visualization ID&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Set visualization parameters&lt;br /&gt;arguments: sessionID, visualizationID, parameter map&lt;br /&gt;return value:&lt;br /&gt;side effect: set the values of the specified visualization instance to the values of the given visualization-type-specific parameter map, which may contain values like which data rows/columns to visualize in which way, or which color map to use.&lt;/li&gt;&lt;li&gt;Set selection query&lt;br /&gt;arguments: data set query which can deduce a set of selected records.&lt;br /&gt;return value:&lt;br /&gt;side effect:&lt;/li&gt;&lt;li&gt;Set selection polygon&lt;br /&gt;arguments: sessionID, visualizationID, width, height, and a polygon (all in rendered-visualization-image-pixel-coordinates)&lt;br /&gt;return value:&lt;br /&gt;side effect: calls "Set selection query" with a query which derives the set of records that lie inside the specified polygon in the specified rendered visualization instance.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Until now, there's no heavy lifting whatsoever necessary. Here are the compute-intensive tasks:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Render visualization&lt;br /&gt;arguments: sessionID, visualizationID, width, height&lt;br /&gt;return value: an image of the rendered visualization (using the current data set of the session, representing visually the current selection, and the current parameters of the specified visualization instance), with the specified (width, height) pixel dimensions&lt;br /&gt;side effect: none, or perhaps do some setup which improves the speed of future renders.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There would also need to be some notification mechanism to signal the client to re-render each visualization when the selection changes, and when visualization parameters are modified (potentially by another user looking at the same visualization - that's the only thing I can see is necessary for collaboration)&lt;br /&gt;&lt;br /&gt;Thats the idea, to be implemented to run on a cluster, perhaps in the cloud.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1766491966625186138?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1766491966625186138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1766491966625186138' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1766491966625186138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1766491966625186138'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/05/visualization-system-ideas.html' title='Visualization System Ideas'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1854795691460144396</id><published>2009-05-07T17:30:00.000-07:00</published><updated>2009-05-07T18:17:03.501-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='gui'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>Model-View-Controller GUI in Clojure</title><content type='html'>I've been experimenting with ways of coding GUIs which loosely follow the Model-View-Controller paradigm in &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;, with some success. This post describes a simple working example - a gui that draws the text you type in the box.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="http://farm4.static.flickr.com/3643/3511039061_6f46e0146b_o.png" alt="Screenshot-GUI Test" width="290" height="81" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The idea is to have a mutable object which encapsulates the application state (model), and gui code which reflects the state (view), and provides a way to change it (controller). In this case, the model is just a string, the view is the panel that draws the string, and the controller is the text field. When you type in the text field and hit enter, the model is changed, and the panel draws the new string.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Creating the Model&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Clojure is incredibly well thought out in terms of mutability and concurrency, and provides several primitives for dealing with mutable objects. I used a Clojure &lt;a href="http://clojure.org/refs"&gt;ref&lt;/a&gt; object as the model, which wraps a string. The model is created at the top level, and pushed down as an argument to the GUI code (which conveniently closes over it, making it a persistently available pointer). The following code creates the model:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(ref "Hello MVC!")&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Reading the Model&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The text field is initialized with the value of the model with the following code:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;...&lt;br /&gt;(doto (JTextField.)&lt;br /&gt;  (.setText @model)&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;note - "@" serves to dereference a Clojure reference, yielding in this case the string wrapped by the model object.&lt;br /&gt;&lt;br /&gt;The graphics panel reads and draws the model's every time it paints itself, with the following code:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(paint [g]&lt;br /&gt;(doto g&lt;/code&gt;&lt;code&gt;&lt;br /&gt;  ...&lt;br /&gt;&lt;/code&gt;&lt;code&gt;    (.drawString @model 20 40)&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Mutating the Model&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The model is mutated in the code of the ActionListener added to the text field:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(dosync (ref-set model new-text))&lt;/code&gt;&lt;/pre&gt;note - dosync performs a transaction, which is necessary when mutating Clojure references. (ref-set reference new-value) sets the value of the reference.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Listening to the Model&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Clojure has this really cool "&lt;a href="http://clojure.org/api#toc65"&gt;add-watch&lt;/a&gt;" feature where you can attach an update function to any mutable object! The function gets called every time the object changes. The following line attaches a watch function to the model which repaints the panel when the model changes:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(add-watch model "repaint" (fn [k r o n] (.repaint panel)))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Code&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; Here is the code, totaling 74 lines. Any comments are appreciated.&lt;br /&gt;&lt;br /&gt;If anyone knows how I can get nice syntax-highlighted HTML for this code, please let me know!&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;;A test program exploring how to structure GUI code in Clojure&lt;br /&gt;;The GUI draws whatever you type in the text field nicely in the panel below.&lt;br /&gt;;license: Public domain&lt;br /&gt;&lt;br /&gt;(import '(javax.swing JFrame JLabel JTextField JButton JPanel)&lt;br /&gt;      '(java.awt.event ActionListener)&lt;br /&gt;      '(java.awt GridBagLayout GridBagConstraints Color Font RenderingHints))&lt;br /&gt;&lt;br /&gt;(defn make-model [] (ref "Hello MVC!"))&lt;br /&gt;&lt;br /&gt;(defn make-graphics-panel [model]&lt;br /&gt;(let [panel&lt;br /&gt;  (proxy [JPanel] []&lt;br /&gt;    (JPanel [] (println "in constructor"))&lt;br /&gt;    (paint [g]&lt;br /&gt;       (doto g&lt;br /&gt;                  ;clear the background&lt;br /&gt;         (.setColor (. Color black))&lt;br /&gt;         (.fillRect 0 0 (.getWidth this) (.getHeight this))&lt;br /&gt;&lt;br /&gt;                  ;draw the text&lt;br /&gt;         (.setRenderingHint (. RenderingHints KEY_ANTIALIASING)&lt;br /&gt;                    (. RenderingHints VALUE_ANTIALIAS_ON))&lt;br /&gt;         (.setFont (Font. "Serif" (. Font PLAIN) 40))&lt;br /&gt;         (.setColor (. Color white))&lt;br /&gt;         (.drawString @model 20 40))))]&lt;br /&gt;&lt;br /&gt;                  ;repaint when the model changes&lt;br /&gt;  (add-watch model "repaint" (fn [k r o n] (.repaint panel)))&lt;br /&gt;  panel))&lt;br /&gt;&lt;br /&gt;(defn make-text-field [model]&lt;br /&gt;(doto (JTextField.)&lt;br /&gt;  (.setText @model)&lt;br /&gt;  (.addActionListener&lt;br /&gt;   (proxy [ActionListener] []&lt;br /&gt;     (actionPerformed [e]&lt;br /&gt;   (let [new-text (.getActionCommand e)]&lt;br /&gt;     (dosync (ref-set model new-text))))))))&lt;br /&gt;&lt;br /&gt;(defn make-gui-panel [model]&lt;br /&gt;(defn make-text-field-constraints []&lt;br /&gt;  (let [c (GridBagConstraints.)]&lt;br /&gt;    (set! (.fill c) (. GridBagConstraints HORIZONTAL))&lt;br /&gt;    (set! (.weightx c) 1)&lt;br /&gt;    c))&lt;br /&gt;&lt;br /&gt;(defn make-panel-constraints []&lt;br /&gt;  (let [c (GridBagConstraints.)]&lt;br /&gt;    (set! (.gridy c) 1)&lt;br /&gt;    (set! (.weighty c) 1)&lt;br /&gt;    (set! (.fill c) (. GridBagConstraints BOTH))&lt;br /&gt;    c))&lt;br /&gt;&lt;br /&gt;(let [gridbag (GridBagLayout.)&lt;br /&gt;      text-field (make-text-field model)&lt;br /&gt;      panel (make-graphics-panel model)]&lt;br /&gt;                  ;set up the gridbag constraints&lt;br /&gt;  (doto gridbag&lt;br /&gt;    (.setConstraints text-field (make-text-field-constraints))&lt;br /&gt;    (.setConstraints panel (make-panel-constraints)))&lt;br /&gt;                  ;add the components to the panel and return it&lt;br /&gt;  (doto (JPanel.)&lt;br /&gt;    (.setLayout gridbag)&lt;br /&gt;    (.add text-field)&lt;br /&gt;    (.add panel))))&lt;br /&gt;&lt;br /&gt;(defn show-in-frame [panel width height frame-title]&lt;br /&gt;(doto (JFrame. frame-title)&lt;br /&gt;  (.add panel)&lt;br /&gt;  (.setSize width height)&lt;br /&gt;  (.setVisible true)))&lt;br /&gt;&lt;br /&gt;(show-in-frame (make-gui-panel (make-model)) 300 110 "GUI Test")&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1854795691460144396?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1854795691460144396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1854795691460144396' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1854795691460144396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1854795691460144396'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/05/model-view-controller-gui-in-clojure.html' title='Model-View-Controller GUI in Clojure'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4292156054027086824</id><published>2009-04-14T12:44:00.000-07:00</published><updated>2009-04-14T12:47:57.241-07:00</updated><title type='text'>The Tree Draws Well</title><content type='html'>I made the AST drawing program use a physics-like layout algorithm for drawing the abstract syntax tree of code parsed with my tiny lisp interpreter. Here's how it looks for fibbonacci:&lt;br /&gt;&lt;img src="http://www.curransoft.com/code/fib_visual_ast_20090414.PNG" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/code/parallisp_20090414.zip"&gt;the code&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4292156054027086824?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4292156054027086824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4292156054027086824' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4292156054027086824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4292156054027086824'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/tree-draws-well.html' title='The Tree Draws Well'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1910744077806721478</id><published>2009-04-09T17:08:00.001-07:00</published><updated>2009-04-09T17:18:21.079-07:00</updated><title type='text'>Visualizing the Abstract Syntax Tree</title><content type='html'>I've decided to start on an abstract syntax tree visualization for my &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/04/factorial-is-possible.html"&gt;tiny Lisp interpreter&lt;/a&gt;. So far it just walks the tree and assigns incrementing X and Y locations based on depth and location in the list. The next step is to make a mini-physics simulation which minimizes the edge lengths and prevents overlaps. That should make much nicer looking trees.&lt;br /&gt;&lt;br /&gt;I'm not sure if this is a standard way of visualizing Lisp abstract syntax trees - representing lists with a dot. I figured I can't put the function name at the node, because then it couldn't handle code that evaluates to a function that was returned from other code, like ((fn (x y z) (+ x y z)) 1 2 3)&lt;br /&gt;&lt;br /&gt;Here's what it looks like to far:&lt;br /&gt;&lt;img src="http://www.curransoft.com/code/addition_visual_ast_20090409.PNG" /&gt;&lt;br /&gt;&lt;br /&gt;It has overlap issues, here's what it does to fibbonacci:&lt;br /&gt;&lt;img src="http://www.curransoft.com/code/fib_visual_ast_20090409.PNG" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/code/parallisp_20090409_3.zip"&gt;the code&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1910744077806721478?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1910744077806721478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1910744077806721478' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1910744077806721478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1910744077806721478'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/visualizing-abstract-syntax-tree.html' title='Visualizing the Abstract Syntax Tree'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1163352476416233943</id><published>2009-04-08T22:43:00.001-07:00</published><updated>2009-04-08T22:58:02.932-07:00</updated><title type='text'>Factorial is possible!</title><content type='html'>I was able to add the minimum functionality necessary to implement factorial to my &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/04/lambdas-are-here.html"&gt;tiny Lisp interpreter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now the language has the following built-in functions: +,-,*,def,fn,and if. "if" is actually a function, because I made the function implementation responsible for evaluating its arguments, which are passed in as unevaluated abstract syntax trees. I'm not sure it that's correct, but it works for now.&lt;br /&gt;&lt;br /&gt;Implementing all the primitives made me realize that those functions in Lisps take an arbitrary number of arguments. For example, in Clojure:&lt;br /&gt;(&lt;&gt; true&lt;br /&gt; but&lt;br /&gt;(&lt;&gt; false&lt;br /&gt;&lt;br /&gt;Implementing "if" involved clearly defining how booleans are represented. I decided that anything non-nil is true, and true is arbitrarily chosen as the number 1. This isn't very readable for printing out results, but it gets the job done. Maybe it would be a good idea to introduce a boolean type...not sure...maybe the just the notion of a "named constant"...&lt;br /&gt;&lt;br /&gt;In any case, factorial works:&lt;br /&gt;(def ! (fn (x) (if (&lt; x 2) 1 (* x (! (- x 1))))))&lt;br /&gt;(! 6) -&gt; 720 (which is 6*5*4*3*2*1)&lt;br /&gt;&lt;br /&gt;Sweet!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/code/parallisp_20090409_2.zip"&gt;the code&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1163352476416233943?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1163352476416233943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1163352476416233943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1163352476416233943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1163352476416233943'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/factorial-is-possible.html' title='Factorial is possible!'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4040203961924364966</id><published>2009-04-08T21:55:00.000-07:00</published><updated>2009-04-08T22:03:18.478-07:00</updated><title type='text'>Lambdas are here!</title><content type='html'>I was able to implement lambdas in my &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/04/progress-in-tiny-lisp-interpreter.html"&gt;tiny Lisp interpreter&lt;/a&gt;, which required introducing local environments which delegate to their parents when lookup fails. I used "fn" instead of "lambda", like Clojure.&lt;br /&gt;&lt;br /&gt;Now it can do stuff like:&lt;br /&gt;(def double (fn (x) (+ x x)))&lt;br /&gt;(double 100) -&gt; 200&lt;br /&gt;&lt;br /&gt;Now we're getting somewhere!&lt;br /&gt;&lt;br /&gt;Next we'll need "if", then recursion will become possible.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/code/parallisp_20090409_1.zip"&gt;the code&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4040203961924364966?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4040203961924364966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4040203961924364966' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4040203961924364966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4040203961924364966'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/lambdas-are-here.html' title='Lambdas are here!'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-6481581639717361965</id><published>2009-04-08T20:32:00.000-07:00</published><updated>2009-04-08T20:43:10.816-07:00</updated><title type='text'>Progress in Tiny Lisp Interpreter</title><content type='html'>I have added a proper global environment to my &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/04/tiny-lisp-interpreter.html"&gt;tiny Lisp interpreter&lt;/a&gt;, introduced the notion of symbols, and implemented the def function. Now it can do stuff like:&lt;br /&gt;(def a 8) -&gt; 8&lt;br /&gt;a -&gt; 8&lt;br /&gt;(def b (+ 5 6)) -&gt; 11&lt;br /&gt;b -&gt; 11&lt;br /&gt;(+ a b) -&gt; 19&lt;br /&gt;&lt;br /&gt;I wonder if, for a massively parallelized interpreter, it would be better to disallow redefinition of bindings. I would imagine it has benefits for distribution - if a symbols binding is guaranteed never to change, then the system could replicate and pass along the enclosing environment as fixed values when distribution across machines happens. Perhaps this is why &lt;a href="http://en.wikipedia.org/wiki/Erlang_%28programming_language%29"&gt;Erlang&lt;/a&gt; is single assignment...&lt;br /&gt;&lt;br /&gt;The next step is, hopefully, to implement lambda!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.curransoft.com/code/parallisp_20090409.zip"&gt;Here&lt;/a&gt; is the code for those interested.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-6481581639717361965?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/6481581639717361965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=6481581639717361965' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6481581639717361965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6481581639717361965'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/progress-in-tiny-lisp-interpreter.html' title='Progress in Tiny Lisp Interpreter'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-7465946064715596988</id><published>2009-04-07T22:31:00.000-07:00</published><updated>2009-04-07T22:52:38.121-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='interpreter'/><title type='text'>A Tiny Lisp Interpreter</title><content type='html'>I ventured to write a simple Lisp interpreter in Java, and so far I've got a basic interpreter that is able to add numbers in less than 300 lines!&lt;br /&gt;&lt;br /&gt;The only thing it can do now is parse and evaluate expressions like (+ 1 (+ (+ 1 2) 3 (+ 5 5))). Not very impressive, but it's a start. It has the essentials though: a recursive descent parser that transforms text into an abstract syntax tree (which is actually just (cons cells) filled with numbers and functions), and an eval/apply tree walker that runs the code.&lt;br /&gt;&lt;br /&gt;It blows my mind that code is data in Lisps, and there is no syntax except parentheses and white space. Those aspects made writing the interpreter a lot easier than I expected. I found myself needing to write functional code in Java to make the thing work - for example, there is a tree walker that generates the code from the abstract syntax tree. That code was more natural to phrase functionally instead of object oriented-ly - x.toString() became toString(x), and suddenly the implementation became more straightforward.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://curransoft.com/code/Parallisp_20090408.zip"&gt;Here is the code&lt;/a&gt; so far in case anyone is interested, (I hereby release it into the public domain!) I hope to eventually make a front end that visualizes code running in a simulated sea of parallel processors, in an effort to understand how I could implement such a system to run in an actual sea of processors.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-7465946064715596988?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/7465946064715596988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=7465946064715596988' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7465946064715596988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7465946064715596988'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/tiny-lisp-interpreter.html' title='A Tiny Lisp Interpreter'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2488404802952081174</id><published>2009-04-07T16:56:00.000-07:00</published><updated>2009-04-08T22:04:29.150-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='aplications'/><category scheme='http://www.blogger.com/atom/ns#' term='parallelization'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='cuda'/><title type='text'>What is Compute Intensive?</title><content type='html'>I'm trying to think of all the fields that could practically benefit from the ability to handle massive amounts of data, and massive amounts of computation. Please comment if you have more ideas!&lt;br /&gt;&lt;br /&gt;Bioinformatics - useful for drug discovery and scientific understanding:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Genomics&lt;/span&gt; - vast amounts of sequence data&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Proteomics&lt;/span&gt; - protein folding simulations need lots of compute power&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Microarray&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;Analysis&lt;/span&gt; - very large data sets are generated from microarray experiments, which need to be statistically analyzed, which requires heavy computing power.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Geospatial Information Systems&lt;/span&gt; - useful in understanding soceity and natural geographic phenomena - Data sets of geographically grounded indicators (think the Census) are very large, and progress over time. Statistical analysis of these data sets is very compute intensive&lt;br /&gt;Computer Graphics:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Gaming&lt;/span&gt; - fun - graphics are compute intensive&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Computer Vision &lt;/span&gt;- useful in manufacturing, robotics, understanding perception - compute intensive&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Physics Simulations&lt;/span&gt; - advancing knowledge in physics - Compute Intensive&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Weather Simulations&lt;/span&gt; - observing and predicting the weather - VERY data and compute intensive&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Text mining&lt;/span&gt; - information aggregation and summarization, search - Data and compute intensive&lt;br /&gt;&lt;br /&gt;I'm envisioning a computational system which assumes an infinite sea of processors (similar to the CUDA model of computation), and uses instead of a single stack, a branching stack, in which everything that can happen in parallel does hapen in parallel. I can see that such a system is implementable on GPUs with CUDA (or possibly OpenCL, I don't know much about that yet) by implementing a Lisp-like eval-apply loop which only acts on leaves of the stack tree (which can be compacted in log(n) time in parallel).&lt;br /&gt;&lt;br /&gt;If the system can also be designed in such a way that it can orchestrate and evolve itself (its repetitive computation delegation decisions) over a cloud of machines with various compute facilities (both GPUs and *-core CPUs) with speed optimization as an emergent property, then it could change the world ... but only if people actually need it for something practical.&lt;br /&gt;&lt;br /&gt;Could people actually benefit from such a system? Or is it just an academic pursuit?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2488404802952081174?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2488404802952081174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2488404802952081174' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2488404802952081174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2488404802952081174'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/what-is-compute-intensive.html' title='What is Compute Intensive?'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2348765152289181157</id><published>2009-04-06T19:31:00.000-07:00</published><updated>2009-04-06T19:39:06.929-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='memoization'/><title type='text'>Memoization - wtf?</title><content type='html'>This is the one of the coolest thing I have seen in a while. Try to grok this code:&lt;br /&gt;&lt;pre class="text" style="font-family: monospace;"&gt;&lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="macro"&gt;defn&lt;/span&gt; memoize &lt;span class="brackets"&gt;[&lt;/span&gt;f&lt;span class="brackets"&gt;]&lt;/span&gt;&lt;br /&gt; &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="macro"&gt;let&lt;/span&gt; &lt;span class="brackets"&gt;[&lt;/span&gt;mem &lt;span class="parens"&gt;(&lt;/span&gt;atom &lt;span class="curlybrackets"&gt;{&lt;/span&gt;&lt;span class="curlybrackets"&gt;}&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="brackets"&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="macro"&gt;fn&lt;/span&gt; &lt;span class="brackets"&gt;[&lt;/span&gt;&lt;span class="preencoded"&gt;&amp;amp;&lt;/span&gt; args&lt;span class="brackets"&gt;]&lt;/span&gt;&lt;br /&gt;     &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="specialops"&gt;if&lt;/span&gt;&lt;span class="function"&gt;-&lt;/span&gt;&lt;span class="macro"&gt;let&lt;/span&gt; &lt;span class="brackets"&gt;[&lt;/span&gt;e &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="function"&gt;find&lt;/span&gt; @mem args&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="brackets"&gt;]&lt;/span&gt;&lt;br /&gt;       &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="function"&gt;val&lt;/span&gt; e&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="macro"&gt;let&lt;/span&gt; &lt;span class="brackets"&gt;[&lt;/span&gt;ret &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="function"&gt;apply&lt;/span&gt; f args&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="brackets"&gt;]&lt;/span&gt;&lt;br /&gt;         &lt;span class="parens"&gt;(&lt;/span&gt;swap! mem &lt;span class="function"&gt;assoc&lt;/span&gt; args ret&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;         ret&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="macro"&gt;defn&lt;/span&gt; fib &lt;span class="brackets"&gt;[&lt;/span&gt;n&lt;span class="brackets"&gt;]&lt;/span&gt;&lt;br /&gt; &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="specialops"&gt;if&lt;/span&gt; &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="preencoded"&gt;&lt;&lt;/span&gt;= n 1&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;   n&lt;br /&gt;   &lt;span class="parens"&gt;(&lt;/span&gt;+ &lt;span class="parens"&gt;(&lt;/span&gt;fib &lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="function"&gt;dec&lt;/span&gt; n&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt; &lt;span class="parens"&gt;(&lt;/span&gt;fib &lt;span class="parens"&gt;(&lt;/span&gt;- n 2&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="macro"&gt;time&lt;/span&gt; &lt;span class="parens"&gt;(&lt;/span&gt;fib 35&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;user=&lt;span class="preencoded"&gt;&gt;&lt;/span&gt; &lt;span class="string"&gt;"Elapsed time: 941.445 msecs"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="specialops"&gt;def&lt;/span&gt; fib &lt;span class="parens"&gt;(&lt;/span&gt;memoize fib&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="parens"&gt;(&lt;/span&gt;&lt;span class="macro"&gt;time&lt;/span&gt; &lt;span class="parens"&gt;(&lt;/span&gt;fib 35&lt;span class="parens"&gt;)&lt;/span&gt;&lt;span class="parens"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;user=&lt;span class="preencoded"&gt;&gt;&lt;/span&gt; &lt;span class="string"&gt;"Elapsed time: 0.044 msecs"&lt;/span&gt;&lt;/pre&gt;What the heck!?&lt;br /&gt;&lt;br /&gt;It wraps a function with a function that caches its return values for each signature it sees and returns the pre-baked cakes instead of baking the same cake over and over. Sweet! What a great idea!&lt;br /&gt;&lt;br /&gt;Source: &lt;a href="http://clojure.org/atoms"&gt;Clojure Atoms&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2348765152289181157?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2348765152289181157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2348765152289181157' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2348765152289181157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2348765152289181157'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/memoization-wtf.html' title='Memoization - wtf?'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3361858754774064013</id><published>2009-04-03T22:34:00.000-07:00</published><updated>2009-04-05T19:39:42.505-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='JOGL'/><title type='text'>OpenGL in Clojure</title><content type='html'>After much struggling I finally got a simple OpenGL example working in Clojure!&lt;br /&gt;&lt;br /&gt;Here's a port of the JOGL example in Wikipedia to Clojure:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;;This is a Clojure port of the JOGL example in Wikipedia&lt;br /&gt;;Author: Curran Kelleher&lt;br /&gt;;License: Public Domain&lt;br /&gt;;dependencies: jogl.jar, gluegen-rt.jar&lt;br /&gt;&lt;br /&gt;;for the REPL (use C-x C-e):&lt;br /&gt;(comment&lt;br /&gt;;these are the default paths of the jars in Ubuntu&lt;br /&gt;(add-classpath "file:/usr/share/java/jogl.jar")&lt;br /&gt;(add-classpath "file:/usr/share/java/gluegen-rt.jar")&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;(import '(java.awt Frame)&lt;br /&gt;  '(java.awt.event WindowListener WindowAdapter KeyListener KeyEvent)&lt;br /&gt;  '(javax.media.opengl GLCanvas GLEventListener GL GLAutoDrawable)&lt;br /&gt;  '(javax.media.opengl.glu GLU)&lt;br /&gt;  '(com.sun.opengl.util Animator))&lt;br /&gt;(def rotateT 0)&lt;br /&gt;(def glu (new GLU))&lt;br /&gt;(def canvas (new GLCanvas))&lt;br /&gt;(def frame (new Frame "Jogl 3D Shape/Rotation"))&lt;br /&gt;(def animator (new Animator canvas))&lt;br /&gt;(defn exit "Stops animation and closes the OpenGL frame." []&lt;br /&gt;(.stop animator)&lt;br /&gt;(.dispose frame))&lt;br /&gt;&lt;br /&gt;(.addGLEventListener&lt;br /&gt;canvas&lt;br /&gt;(proxy [GLEventListener] []&lt;br /&gt; (display&lt;br /&gt;  [#^GLAutoDrawable drawable]&lt;br /&gt;  (doto (.getGL drawable)&lt;br /&gt;    (.glClear (. GL GL_COLOR_BUFFER_BIT))&lt;br /&gt;    (.glClear (. GL GL_DEPTH_BUFFER_BIT))&lt;br /&gt;    (.glLoadIdentity)&lt;br /&gt;    (.glTranslatef 0 0 -5)&lt;br /&gt;&lt;br /&gt;    (.glRotatef rotateT 1 0 0)&lt;br /&gt;    (.glRotatef rotateT 0 1 0)&lt;br /&gt;    (.glRotatef rotateT 0 0 1)&lt;br /&gt;    (.glRotatef rotateT 0 1 0)&lt;br /&gt;              &lt;br /&gt;    (.glBegin (. GL GL_TRIANGLES))&lt;br /&gt;&lt;br /&gt;    ; Front&lt;br /&gt;    (.glColor3f 0 1 1)&lt;br /&gt;    (.glVertex3f 0 1 0)&lt;br /&gt;    (.glColor3f 0 0 1)&lt;br /&gt;    (.glVertex3f -1 -1 1)&lt;br /&gt;    (.glColor3f 0 0 0)&lt;br /&gt;    (.glVertex3f 1 -1 1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    ; Right Side Facing Front&lt;br /&gt;    (.glColor3f 0 1 1)&lt;br /&gt;    (.glVertex3f 0 1 0)&lt;br /&gt;    (.glColor3f 0 0 1)&lt;br /&gt;    (.glVertex3f 1 -1 1)&lt;br /&gt;    (.glColor3f 0 0 0)&lt;br /&gt;    (.glVertex3f 0 -1 -1)&lt;br /&gt;&lt;br /&gt;    ; Left Side Facing Front&lt;br /&gt;    (.glColor3f 0 1 1)&lt;br /&gt;    (.glVertex3f 0 1 0)&lt;br /&gt;    (.glColor3f 0 0 1)&lt;br /&gt;    (.glVertex3f 0 -1 -1)&lt;br /&gt;    (.glColor3f 0 0 0)&lt;br /&gt;    (.glVertex3f -1 -1 1)&lt;br /&gt;&lt;br /&gt;    ;Bottom&lt;br /&gt;    (.glColor3f 0 0 0)&lt;br /&gt;    (.glVertex3f -1 -1 1)&lt;br /&gt;    (.glColor3f 0.1 0.1 0.1)&lt;br /&gt;    (.glVertex3f 1 -1 1)&lt;br /&gt;    (.glColor3f 0.2 0.2 0.2)&lt;br /&gt;    (.glVertex3f 0 -1 -1)&lt;br /&gt;&lt;br /&gt;    (.glEnd))&lt;br /&gt;  (def rotateT (+ 0.2 rotateT)))&lt;br /&gt;&lt;br /&gt; (displayChanged [drawable m d])&lt;br /&gt;&lt;br /&gt; (init&lt;br /&gt;  [#^GLAutoDrawable drawable]&lt;br /&gt;  (doto (.getGL drawable)&lt;br /&gt;    (.glShadeModel (. GL GL_SMOOTH))&lt;br /&gt;    (.glClearColor 0 0 0 0)&lt;br /&gt;    (.glClearDepth 1)&lt;br /&gt;    (.glEnable (. GL GL_DEPTH_TEST))&lt;br /&gt;    (.glDepthFunc (. GL GL_LEQUAL))&lt;br /&gt;    (.glHint (. GL GL_PERSPECTIVE_CORRECTION_HINT)&lt;br /&gt;         (. GL GL_NICEST)))&lt;br /&gt;  (.addKeyListener&lt;br /&gt;   drawable&lt;br /&gt;   (proxy [KeyListener] []&lt;br /&gt;     (keyPressed&lt;br /&gt;  [e]&lt;br /&gt;  (when (= (.getKeyCode e) (. KeyEvent VK_ESCAPE))&lt;br /&gt;    (exit))))))&lt;br /&gt;&lt;br /&gt; (reshape&lt;br /&gt;  [#^GLAutoDrawable drawable x y w h]&lt;br /&gt;  (when (&amp;gt; h 0)&lt;br /&gt;    (let [gl (.getGL drawable)]&lt;br /&gt;  (.glMatrixMode gl (. GL GL_PROJECTION))&lt;br /&gt;  (.glLoadIdentity gl)&lt;br /&gt;  (.gluPerspective glu 50 (/ w h) 1 1000)&lt;br /&gt;  (.glMatrixMode gl (. GL GL_MODELVIEW))&lt;br /&gt;  (.glLoadIdentity gl))))))&lt;br /&gt;&lt;br /&gt;(doto frame&lt;br /&gt;(.add canvas)&lt;br /&gt;(.setSize 640 480)&lt;br /&gt;(.setUndecorated true)&lt;br /&gt;(.setExtendedState (. Frame MAXIMIZED_BOTH))&lt;br /&gt;(.addWindowListener&lt;br /&gt; (proxy [WindowAdapter] []&lt;br /&gt;   (windowClosing [e] (exit))))&lt;br /&gt;(.setVisible true))&lt;br /&gt;(.start animator)&lt;br /&gt;(.requestFocus canvas)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's a shell script that will run it:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;#!/bin/sh&lt;br /&gt;java -cp $CLOJURE_EXT/clojure.jar:/usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar clojure.main joglExample.clj&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The libraries can be installed in Ubuntu with&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install libjogl-java&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's the refactored Java example from Wikipedia:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;import javax.media.opengl.GL;&lt;br /&gt;import javax.media.opengl.GLEventListener;&lt;br /&gt;import javax.media.opengl.GLAutoDrawable;&lt;br /&gt;import javax.media.opengl.glu.GLU;&lt;br /&gt;import java.awt.event.KeyEvent;&lt;br /&gt;import java.awt.event.KeyListener;&lt;br /&gt;import javax.media.opengl.GLCanvas;&lt;br /&gt;import java.awt.Frame;&lt;br /&gt;import java.awt.event.WindowAdapter;&lt;br /&gt;import java.awt.event.WindowEvent;&lt;br /&gt;import com.sun.opengl.util.Animator;&lt;br /&gt;&lt;br /&gt;public class joglExample implements GLEventListener, KeyListener {&lt;br /&gt;  float rotateT = 0.0f;&lt;br /&gt;  static GLU glu = new GLU();&lt;br /&gt;  static GLCanvas canvas = new GLCanvas();&lt;br /&gt;  static Frame frame = new Frame("Jogl 3D Shape/Rotation");&lt;br /&gt;  static Animator animator = new Animator(canvas);&lt;br /&gt;  public void display(GLAutoDrawable gLDrawable) {&lt;br /&gt;  final GL gl = gLDrawable.getGL();&lt;br /&gt;  gl.glClear(GL.GL_COLOR_BUFFER_BIT);&lt;br /&gt;  gl.glClear(GL.GL_DEPTH_BUFFER_BIT);&lt;br /&gt;  gl.glLoadIdentity();&lt;br /&gt;  gl.glTranslatef(0.0f, 0.0f, -5.0f);&lt;br /&gt;&lt;br /&gt;  gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);&lt;br /&gt;  gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);&lt;br /&gt;  gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);&lt;br /&gt;  gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);&lt;br /&gt;&lt;br /&gt;  gl.glBegin(GL.GL_TRIANGLES);&lt;br /&gt;&lt;br /&gt;  // Front&lt;br /&gt;  gl.glColor3f(0.0f, 1.0f, 1.0f);&lt;br /&gt;  gl.glVertex3f(0.0f, 1.0f, 0.0f);&lt;br /&gt;  gl.glColor3f(0.0f, 0.0f, 1.0f);&lt;br /&gt;  gl.glVertex3f(-1.0f, -1.0f, 1.0f);&lt;br /&gt;  gl.glColor3f(0.0f, 0.0f, 0.0f);&lt;br /&gt;  gl.glVertex3f(1.0f, -1.0f, 1.0f);&lt;br /&gt;&lt;br /&gt;  // Right Side Facing Front&lt;br /&gt;  gl.glColor3f(0.0f, 1.0f, 1.0f);&lt;br /&gt;  gl.glVertex3f(0.0f, 1.0f, 0.0f);&lt;br /&gt;  gl.glColor3f(0.0f, 0.0f, 1.0f);&lt;br /&gt;  gl.glVertex3f(1.0f, -1.0f, 1.0f);&lt;br /&gt;  gl.glColor3f(0.0f, 0.0f, 0.0f);&lt;br /&gt;  gl.glVertex3f(0.0f, -1.0f, -1.0f);&lt;br /&gt;&lt;br /&gt;  // Left Side Facing Front&lt;br /&gt;  gl.glColor3f(0.0f, 1.0f, 1.0f);&lt;br /&gt;  gl.glVertex3f(0.0f, 1.0f, 0.0f);&lt;br /&gt;  gl.glColor3f(0.0f, 0.0f, 1.0f);&lt;br /&gt;  gl.glVertex3f(0.0f, -1.0f, -1.0f);&lt;br /&gt;  gl.glColor3f(0.0f, 0.0f, 0.0f);&lt;br /&gt;  gl.glVertex3f(-1.0f, -1.0f, 1.0f);&lt;br /&gt;&lt;br /&gt;  // Bottom&lt;br /&gt;  gl.glColor3f(0.0f, 0.0f, 0.0f);&lt;br /&gt;  gl.glVertex3f(-1.0f, -1.0f, 1.0f);&lt;br /&gt;  gl.glColor3f(0.1f, 0.1f, 0.1f);&lt;br /&gt;  gl.glVertex3f(1.0f, -1.0f, 1.0f);&lt;br /&gt;  gl.glColor3f(0.2f, 0.2f, 0.2f);&lt;br /&gt;  gl.glVertex3f(0.0f, -1.0f, -1.0f);&lt;br /&gt;&lt;br /&gt;  gl.glEnd();&lt;br /&gt;&lt;br /&gt;  rotateT += 0.2f;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void displayChanged(GLAutoDrawable gLDrawable,&lt;br /&gt;                 boolean modeChanged, boolean deviceChanged) {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void init(GLAutoDrawable gLDrawable) {&lt;br /&gt;  GL gl = gLDrawable.getGL();&lt;br /&gt;  gl.glShadeModel(GL.GL_SMOOTH);&lt;br /&gt;  gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);&lt;br /&gt;  gl.glClearDepth(1.0f);&lt;br /&gt;  gl.glEnable(GL.GL_DEPTH_TEST);&lt;br /&gt;  gl.glDepthFunc(GL.GL_LEQUAL);&lt;br /&gt;  gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,&lt;br /&gt;        GL.GL_NICEST);&lt;br /&gt;  gLDrawable.addKeyListener(this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void reshape(GLAutoDrawable gLDrawable, int x,&lt;br /&gt;          int y, int width, int height) {&lt;br /&gt;  GL gl = gLDrawable.getGL();&lt;br /&gt;  if(height &amp;lt;= 0) {&lt;br /&gt;      height = 1;&lt;br /&gt;  }&lt;br /&gt;  float h = (float)width / (float)height;&lt;br /&gt;  gl.glMatrixMode(GL.GL_PROJECTION);&lt;br /&gt;  gl.glLoadIdentity();&lt;br /&gt;  glu.gluPerspective(50.0f, h, 1.0, 1000.0);&lt;br /&gt;  gl.glMatrixMode(GL.GL_MODELVIEW);&lt;br /&gt;  gl.glLoadIdentity();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void keyPressed(KeyEvent e) {&lt;br /&gt;  if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {&lt;br /&gt;      exit();&lt;br /&gt;  }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void keyReleased(KeyEvent e) {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void keyTyped(KeyEvent e) {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static void exit(){&lt;br /&gt;  animator.stop();&lt;br /&gt;  frame.dispose();&lt;br /&gt;  System.exit(0);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;  canvas.addGLEventListener(new joglExample());&lt;br /&gt;  frame.add(canvas);&lt;br /&gt;  frame.setSize(640, 480);&lt;br /&gt;  frame.setUndecorated(true);&lt;br /&gt;  frame.setExtendedState(Frame.MAXIMIZED_BOTH);&lt;br /&gt;  frame.addWindowListener(new WindowAdapter() {&lt;br /&gt;      public void windowClosing(WindowEvent e) {&lt;br /&gt;          exit();&lt;br /&gt;      }&lt;br /&gt;      });&lt;br /&gt;  frame.setVisible(true);&lt;br /&gt;  animator.start();&lt;br /&gt;  canvas.requestFocus();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here's a shell script that will run it:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;#!/bin/sh&lt;br /&gt;javac -cp /usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar joglExample.java&lt;br /&gt;java -cp ./:/usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar joglExample&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://groups.google.com/group/clojure/browse_thread/thread/74e70ce02d608c15"&gt;Gears demo in Clojure&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Jogl"&gt;Wikipedia JOGL demo&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3361858754774064013?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3361858754774064013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3361858754774064013' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3361858754774064013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3361858754774064013'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/04/opengl-in-clojure.html' title='OpenGL in Clojure'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4554569614646580382</id><published>2009-03-25T10:44:00.001-07:00</published><updated>2009-04-05T19:57:58.744-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Learning Clojure and Emacs</title><content type='html'>I had an opportunity to attend the&lt;a href="http://www.international-lisp-conference.org/2009/index"&gt; International Lisp Conference 2009&lt;/a&gt;. It was very interesting and inspiring. I learned that for all the greatness and age of Lisp, it is still a crufty and fragmented platform in practice.&lt;br /&gt;&lt;br /&gt;However, lots of people believe that &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; solves many of Lisps problems, and may be the key to the future of Lisp. Clojure is a modern dialect of Lisp that compiles to Java bytecode, cleans up much of Lisps cruft and antiquated naming, enables Java &lt;-&gt; Lisp interoperability, and has built-in support for concurrency.&lt;br /&gt;&lt;br /&gt;After I expressed my frustrations with learning Lisp and Emacs, one guy at the conference said to me matter of factly "You're going to have to battle the language and the IDE at the same time. That's how one starts on the road to Lisp. Once you get past the initial hump though, I guarantee you'll never want to go back to Java. Once you get there, you should fill out the &lt;a href="http://www.cliki.net/The%20Road%20to%20Lisp%20Survey"&gt;road to Lisp survey&lt;/a&gt;!"&lt;br /&gt;&lt;br /&gt;There does seem to be something powerful lurking in Lisp, because there are endless testimonials (&lt;a href="http://www.blogger.com/Beating%20the%20Averages%20by%20Paul%20Graham"&gt;Beating the Averages&lt;/a&gt; by Paul Graham is particularly famous and well written) on how Lisp enabled lightning fast adaptive development, is fun to program, is amazingly powerfull, is elegant, beautiful, and so on. That said, I thought I'd give Clojure a try. Emacs seems to be hailed as the best Lisp IDE, so I'll try that too.&lt;br /&gt;&lt;br /&gt;Here's the beginning (and perhaps end, only time will tell) of my modern day adventure on the road to Lisp: Clojure + Emacs + Ant + Ubuntu:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Setting Up Clojure and Emacs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#Install Java, Ant, Subversion, and Git.&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install openjdk-6-jdk ant subversion git-core emacs -y&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#Run these simple setup scripts derived from these tutorials from Riddell: &lt;a href="http://riddell.us/tutorial/clojure/clojure.html"&gt;clojure&lt;/a&gt; &lt;a href="http://riddell.us/tutorial/slime_swank/slime_swank.html"&gt;slime&lt;br /&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.curransoft.com/code/setupClojure.sh&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.curransoft.com/code/setupClojureSlime.sh&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;sh setupClojure.sh&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sh setupClojureSlime.sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The contents of the scripts are as follows (just so you can see):&lt;br /&gt;setupClojure.sh:&lt;br /&gt;&lt;pre face="Andale Mono,Lucida Console,Monaco,fixed,monospace" size="12px" style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;"&gt;&lt;code&gt;#!/bin/sh&lt;br /&gt;# Adapted from http://riddell.us/tutorial/clojure/clojure.html&lt;br /&gt;echo "Making ~/opt directory"&lt;br /&gt;mkdir ~/opt&lt;br /&gt;cd ~/opt&lt;br /&gt;echo "Getting Clojure code from SVN..."&lt;br /&gt;svn co http://clojure.googlecode.com/svn/trunk clojure&lt;br /&gt;cd clojure&lt;br /&gt;echo "Building Clojure..."&lt;br /&gt;ant&lt;br /&gt;mkdir ~/.clojure&lt;br /&gt;cp clojure.jar ~/.clojure&lt;br /&gt;cd ~/opt&lt;br /&gt;echo "Getting Clojure-Contrib code from Git..."&lt;br /&gt;git clone git://github.com/kevinoneill/clojure-contrib.git&lt;br /&gt;cd clojure-contrib&lt;br /&gt;echo "Building Clojure-Contrib"&lt;br /&gt;ant -Dclojure.jar=../clojure/clojure.jar&lt;br /&gt;cp *.jar ~/.clojure&lt;br /&gt;echo "Setting up CLOJURE_EXT environment variable and "clj" alias&lt;br /&gt;&lt;/code&gt;echo "export CLOJURE_EXT=~/.clojure&lt;br /&gt;PATH=\$PATH:~/opt/clojure-contrib/launchers/bash&lt;br /&gt;alias clj=clj-env-dir" &gt;&gt; ~/.bashrc&lt;br /&gt;&lt;code&gt;echo "Done."&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;setupClojureSlime.sh:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;#!/bin/sh&lt;br /&gt;# Adapted from http://riddell.us/tutorial/slime_swank/slime_swank.html&lt;br /&gt;cd ~/opt&lt;br /&gt;echo "Getting Clojure-Mode from GIT..."&lt;br /&gt;git clone git://github.com/jochu/clojure-mode.git&lt;br /&gt;echo "Getting Slime from GIT..."&lt;br /&gt;git clone git://git.boinkor.net/slime.git&lt;br /&gt;echo "Getting Slime from GIT..."&lt;br /&gt;git clone git://github.com/jochu/swank-clojure.git&lt;br /&gt;echo "Configuring Emacs (appending to ~/.emacs"&lt;br /&gt;echo ";; clojure-mode&lt;br /&gt;(add-to-list 'load-path \"~/opt/clojure-mode\")&lt;br /&gt;(require 'clojure-mode)&lt;br /&gt;;; swank-clojure&lt;br /&gt;(add-to-list 'load-path \"~/opt/swank-clojure\")&lt;br /&gt;(require 'swank-clojure-autoload)&lt;br /&gt;(swank-clojure-config&lt;br /&gt;(setq swank-clojure-jar-path \"~/.clojure/clojure.jar\")&lt;br /&gt;(setq swank-clojure-extra-classpaths&lt;br /&gt;(list \"~/.clojure/clojure-contrib.jar\")))&lt;br /&gt;;; slime&lt;br /&gt;(eval-after-load \"slime\"&lt;br /&gt;'(progn (slime-setup '(slime-repl))))&lt;br /&gt;&lt;br /&gt;(add-to-list 'load-path \"~/opt/slime\")&lt;br /&gt;(require 'slime)&lt;br /&gt;(slime-setup)"&amp;gt;&amp;gt;$HOME/.emacs&lt;br /&gt;echo "Done."&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In Emacs:&lt;br /&gt;M-x slime&lt;br /&gt;&lt;br /&gt;It works! You should get a REPL (Read-eval-print loop) in which you can type&lt;br /&gt;(+ 41 1) and get 42.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt; Learning Emacs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;As for learning Emacs, here's what I learned:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;emacs -nw&lt;/span&gt; starts the terminal version of emacs&lt;br /&gt;&lt;br /&gt;To get to the built-in tutorial (which is awesome for getting started), open emacs, and hit C-h t (hit Control+h, then hit t). Here are the main points of the tutorial:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;C-x means Control+x&lt;/li&gt;&lt;li&gt;M-x means Alt+x&lt;/li&gt;&lt;li&gt;C-x C-c closes emacs&lt;/li&gt;&lt;li&gt;C-v is page down&lt;/li&gt;&lt;li&gt;M-v is page up (Ironically, this collides with the very menu item which when clicked will solve the collision problem)&lt;/li&gt;&lt;li&gt;C-l centers vertically on the cursor&lt;/li&gt;&lt;li&gt;C-p is up arrow&lt;/li&gt;&lt;li&gt;C-n is down arrow&lt;/li&gt;&lt;li&gt;C-b is left arrow&lt;/li&gt;&lt;li&gt;C-f is right arrow&lt;/li&gt;&lt;li&gt;C-a is home (go to beginning of line)&lt;/li&gt;&lt;li&gt;C-e is end (go to end of line)&lt;/li&gt;&lt;li&gt;M-&lt;&gt; goes to end of file&lt;/li&gt;&lt;li&gt;C-u  gives commands numeric arguments&lt;/li&gt;&lt;li&gt;(for example C-u 8 * types ******** and C-u 10 C-n goes down 10 lines)&lt;/li&gt;&lt;li&gt;M- is another way of giving commands numeric arguments&lt;/li&gt;&lt;li&gt;C-g cancels/stops/escapes things&lt;/li&gt;&lt;li&gt;C-x 1 closes all other windows (try C-h k C-f then C-x 1)&lt;/li&gt;&lt;li&gt;C-d is the delete key&lt;/li&gt;&lt;li&gt;C-k kills (deletes but copies) the rest of a line&lt;/li&gt;&lt;li&gt;C-spacebar sets a marker, and C-w kills text between the marker and the cursor&lt;/li&gt;&lt;li&gt;C-y pastes the killed text&lt;/li&gt;&lt;li&gt;M-y cycles in place through all sets of killed text (way cool! The clipboard is a stack!)&lt;/li&gt;&lt;li&gt;C-/ is undo (C-x u and C-_ are also). Redo is undo after do - Emacs has a very unique way of handling redo - once a sequence of undos is broken by doing something (typing a character for example), the undos become events which can themselves be undone, making them effectively redos. So there is only undo, but it can be used to undo undos (which is to do a redo).&lt;/li&gt;&lt;li&gt;C-x C-f opens ("finds") a file&lt;/li&gt;&lt;li&gt;C-x C-s saves a file&lt;/li&gt;&lt;li&gt;C-x C-b list buffers (remember C-x 1 to hide the list)&lt;/li&gt;&lt;li&gt;C-x s saves some buffers (prompts you)&lt;/li&gt;&lt;li&gt;C-z suspend&lt;/li&gt;&lt;li&gt;fg (in terminal) resume&lt;/li&gt;&lt;li&gt;M-x replace-string  stringtofind  replacement  - replaces a string (repls autocompletes nicely)&lt;/li&gt;&lt;li&gt;C-s is search (C-s to go to next, enter to move cursor to search result, C-g to stop search)&lt;/li&gt;&lt;li&gt;C-r is backwards search&lt;/li&gt;&lt;li&gt;C-x 2  splits into two windows vertically&lt;br /&gt;&lt;/li&gt;&lt;li&gt;C-x 3  splits into two windows horizontally&lt;br /&gt;&lt;/li&gt;&lt;li&gt;C-x o go to the other window&lt;/li&gt;&lt;li&gt;C-x 4 C-f open file in new window&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Really Learning Emacs&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;To replace commas with newlines:&lt;br /&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;M-x replace-string ,C-q C-j&lt;/li&gt;&lt;li&gt;C-x 0 close window&lt;/li&gt;&lt;li&gt;Giving arguments to C-x o is useful for navigating more than 2 windows (&lt;a href="http://www.cs.utah.edu/dept/old/texinfo/emacs18/emacs_21.html"&gt;Emacs manual on Windows&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Copy and Paste (from &lt;a href="http://philip.greenspun.com/teaching/manuals/usermanual/emacs.html"&gt;here&lt;/a&gt;):&lt;br /&gt;C-space set mark&lt;br /&gt;C-w cut text between mark and cursor&lt;br /&gt;M-w copy all text between mark and cursor&lt;br /&gt;C-y paste&lt;/li&gt;&lt;li&gt;C-x k  Close buffer&lt;/li&gt;&lt;li&gt;M-x cd  change working directory&lt;/li&gt;&lt;li&gt;You can record little scripts, called emacs macros (from &lt;a href="http://www.delorie.com/gnu/docs/emacs/emacs_487.html"&gt;emacs manual&lt;/a&gt;):&lt;br /&gt;C-x (  Start defining a keyboard macro (start-kbd-macro).&lt;br /&gt;C-x )  End the definition of a keyboard macro (end-kbd-macro).&lt;br /&gt;C-x e  Execute the most recent keyboard macro (call-last-kbd-macro).&lt;/li&gt;&lt;li&gt;C-M-\  Autoformat/"indent region"/autoindent&lt;br /&gt;&lt;/li&gt;&lt;li&gt;C-j newline and tab&lt;/li&gt;&lt;li&gt;M-^ merge (join) lines (lots of Indentation tips from the &lt;a href="http://sunsite.univie.ac.at/textbooks/emacs/emacs_24.html#SEC208"&gt;emacs manual&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Learning SLIME&lt;/span&gt;&lt;/span&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;(Superior Lisp Interaction Mode for Emacs)&lt;br /&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;Here is a summary of &lt;a href="http://bc.tech.coop/blog/050501.html"&gt;this excellent tutorial&lt;/a&gt;, with some modifications:&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Start slime with M-x slime&lt;br /&gt;You'll get a REPL - Read Eval Print Loop&lt;br /&gt;&lt;/span&gt;Type 234, it will evaluate to 234&lt;br /&gt;Type hello, you will get an error. To get out of SLDB (Slime Debugger), hit 0&lt;br /&gt;M-p and M-n act like up and down arrows for browsing command history&lt;br /&gt;Split Emacs into two vertical windows with C-x 2&lt;br /&gt;In one window, use C-x C-f to open a new file called hello.clj&lt;br /&gt;Buffer and window manipulation review:&lt;br /&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;ul&gt;&lt;li&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;C-x o: move the cursor to the "o"ther window.&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/li&gt;&lt;li&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;C-x 1: Make there be only one window (the one with the cursor in it)&lt;/li&gt;&lt;li&gt;C-x 2: Split the current window vertically into two windows&lt;/li&gt;&lt;li&gt;C-x b: Switch the current window to a different buffer, whose name I will type. (Space does name completion.)&lt;/li&gt;&lt;li&gt;C-x C-b: Show a list of all the buffers (along with some other information like what Emacs mode each one is in, what file is loaded into each one, etc.). Moving the cursor over one and hitting enter loads that buffer into the current window.&lt;/li&gt;&lt;/ul&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Really Learning Slime&lt;/span&gt;&lt;br /&gt;Adapted from &lt;a href="http://riddell.us/tutorial/slime_swank/slime_swank.html"&gt;this tutorial&lt;/a&gt;, &lt;a href="http://common-lisp.net/project/slime/doc/slime.pdf"&gt;the Slime Manual&lt;/a&gt;, &lt;a href="http://clojure-log.n01se.net/date/2008-05-31.html"&gt;this conversation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It seems nearly impossible to find reasonable documentation for how people actually use Slime! Very frustrating. It's either a huge manual or an isolated snippet. Here's what I've found. Start from a fresh Emacs and follow these steps to learn how to use Slime:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;M-x slime  this starts Slime and gives you a REPL&lt;/li&gt;&lt;li&gt;C-x 2  splits the screen in half&lt;/li&gt;&lt;li&gt;C-x C-f test.clj  creates and opens the file test.clj&lt;/li&gt;&lt;li&gt;Paste the following code into test.clj (using Shift+insert)&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(import ;imports necessary just like in Java                                &lt;br /&gt;'(java.awt Graphics)&lt;br /&gt;'(javax.swing JPanel JFrame))&lt;br /&gt;(defn render [#^Graphics g] ;"#^" is an optional type hint to the compiler  &lt;br /&gt;(doto g ;"doto" lets you call successive functions on an object        &lt;br /&gt;(.drawString "Hello World!" 10 20)));draw "Hello World!" on the graphics passed in&lt;br /&gt;(def panel (proxy [JPanel] [] ;proxy creates anonymous subclasses           &lt;br /&gt;(paint [g] (render g)))); this line overrides JPanel's paint method&lt;br /&gt;(def frame (doto (new JFrame);doto returns its first argument               &lt;br /&gt;(.add panel);add the panel to the frame                        &lt;br /&gt;(.setBounds 100 100 100 60);set the dimensions of the frame    &lt;br /&gt;(.setVisible true)));show the frame&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C-c C-k compiles and runs the current buffer, which will pop up a window&lt;/li&gt;&lt;li&gt;Change "Hello World!" to something else&lt;/li&gt;&lt;li&gt;C-c C-c compile current top-level form (it blinks!)&lt;/li&gt;&lt;li&gt;Now resize the java window to trigger a repaint - it paints the new value&lt;/li&gt;&lt;li&gt;In the Repl (C-x C-o gets you there), enter&lt;br /&gt;(. frame setBounds 0 0 500 500)&lt;br /&gt;You'll see the frame change.&lt;/li&gt;&lt;li&gt;This is the Lisper's notion of "incremental development" or "live coding" - no rebuild is necessary, you can make changes live! Amazing!&lt;/li&gt;&lt;li&gt;Here's another example of creating a Java GUI:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(doto (JFrame.)&lt;br /&gt;(.add&lt;br /&gt;(doto (JButton. "Click me!")&lt;br /&gt;(.addActionListener&lt;br /&gt; (proxy [ActionListener] []&lt;br /&gt;   (actionPerformed [e] (println "Clicked!"))))))&lt;br /&gt;(.setBounds 400 400 200 200)&lt;br /&gt;(.setVisible true))&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Println calls and compile errors go to the buffer *inferior-lisp*, so it's nice to have it open. If you put the cursor at the end it scrolls output for you as it comes.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Misc tips:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;C-h b describes all available keybindings (very useful)&lt;/li&gt;&lt;li&gt;q hides notifications&lt;/li&gt;&lt;li&gt;C-x C-e evaluates the expression before the cursor (ONLY that expression)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Learning Basic Clojure&lt;/span&gt;&lt;/span&gt; The essentials of Lisp&lt;br /&gt;Adapted from &lt;a href="http://video.google.com/videoplay?docid=5546836985338782440&amp;amp;ei=VIbOSbiwCoOeqgKwm4itBw&amp;amp;q=sicp"&gt;Structure and Interpretation of Computer Programs lecture by Hal Abelson&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The essence of a language are its primitives, means of combination, and means of abstraction:&lt;/li&gt;&lt;li&gt;Basic primitives are numbers: 5 -&gt; 5, 1.5 -&gt; 1.5&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Combination is parentheses-based: (+ 5 6) -&gt; 11&lt;/li&gt;&lt;li&gt;Definitions are a means of abstraction: (def a 5), a -&gt; 5&lt;/li&gt;&lt;li&gt;Functions are another means of abstraction:&lt;br /&gt;(defn square [x] (* x x))&lt;br /&gt;(square 5) -&gt; 25&lt;/li&gt;&lt;li&gt;Functions can also be defined like this (fn is like lambda in Lisp):&lt;br /&gt;(def square (fn [x] (* x x)))&lt;br /&gt;defn... is "syntactic sugar" for def...fn... (they mean the same exact thing)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Conditional execution using "if" works as follows:&lt;br /&gt;(defn abs [x] (if (&amp;lt; x 0) (- x) x))&lt;br /&gt;Conditional execution using "cond" works as follows (cond works with an arbitrary number of conditional-result pairs):&lt;br /&gt;(defn abs [x] (cond (&amp;lt; x 0) (- x) (= x 0) 0 (&amp;gt; x 0) x))&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Learning Clojure&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;&lt;a href="http://www.moxleystratton.com/article/clojure/for-non-lisp-programmers"&gt;This tutorial&lt;/a&gt; is awesome. Here are the key points:&lt;br /&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;&lt;ul&gt;&lt;li&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;important atoms: true, false, nil&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;&lt;/li&gt;&lt;li&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;Strings: "hello"&lt;/li&gt;&lt;li&gt;Lists: (list 1 2 3) is equivalent to '(1 2 3)&lt;/li&gt;&lt;li&gt;Keywords - like variables but with no bindings: :a :b :foo&lt;/li&gt;&lt;li&gt;Addition: (+ 3 3 3)&lt;/li&gt;&lt;li&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;Vectors (like lists): [1 2 3] or (vector 1 2 3)&lt;/li&gt;&lt;li&gt;Maps (dictionaries): {"a" 1, "b" 2, "c" 3}&lt;/li&gt;&lt;li&gt;Map access: (get {"a" 1, "b" 2, "c" 3} "b") evaluates to 2 (commas are whitespace - they'rs not necessary but help readability)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Map access: ({"a" 1, "b" 2, "c" 3} "b") evaluates to 2&lt;/li&gt;&lt;li&gt;Definition (assignment): (def x 5) is like int x=5; in Java&lt;/li&gt;&lt;li&gt;Definition (assignment): (def my-list '(1 2 3)) is like int[] myList={1,2,3}; in Java&lt;/li&gt;&lt;li&gt;Defining functions: (defn election-year? [year] (zero? (rem year 4))) is like boolean electionYear(int year){return year%4==0;} in Java&lt;/li&gt;&lt;li&gt;Lambdas: (fn [x] (+ x 1)) creates a function that increments x&lt;/li&gt;&lt;li&gt;Lambdas: ((fn [x] (+ x 1)) 9) evaluates to 10&lt;/li&gt;&lt;li&gt;Documentation: (doc first) prints documentation for the function "first"&lt;/li&gt;&lt;li&gt;Documentation: (defn plus-one "Returns x+1" [x](+ x 1)) gives plus-one "Returns x+1" as a documentation string.&lt;/li&gt;&lt;li&gt;String contatenation: (str "Hello," " world!") evaluates to "Hello, world!"&lt;/li&gt;&lt;li&gt;If: (if (= 1 1) "yes" "no") is like 1==1?"yes":"no", and evaluates to "yes"&lt;/li&gt;&lt;li&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;Do: (do (println "Hello.") (+ 2 2)) executes &lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;(println "Hello.") then (+ 2 2) and evaluates to 4. This is how you can do sequences of stuff.&lt;/li&gt;&lt;li&gt;When (a conditional version of do): (when true (println "Hello, world") "Yes") executes (println "Hello, world") and evaluates to "Yes"&lt;/li&gt;&lt;li&gt;Let: (let [x 2, y 8] (+ x y)) evaluates to 10. The let form creates a temporary var (x and y in this case), that can only be used inside the body of the let expression.&lt;/li&gt;&lt;li&gt;Java integration: (. (new java.util.Date) (toString)) evaluates to "Thu Mar 26 20:41:12 EST 2009"&lt;/li&gt;&lt;li&gt;import: (import '(java.io FileReader))&lt;/li&gt;&lt;li&gt;Constructor invocation: (new FileReader "source.txt")&lt;br /&gt;Syntactic sugar f: (FileReader. "source.txt")&lt;/li&gt;&lt;li&gt;For loop: (loop [i 0](when (&lt;&gt;&lt;/li&gt;&lt;li&gt;For loop: (dorun (for [i (range 0 5)] (println i)))&lt;/li&gt;&lt;li&gt;For loop: (doseq i (range 0 5) (println i))&lt;/li&gt;&lt;li&gt;Sequences (Very important concept, read more &lt;a href="http://clojure.org/sequences"&gt;here&lt;/a&gt;):&lt;br /&gt;(seq [1 2 3]) creates a sequence from the vector [1 2 3]&lt;br /&gt;The following functions act on sequences: first, rest, cons&lt;/li&gt;&lt;li&gt;first (like &lt;a href="http://www.rattlesnake.com/intro/car-_0026-cdr.html"&gt;car&lt;/a&gt;): (first '("one" "two" "three")) evaluates to "one"&lt;/li&gt;&lt;li&gt;rest (like &lt;a href="http://www.rattlesnake.com/intro/car-_0026-cdr.html"&gt;cdr&lt;/a&gt;): (rest '("one" "two" "three")) evaluates to ("two" three")&lt;/li&gt;&lt;li&gt;cons: (cons 1 [2 3]) evaluates to (1 2 3)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Practical &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Clojure -&lt;/span&gt;&lt;/span&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Java Interop&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Here's an illustrative Java GUI example, taken from &lt;a href="http://clojure.org/jvm_hosted"&gt;here&lt;/a&gt;:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(import '(javax.swing JFrame JLabel JTextField JButton)&lt;br /&gt;'(java.awt.event ActionListener)&lt;br /&gt;'(java.awt GridLayout))&lt;br /&gt;(defn celsius []&lt;br /&gt;(let [frame (JFrame. "Celsius Converter")&lt;br /&gt;temp-text (JTextField.)&lt;br /&gt;celsius-label (JLabel. "Celsius")&lt;br /&gt;convert-button (JButton. "Convert")&lt;br /&gt;fahrenheit-label (JLabel. "Fahrenheit")]&lt;br /&gt;(.addActionListener convert-button&lt;br /&gt;(proxy [ActionListener] []&lt;br /&gt;(actionPerformed [evt]&lt;br /&gt;(let [c (Double/parseDouble (.getText temp-text))]&lt;br /&gt;(.setText fahrenheit-label&lt;br /&gt;(str (+ 32 (* 1.8 c)) " Fahrenheit"))))))&lt;br /&gt;(doto frame&lt;br /&gt;(.setLayout (GridLayout. 2 2 3 3))&lt;br /&gt;(.add temp-text)&lt;br /&gt;(.add celsius-label)&lt;br /&gt;(.add convert-button)&lt;br /&gt;(.add fahrenheit-label)&lt;br /&gt;(.setSize 300 80)&lt;br /&gt;(.setVisible true))))&lt;br /&gt;(celsius)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Conclusion&lt;/span&gt;&lt;br /&gt;Well, I guess I'm on the road to Lisp. So far I'm sold - there are lots of great ideas in the Lisp paradigm, and Clojure seems very elegant and usable. Livecoding was totally alien to me before, and it seems like a much better - and more fun! - way of doing things than the conventional edit-compile-run cycle.&lt;br /&gt;&lt;br /&gt;It's still a mystery how object orientation and multithreading are accomplished in Clojure, but it seems like those things are also doable. Macros are also still a mystery to me - people seem to think they are some kind of holy grail. So, though I've made some progress, there's still lots to look forward to!&lt;br /&gt;&lt;br /&gt;&lt;number&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;number&gt;&lt;number&gt;&lt;enter&gt;&lt;enter&gt;&lt;enter&gt;&lt;tab&gt;&lt;tab&gt;Links:&lt;br /&gt;&lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;&lt;br /&gt;&lt;a href="http://riddell.us/tutorial/slime_swank/slime_swank.html"&gt;Clojure with Emacs and Slime/Swank on Ubuntu&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started"&gt;Clojure Wikibook - Programming/Getting Started&lt;/a&gt;&lt;br /&gt;&lt;a href="http://grok2.tripod.com/"&gt;Emacs for vi users&lt;/a&gt;&lt;br /&gt;&lt;a href="http://jeremy.zawodny.com/blog/archives/008872.html"&gt;Emacs replace with Newline&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bc.tech.coop/blog/050501.html"&gt;Slime Tutorial&lt;/a&gt;&lt;br /&gt;&lt;a href="http://common-lisp.net/project/slime/doc/slime.pdf"&gt;Slime Manual (PDF)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.moxleystratton.com/article/clojure/for-non-lisp-programmers"&gt;Clojure Tutorial for Non-Lispers&lt;/a&gt;&lt;br /&gt;&lt;a href="http://robert.zubek.net/blog/2008/04/26/clojure-web-server/"&gt;Clojure Web Server (in less than 100 lines)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://loufranco.com/blog/files/category-20-days-of-clojure.html"&gt;20 Days of Clojure&lt;/a&gt;&lt;/tab&gt;&lt;/tab&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/enter&gt;&lt;/number&gt;&lt;/number&gt;&lt;/number&gt;&lt;br /&gt;&lt;a href="http://blip.tv/file/812787"&gt;concurrency talk&lt;/a&gt; by Rich Hickey - great overview of the hard concurrency problems that Clojure solves.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4554569614646580382?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4554569614646580382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4554569614646580382' title='113 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4554569614646580382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4554569614646580382'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/03/learning-clojure-and-emacs.html' title='Learning Clojure and Emacs'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>113</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-7908024302188153212</id><published>2009-02-28T11:50:00.000-08:00</published><updated>2009-06-08T12:58:12.010-07:00</updated><title type='text'>Getting Started with JPA</title><content type='html'>JPA, the Java Persistence API, is the current standard technology for object-relational mapping in Java (mapping Java objects to relational databases and back). This guide walks through how to create a Web Service in Glassfish which uses JPA to interact with a local MySQL database, using Eclipse as the development environment.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ingredients:&lt;/span&gt;&lt;br /&gt;Ubuntu Linux 8.10&lt;br /&gt;Glassfish 2.1 (&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/01/installing-glassfish.html"&gt;how to install&lt;/a&gt;)&lt;br /&gt;Eclipse Ganymede (Java EE version)&lt;br /&gt;MySQL 5 (install with &lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install mysql-server mysql-client&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Steps:&lt;br /&gt;&lt;/span&gt;Create a new project:&lt;br /&gt;In Eclipse: New -&gt; Project -&gt; Dynamic Web Project -&gt; name: "JPA_Test", Target Runtime: "GlassFish v2 Java EE 5" (if Glassfish is not listed, click New-&gt;Download additional Server Adapters-&gt;choose Glassfish ...) -&gt; Finish&lt;br /&gt;&lt;br /&gt;Create the following classes:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package test;&lt;br /&gt;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;public class Customer {&lt;br /&gt;private String name;&lt;br /&gt;private int id;&lt;br /&gt;&lt;br /&gt;public String getName() {&lt;br /&gt;  return name;&lt;br /&gt;}&lt;br /&gt;public void setName(String name) {&lt;br /&gt;  this.name = name;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Id&lt;br /&gt;public int getId() {&lt;br /&gt;  return id;&lt;br /&gt;}&lt;br /&gt;public void setId(int id) {&lt;br /&gt;  this.id = id;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;and&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package test;&lt;br /&gt;&lt;br /&gt;import javax.annotation.Resource;&lt;br /&gt;import javax.jws.WebService;&lt;br /&gt;import javax.persistence.EntityManager;&lt;br /&gt;import javax.persistence.EntityManagerFactory;&lt;br /&gt;import javax.persistence.PersistenceUnit;&lt;br /&gt;import javax.transaction.UserTransaction;&lt;br /&gt;&lt;br /&gt;@WebService&lt;br /&gt;public class Test {&lt;br /&gt;&lt;br /&gt;@PersistenceUnit&lt;br /&gt;private EntityManagerFactory emf;&lt;br /&gt;&lt;br /&gt;@Resource&lt;br /&gt;private UserTransaction utx;&lt;br /&gt;&lt;br /&gt;public boolean putCustomer(String name, int id) {&lt;br /&gt;  EntityManager em = emf.createEntityManager();&lt;br /&gt;  try {&lt;br /&gt;      utx.begin();&lt;br /&gt;&lt;br /&gt;      Customer c = new Customer();&lt;br /&gt;      c.setId(id);&lt;br /&gt;      c.setName(name);&lt;br /&gt;&lt;br /&gt;      em.persist(c);&lt;br /&gt;      utx.commit();&lt;br /&gt;      em.close();&lt;br /&gt;  } catch (Exception e) {&lt;br /&gt;      em.close();&lt;br /&gt;      e.printStackTrace();&lt;br /&gt;      return false;&lt;br /&gt;  }&lt;br /&gt;  return true;&lt;br /&gt;}&lt;br /&gt;public String getCustomerName(int id) {&lt;br /&gt;  EntityManager em = emf.createEntityManager();&lt;br /&gt;  Customer c = em.find(Customer.class, id);&lt;br /&gt;  return c.getName();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Under src/META-INF, put a file called persistence.xml with the following contents:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"&amp;gt;&lt;br /&gt;&amp;lt;persistence-unit name="pu1"  transaction-type="RESOURCE_LOCAL"&amp;gt;&lt;br /&gt;   &amp;lt;class&amp;gt;test.Customer&amp;lt;/class&amp;gt;&lt;br /&gt;   &amp;lt;properties&amp;gt;&lt;br /&gt;       &amp;lt;property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/test"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="toplink.jdbc.user" value="root"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="toplink.jdbc.password" value="root"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="toplink.logging.level" value="INFO"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="toplink.ddl-generation" value="drop-and-create-tables"/&amp;gt;&lt;br /&gt;   &amp;lt;/properties&amp;gt;&lt;br /&gt;&amp;lt;/persistence-unit&amp;gt;&lt;br /&gt;&amp;lt;/persistence&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Create the MySQL database to use:&lt;br /&gt;#Start the MySQL Terminal:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql -u root -p&lt;/span&gt;&lt;br /&gt;#create a database called test&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mysql&gt; CREATE DATABASE test;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Launch it:&lt;br /&gt;In Eclipse: Right click on project -&gt; Run As -&gt; Run on Server -&gt; Choose Glassfish as the server -&gt; Finish&lt;br /&gt;&lt;br /&gt;Test it:&lt;br /&gt;Go to http://localhost:4848/ -&gt; log in -&gt; Web Services -&gt; choose the "Test" web service -&gt; click the "Test" button -&gt; Enter some test info, like "Jack" as arg0 and "0" as arg2 -&gt; click the "putCustomer" button -&gt; see "True" if success, False or an exception if not.&lt;br /&gt;&lt;br /&gt;If it doesn't work, the Glassfish Log Viewer tab in Eclipse is very useful.&lt;br /&gt;&lt;br /&gt;Good luck!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Common Errors:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;javax.xml.ws.soap.SOAPFaultException: Object: .... is not a known entity type.  at ...&lt;/span&gt;&lt;br /&gt;This means that you tried to use a class with JPA that you didn't declare in your persistence.xml. Sometimes this happens even if you did declare the type, and often a restart of the server will fix it (I hate server bugs like that).&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near...&lt;/span&gt;&lt;br /&gt;This may mean that you are using a SQL keyword as a class or property name. Avoid all SQL keywords, like "value" or "column".&lt;br /&gt;&lt;br /&gt;Sources:&lt;br /&gt;&lt;a href="http://weblogs.java.net/blog/ss141213/archive/2005/12/introduction_to.html"&gt;Great tutorial by Sahoo&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.databasef1.com/tutorial/mysql-create-user.html"&gt;MySQL tips&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.dbnetworx.de/brain-backup/tutorial-running-and-facelets-support-in-netbeans-with-jpa-glassfish-and-mysql-5/"&gt;JPA tutorial for NetBeans&lt;/a&gt;&lt;br /&gt;&lt;a href="https://glassfish.dev.java.net/javaee5/persistence/persistence-example.html"&gt;Persistence example from Glassfish&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-7908024302188153212?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/7908024302188153212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=7908024302188153212' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7908024302188153212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7908024302188153212'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/02/getting-started-with-jpa.html' title='Getting Started with JPA'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-16012871217461625</id><published>2009-01-21T21:37:00.000-08:00</published><updated>2009-06-11T10:25:04.083-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish'/><title type='text'>Installing GlassFish</title><content type='html'>&lt;span&gt;Cooking up some GlassFish in Linux&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;(from &lt;a href="https://glassfish.dev.java.net/downloads/quickstart/index.html"&gt;here&lt;/a&gt; and &lt;a href="https://jax-ws.dev.java.net/guide/Developing_with_Eclipse.html"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;I put all these commands in a shell script, which can be executed with:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://bitbucket.org/curran/ubuntuautomation/raw/21ad83206eca/install_glassfish_v2_1.sh &amp;amp;&amp;amp; sh ./install_glassfish_v2_1.sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Installing Glassfish:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;(mkdir &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;~/opt&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd ~/opt&lt;/span&gt;&lt;br /&gt;# download glassfish&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://java.net/download/javaee5/v2ur2/promoted/Linux/glassfish-installer-v2ur2-b04-linux.jar&lt;br /&gt;&lt;/span&gt;# unzip glassfish&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;java -Xmx256m -jar glassfish-installer-v2ur2-b04-linux.jar&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd glassfish/&lt;br /&gt;&lt;/span&gt;# give the bin directory execute permissions&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod -R +x lib/ant/bin&lt;br /&gt;&lt;/span&gt;# run the setup&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;lib/ant/bin/ant -f setup.xml&lt;br /&gt;&lt;/span&gt;# add the glassfish bin directory to the PATH environment veriable&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "PATH=\$PATH:$HOME/opt/glassfish/bin&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;export PATH" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using Glassfish&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# to start the server, restart the terminal (for PATH to update) then run&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;asadmin start-domain domain1&lt;/span&gt;&lt;br /&gt;# to verify glassfish is working, go to &lt;a href="http://localhost:8080/"&gt;http://localhost:8080/&lt;/a&gt;&lt;br /&gt;# the admin GUI, which we'll use later, is at &lt;a href="http://localhost:4848/"&gt;http://localhost:4848/&lt;/a&gt;&lt;br /&gt;#   user: admin pass: adminadmin&lt;br /&gt;&lt;br /&gt;# to stop the server&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;asadmin stop-domain domain1&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;#To deploy a WAR file, put it in the autodeploy directory.&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mv yourwarfile.war ~/opt/glassfish/domains/domain1/autodeploy/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#To view the last 50 lines of the log file:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;tail -n 50 ~&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;/opt/glassfish/domains/domain1&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;/logs/server.log&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-weight: bold;"&gt;Notes on MySQL and Flash access&lt;/span&gt;&lt;br /&gt;# if you want MySQL support, put the lib in the right place:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.7.zip/from/http://mysql.mirror.redwire.net/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unzip&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; mysql-connector-java-5.1.7.zip&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-size:100%;" &gt;&lt;br /&gt;mv mysql-connector-java-5.1.7/mysql-connector-java-5.1.7-bin.jar ~/opt/glassfish/lib/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# if you want to access a web service through a flash-based client, you need a permissive crossdomain.xml file placed in the domain root that looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"&amp;gt;&lt;br /&gt;&amp;lt;cross-domain-policy&amp;gt;&lt;br /&gt;&amp;lt;allow-access-from domain="*"/&amp;gt;&lt;br /&gt;&amp;lt;site-control permitted-cross-domain-policies="all" /&amp;gt;&lt;br /&gt;&amp;lt;allow-http-request-headers-from domain="*" headers="SOAPAction"/&amp;gt;&lt;br /&gt;&amp;lt;/cross-domain-policy&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using the Ubuntu Package&lt;/span&gt;&lt;br /&gt;On second thought I went back and tried using the Ubuntu package. Here are some tidbits of insight, though I eventually gave up on it.&lt;br /&gt;&lt;br /&gt;This useful command finds all files and directories with "glassfish" in them:&lt;br /&gt;sudo find / -name '*glassfish*'&lt;br /&gt;&lt;br /&gt;Here are the important locations:&lt;br /&gt;&lt;br /&gt;asadmin: /usr/share/glassfishv2/bin/asadmin&lt;br /&gt;autodeploy directory: /var/lib/glassfishv2/domains/domain1/autodeploy&lt;br /&gt;log file : /var/lib/glassfishv2/domains/domain1/logs&lt;br /&gt;&lt;br /&gt;To (try to) deploy a WAR file, put it in the autodeploy directory.&lt;br /&gt;&lt;br /&gt;To view the last 100 lines of the log file:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;tail -n 100 /var/lib/glassfishv2/domains/domain1/logs/server.log&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Again I gave up on the Ubuntu package. There is just too much wrong with it:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The asadmin command doesn't work!&lt;/li&gt;&lt;li&gt;The directories are exploded into two locations, I don't get that at all.&lt;/li&gt;&lt;li&gt;Root permissions seems necessary to manipulate glassfish, this seems wrong.&lt;/li&gt;&lt;li&gt;Somehow when I deployed a WAR with a web service in it, the web service doesn't actually deploy. Very frustrating.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Enjoy!&lt;/span&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/6461387352629250590-16012871217461625?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/16012871217461625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=16012871217461625' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/16012871217461625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/16012871217461625'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/01/installing-glassfish.html' title='Installing GlassFish'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2010137726693492579</id><published>2009-01-21T21:02:00.000-08:00</published><updated>2010-08-24T09:24:11.846-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='flex builder'/><title type='text'>Flex Builder in Linux (outdated)</title><content type='html'>&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;This is an older version of this guide. &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2010/08/flex-builder-in-linux.html"&gt;Here&lt;/a&gt; is the new one&lt;br /&gt;&lt;br /&gt;Here's how to get Flex Builder working in Linux.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;mkdir ~/&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;opt&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;cd ~/opt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mkdir flex&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd flex&lt;/span&gt;&lt;br /&gt;# &lt;a href="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/europa/winter/eclipse-java-europa-winter-linux-gtk.tar.gz"&gt;download eclipse &lt;/a&gt;(3.3 because newer versions of Eclipse break Flex Builder)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/europa/winter/eclipse-java-europa-winter-linux-gtk.tar.gz&lt;/span&gt;&lt;br /&gt;# install eclipse&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 102, 0);"&gt;gunzip &lt; &lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;eclipse-java-europa-winter-linux-gtk.tar.gz&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 102, 0);"&gt; | tar xvf -&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;# create a "flexbuilder" launcher that points to this Eclipse&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;sudo sh -c 'echo "&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;#!/bin/sh \n export MOZILLA_FIVE_HOME=\"/usr/lib/mozilla/\"&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;\n export ECLIPSE_HOME=\"\$HOME/opt/flex/eclipse\" \n \$ECLIPSE_HOME/eclipse \$*&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;" &gt; &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;/bin/flexbuilder&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;sudo chmod +x /bin/&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;font-size:100%;"  &gt;flexbuilder&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#to increase memory (sometimes this is a problem), add the following to the eclipse command in the launch script:&lt;br /&gt;#-vmargs -Xms128m -Xmx1024m -XX:MaxPermSize=128m&lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;export MOZILLA_FIVE_HOME="/usr/lib/mozilla/"&lt;br /&gt;&lt;br /&gt;export ECLIPSE_HOME="$HOME/opt/flex/eclipse"&lt;br /&gt;$ECLIPSE_HOME/eclipse -vmargs -Xms128m -Xmx1024m -XX:MaxPermSize=128m$*&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# &lt;a href="http://labs.adobe.com/downloads/flexbuilder_linux.html"&gt;download flex builder&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://download.macromedia.com/pub/labs/flex/flexbuilder_linux/flexbuilder_linux_install_a4_081408.bin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# install flex builder&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod +x flexbuilder_linux_install_a4_081408.bin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;./flexbuilder_linux_install_a4_081408.bin&lt;/span&gt;&lt;br /&gt;# under "Where Would You Like Flex Builder Installed?", set it to&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;/home/yourusername/opt/flex/flexbuilder&lt;/span&gt;&lt;br /&gt;# under "Please Choose an Existing Eclipse Folder" set it to&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;/home/yourusername/opt/flex/eclipse&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Alt+F2 -&gt; type "flexbuilder" to launch.&lt;br /&gt;&lt;br /&gt;I would advise to keep separate workspaces for Flex and Java projects, because I've seen some funky behavior that indicates the Flex Builder plugin interferes with some Java features.&lt;br /&gt;&lt;br /&gt;Lets try it out:&lt;br /&gt;In Eclipse -&gt; New -&gt; Flex Project -&gt; give a name -&gt; Finish&lt;br /&gt;&lt;br /&gt;Paste the following:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&amp;gt;&lt;br /&gt;&amp;lt;mx:Label text="Hello Flex in Linux!"/&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;F11 to run, it should pop up in Firefox.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2010137726693492579?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2010137726693492579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2010137726693492579' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2010137726693492579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2010137726693492579'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/01/flex-builder-in-linux.html' title='Flex Builder in Linux (outdated)'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2653789075510291579</id><published>2009-01-19T07:23:00.000-08:00</published><updated>2009-01-21T21:40:03.113-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='WebServices'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish'/><title type='text'>Flex, WebServices, Glassfish, Eclipse</title><content type='html'>&lt;span style="font-size:78%;"&gt;1/20/2009&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was able to get a Flex client to invoke my first Web Service. I found that on the server side, a Web Service is trivial to code and deploy in a GlassFish server from Eclipse - a welcome relief from the complex BlazeDS configurations we've been dealing with. To make an existing class into a Web Service, only a @WebService annotation is needed. On the client side, the invoking code is pretty straightforward - just setting up a few listeners for response and faults. I observed that the Web Service call time (from a client on the same local network as the server, but a different machine) consistently has a pretty even distribution between 15 and 65 milliseconds.&lt;br /&gt;&lt;br /&gt;This guide details steps in Ubuntu Linux for creating an end to end system with a &lt;a href="http://www.adobe.com/products/flex/"&gt;Flex&lt;/a&gt; web GUI which invokes a &lt;a href="http://en.wikipedia.org/wiki/Web_service"&gt;Web Service&lt;/a&gt; in a &lt;a href="https://glassfish.dev.java.net/"&gt;Glassfish&lt;/a&gt; server. The steps are as follows, assuming a fresh Ubuntu:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install OpenJDK, Eclipse, and GlassFish&lt;/li&gt;&lt;li&gt;Configure Eclipse for GlassFish&lt;/li&gt;&lt;li&gt;Write, deploy, and test an "Echo" Web Service&lt;/li&gt;&lt;li&gt;Install FlexBuilder Linux Alpha&lt;/li&gt;&lt;li&gt;Write the "Echo" client&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Install OpenJDK, Eclipse, and GlassFish&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style="font-weight: bold;" href="http://lifeofaprogrammergeek.blogspot.com/2008/04/eclipse-java-development-in-ubuntu.html"&gt;Install OpenJDK and Eclipse&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/01/installing-glassfish.html"&gt;&lt;span style="font-weight: bold;"&gt;Install GlassFish&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Configure Eclipse for GlassFish&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In Eclipse:&lt;br /&gt;New -&gt; Project -&gt; Web -&gt; Dynamic Web Project -&gt; Next -&gt;&lt;br /&gt;under "Target Runtime" -&gt; New... -&gt; click "download additional server adapters" -&gt;&lt;br /&gt;select "GlassFish Java EE 5 Server" -&gt; Next -&gt; accept the terms, Finish -&gt; OK -&gt; Yes, restart now&lt;br /&gt;&lt;br /&gt;New -&gt; Dynamic Web Project -&gt; Next -&gt;&lt;br /&gt;Name:EchoService&lt;br /&gt;Make sure "Target Runtime" is set to "GlassFish v2 Java EE 5"&lt;br /&gt;-&gt; Finish&lt;br /&gt;&lt;br /&gt;Right click EchoService/WebContent/index.jsp -&gt; Run As -&gt; Run on Server -&gt; localhost GlassFish should be automatically selected, Finish&lt;br /&gt;In the console, you'll be prompted for the admin username and password - enter user: admin, pass:adminadmin&lt;br /&gt;&lt;br /&gt;If all goes well you should see an emphatic &lt;span style="font-size:130%;"&gt;Hello World!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Write, deploy, and test an "Echo" Web Service&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the EchoService project -&gt; New -&gt; Class -&gt; Name:Echo, Package:echo -&gt; Finish&lt;br /&gt;Paste the following:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package echo;&lt;br /&gt;import javax.jws.WebService;&lt;br /&gt;&lt;br /&gt;@WebService&lt;br /&gt;public class Echo {&lt;br /&gt;public String echo(String input) {&lt;br /&gt;  return input;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The only thing you need to do to write a web service is to add the @WebService annotation.&lt;br /&gt;&lt;br /&gt;Right click Echo.java -&gt; Run As -&gt; Run on Server -&gt; Finish&lt;br /&gt;&lt;br /&gt;Eclipse will display an error page at "http://localhost:8080/EchoService/WEB-INF/classes/echo/Echo.java", but thats fine, because that's not what we're trying to accomplish.&lt;br /&gt;&lt;br /&gt;To see the service, use the GlassFish admin GUI&lt;br /&gt;Go to &lt;a href="http://localhost:4848/"&gt;http://localhost:4848/&lt;/a&gt; user: admin pass: adminadmin&lt;br /&gt;On the left panel, click "Web Services" -&gt; Echo -&gt; Test -&gt;&lt;br /&gt;follow the http link (&lt;a href="http://localhost:8080//EchoService/EchoService?Tester"&gt;http://localhost:8080//EchoService/EchoService?Tester&lt;/a&gt;)&lt;br /&gt;Enter "Hello World", then you should see the SOAP messages:&lt;br /&gt;&lt;br /&gt;SOAP Request:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"&amp;gt;&lt;br /&gt;&amp;lt;S:Header/&amp;gt;&lt;br /&gt;&amp;lt;S:Body&amp;gt;&lt;br /&gt;&amp;lt;ns2:echo xmlns:ns2="http://echo/"&amp;gt;&lt;br /&gt;&amp;lt;arg0&amp;gt;Hello World!&amp;lt;/arg0&amp;gt;&lt;br /&gt;&amp;lt;/ns2:echo&amp;gt;&lt;br /&gt;&amp;lt;/S:Body&amp;gt;&lt;br /&gt;&amp;lt;/S:Envelope&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;SOAP Response:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"&amp;gt;&lt;br /&gt;&amp;lt;S:Body&amp;gt;&lt;br /&gt;&amp;lt;ns2:echoResponse xmlns:ns2="http://echo/"&amp;gt;&lt;br /&gt;&amp;lt;return&amp;gt;Hello World!&amp;lt;/return&amp;gt;&lt;br /&gt;&amp;lt;/ns2:echoResponse&amp;gt;&lt;br /&gt;&amp;lt;/S:Body&amp;gt;&lt;br /&gt;&amp;lt;/S:Envelope&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2009/01/flex-builder-in-linux.html"&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Install Flex Builder&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Write the "Echo" client&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Create an EchoService Flex Client (sources: &lt;a href="http://blog.flexexamples.com/2008/04/14/calling-a-simple-web-service-from-flex-using-the-webservice-class/"&gt;here&lt;/a&gt; and &lt;a href="http://www.adobe.com/devnet/flex/articles/flexbuilder_ws.html"&gt;here&lt;/a&gt; and &lt;a href="http://www.brucephillips.name/blog/index.cfm/2006/10/22/Using-XML-in-Flex--Tutorial-Part-4--WebService"&gt;here&lt;/a&gt; (&lt;a href="http://www.brucephillips.name/flex/webserviceexample/bin/srcview/index.html"&gt;source code&lt;/a&gt;), &lt;a href="http://livedocs.adobe.com/flex/3/langref/"&gt;Flex docs&lt;/a&gt; were also useful)&lt;br /&gt;The URL of your WSDL file is at http://localhost:8080//EchoService/EchoService?WSDL&lt;br /&gt;&lt;br /&gt;The following MXML code defines a simple GUI which calls the EchoService&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&amp;gt;&lt;br /&gt;&amp;lt;mx:Script&amp;gt;&lt;br /&gt;&amp;lt;![CDATA[&lt;br /&gt; import mx.controls.Alert;&lt;br /&gt; import mx.rpc.events.ResultEvent;&lt;br /&gt; import mx.rpc.events.FaultEvent;&lt;br /&gt;&lt;br /&gt; private var startTime:int;&lt;br /&gt; private var endTime:int;&lt;br /&gt;&lt;br /&gt; private function button_click():void {&lt;br /&gt;     webService.echo.send(textInput.text);&lt;br /&gt;     startTime = getTimer();&lt;br /&gt;     timeLabel.text = "";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private function echo_result(evt:ResultEvent):void {&lt;br /&gt;     resultLabel.text = "Result: "+evt.result.toString()&lt;br /&gt;     calcTime();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private function echo_fault(evt:FaultEvent):void {&lt;br /&gt;     Alert.show(evt.type);&lt;br /&gt;     calcTime();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private function calcTime():void {&lt;br /&gt;     endTime = getTimer();&lt;br /&gt;     timeLabel.text = "Time: " + (endTime - startTime) + "ms";&lt;br /&gt; }&lt;br /&gt;]]&amp;gt;&lt;br /&gt;&amp;lt;/mx:Script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;mx:WebService id="webService"&lt;br /&gt;&amp;lt;!-- replace this ip address with your own --&amp;gt;&lt;br /&gt; wsdl="http://129.63.16.175:8080//EchoService//EchoService?WSDL"&amp;gt;&lt;br /&gt;&amp;lt;mx:operation name="echo"&lt;br /&gt;     resultFormat="object"&lt;br /&gt;     result="echo_result(event);"&lt;br /&gt;     fault="echo_fault(event);"&amp;gt;&lt;br /&gt;&amp;lt;/mx:operation&amp;gt;&lt;br /&gt;&amp;lt;/mx:WebService&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;mx:Button id="button" label="Call service" click="button_click();" /&amp;gt;&lt;br /&gt;&amp;lt;mx:Label text="input:" /&amp;gt;&lt;br /&gt;&amp;lt;mx:TextInput id="textInput" text="Hello Flex!"/&amp;gt;&lt;br /&gt;&amp;lt;mx:Label id="timeLabel" /&amp;gt;&lt;br /&gt;&amp;lt;mx:Label id="resultLabel" /&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Replace the ip of the web service with "localhost" or your server ip, which you can find by executing&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' |cut -d: -f2 | awk '{ print $1}'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Alternatively, you could set up the web service in ActionScript as opposed to MXML:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"&amp;gt;&lt;br /&gt;&amp;lt;mx:Script&amp;gt;&lt;br /&gt;&amp;lt;![CDATA[&lt;br /&gt;    import mx.rpc.soap.WebService;&lt;br /&gt;    import mx.controls.Alert;&lt;br /&gt;    import mx.rpc.events.ResultEvent;&lt;br /&gt;    import mx.rpc.events.FaultEvent;&lt;br /&gt;&lt;br /&gt;    private var startTime:int;&lt;br /&gt;    private var endTime:int;&lt;br /&gt;    private var webService:WebService;&lt;br /&gt;&lt;br /&gt;    private function init():void{&lt;br /&gt;        webService = new WebService();&lt;br /&gt;        //replace this ip address with your own&lt;br /&gt;        webService.wsdl = "http://129.63.16.175:8080//EchoService//EchoService?WSDL"&lt;br /&gt;        webService.echo.resultFormat = "object"&lt;br /&gt;        webService.echo.addEventListener("result", echo_result);&lt;br /&gt;        webService.echo.addEventListener("fault", echo_fault);&lt;br /&gt;        webService.loadWSDL();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private function button_click():void {&lt;br /&gt;        webService.echo.send(textInput.text);&lt;br /&gt;        startTime = getTimer();&lt;br /&gt;        timeLabel.text = "";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private function echo_result(evt:ResultEvent):void {&lt;br /&gt;        resultLabel.text = "Result: "+evt.result.toString()&lt;br /&gt;        calcTime();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private function echo_fault(evt:FaultEvent):void {&lt;br /&gt;        Alert.show(evt.type);&lt;br /&gt;        calcTime();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private function calcTime():void {&lt;br /&gt;        endTime = getTimer();&lt;br /&gt;        timeLabel.text = "Time: " + (endTime - startTime) + "ms";&lt;br /&gt;    }&lt;br /&gt;]]&amp;gt;&lt;br /&gt;&amp;lt;/mx:Script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;mx:Button id="button" label="Call service" click="button_click();" /&amp;gt;&lt;br /&gt;&amp;lt;mx:Label text="input:" /&amp;gt;&lt;br /&gt;&amp;lt;mx:TextInput id="textInput" text="Hello Flex!"/&amp;gt;&lt;br /&gt;&amp;lt;mx:Label id="timeLabel" /&amp;gt;&lt;br /&gt;&amp;lt;mx:Label id="resultLabel" /&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Notes:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Build Failing due to Constructor issue&lt;/span&gt;&lt;br /&gt;I was confused for a while about this error:&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;CLI171 Command deploydir failed : Deploying application in domain failed; Deployment Error -- Exception occured in the wsgen process javax.xml.ws.WebServiceException: Unable to create JAXBContext&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;BUILD FAILED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;/home/curran/workspace/.metadata/.plugins/org.eclipse.jst.server.generic.core/serverdef/sunappsrv-ant.xml:203: The following error occurred while executing this line:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;/home/curran/workspace/.metadata/.plugins/org.eclipse.jst.server.generic.core/serverdef/sunappsrv-ant.xml:119: exec returned: 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I realized by reading the log file and reading &lt;a href="http://io.typepad.com/eben_hewitt_on_java/2007/05/dealing_with_th.html"&gt;this&lt;/a&gt; that the reason is because the exception type my service threw didn't have a no-argument constructor, which is apparently a requisite property of objects you send over the wire FROM a seb service.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Tracing Server-side Exceptions&lt;/span&gt;&lt;br /&gt;they are appended to the log file at ~/opt/glassfish/domains/domain1/logs/server.log&lt;br /&gt;&lt;br /&gt;To see the latest exceptions:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cat ~/opt/glassfish/domains/domain1/logs/server.log&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Adding JARS to the server code dependency&lt;/span&gt;&lt;br /&gt;put the jars you need into WebContent/WEB_INF/lib of your project&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2653789075510291579?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2653789075510291579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2653789075510291579' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2653789075510291579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2653789075510291579'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/01/flex-webservices-glassfish-eclipse.html' title='Flex, WebServices, Glassfish, Eclipse'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2875407789398384508</id><published>2009-01-18T10:01:00.000-08:00</published><updated>2009-01-18T14:57:50.673-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Axis2'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='soa'/><title type='text'>SOA in Eclipse Links</title><content type='html'>This Presentation (&lt;a href="http://eclipseworld.net/pdfs/eclipseworld_2008_dai307.pdf"&gt;Part 1&lt;/a&gt;, &lt;a href="http://eclipseworld.net/pdfs/eclipseworld_2008_dai407.pdf"&gt;Part 2&lt;/a&gt;) about the Eclipse WTP and SOA looks really useful.&lt;br /&gt;&lt;br /&gt;Here's some raw incoherent notes for setup of Eclipse, OpenDJK, and Tomcat in Ubuntu 8.10.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/04/eclipse-java-development-in-ubuntu.html"&gt;Install OpenJDK and Eclipse&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;# Install Tomcat manually. Don't use the Ubuntu tomcat6 package, because it spreads tomcat across the filesystem, making it difficult to configure Eclipse.&lt;br /&gt;# &lt;a href="http://tomcat.apache.org/download-60.cgi"&gt;Download&lt;/a&gt; tomcat&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd ~/opt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.ip97.com/apache.org/tomcat/tomcat-6/v6.0.18/bin/apache-tomcat-6.0.18.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;tar -zxvf apache-tomcat-6.0.18.tar.gz&lt;/span&gt;&lt;br /&gt;# Start the server&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;~/opt/apache-tomcat-6.0.18/bin/startup.sh&lt;/span&gt;&lt;br /&gt;#Go to http://localhost:8080/ to test&lt;br /&gt;#This is the command to shutdown&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;~/opt/apache-tomcat-6.0.18/bin/shutdown.sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Configure the Tomcat runtime in Eclipse:&lt;br /&gt;In Eclipse, at Window -&gt; Preferences -&gt; Server -&gt; Runtime Environment -&gt; Add -&gt; Apache Tomcat v6.0 -&gt; Next -&gt; set "Tomcat Installation Directory" to /opt -&gt; Finish -&gt; OK&lt;br /&gt;&lt;br /&gt;&lt;a href="http://myfaces.apache.org/download.html"&gt;Download Apache MyFaces libraries&lt;/a&gt;&lt;br /&gt;cd ~/opt&lt;br /&gt;wget http://mirror.its.uidaho.edu/pub/apache/myfaces/binaries/myfaces-core-1.2.5-bin.zip&lt;br /&gt;unzip myfaces-core-1.2.5-bin.zip&lt;br /&gt;&lt;br /&gt;# we need jet another jar that nobody mentioned&lt;br /&gt;cd myfaces-core-1.2.5-bin/lib&lt;br /&gt;wget http://download.java.net/maven/1/jstl/jars/jstl-1.2.jar&lt;br /&gt;&lt;br /&gt;In Eclipse:&lt;br /&gt;Project -&gt; Properties -&gt; Project Facets -&gt; check "JavaServerFaces"&lt;br /&gt;in the configuration, add ALL the jars in myfaces-core-1.2.5-bin/lib&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://forum.sabayonlinux.org/viewtopic.php?f=5&amp;amp;t=7894"&gt;Symbolic Links Advice&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.mkyong.com/tomcat/how-to-install-tomcat-in-ubuntu/"&gt;Tomcat in Ubuntu: apt-get vs manual install&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2875407789398384508?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2875407789398384508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2875407789398384508' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2875407789398384508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2875407789398384508'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/01/soa-in-eclipse-links.html' title='SOA in Eclipse Links'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1081018480540408398</id><published>2009-01-18T10:00:00.000-08:00</published><updated>2009-06-08T13:09:20.158-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu Linux</title><content type='html'>I just installed the latest Ubuntu Linux, and thought I'd write a post for people new to Linux, who are curious but have kept their distance.&lt;br /&gt;&lt;br /&gt;Ubuntu Linux is a complete free operating system - a competitor to Windows and Mac build with a philosophy of openness rather than a proprietary model. &lt;a href="http://en.wikipedia.org/wiki/Linux_kernel"&gt;Linux alone&lt;/a&gt; (the "kernel") provides the bare essentials of an operating system, so people package it into readily usable forms - together with many open source applications and components. These are called distributions. Presently, Ubuntu is the most popular Linux distribution. It makes Linux simple for anyone to set up and use.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Getting Started&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To install Ubuntu, &lt;a href="http://www.ubuntu.com/getubuntu/download"&gt;download the latest version&lt;/a&gt;, burn it to a CD, and boot to the CD. You can try it out without installing or risking anything. This gives you an impression of the look and feel, and lets you try preinstalled applications, but is much slower than normal because it's running directly off the CD. You can install Ubuntu alongside an existing Windows installation, as a "dual boot" setup where you can choose when you start the computer which system to use. This is the default setting in the installer.&lt;br /&gt;&lt;br /&gt;Once you have it installed, you can figure out what everything is by clicking or right clicking on it. You can customize the panels as much as you want - delete things, add things by dragging and dropping.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Installing Programs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of the most different things from Windows is the way in which software is installed and managed. In Ubuntu, there is an entire body of software dedicated to installing, updating, and uninstalling applications in the form of "packages". This is called a package manager. Ubuntu's package manager is APT - Advanced Packaging Tool.&lt;br /&gt;&lt;br /&gt;Ubuntu maintains a huge list of applications that can be automatically installed by the package manager. To install or remove programs, you can go to Applications -&gt; Add/Remove, which lets you browse and search packages. To install or uninstall something, check or uncheck the box next to the package, then hit "Apply Changes." After a program is installed, it will appear in the "Applications" menu, filed in the right place.&lt;br /&gt;&lt;br /&gt;Another program besides Ubuntu's "Add/Remove Programs" which lets you graphically manage packages is &lt;a href="http://www.nongnu.org/synaptic/"&gt;Synaptic&lt;/a&gt; - it also uses APT under the hood.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Standard Tools&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ubuntu comes preinstalled with open source alternatives for most tools most people use already:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Office -&gt; OpenOffice&lt;/li&gt;&lt;li&gt;Photoshop -&gt; GIMP&lt;/li&gt;&lt;li&gt;Internet Explorer, Safari -&gt; Firefox&lt;/li&gt;&lt;li&gt;AIM (or any IM client) -&gt; Pidgin&lt;/li&gt;&lt;li&gt;Skype -&gt; Egika Softphone&lt;/li&gt;&lt;li&gt;Outlook -&gt; Evolution Mail and Calendar&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;Keyboard Shortcuts&lt;/span&gt;&lt;br /&gt;There are numerous standard keyboard shortcuts which make working in Ubuntu very efficient:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Alt+tab  - switch between windows&lt;/li&gt;&lt;li&gt;Control+alt+ left/right arrow keys - switch between desktops&lt;/li&gt;&lt;li&gt;Alt+F4 - close the current window&lt;/li&gt;&lt;li&gt;F11 - fullscreen mode&lt;/li&gt;&lt;li&gt;F2 - rename a file&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;The Terminal&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The terminal is very powerful. It allows you to enter commands to the operating system directly. Most stuff that you can do in Ubuntu with menus, windows, and buttons can probably also be done by entering a command in the terminal. It can be found under Applications -&gt; Accessories -&gt; Terminal.&lt;br /&gt;&lt;br /&gt;One common use for the terminal is to install programs. For example, to install &lt;a href="http://www.winehq.org/"&gt;Wine&lt;/a&gt;, a system which lets you run &lt;a href="http://appdb.winehq.org/"&gt;most Windows programs&lt;/a&gt; in Linux, can be installed with one command:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install wine&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"sudo" gives you the power to change system files (you must manually enter your password - this is one reason why Linux is so secure)&lt;br /&gt;"apt-get install" is the command to access the installation mechanism of Ubuntu's package manager APT (Advanced Packaging Tool)&lt;br /&gt;"wine" is the name of the Ubuntu package you want APT to install. There are thousands of &lt;a href="http://packages.ubuntu.com/intrepid/"&gt;Ubuntu packages&lt;/a&gt; available.&lt;br /&gt;&lt;br /&gt;You could also install any package from Applications -&gt; Add/Remove (in fact, that program uses the &lt;span style="color: rgb(0, 102, 0);"&gt;apt-get install&lt;/span&gt; command), but once you know the package names of the programs you use often, you'll find it's faster to use the terminal.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Graphics Drivers&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ubuntu can readily install proprietary graphics drivers for you (NVidia, ATI), but you need to explicitly do it: System -&gt; Administration -&gt; Hardware Drivers -&gt; click the one you want -&gt; Activate (restart probably required). These drivers are not automatically installed because they are not open source - they are packages containing propreitary software.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Desktop The Infamous Desktop Cube&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you have a decent graphics card, and drivers installed, then some desktop effects should be enabled by default:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Window key+ e - show all desktops&lt;/li&gt;&lt;li&gt;Shift+alt+up arrow - show all windows&lt;/li&gt;&lt;li&gt;Window key+n - invert the colors of the current window&lt;/li&gt;&lt;/ul&gt;To get the desktop cube, you'll need to install the settings manager for the desktop effects, which is actually it's own project called &lt;a href="http://compiz.org/"&gt;compiz&lt;/a&gt;. Enter the following command in the terminal to install the settings manager:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install compizconfig-settings-manager&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now open System -&gt; Preferences -&gt; CompizConfig Settings Manager. There, under "Desktop" check the box next to "Desktop Cube" (click yes, disable Desktop Wall) and also check "Rotate Cube" (Effects -&gt; 3D Windows is cool too). Now try control+alt+arrows to switch between desktops. Control+alt+drag mouse lets you rotate the cube.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;I hope you enjoy Ubuntu!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;Pl&lt;/span&gt;&lt;span&gt;ease comment on this post if you have questions (such as "how do I do xyz that's really easy in Windows?"), comments, or suggestions for this introduction.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1081018480540408398?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1081018480540408398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1081018480540408398' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1081018480540408398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1081018480540408398'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/11/ubuntu-linux.html' title='Ubuntu Linux'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5661399149670675695</id><published>2009-01-18T04:30:00.000-08:00</published><updated>2009-06-08T09:43:03.352-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='sun java'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Eclipse Java development in Ubuntu</title><content type='html'>&lt;span style="font-family: arial;font-family:arial;font-size:100%;"  &gt;&lt;span style="font-size:78%;"&gt;Updated 1/18/2009&lt;/span&gt;&lt;br /&gt;In Ubuntu 8.10, here's how I got set up for Java EE development using Eclipse and OpenJDK.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold; font-family: arial;font-family:arial;font-size:100%;"  &gt;Install Java&lt;/span&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;sudo apt-get install openjdk-6-jdk -y&lt;/span&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold; font-family: arial;font-family:arial;font-size:100%;"  &gt;Install Eclipse&lt;/span&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: arial;font-family:arial;font-size:100%;"  &gt;I don't recommend &lt;span style="color: rgb(0, 102, 0);"&gt;apt-get install eclipse&lt;/span&gt;, it installs an old version doesn't work for me. Install eclipse manually instead(taken from &lt;/span&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;a href="https://help.ubuntu.com/community/EclipseIDE"&gt;this guide&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family: arial;font-family:arial;font-size:100%;"  &gt;):&lt;/span&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;br /&gt;&lt;a href="http://www.eclipse.org/downloads/"&gt;# Download the latest eclipse&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family: arial;font-family:arial;font-size:100%;"  &gt; archive&lt;/span&gt;&lt;span style="font-family: arial;font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;mkdir ~/opt&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd ~/opt&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: arial;font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://mirrors.ibiblio.org/pub/mirrors/eclipse/technology/epp/downloads/release/ganymede/SR2/eclipse-jee-ganymede-SR2-linux-gtk.tar.gz&lt;br /&gt;tar xzvf eclipse-jee-ganymede-SR2-linux-gtk.tar.gz&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;br /&gt;# create the launcher script and give it execute permissions&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;sudo sh -c 'echo "&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;#!/bin/sh \n&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt; export ECLIPSE_HOME=\"\$HOME/opt/eclipse\" \n \$ECLIPSE_HOME/eclipse \$*&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;" &gt; &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;/bin/eclipse&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: arial;font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;sudo chmod +x /bin/eclipse&lt;/span&gt;&lt;pre style="font-family: arial;font-family:arial;" &gt;&lt;span style="font-size:100%;"&gt;Now you can run eclipse by hitting alt+f2 and typing "eclipse"&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Script&lt;/span&gt;&lt;br /&gt;I created a shell script of these instructions, and it can be executed with:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://bitbucket.org/curran/ubuntuautomation/raw/aa93f53ada5a/install_eclipse.sh &amp;amp;&amp;amp; sh ./install_eclipse.sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Links:&lt;/span&gt;&lt;span style="text-decoration: underline;font-size:100%;" &gt;&lt;br /&gt;&lt;a href="https://help.ubuntu.com/community/EclipseIDE"&gt;Ubuntu Eclipse guide&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://dambalah.com/2007/09/21/install-java-on-ubuntu/"&gt;A nice installation tutorial&lt;/a&gt;&lt;br /&gt;&lt;a href="http://flurdy.com/docs/eclipse/install.html"&gt;Another good Ubuntu tutorial&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5661399149670675695?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5661399149670675695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5661399149670675695' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5661399149670675695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5661399149670675695'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/04/eclipse-java-development-in-ubuntu.html' title='Eclipse Java development in Ubuntu'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-6770673148029588545</id><published>2009-01-17T16:12:00.000-08:00</published><updated>2009-01-17T19:18:50.443-08:00</updated><title type='text'>WSAS IDE Broken</title><content type='html'>A summary of my first experience with WSAS IDE. Mostly taken from&lt;a href="http://www.ibm.com/developerworks/library/os-eclipse-wso2wsas/index.html"&gt; this great tutorial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wso2.org/downloads/wsas/2.3/"&gt;Download WSAS v2.3&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;unzip to C:\&lt;br /&gt;&lt;br /&gt;in C:\wso2wsas-2.3\bin execute install.bat (JAVA_HOME must be set first)&lt;br /&gt;choose 1) Eclipse WTP Plugin Installation&lt;br /&gt;at "Please enter Eclipse WTP Home :", enter C:\Program Files\eclipse (or wherever yours is)&lt;br /&gt;success!&lt;br /&gt;&lt;br /&gt;Open Eclipse&lt;br /&gt;Window -&gt; Preferences -&gt; Web Services -&gt; WSAS Preferences -&gt; set "WSAS Runtime" to "C:\wso2wsas-2.3" -&gt; OK&lt;br /&gt;New -&gt; Project -&gt; Web -&gt; Dynamic Web Project -&gt; Next -&gt; under "Target Runtime" hit "New..." -&gt; WSO2 -&gt; WSO2 WSAS -&gt; Finish -&gt; ProjectName: "TestService"&lt;br /&gt;&lt;br /&gt;I ran into a bug and got really frustrated, so I posted this to the &lt;a href="https://wso2.org/forum/thread/4768"&gt;WSAS Forum&lt;/a&gt;:&lt;br /&gt;&lt;p&gt;Hello,  I am trying to get started with WSAS IDE, but constantly having the same problem. I followed &lt;a href="http://www.ibm.com/developerworks/library/os-eclipse-wso2wsas/index.html"&gt;this guide&lt;/a&gt;  to get started. I am using Eclipse Ganymede for Java EE version 3.4.1, and WSAS 2.3. I'd like to use the beta, but it doesn't contain the WSAS IDE installer (or does it? am I missing it?).&lt;/p&gt; &lt;p&gt;Here's the bug: In both Windows XP and Ubuntu Hardy, when I go New -&gt; Project -&gt; Web -&gt; Dynamic Web Project -&gt; set Target Runtime to WSO WSAS, I get the error message "Runtime "WSO2 WSAS" is invalid. Missing classpath entry \serverRootDirectory\lib"&lt;/p&gt; &lt;p&gt;The problem is documented by others &lt;a href="http://www.shearer.org.uk/2008/09/wsas-and-eclipse-integration.html"&gt;here&lt;/a&gt; and &lt;a href="http://wso2.org/forum/thread/3866"&gt;here&lt;/a&gt;. The only solution I have seen is to unjar org.wso2.wsf.ide.server.wsas-2.2.jar, edit the file wsas.serverdef, setting the "default" field to point to your WSAS directory, rejar the file, and replace the old jar.&lt;/p&gt; &lt;p&gt;This is ridiculous. I really want to use WSAS IDE in my group, but I'll have a hard time convincing the group to adopt it when it requires something this silly to get working at all.&lt;/p&gt; &lt;p&gt;This bug is a deal breaker.&lt;/p&gt; &lt;p&gt;Does anyone know if this will be fixed in 3.0? Is there a recommended older version that doesn't have this problem?&lt;/p&gt; &lt;p&gt;Thanks very much, any help is greatly appreciated!&lt;/p&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Links:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://wso2.org/library/2839"&gt;WSO Tutorial from 2007&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ibm.com/developerworks/library/os-eclipse-wso2wsas/index.html"&gt;IBM Tutorial from 2008&lt;/a&gt; (really good!)&lt;a href="http://www.shearer.org.uk/2008/09/wsas-and-eclipse-integration.html"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wso2.org/project/wsas/java/2.2/docs/index_docs.html"&gt;WSAS Documentation&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wso2.org/project/wsas/java/2.2/docs/tools/ide.html"&gt;WSAS IDE Instructions&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://wso2.org/forum/thread/3866"&gt;Forum Thread on classpath error&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-6770673148029588545?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/6770673148029588545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=6770673148029588545' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6770673148029588545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6770673148029588545'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2009/01/wsas-ide-broken.html' title='WSAS IDE Broken'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5745012984192306563</id><published>2008-12-09T12:32:00.000-08:00</published><updated>2008-12-09T12:55:47.777-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Why isn't it easy in python to create an array of all zeros?</title><content type='html'>...wait a minute, how can I create an array of a size n filled with zeros in Python?&lt;br /&gt;&lt;br /&gt;I am very frustrated that this seems nearly impossible. This should be trivial, but I see no built in Python function to do this.&lt;br /&gt;&lt;br /&gt;Java -&gt; int[] a = new int[n];&lt;br /&gt;&lt;br /&gt;Python -&gt; a = []; for i in range(0,5): a.append(0)&lt;br /&gt;&lt;br /&gt;There must be a better way! Why is this so hard to find? I came across &lt;a href="http://pentangle.net/python/handbook/node39.html"&gt;this page&lt;/a&gt; who said "just use zeros(n)" .. well ..&lt;br /&gt;&lt;br /&gt;zeros(n) results in "NameError: name 'zeros' is not defined" ... oh, you need "import numpy"? thanks for leaving that detail out completely...&lt;br /&gt;&lt;br /&gt;I need to import something to create an array of a given size containing all zeros? what? ...but wait,&lt;br /&gt;&lt;br /&gt;import numpy; results in "ImportError: No module named numpy" Woah, NumPy is not there by default? I need to install an extra package, which other machines aren't guaranteed to have, meaning my code has an extra dependency just because it creates an zeroed array in one line?&lt;br /&gt;&lt;br /&gt;Why isn't this easy? Python has been good to me most of the time, but this is so frustrating - why force the programmer to iterate through an array of [1,2,3,4,5] adding 5 zeros, either that or install an extra package? This is nuts.&lt;br /&gt;&lt;br /&gt;I'd like to think that I am the one missing something, and there is a better way. Do you know of one?&lt;br /&gt;&lt;br /&gt;**update**&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cs.wlu.edu/%7Enecaise/python/Collections/ListBasics"&gt;Found it&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;Python: a=&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;*&lt;span class="nu0"&gt;n&lt;br /&gt;Java: int[] a = new int[n]&lt;br /&gt;&lt;br /&gt;much better.&lt;br /&gt;&lt;br /&gt;jeez that took way too long to find. Here are some search beacons for people who have the same issue:&lt;br /&gt;how to create a n array of length in in python&lt;br /&gt;python predetermined size array&lt;br /&gt;python zero function missing&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/6461387352629250590-5745012984192306563?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5745012984192306563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5745012984192306563' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5745012984192306563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5745012984192306563'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/12/why-isnt-it-easy-in-python-to-create.html' title='Why isn&apos;t it easy in python to create an array of all zeros?'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8916521818540503864</id><published>2008-11-17T14:34:00.000-08:00</published><updated>2008-11-19T11:32:58.064-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xargs'/><category scheme='http://www.blogger.com/atom/ns#' term='recursive'/><category scheme='http://www.blogger.com/atom/ns#' term='string replace'/><category scheme='http://www.blogger.com/atom/ns#' term='find'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='pipes'/><category scheme='http://www.blogger.com/atom/ns#' term='replace'/><category scheme='http://www.blogger.com/atom/ns#' term='sed'/><title type='text'>Global String Replace in all PHP files in a given directory tree</title><content type='html'>The beauty of the unix shell never ceases to amaze me. I wanted to install an email notification plugin for two wordpress blogs that are using the same database. Unfortunately, the email plugin always uses a hard-coded table name in the database you give it on installation, so the two plugins for the separate blogs end up using the same database table, forwarding emails from both blogs to everyone on that list.&lt;br /&gt;&lt;br /&gt;To fix this, I needed to replace all instances of the hard-coded table name 'wp_email_list' in all the PHP files (all in the ./temp directory) with something else, say 'wp_email_list_2', before running the install script. I figured out how to do this with one line of Unix:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;find ./temp -name '*.php' | xargs sed -i 's/wp_email_list/wp_email_list_2/g'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/10/wordpress-email-notifications.html"&gt;Here's where it's used&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-8916521818540503864?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8916521818540503864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8916521818540503864' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8916521818540503864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8916521818540503864'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/11/global-string-replace-in-all-php-files.html' title='Global String Replace in all PHP files in a given directory tree'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-3491817855452603394</id><published>2008-11-14T07:13:00.000-08:00</published><updated>2009-07-31T11:51:22.494-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='Rserve'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>Interfacing to R from Java</title><content type='html'>I'd like to write some Java code which interfaces to &lt;a href="http://en.wikipedia.org/wiki/R_%28programming_language%29"&gt;R&lt;/a&gt; (a statistical computing language). This post describes how to set up and code a Java program which interfaces to R. Here's how I did it in Ubuntu Linux and Eclipse:&lt;br /&gt;&lt;br /&gt;#install R&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install r-base&lt;/span&gt;&lt;br /&gt;#install rserve&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install r-cran-rserve&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;#start Rserve as a daemon (&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;default port for Rserve is 6311&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;R CMD Rserve&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#Make a Java project in Eclipse.&lt;br /&gt;#Make a directory called lib under that project.&lt;br /&gt;#Open a terminal, go to the lib directory, execute&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.rforge.net/Rserve/files/RserveEngine.jar&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.rforge.net/Rserve/files/REngine.jar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In Eclipse, refresh (F5), right click those library files -&gt; add to build path.&lt;br /&gt;&lt;br /&gt;Paste the following code:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;public static void main(String[] args) {&lt;br /&gt;try {&lt;br /&gt; // Establish the R connection&lt;br /&gt; RConnection c = new RConnection();&lt;br /&gt;&lt;br /&gt; // Create test data (Java array, R Vector)&lt;br /&gt; int n = 100;&lt;br /&gt; double[] dataX = new double[n];&lt;br /&gt; double[] dataY = new double[n];&lt;br /&gt;&lt;br /&gt; for (int i = 0; i &lt; l =" c.eval(" lx =" (double[])" ly =" (double[])" lx = ");   for (int i = 0; i &lt; n; i++)    System.out.print(lx[i]+" ly = ");   for (int i = 0; i &lt; n; i++)    System.out.print(ly[i]+"&gt;&lt;/pre&gt;I also figured out how to start Rserve from within Java. Here's the code:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;public static void main(String[] args) {&lt;br /&gt;     Rconnection c = getLocalRconnection();&lt;br /&gt;     if (c != null) {&lt;br /&gt;         try {&lt;br /&gt;             double[] d = c.eval("rnorm(10)").asDoubleArray();&lt;br /&gt;             for (double n : d)&lt;br /&gt;                 System.out.println(n);&lt;br /&gt;         } catch (RSrvException e) {&lt;br /&gt;             e.printStackTrace();&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static Rconnection getLocalRconnection() {&lt;br /&gt;     try {&lt;br /&gt;         return new Rconnection();&lt;br /&gt;     } catch (RSrvException e) {&lt;br /&gt;         //If we get this kind of error, it may be because Rserve is not running&lt;br /&gt;         if (e.getMessage().equals("Cannot connect: Connection refused")) {&lt;br /&gt;             try {&lt;br /&gt;                 String rserveStartCommand = "R CMD Rserve --vanilla";&lt;br /&gt;                 //do a blocking call to the shell command for starting Rserve&lt;br /&gt;                 int exitValue = Runtime.getRuntime().exec(rserveStartCommand).waitFor();&lt;br /&gt;                 //if it returned success, try connecting again&lt;br /&gt;                 if (exitValue == 0)&lt;br /&gt;                     return new Rconnection();&lt;br /&gt;                 //otherwise, Rserve is probably not installed&lt;br /&gt;                 else&lt;br /&gt;                     System.err.println("Could not start Rserve - is it installed properly? Shell command \""+rserveStartCommand+"\" exited with exit value "+exitValue+".");&lt;br /&gt;             } catch (Exception e1) {&lt;br /&gt;                 e1.printStackTrace();&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;         else&lt;br /&gt;             e.printStackTrace();&lt;br /&gt;     }&lt;br /&gt;     return null;&lt;br /&gt; }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;Links:&lt;a href="http://www.rforge.net/JRI/"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://stats.math.uni-augsburg.de/Rserve/down.shtml"&gt;&lt;/a&gt;&lt;a href="http://www.rforge.net/Rserve/files/"&gt;Rserve downloads (includes libs)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-3491817855452603394?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/3491817855452603394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=3491817855452603394' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3491817855452603394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/3491817855452603394'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/11/interfacing-to-r-from-java.html' title='Interfacing to R from Java'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5823528985277016497</id><published>2008-11-13T15:04:00.000-08:00</published><updated>2008-11-22T15:33:02.724-08:00</updated><title type='text'>First Stab: JAX-WS Web Services in Ubuntu</title><content type='html'>Raw personal notes from my first experience installing GlassFish and deploying a WebService. I'll be posting a cleaned up version soon.&lt;br /&gt;&lt;br /&gt;From a fresh Ubuntu 8.10 install:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install openjdk-6-jdk glassfishv2 -y&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now the server is installed and started - go to http://localhost:8080/ to see.&lt;br /&gt;&lt;br /&gt;I guess install-dir is /usr/share/glassfishv2&lt;br /&gt;&lt;br /&gt;..from &lt;a href="https://glassfish.dev.java.net/downloads/quickstart/index.html"&gt;QuickStart&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;Add path to PATH:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "PATH=\$PATH:/usr/share/glassfishv2/bin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;export PATH" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;br /&gt;restart terminal&lt;br /&gt;&lt;br /&gt;After some hunting, I found from the config file (asenv.conf) from the line:&lt;br /&gt;AS_DEF_DOMAINS_PATH="/var/lib/glassfishv2/domains"&lt;br /&gt;that the "domains" directory is here (different from the outdated &lt;a href="https://glassfish.dev.java.net/downloads/quickstart/index.html"&gt;QuickStart&lt;/a&gt;):&lt;br /&gt;/var/lib/glassfishv2/domains&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Deploy a test:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://glassfish.dev.java.net/downloads/quickstart/hello.war&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mv hello.war /var/lib/glassfishv2/domains/domain1/autodeploy/&lt;/span&gt;&lt;br /&gt;It worked! go to &lt;a href="http://localhost:8080/hello/"&gt;http://localhost:8080/hello/&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;War files can be deployed in GlassFish by putting them in &lt;span style="color: rgb(0, 102, 0);"&gt;autodeploy.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Web Admin of Glassfish:&lt;/span&gt;&lt;br /&gt;Go to &lt;a href="http://localhost:4848/"&gt;http://localhost:4848/&lt;/a&gt; user: admin pass: adminadmin&lt;br /&gt;sweet!&lt;br /&gt;&lt;br /&gt;...from &lt;a href="https://metro.dev.java.net/getting-started/basic.html"&gt;Building a JAX-WS Application in the Metro Environment&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget https://metro.dev.java.net/getting-started/wsit-jaxws-fromjava.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unzip wsit-jaxws-fromjava.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm wsit-jaxws-fromjava.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd wsit-jaxws-fromjava/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;AS_HOME=/usr/share/glassfishv2/bin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;export AS_HOME&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ant server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;it breaks because it's expecting domains/domain1 to be under &lt;span style="color: rgb(0, 0, 0);"&gt;/usr/share/glassfishv2/bin&lt;/span&gt;, but instead it's under /var/lib/glassfishv2/.&lt;br /&gt;comment out line 235 of build.xml&lt;br /&gt;     &lt;!-- &lt;antcall target="deploy"&gt; argh we'll do it ourselves --&gt;&lt;br /&gt;&lt;br /&gt;try again:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ant server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now there is a war, which we can move into autodeploy:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo mv ./build/war/wsit-jaxws-fromjava.war /var/lib/glassfishv2/domains/domain1/autodeploy/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Verify that it's working:&lt;br /&gt;&lt;a href="http://localhost:8080/wsit-jaxws-fromjava/addnumbers?wsdl"&gt;http://localhost:8080/wsit-jaxws-fromjava/addnumbers?wsdl&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;building the client:&lt;br /&gt;and ///arrgh - persueing another path, this ant execution is all messed up&lt;br /&gt;&lt;br /&gt;...using &lt;a href="https://jax-ws.dev.java.net/guide/Developing_with_Eclipse.html"&gt;Developing Metro in Eclipse&lt;/a&gt;...&lt;br /&gt;Eclipse can't access the domain. solution [seems like a hack - why is is like this in the first place? is it normal for the root to own the default domain?]:&lt;br /&gt;sudo chmod -R 777 /var/lib/glassfishv2&lt;br /&gt;&lt;br /&gt;..after following instructions...&lt;br /&gt;&lt;br /&gt;it works!!&lt;br /&gt;&lt;br /&gt;..Addendum..&lt;br /&gt;to start glassfish, execute&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;/usr/share/glassfishv2/bin/asadmin start-domain domain1&lt;/span&gt;&lt;br /&gt;user: admin&lt;br /&gt;pass: adminadmin&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="https://glassfish.dev.java.net/downloads/quickstart/index.html"&gt;Glassfish: getting started&lt;/a&gt;&lt;br /&gt;&lt;a href="https://metro.dev.java.net/getting-started/basic.html"&gt;Getting Started with Metro&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ammmore.federicocarrara.it/wp-content/howto.txt"&gt;Some guy's installation notes&lt;/a&gt;&lt;br /&gt;&lt;a href="https://jax-ws.dev.java.net/guide/Developing_with_Eclipse.html"&gt;Developing Metro in Eclipse&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5823528985277016497?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5823528985277016497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5823528985277016497' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5823528985277016497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5823528985277016497'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/11/first-stab-jax-ws-web-services-in.html' title='First Stab: JAX-WS Web Services in Ubuntu'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8089562109606660737</id><published>2008-11-12T11:15:00.001-08:00</published><updated>2008-11-12T11:26:53.706-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='word count'/><category scheme='http://www.blogger.com/atom/ns#' term='lines of code'/><category scheme='http://www.blogger.com/atom/ns#' term='line count'/><title type='text'>Recursive Word Count</title><content type='html'>&lt;a href="http://www.terminally-incoherent.com/blog/2007/03/08/recursive-word-count/"&gt;Here&lt;/a&gt; is a golden link I dug up recently for how to do recursive line count in Unix - it will tell you how many lines of Java code total are in a given directory:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wc -l `find . -name *.java`&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ahh, beautiful!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-8089562109606660737?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8089562109606660737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8089562109606660737' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8089562109606660737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8089562109606660737'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/11/recursive-word-count.html' title='Recursive Word Count'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-6709967852091576817</id><published>2008-10-29T11:39:00.000-07:00</published><updated>2008-11-17T15:37:51.873-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='notification'/><category scheme='http://www.blogger.com/atom/ns#' term='email'/><category scheme='http://www.blogger.com/atom/ns#' term='WordPress'/><title type='text'>Wordpress Email Notifications</title><content type='html'>I want Wordpress to notify people through email of new posts. Here's how I got email notifications working on my existing &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/09/installing-wordpress-blog.html"&gt;installation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In your wordpress directory (the one which contains wp-content):&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.watershedstudio.com/files/email_notification_v2.3.1.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unzip email_notification_v2.3.1.zip -d ./temp&lt;/span&gt;&lt;br /&gt;#The following line is a hack to use a different table name than the default (to keep two installations in the same database distinct)&lt;br /&gt;#find ./temp -name '*.*' | xargs sed -i 's/wp_email_list/wp_email_list_2/g'&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cp -r temp/maillist/ ./maillist/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cp -r temp/wordpress/wp-content/plugins/wp-email-notification/ ./wp-content/plugins/wp-email-notification/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod 666 maillist/wpemn_config.php&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm -r ./temp&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm email_notification_v2.3.1.zip&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;open in a browser yoursite.com/maillist/install.php&lt;br /&gt;In the installer, be sure to set: Default Notification Value: Yes - this triggers sending notifications for new posts.&lt;br /&gt;&lt;br /&gt;After finishing that, remove the installer:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm maillist/install.php&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Go to yoursite.com/wp-admin/plugins.php and click "activate" next to the entry WordPress Email Notification Plugin v2.3.1&lt;br /&gt;&lt;br /&gt;Now you should have an admin GUI under Manage -&gt; Email Notification&lt;br /&gt;&lt;br /&gt;The last thing is to add a text box somewhere for the user to subscribe to the mailing list. We need get our hands dirty and edit some PHP to do this. I wanted to add it to the sidebar, so I added&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;li&amp;gt;&amp;lt;h3&amp;gt;Email Notifications&amp;lt;/h3&amp;gt;&lt;br /&gt;    &amp;lt;form method="post" action="maillist/index.php"&amp;gt;Enter your e-mail address here to receive notifications of new posts&amp;lt;br /&amp;gt;&lt;br /&gt;    &amp;lt;input type="text" name="email" size="12" maxlength="50" /&amp;gt;&lt;br /&gt;    &amp;lt;input type="submit" name="submit" value="Sign me up!" /&amp;gt;&lt;br /&gt;    &amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;to the file wp-content/themes/aeros/sidebar.php (I'm using the aeros theme, this will be whatever theme you are using, and the placement may be different), right before the end - before these lines&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&amp;lt;!-- end sidebar --&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;/span&gt;It works!!!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://watershedstudio.com/portfolio/software-development/wordpress-email-notification-plugin"&gt;Email Notification Plugin&lt;/a&gt; - Instructions taken mostly from the install.txt in this download.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-6709967852091576817?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/6709967852091576817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=6709967852091576817' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6709967852091576817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6709967852091576817'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/10/wordpress-email-notifications.html' title='Wordpress Email Notifications'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1624541632051722817</id><published>2008-10-27T12:54:00.001-07:00</published><updated>2009-02-03T14:19:55.098-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='pseudocode'/><title type='text'>Algorithms in LaTeX</title><content type='html'>I was pleased to find that getting your pseudocode to look exactly like the code in Introduction to Algorithms textbook is straightforward - just use &lt;a href="http://www.cs.dartmouth.edu/%7Ethc/clrscode/"&gt;this clrscode package&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;If you're using texlive, you can install the clrscode package by installing the following Ubuntu package:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install texlive-science&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1624541632051722817?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1624541632051722817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1624541632051722817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1624541632051722817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1624541632051722817'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/10/algorithms-in-latex.html' title='Algorithms in LaTeX'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-6040038970684103376</id><published>2008-09-30T11:15:00.000-07:00</published><updated>2008-09-30T11:34:05.110-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Using Vim for LaTeX</title><content type='html'>I found myself wanting some of the nice features of Vim while editing LaTeX in Kile, so I tried using Vim for LaTeX. It works very well, and I figured out a great way of setting up - mapping a keystroke to compiling the LaTex document, and having a document viewer constantly open, looking at the LaTeX output. Keeping one viewer open the advantage over opening a new one every time that it stays in the same place in the document.&lt;br /&gt;&lt;br /&gt;The puzzle I solved and want to share with the world is how to add the feature that ctrl+F11 maps to the action of compiling the currently open document and clearing the terminal when no errors occurred, using one console command. Here it is:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo 'map &lt;c-f11&gt; :w&lt;cr&gt;:!latex % &amp;amp;&amp;amp; clear&lt;enter&gt;' &gt;&gt; ~/.vimrc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;a href="http://www.nabble.com/Compiling-LaTeX-within-vim---Two-Questions-td15247365.html"&gt;Compiling LaTeX within vim&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-6040038970684103376?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/6040038970684103376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=6040038970684103376' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6040038970684103376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6040038970684103376'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/using-vim-for-latex.html' title='Using Vim for LaTeX'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-726197381739013057</id><published>2008-09-24T07:14:00.000-07:00</published><updated>2008-11-17T13:17:52.400-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='WordPress'/><title type='text'>Installing a WordPress Blog</title><content type='html'>Here's how I ended up installing a WordPress blog on a server at my university:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;# ssh into the server:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ssh username@host.name&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;# Create the directory for the blog:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd public_html&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mkdir blogdirectory&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;# Download and unzip WordPress there&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd blogdirectory&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://wordpress.org/latest.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unzip wordpress-2.6.3.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mv wordpress/* ./&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm wordpress-2.6.3.zip&lt;br /&gt;rm -r wordpress&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;# Edit wp-config.php&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mv wp-config-sample.php wp-config.php&lt;/span&gt;&lt;br /&gt;# Edit the database details of wp-config.php&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;#Install to the Database&lt;/span&gt;&lt;br /&gt;Navigate in a web browser to the location of the blog, this will start an install process which asks for a blog title and your email. That's it!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Editing Themes&lt;/span&gt;&lt;br /&gt;I wanted the posts to show the author. It turns out there is no GUI for this, you need to edit a PHP file. It turned out to be very easy - just change line 11 in blog/wp-content/themes/default/index.php from&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;small&amp;gt;&amp;lt;?php the_time('F jS, Y') ?&amp;gt; &amp;lt;!-- by &amp;lt;?php the_author() ?&amp;gt; --&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;to&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;small&amp;gt;&amp;lt;?php the_time('F jS, Y') ?&amp;gt;  by &amp;lt;?php the_author() ?&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Also, you could give write permissions to all the theme files, so you could use the WordPress Theme Editor GUI for editing the PHP files:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd blog&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod -R 777 wp-content&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Password Protecting the Directory&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd blog&lt;/span&gt;&lt;br /&gt;# Create the password file&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;htpasswd -c .htpasswd username&lt;/span&gt;&lt;br /&gt;# Create the .htaccess file, changing &lt;span style="color: rgb(0, 0, 0);"&gt;/full/path/to/.htpasswd to the path to the blog directory, and "Password Protected Site"" to the message you want displayed to users as the password is being asked for&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "AuthUserFile /full/path/to/.htpasswd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;AuthType Basic&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;AuthName \"Password Protected Site\"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;Require valid-user" &gt; .htaccess&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I moved the blog directory without following &lt;a href="http://www.saibharadwaj.com/blog/?p=17"&gt;the instructions&lt;/a&gt;, so I had to do some rearranging which involved creating a symlink from the old directory to the new one (where newlocation and oldlocation are the full paths to your new and old locations on the same server)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ln -s newlocation oldlocation&lt;/span&gt;&lt;br /&gt;Then I changed the URL in the WordPress admin GUI to the new one (accessed from the old location through the symlink) Then I removed the symlink&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unlink oldlocation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Installing a Theme&lt;/span&gt;&lt;br /&gt;I picked the Aero theme from &lt;a href="http://wordpress.org/extend/themes/"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;cd wp-content/themes/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;wget http://wordpress.org/extend/themes/download/aeros.1.0.4.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;unzip aeros.1.0.4.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;rm aeros.1.0.4.zip&lt;/span&gt;&lt;br /&gt;Now you can navigate to the themes page of the GUI and select the new theme.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Changing the Maximum Upload Size&lt;/span&gt;&lt;br /&gt;I tried to upload media from the posts page, and it told me "This file is too big. Your php.ini upload_max_filesize is 2M" I found &lt;a href="http://www.theblogexperiment.com/blog-forum/showthread.php?t=1830%20upload_max_filesize"&gt;this post&lt;/a&gt;, and their method worked - adding some stuff to .htaccess. Here's what I did:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd blog&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "php_value upload_max_filesize 30M&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;php_value post_max_size 30M&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;php_value memory_limit 128M&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;php_value max_execution_time 3600" &gt;&gt; .htaccess&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Using LaTeX&lt;/span&gt;&lt;br /&gt;&lt;a href="http://wordpress.org/extend/plugins/latex/"&gt;Here &lt;/a&gt;is the site of the LaTeX Wordpress plugin. Here's how to install it:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd blog/wp-content/plugins&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://downloads.wordpress.org/plugin/latex.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unzip latex.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm  latex.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd ../../wp-content&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mkdir cache&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod 777 cache&lt;/span&gt;&lt;br /&gt;Now go to the plugins page from the WordPress GUI, and click "Activate" next to "Latex for WordPress" to enable the plugin. Now, text surrounded by $$...$$ will appear as beautiful rendered image of LaTeX. This plugin uses the WordPress.com LaTeX service. Try this for example:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;$$\Theta = \Omega(\delta)$$&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Appears as&lt;br /&gt;&lt;br /&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_c8St2I7onXQ/SN1cEDtoZHI/AAAAAAAAAFc/RM98aiBpAZY/s200/tex.png" alt="" id="BLOGGER_PHOTO_ID_5250453965369795698" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;You can also &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/10/wordpress-email-notifications.html"&gt;add email notifications of posts&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://codex.wordpress.org/Installing_WordPress"&gt;Official Install Page&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.saibharadwaj.com/blog/?p=17"&gt;move instructions&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wordpress.org/extend/plugins/latex/"&gt;LaTeX plugin&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-726197381739013057?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/726197381739013057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=726197381739013057' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/726197381739013057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/726197381739013057'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/installing-wordpress-blog.html' title='Installing a WordPress Blog'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_c8St2I7onXQ/SN1cEDtoZHI/AAAAAAAAAFc/RM98aiBpAZY/s72-c/tex.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2658432780593693754</id><published>2008-09-23T11:42:00.000-07:00</published><updated>2008-09-23T11:46:19.417-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='file management'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='regular expressions'/><title type='text'>Remove Files By Type in Unix</title><content type='html'>This is sweet! Remove all files except those ending in .tex:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm !(*.tex)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://www.unix.com/unix-dummies-questions-answers/51400-how-remove-all-except-one-file.html"&gt;Original&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2658432780593693754?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2658432780593693754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2658432780593693754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2658432780593693754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2658432780593693754'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/remove-files-by-type-in-unix.html' title='Remove Files By Type in Unix'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4401981220034468125</id><published>2008-09-22T13:50:00.000-07:00</published><updated>2010-09-12T19:39:29.224-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='openjdk'/><title type='text'>Setting Up Tomcat</title><content type='html'>&lt;div&gt;Below are instructions for two ways of installing and running Tomcat: through the Ubuntu package and manually. I prefer manually installing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Using the Ubuntu package:&lt;/b&gt;&lt;/div&gt;&lt;a href="http://en.wikipedia.org/wiki/Apache_Tomcat"&gt;Tomcat&lt;/a&gt; setup in Ubuntu 8.04:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;#Install OpenJDK&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install openjdk-6-jre openjdk-6-jdk -y &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo update-java-alternatives -s java-6-openjdk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;#Install Tomcat&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install tomcat5.5 -y&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We can see it's running by executing&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo /etc/init.d/tomcat5.5 status&lt;/span&gt;&lt;br /&gt;stop it with&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo /etc/init.d/tomcat5.5 stop&lt;/span&gt;&lt;br /&gt;start it with&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo /etc/init.d/tomcat5.5 start&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Manually:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;b&gt;&lt;div&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;echo "&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;div style="display: inline !important; "&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" &gt;export JRE_HOME=/usr/lib/jvm/java-6-openjdk/&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;div style="display: inline !important; "&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" &gt;" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;wget http://apache.mirrors.tds.net//tomcat/tomcat-7/v7.0.2-beta/bin/apache-tomcat-7.0.2.zip&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;unzip &lt;/span&gt;&lt;/span&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;apache-tomcat-7.0.2.zip&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;rm &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;apache-tomcat-7.0.2.zip&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;cd apache-tomcat-7.0.2&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" &gt;cat RUNNING.txt&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;div style="display: inline !important; "&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" &gt;chmod +x *.sh&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;./startup.sh&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;b&gt;&lt;div style="display: inline !important; "&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;mkdir ~/opt&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;cd ~/opt&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;wget&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;Links:&lt;br /&gt;&lt;a href="http://douglasjarquin.com/articles/java-and-tomcat-on-ubuntu-hardy/"&gt;Nice Setup guide&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/6461387352629250590-4401981220034468125?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4401981220034468125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4401981220034468125' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4401981220034468125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4401981220034468125'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/setting-up-tomcat.html' title='Setting Up Tomcat'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2937697506494138138</id><published>2008-09-22T10:08:00.000-07:00</published><updated>2008-09-22T10:12:28.502-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='password protect'/><category scheme='http://www.blogger.com/atom/ns#' term='password'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><title type='text'>Password Protecting a Folder</title><content type='html'>I wanted to password protect an entire directory of a website. &lt;a href="http://www.elated.com/articles/password-protecting-your-pages-with-htaccess/"&gt;Here&lt;/a&gt;'s a great guide for using .htaccess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2937697506494138138?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2937697506494138138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2937697506494138138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2937697506494138138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2937697506494138138'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/password-protecting-folder.html' title='Password Protecting a Folder'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1628375193443055861</id><published>2008-09-08T08:59:00.000-07:00</published><updated>2010-10-02T16:28:24.490-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Starting to Learn Flex</title><content type='html'>I want to do &lt;a href="http://en.wikipedia.org/wiki/Adobe_Flash"&gt;&lt;/a&gt; development in Ubuntu Linux, here's how I got started:&lt;br /&gt;&lt;span style="font-size:180%;"&gt;#install the Flash plugin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install flashplugin-nonfree&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;# Install Sun's Java&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;" &gt;sudo apt-get install sun-java6-jdk&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;the "java" command still points to the old version. We can change that with&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);font-family:arial;" &gt;sudo update-java-alternatives -s java-6-sun&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;# Install the Flex SDK (I chose the most recent fully Open Source version from &lt;/span&gt;&lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3"&gt;the download page&lt;/a&gt;)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://flexorg.wip3.adobe.com/flexsdk/3.1.0.2710/flex_sdk_3.1.0.2710_mpl.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo unzip -d &lt;/span&gt;&lt;strong style="font-weight: normal; color: rgb(0, 102, 0);"&gt;/opt/flex_sdk_3 &lt;/strong&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;flex_sdk_3.1.0.2710_mpl.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo chmod +x /opt/flex_sdk_3/bin/mxmlc&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm flex_sdk_3.1.0.2710_mpl.zip&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;# Add the Flex compiler to your path&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "# Flex stuff&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;PATH=\$PATH:/opt/flex_sdk_3/bin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;export PATH&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;br /&gt;# restart the terminal for the changes to take effect.&lt;br /&gt;# test if it worked by typing "mxmlc"&lt;br /&gt;I got the error:&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;bash: /opt/flex_sdk_3/bin/mxmlc: /bin/sh^M: bad interpreter: No such file or directory&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What?! The dos newlines are causing errors in the shell script? Arrgh&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install tofrodos&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo fromdos /opt/flex_sdk_3/bin/mxmlc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;# Compile and Run an Example&lt;span style="font-size:100%;"&gt; (taken from &lt;a href="http://www.adobe.com/devnet/flex/quickstart/coding_with_mxml_and_actionscript/"&gt;Here&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;# Put the following text in button.mxml&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application&lt;br /&gt; xmlns:mx="http://www.adobe.com/2006/mxml"&lt;br /&gt; horizontalAlign="center" verticalAlign="center"&lt;br /&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;mx:Button id="myButton" label="I'm a button!" /&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;# Compile it into an SWF&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mxmlc button.mxml&lt;/span&gt;&lt;br /&gt;# Run it in firefox&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;firefox button.swf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hooray!!!&lt;br /&gt;&lt;br /&gt;..more to come&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://www.cyberciti.biz/faq/ubuntu-linux-how-to-install-flash-player-for-firefox/"&gt;Installation Tips&lt;/a&gt;&lt;br /&gt;Wikipedia: &lt;a href="http://en.wikipedia.org/wiki/Adobe_Flash"&gt;Flash&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Macromedia_Flex"&gt;Flex&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/ActionScript"&gt;ActionScript&lt;/a&gt;&lt;br /&gt;&lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3"&gt;Adobe Flex Open Source download page&lt;/a&gt;&lt;br /&gt;&lt;a href="http://freedomculture.wordpress.com/2007/05/13/adobe-flex-development-on-ubuntu-linux/"&gt;Older guide to installinf Flex in Ubuntu&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bottomupflash.wordpress.com/"&gt;Blog about learning Flash&lt;/a&gt;&lt;br /&gt;&lt;a href="http://asantoso.wordpress.com/2008/05/18/flex-3-sdk-command-line-development-with-example-on-linux/"&gt;Linux Flex Tutorial&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.adobe.com/devnet/flex/quickstart/coding_with_mxml_and_actionscript/"&gt;Adobe Flex - Getting Started&lt;/a&gt;&lt;br /&gt;&lt;a href="http://livedocs.adobe.com/blazeds/1/blazeds_devguide/lcoverview_4.html#1072892"&gt;FLEX and BlazeDS&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1628375193443055861?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1628375193443055861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1628375193443055861' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1628375193443055861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1628375193443055861'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/starting-to-learn-flash.html' title='Starting to Learn Flex'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4261560696528461647</id><published>2008-09-05T09:06:00.000-07:00</published><updated>2008-09-05T09:22:14.691-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desktop background'/><category scheme='http://www.blogger.com/atom/ns#' term='wallpaper'/><category scheme='http://www.blogger.com/atom/ns#' term='background'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Setting the Background with a Command</title><content type='html'># Get the picture from a URL&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://farm2.static.flickr.com/1121/1383497195_9baa091855_o.jpg -O ~/background.jpg&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# Set the background&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;gconftool-2 -t string -s ~/background.jpg&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4261560696528461647?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4261560696528461647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=4261560696528461647' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4261560696528461647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/4261560696528461647'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/setting-background-with-command.html' title='Setting the Background with a Command'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-6091791125005904863</id><published>2008-09-02T12:50:00.000-07:00</published><updated>2008-09-05T10:40:19.888-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dual computer'/><category scheme='http://www.blogger.com/atom/ns#' term='autostart'/><category scheme='http://www.blogger.com/atom/ns#' term='ip address'/><category scheme='http://www.blogger.com/atom/ns#' term='synergy'/><title type='text'>Setting Up Synergy</title><content type='html'>&lt;a href="http://synergy2.sourceforge.net/"&gt;Synergy&lt;/a&gt; is a really cool thing that lets you use one keyboard and mouse to control many separate computers and have a common clipboard (they can even be running different operating systems!) I want to set up my desktop to control my laptop (as though it were a third monitor in addition to my &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/05/ubuntu-nvidia-dual-screen-setup.html"&gt;dual head desktop&lt;/a&gt;). Instructions for Windows and Mac can be found in the &lt;a href="http://synergy2.sourceforge.net/"&gt;Synergy documentation&lt;/a&gt;. Here's how I got it working in Ubuntu Linux:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Setting Up&lt;/span&gt;&lt;br /&gt;On both computers, install Synergy (green commands can be pasted into the terminal with ctrl+insert)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install synergy -y&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We'll need the host names of the two computers to use in the config files. Go to the computer on the left and execute the command hostname. Here's a sample output:&lt;br /&gt;$&lt;span style="color: rgb(0, 102, 0);"&gt;hostname&lt;/span&gt;&lt;br /&gt;awesomedesktop&lt;br /&gt;&lt;br /&gt;Now do the same for the machine on the right:&lt;br /&gt;$&lt;span style="color: rgb(0, 102, 0);"&gt;hostname&lt;/span&gt;&lt;br /&gt;awesomelaptop&lt;br /&gt;&lt;br /&gt;One of them is going to be the server, lets say the one on the left - awesomedesktop. In the computer at the left, execute the following commands, but replace "awesomelaptop" with the hostname of the computer on the right.&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;screen1=`hostname`&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;screen2=awesomelaptop&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Or, it the server is on the right, swap 1 and 2:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;screen2=`hostname`&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;screen1=awesomelaptop&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Paste all of this at once into the terminal:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "section: screens&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;   $screen1:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;   $screen2:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;section: links&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;   $screen1:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;       right = $screen2&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;   $screen2:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;       left = $screen1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;end" &gt; ~/&lt;span style="color: rgb(0, 102, 0);"&gt;.&lt;/span&gt;synergy.conf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To see the contents of the new file, execute&lt;br /&gt;cat .synergy.conf&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Getting it Going&lt;/span&gt;&lt;br /&gt;On the computer on the left, start the synergy server by executing&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;synergys -f&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On the computer on the right, start the client by executing&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;synergyc -f server-ip&lt;/span&gt;&lt;br /&gt;where server-ip is replaced by the IP address of the server, which can be obtained by executing (on the server)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ifconfig&lt;/span&gt;&lt;br /&gt;or to get &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; the IP address:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' |cut -d: -f2 | awk '{ print $1}'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Starting it Automatically&lt;/span&gt;&lt;br /&gt;Automatically starting things go in ~/.profile, so we'll put our commands there.&lt;br /&gt;On the server, execute:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo synergys &gt;&gt; ~/.profile&lt;/span&gt;&lt;br /&gt;On the client (again replacing &lt;span style="color: rgb(0, 102, 0);"&gt;server-ip&lt;/span&gt;):&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo synergyc &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;server-ip&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; &gt;&gt; ~/.profile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://synergy2.sourceforge.net/"&gt;Synergy documentation&lt;/a&gt;&lt;br /&gt;&lt;a href="https://help.ubuntu.com/community/SynergyHowto"&gt;Ubuntu Synergy Documentation&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-6091791125005904863?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/6091791125005904863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=6091791125005904863' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6091791125005904863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/6091791125005904863'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/setting-up-synergy.html' title='Setting Up Synergy'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2569233628248917713</id><published>2008-09-02T10:37:00.001-07:00</published><updated>2008-09-02T12:50:02.181-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ip'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><category scheme='http://www.blogger.com/atom/ns#' term='dhcp'/><title type='text'>Assigning a Static IP address in Ubuntu</title><content type='html'>I had some internet problems at a hotel, and I learned a bit about networking. My Ubuntu 8.04.1 desktop said "Wired network connection with a self-assigned address", and wouldn't connect to the internet, while at the same time my Ubuntu laptop was accessing the internet just fine. After a while talking with the help desk people, I learned that it was because the desktop was not being assigned an IP address by the &lt;a href="http://en.wikipedia.org/wiki/Dhcp"&gt;DHCP&lt;/a&gt; server. Here are some useful things I learned:&lt;br /&gt;&lt;br /&gt;To find out your own IP and MAC address:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ifconfig&lt;/span&gt;&lt;br /&gt;IP address is labeled "inet addr", and MAC address is labeled "HWaddr"&lt;br /&gt;&lt;br /&gt;To manually assign your computer a static IP address given to you in the command line:&lt;br /&gt;&lt;a href="http://www.cyberciti.biz/faq/linux-change-ip-address/"&gt;Temporarily&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cyberciti.biz/tips/howto-ubuntu-linux-convert-dhcp-network-configuration-to-static-ip-configuration.html"&gt;Permanently&lt;/a&gt;&lt;br /&gt;Or use the GUI:&lt;br /&gt;System -&gt; Administration -&gt; Network&lt;br /&gt;Here you need to hit "Unlock" at the bottom. I missed this fact and thought the GUI was useless for a while.&lt;br /&gt;&lt;br /&gt;I tried setting all the information from the command line, but it didn't work until I just opened and closed the GUI, so I guess I was missing some kind of initialization or reset command.&lt;br /&gt;&lt;br /&gt;It was suggested that I need to change my link speed from 100 to 10, and duplex mode from full to half. To see your current configuration, use&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo ethtool eth0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To set the link speed to 100, and set half duplex, execute&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo ethtool -s eth0 speed 10 duplex half&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To get assigned an IP address (or at least attempt to), execute&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo dhclient eth0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You should see "bound to 169.168...." or something. If the address begins with 196.254...., then it was not assigned by the DHCP server, it was self-assigned, meaning it cannot connect to the internet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2569233628248917713?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2569233628248917713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2569233628248917713' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2569233628248917713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2569233628248917713'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/09/assigning-permant-ip-address.html' title='Assigning a Static IP address in Ubuntu'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-9024016718276657119</id><published>2008-08-31T15:37:00.000-07:00</published><updated>2008-09-04T18:04:31.805-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='g++'/><category scheme='http://www.blogger.com/atom/ns#' term='muparser'/><category scheme='http://www.blogger.com/atom/ns#' term='parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='expression parser'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><category scheme='http://www.blogger.com/atom/ns#' term='math parser'/><title type='text'>muParser</title><content type='html'>I was thinking of using &lt;a href="http://muparser.sourceforge.net/"&gt;muParser&lt;/a&gt;, a fast math parser C++ library, in some projects. Here's how I got it working in Ubuntu with a test program.&lt;br /&gt;&lt;br /&gt;#Install the muParser library and headers&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install libmuparser0 libmuparser-dev -y&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was appalled to see that the &lt;a href="http://muparser.sourceforge.net/mup_version.html#idExample"&gt;sample code&lt;/a&gt; didn't work ("pi" was used but not defined)! The lines in red are the changed I had to make to get it to work. Paste this into test.cpp:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;#include "&lt;span style="color: rgb(255, 0, 0);"&gt;muParser/&lt;/span&gt;muParser.h"&lt;br /&gt;#include &amp;lt;math.h&amp;gt;&lt;br /&gt;// Function callback&lt;br /&gt;double MyFunction(double a_fVal)&lt;br /&gt;{&lt;br /&gt;return a_fVal*a_fVal;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// main program&lt;br /&gt;int main(int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt;using namespace mu;&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;   double fVal = 1;&lt;br /&gt;   Parser p;&lt;br /&gt;   &lt;span style="color: rgb(255, 0, 0);"&gt;p.DefineConst("pi", M_PI);&lt;/span&gt;&lt;br /&gt;   p.DefineVar("a", &amp;amp;fVal);&lt;br /&gt;   p.DefineFun("MyFunc", MyFunction);&lt;br /&gt;   p.SetExpr("MyFunc(a)*pi+min(10,a)");&lt;br /&gt;   std::cout &amp;lt;&amp;lt; p.Eval() &amp;lt;&amp;lt; "\n";&lt;br /&gt;}&lt;br /&gt;catch (Parser::exception_type &amp;amp;e)&lt;br /&gt;{&lt;br /&gt;   std::cout &amp;lt;&amp;lt; e.GetMsg() &amp;lt;&amp;lt; "\n";&lt;br /&gt;}&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Compile and run it with&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;g++ test.cpp -lmuparser &amp;amp;&amp;amp; ./a.out&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's an example which takes an expression, and generates a table if input and output values:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;#include "muParser/muParser.h"&lt;br /&gt;#include &amp;lt;math.h&amp;gt;&lt;br /&gt;using namespace mu;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt;  Parser p;&lt;br /&gt;  double x = 0;&lt;br /&gt;  char input[80];&lt;br /&gt;&lt;br /&gt;  p.DefineConst("pi", M_PI);&lt;br /&gt;  p.DefineConst("e", M_E);&lt;br /&gt;  p.DefineVar("x", &amp;amp;x);&lt;br /&gt;&lt;br /&gt;  cin &amp;gt;&amp;gt; input;&lt;br /&gt;  p.SetExpr(input);&lt;br /&gt;  try&lt;br /&gt;  {&lt;br /&gt;      for(x = -10; x &amp;lt;= 10;x++)&lt;br /&gt;          cout &amp;lt;&amp;lt; "X = " &amp;lt;&amp;lt; x &amp;lt;&amp;lt; "\t" &amp;lt;&amp;lt; input &amp;lt;&amp;lt; " = " &amp;lt;&amp;lt; p.Eval() &amp;lt;&amp;lt; "\n";&lt;br /&gt;  }&lt;br /&gt;  catch (Parser::exception_type &amp;amp;e)&lt;br /&gt;  {&lt;br /&gt;      std::cout &amp;lt;&amp;lt; e.GetMsg() &amp;lt;&amp;lt; "\n";&lt;br /&gt;  }&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;If you save it as table.cpp, compile and run with&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;g++ &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;table&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;.cpp -lmuparser &amp;amp;&amp;amp; ./a.out&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Enter expressions into the console like this:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;sin(x^2)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;and you'll get this:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;X = -10    sin(x^2) = -0.506366&lt;br /&gt;X = -9    sin(x^2) = -0.629888&lt;br /&gt;X = -8    sin(x^2) = 0.920026&lt;br /&gt;X = -7    sin(x^2) = -0.953753&lt;br /&gt;X = -6    sin(x^2) = -0.991779&lt;br /&gt;X = -5    sin(x^2) = -0.132352&lt;br /&gt;X = -4    sin(x^2) = -0.287903&lt;br /&gt;X = -3    sin(x^2) = 0.412118&lt;br /&gt;X = -2    sin(x^2) = -0.756802&lt;br /&gt;X = -1    sin(x^2) = 0.841471&lt;br /&gt;X = 0    sin(x^2) = 0&lt;br /&gt;X = 1    sin(x^2) = 0.841471&lt;br /&gt;X = 2    sin(x^2) = -0.756802&lt;br /&gt;X = 3    sin(x^2) = 0.412118&lt;br /&gt;X = 4    sin(x^2) = -0.287903&lt;br /&gt;X = 5    sin(x^2) = -0.132352&lt;br /&gt;X = 6    sin(x^2) = -0.991779&lt;br /&gt;X = 7    sin(x^2) = -0.953753&lt;br /&gt;X = 8    sin(x^2) = 0.920026&lt;br /&gt;X = 9    sin(x^2) = -0.629888&lt;br /&gt;X = 10    sin(x^2) = -0.506366&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://muparser.sourceforge.net/"&gt;muParser web site&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-9024016718276657119?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/9024016718276657119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=9024016718276657119' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/9024016718276657119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/9024016718276657119'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/muparser.html' title='muParser'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-2563306762113629843</id><published>2008-08-28T21:12:00.000-07:00</published><updated>2008-08-28T21:14:41.381-07:00</updated><title type='text'>CUDA in Ubuntu, a hack</title><content type='html'>This is an outdated way of setting up CUDA 1.1 in Ubunt 8.04. I'm posting it just so it's not lost. An up to date guide can be found &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/05/cuda-development-in-ubuntu.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This guide is written to work with a fresh installation of &lt;a href="http://www.ubuntu.com/getubuntu/download"&gt;Ubuntu 8.04 (Hardy Heron)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Green means it is a command. You can paste lines into the console with ctrl+shift.&lt;br /&gt;&lt;br /&gt;#install drivers from Ubuntu&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install nvidia-glx-new -y&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo nvidia-xconfig&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#reboot&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo reboot&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#install the toolkit (doesn't work with findcuda.CMake)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://developer.download.nvidia.com/compute/cuda/1_1/Linux/toolkits/NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod +x NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo ./NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run auto&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Alternatively, use the beta (works with findcuda.CMake):&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://developer.download.nvidia.com/compute/cuda/2.0-Beta2/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod +x &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo ./&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; auto&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#add environment variables&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;echo "# CUDA stuff&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;PATH=\$PATH:/usr/local/cuda/bin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/cuda/lib&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;export PATH&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;export LD_LIBRARY_PATH" &gt;&gt; ~/.bashrc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#restart the terminal for the changes to take effect&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;exit&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#install the SDK (hit enter at all prompts)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://developer.download.nvidia.com/compute/cuda/1_1/Linux/sdk/NVIDIA_CUDA_SDK_1.1_Linux.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod +x NVIDIA_CUDA_SDK_1.1_Linux.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;./NVIDIA_CUDA_SDK_1.1_Linux.run&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#install the libcuda.so file, which the &lt;a name="missingLibcudaSO"&gt;Ubuntu installer doesn't do&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://us.download.nvidia.com/XFree86/Linux-x86/169.12/NVIDIA-Linux-x86-169.12-pkg1.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod +x NVIDIA-Linux-x86-169.12-pkg1.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;./NVIDIA-Linux-x86-169.12-pkg1.run --extract-only&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo mv NVIDIA-Linux-x86-169.12-pkg1/usr/lib/libcuda.so.169.12 /usr/lib/libcuda.so&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm ./NVIDIA-Linux-x86-169.12-pkg1.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm rm -r -f NVIDIA-Linux-x86-169.12-pkg1&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;#install build tools&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install build-essential libglut3-dev &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;gcc-4.1 g++-4.1&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; -y&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#set up gcc and g++ to use version 4.1 (otherwise we get compatibility issues)&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.1 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.2 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#make the example projects&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd NVIDIA_CUDA_SDK/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;make&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#Run an example program and be overwhelmed with parallel bliss&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;~/NVIDIA_CUDA_SDK/bin/linux/release/fluidsGL&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-2563306762113629843?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/2563306762113629843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=2563306762113629843' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2563306762113629843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/2563306762113629843'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/cuda-in-ubuntu-hack.html' title='CUDA in Ubuntu, a hack'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1883298960905105793</id><published>2008-08-28T20:32:00.000-07:00</published><updated>2008-08-28T20:50:11.741-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='envyng'/><category scheme='http://www.blogger.com/atom/ns#' term='nvidia'/><category scheme='http://www.blogger.com/atom/ns#' term='drivers'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='nvidia-glx-new'/><title type='text'>Ways to Install NVidia Drivers in Ubuntu</title><content type='html'>Here are some ways of geting NVidia drivers working in Ubuntu 8.04 that have worked for me.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Using Ubuntu's Installer&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install nvidia-glx-new -y&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo nvidia-xconfig&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo reboot&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;Using EnvyNG&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install envyng-gtk -y&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;envyng -t&lt;/span&gt;&lt;br /&gt;# type "1" to install NVidia drivers&lt;br /&gt;# then "y" to restart&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Using NVidia's Installer&lt;/span&gt;&lt;br /&gt;#from http://www.nvidia.com/object/cuda_get.html -&gt; Linux 32 bit&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/driver/NVIDIA-Linux-x86-177.67-pkg1.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;chmod +x ./NVIDIA-Linux-x86-177.67-pkg1.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo /etc/init.d/gdm stop&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo ./NVIDIA-Linux-x86-177.67-pkg1.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;rm ./NVIDIA-Linux-x86-177.67-pkg1.run&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo /etc/init.d/gdm start&lt;/span&gt;&lt;br /&gt;# this next step resolves a driver conflict.&lt;br /&gt;# if we don't do this, the machine will start in low-graphics mode on reboot&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo gedit /etc/default/linux-restricted-modules-common&lt;/span&gt;&lt;br /&gt;# add 'nv' to DISABLED_MODULES ('DISABLED_MODULES="nv"')&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo reboot&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1883298960905105793?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1883298960905105793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1883298960905105793' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1883298960905105793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1883298960905105793'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/ways-to-install-nvidia-drivers-in.html' title='Ways to Install NVidia Drivers in Ubuntu'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8786096860661813950</id><published>2008-08-28T15:00:00.000-07:00</published><updated>2008-08-28T20:50:06.256-07:00</updated><title type='text'>Failed CUDA Install Attempts</title><content type='html'>Here's a collection of approaches of setting up CUDA 2.0 in Ubuntu 8.04 which failed. I wrote a functioning guide for how to do it &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/05/cuda-development-in-ubuntu.html"&gt;here&lt;/a&gt;, I'm posting these failures just for reference.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Using EnvyNG&lt;/span&gt;&lt;br /&gt;# Install the NVidia drivers with EnvyNG&lt;br /&gt;sudo apt-get update&lt;br /&gt;sudo apt-get install envyng-gtk -y&lt;br /&gt;envyng -t&lt;br /&gt;# type "1" to install NVidia drivers&lt;br /&gt;# then "y" to restart&lt;br /&gt;&lt;br /&gt;# Install the CUDA Toolkit&lt;br /&gt;wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run&lt;br /&gt;chmod +x NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run&lt;br /&gt;sudo ./NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run auto&lt;br /&gt;rm NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run&lt;br /&gt;&lt;br /&gt;# add environment variables&lt;br /&gt;echo "# CUDA stuff&lt;br /&gt;PATH=\$PATH:/usr/local/cuda/bin&lt;br /&gt;LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/cuda/lib&lt;br /&gt;export PATH&lt;br /&gt;export LD_LIBRARY_PATH" &gt;&gt; ~/.bashrc&lt;br /&gt;&lt;br /&gt;# Install the CUDA SDK&lt;br /&gt;wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/sdk/NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run&lt;br /&gt;chmod +x ./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run&lt;br /&gt;./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run&lt;br /&gt;# press enter at both prompts&lt;br /&gt;rm ./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run&lt;br /&gt;&lt;br /&gt;# Install the build tools we need&lt;br /&gt;sudo apt-get install build-essential libglut3-dev -y&lt;br /&gt;&lt;br /&gt;# compile and run an example&lt;br /&gt;cd NVIDIA_CUDA_SDK/&lt;br /&gt;make&lt;br /&gt;~/NVIDIA_CUDA_SDK/bin/linux/release/fluidsGL&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;FluidsGL runs but fails with:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;cufft: ERROR: CUFFT_EXEC_FAILED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;cufft: ERROR: /root/cuda-stuff/sw/rel/gpgpu/toolkit/r2.0/cufft/src/cufft.cu, line 119&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;cufft: ERROR: CUFFT_EXEC_FAILED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;cufft: ERROR: /root/cuda-stuff/sw/rel/gpgpu/toolkit/r2.0/cufft/src/execute.cu, line 1038&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;cufft: ERROR: CUFFT_EXEC_FAILED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;cufft: ERROR: /root/cuda-stuff/sw/rel/gpgpu/toolkit/r2.0/cufft/src/execute.cu, line 284&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:180%;"&gt;Using NVidia's Installer for Ubuntu 7.10&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;# --- Install the &lt;span class="nfakPe"&gt;NVidia&lt;/span&gt; Driver ---&lt;br /&gt;#from &lt;a href="http://www.nvidia.com/object/cuda_get.html" target="_blank"&gt;http://www.&lt;span class="nfakPe"&gt;nvidia&lt;/span&gt;.com/object/&lt;wbr&gt;cuda_get.html&lt;/a&gt; -&gt; Linux 32 bit, Ubuntu 7.10&lt;br /&gt;wget &lt;a href="http://developer.download.nvidia.com/compute/cuda/2_0/linux/driver/NVIDIA-Linux-x86-177.67-pkg1.run" target="_blank"&gt;http://developer.download.&lt;wbr&gt;&lt;span class="nfakPe"&gt;nvidia&lt;/span&gt;.com/compute/cuda/2_0/&lt;wbr&gt;linux/driver/&lt;span class="nfakPe"&gt;NVIDIA&lt;/span&gt;-Linux-x86-&lt;wbr&gt;177.67-pkg1.run&lt;/a&gt;&lt;br /&gt;chmod +x ./&lt;span class="nfakPe"&gt;NVIDIA&lt;/span&gt;-Linux-x86-177.67-pkg1.run&lt;br /&gt;# Install build tools needed for the installer to compile the drivers&lt;br /&gt;sudo apt-get install build-essential -y&lt;br /&gt;&lt;div dir="ltr"&gt;# this will kill the window manager and kick you down to a terminal&lt;br /&gt;sudo /etc/init.d/gdm stop&lt;br /&gt;sudo ./&lt;span class="nfakPe"&gt;NVIDIA&lt;/span&gt;-Linux-x86-177.67-&lt;wbr&gt;pkg1.run&lt;br /&gt;rm ./&lt;span class="nfakPe"&gt;NVIDIA&lt;/span&gt;-Linux-x86-177.67-&lt;wbr&gt;pkg1.run&lt;br /&gt;sudo /etc/init.d/gdm start&lt;br /&gt;#desktop effects are working! Success!&lt;br /&gt;&lt;br /&gt;# --- Install the CUDA Toolkit and SDK&lt;br /&gt;wget &lt;a href="http://developer.download.nvidia.com/compute/cuda/2_0/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run" target="_blank"&gt;http://developer.download.&lt;wbr&gt;&lt;span class="nfakPe"&gt;nvidia&lt;/span&gt;.com/compute/cuda/2_0/&lt;wbr&gt;linux/toolkit/NVIDIA_CUDA_&lt;wbr&gt;Toolkit_2.0_ubuntu7.10_x86.run&lt;/a&gt;&lt;br /&gt;chmod +x NVIDIA_CUDA_Toolkit_2.0_&lt;wbr&gt;ubuntu7.10_x86.run&lt;br /&gt;sudo ./NVIDIA_CUDA_Toolkit_2.0_&lt;wbr&gt;ubuntu7.10_x86.run&lt;br /&gt;sudo apt-get install libglut3-dev -y&lt;br /&gt;rm NVIDIA_CUDA_Toolkit_2.0_&lt;wbr&gt;ubuntu7.10_x86.run&lt;br /&gt;wget &lt;a href="http://developer.download.nvidia.com/compute/cuda/2_0/linux/sdk/NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run" target="_blank"&gt;http://developer.download.&lt;wbr&gt;&lt;span class="nfakPe"&gt;nvidia&lt;/span&gt;.com/compute/cuda/2_0/&lt;wbr&gt;linux/sdk/NVIDIA_CUDA_SDK_2.&lt;wbr&gt;02.0807.1535_linux.run&lt;/a&gt;&lt;br /&gt;chmod +x ./NVIDIA_CUDA_SDK_2.02.0807.&lt;wbr&gt;1535_linux.run&lt;br /&gt;./NVIDIA_CUDA_SDK_2.02.0807.&lt;wbr&gt;1535_linux.run auto&lt;br /&gt;#add environment variables&lt;br /&gt;echo "# CUDA stuff&lt;br /&gt;PATH=\$PATH:/usr/local/cuda/&lt;wbr&gt;bin&lt;br /&gt;LD_LIBRARY_PATH=\$LD_LIBRARY_&lt;wbr&gt;PATH:/usr/local/cuda/lib&lt;br /&gt;export PATH&lt;br /&gt;export LD_LIBRARY_PATH" &gt;&gt; ~/.bashrc&lt;br /&gt;rm ./NVIDIA_CUDA_SDK_2.02.0807.&lt;wbr&gt;1535_linux.run&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Works great! until reboot, then the machine starts in low graphics mode. Any ideas on how to fix this?&lt;/span&gt;&lt;br /&gt;FIXED! Solution: add 'nv' to DISABLED_MODULES in &lt;span style="color: rgb(0, 102, 0);"&gt;/etc/default/linux-restricted-modules-common&lt;/span&gt;,full instructions &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/ways-to-install-nvidia-drivers-in.html"&gt;here&lt;/a&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/6461387352629250590-8786096860661813950?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8786096860661813950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8786096860661813950' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8786096860661813950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8786096860661813950'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/failed-cuda-install-attempts.html' title='Failed CUDA Install Attempts'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5247244074427731365</id><published>2008-08-14T05:34:00.000-07:00</published><updated>2010-12-22T18:02:05.134-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='example'/><category scheme='http://www.blogger.com/atom/ns#' term='sphere'/><category scheme='http://www.blogger.com/atom/ns#' term='rendering'/><category scheme='http://www.blogger.com/atom/ns#' term='inside test'/><category scheme='http://www.blogger.com/atom/ns#' term='cylinder'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><title type='text'>OpenGL example: Rendering Cylinders and Spheres, with Point-Cylinder Inside Test</title><content type='html'>This is a working example illustrating how the &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/07/rendering-cylinder-between-two-points.html"&gt;cylinder rendering&lt;/a&gt;, &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/rendering-sphere-in-opengl.html"&gt;sphere rendering&lt;/a&gt;, and &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/point-cylinder-inside-test.html"&gt;point-cylinder inside test&lt;/a&gt; functions are used.&lt;br /&gt;&lt;br /&gt;If you copy it into the file example.c, compile and run it with the command&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;gcc -lglut -lGL example.c &amp;amp;&amp;amp; ./a.out&lt;/span&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;//This code is in the public domain. --author, Curran Kelleher&lt;br /&gt;#include &amp;lt;GL/glut.h&amp;gt;&lt;br /&gt;#include &amp;lt;GL/gl.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;math.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#define ESCAPE_KEY 27&lt;br /&gt;&lt;br /&gt;float window;&lt;br /&gt;float t = 0.0f;&lt;br /&gt;int pointIsInsideCylinder(float x1, float y1, float z1, float dx,float dy, float dz, float lengthSquared,float radiusSquared ,float xTest,float yTest,float zTest)&lt;br /&gt;{&lt;br /&gt;   float pdx = xTest - x1;&lt;br /&gt;   float pdy = yTest - y1;&lt;br /&gt;   float pdz = zTest - z1;&lt;br /&gt;   float dot = pdx * dx + pdy * dy + pdz * dz;&lt;br /&gt;   int pointIsInside = 0;&lt;br /&gt;   if( dot &amp;gt; 0 &amp;amp;&amp;amp; dot &amp;lt; lengthSquared )&lt;br /&gt;       pointIsInside = pdx*pdx + pdy*pdy + pdz*pdz - dot*dot/lengthSquared &amp;lt; radiusSquared;&lt;br /&gt;   return pointIsInside;&lt;br /&gt;}&lt;br /&gt;int pointIsInsideCylinder_convenient( float x1, float y1, float z1, float x2,float y2, float z2, float radius, float xTest,float yTest,float zTest)&lt;br /&gt;{&lt;br /&gt;   //these things need only to be computed once for a cylinder, and reused for each test point&lt;br /&gt;   float dx = x2 - x1;&lt;br /&gt;   float dy = y2 - y1;&lt;br /&gt;   float dz = z2 - z1;&lt;br /&gt;   float lengthSquared = pow(x2-x1,2)+pow(y2-y1,2)+pow(z2-z1,2);&lt;br /&gt;   float radiusSquared=radius*radius;&lt;br /&gt;   return pointIsInsideCylinder(x1,y1,z1,dx,dy,dz,lengthSquared,radiusSquared,xTest,yTest,zTest);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric)&lt;br /&gt;{&lt;br /&gt;   float vx = x2-x1;&lt;br /&gt;   float vy = y2-y1;&lt;br /&gt;   float vz = z2-z1;&lt;br /&gt;&lt;br /&gt;   //handle the degenerate case of z1 == z2 with an approximation&lt;br /&gt;   if(vz == 0)&lt;br /&gt;       vz = .00000001;&lt;br /&gt;&lt;br /&gt;   float v = sqrt( vx*vx + vy*vy + vz*vz );&lt;br /&gt;   float ax = 57.2957795*acos( vz/v );&lt;br /&gt;   if ( vz &amp;lt; 0.0 )&lt;br /&gt;       ax = -ax;&lt;br /&gt;   float rx = -vy*vz;&lt;br /&gt;   float ry = vx*vz;&lt;br /&gt;   glPushMatrix();&lt;br /&gt;&lt;br /&gt;   //draw the cylinder body&lt;br /&gt;   glTranslatef( x1,y1,z1 );&lt;br /&gt;   glRotatef(ax, rx, ry, 0.0);&lt;br /&gt;   gluQuadricOrientation(quadric,GLU_OUTSIDE);&lt;br /&gt;   gluCylinder(quadric, radius, radius, v, subdivisions, 1);&lt;br /&gt;&lt;br /&gt;   //draw the first cap&lt;br /&gt;   gluQuadricOrientation(quadric,GLU_INSIDE);&lt;br /&gt;   gluDisk( quadric, 0.0, radius, subdivisions, 1);&lt;br /&gt;   glTranslatef( 0,0,v );&lt;br /&gt;&lt;br /&gt;   //draw the second cap&lt;br /&gt;   gluQuadricOrientation(quadric,GLU_OUTSIDE);&lt;br /&gt;   gluDisk( quadric, 0.0, radius, subdivisions, 1);&lt;br /&gt;   glPopMatrix();&lt;br /&gt;}&lt;br /&gt;void renderCylinder_convenient(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions)&lt;br /&gt;{&lt;br /&gt;   //the same quadric can be re-used for drawing many cylinders&lt;br /&gt;   GLUquadricObj *quadric=gluNewQuadric();&lt;br /&gt;   gluQuadricNormals(quadric, GLU_SMOOTH);&lt;br /&gt;   renderCylinder(x1,y1,z1,x2,y2,z2,radius,subdivisions,quadric);&lt;br /&gt;   gluDeleteQuadric(quadric);&lt;br /&gt;}&lt;br /&gt;void renderSphere(float x, float y, float z, float radius,int subdivisions,GLUquadricObj *quadric)&lt;br /&gt;{&lt;br /&gt;   glPushMatrix();&lt;br /&gt;   glTranslatef( x,y,z );&lt;br /&gt;   gluSphere(quadric, radius, subdivisions,subdivisions);&lt;br /&gt;   glPopMatrix();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void renderSphere_convenient(float x, float y, float z, float radius,int subdivisions)&lt;br /&gt;{&lt;br /&gt;   //the same quadric can be re-used for drawing many spheres&lt;br /&gt;   GLUquadricObj *quadric=gluNewQuadric();&lt;br /&gt;   gluQuadricNormals(quadric, GLU_SMOOTH);&lt;br /&gt;   renderSphere(x,y,z,radius,subdivisions,quadric);&lt;br /&gt;   gluDeleteQuadric(quadric);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void display()&lt;br /&gt;{&lt;br /&gt;   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);&lt;br /&gt;&lt;br /&gt;   glLoadIdentity();&lt;br /&gt;   glTranslatef(0,0,-7);&lt;br /&gt;&lt;br /&gt;   //define the cylinder&lt;br /&gt;   float x1 = sin(t);&lt;br /&gt;   float y1 = sin(t/2);&lt;br /&gt;   float z1 = cos(t*1.1);&lt;br /&gt;   float x2 = -sin(t*1.3);&lt;br /&gt;   float y2 = 0;&lt;br /&gt;   float z2 = -cos(t);&lt;br /&gt;   float radius = 0.03+(sin(t)/2+0.5)/3;&lt;br /&gt;&lt;br /&gt;   //render the cylinder&lt;br /&gt;   renderCylinder_convenient(x1,y1,z1,x2,y2,z2,radius,32);&lt;br /&gt;&lt;br /&gt;   //render spheres in a grid which are inside the cylinder&lt;br /&gt;   float gridSize = 20;&lt;br /&gt;   float xTest,yTest,zTest;&lt;br /&gt;   int x,y,z;&lt;br /&gt;   for(x = 0; x &amp;lt; gridSize,xTest = (float)x/gridSize*2-1; x++)&lt;br /&gt;       for(y = 0; y &amp;lt; gridSize,yTest = (float)y/gridSize*2-1; y++)&lt;br /&gt;           for(z = 0; z &amp;lt; gridSize,zTest = (float)z/gridSize*2-1; z++)&lt;br /&gt;               if(pointIsInsideCylinder_convenient(x1,y1,z1,x2,y2,z2,radius,xTest,yTest,zTest))&lt;br /&gt;                   renderSphere_convenient(xTest,yTest,zTest,0.07,8);&lt;br /&gt;&lt;br /&gt;   t+=0.001;&lt;br /&gt;   glutSwapBuffers();&lt;br /&gt;}&lt;br /&gt;void InitGL(int Width, int Height)        &lt;br /&gt;{&lt;br /&gt;   glClearColor(0.0f, 0.0f, 0.0f, 0.0f);&lt;br /&gt;   glClearDepth(1.0);&lt;br /&gt;   glDepthFunc(GL_LESS);&lt;br /&gt;   glEnable(GL_DEPTH_TEST);&lt;br /&gt;&lt;br /&gt;   glShadeModel(GL_SMOOTH);&lt;br /&gt;   glMatrixMode(GL_PROJECTION);&lt;br /&gt;   glLoadIdentity();&lt;br /&gt;   gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);&lt;br /&gt;   glMatrixMode(GL_MODELVIEW);&lt;br /&gt;&lt;br /&gt;   glEnable(GL_LIGHTING);&lt;br /&gt;   GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };&lt;br /&gt;   GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };&lt;br /&gt;   GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };&lt;br /&gt;   glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);&lt;br /&gt;   glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);&lt;br /&gt;   glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);&lt;br /&gt;   glEnable(GL_LIGHT1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void keyPressed(unsigned char key, int x, int y)&lt;br /&gt;{&lt;br /&gt;   if(key == ESCAPE_KEY)&lt;br /&gt;   {&lt;br /&gt;       glutDestroyWindow(window);&lt;br /&gt;       exit(1);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;int main( int argc, char** argv)&lt;br /&gt;{&lt;br /&gt;   glutInit(&amp;amp;argc, argv);&lt;br /&gt;   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);&lt;br /&gt;   glutInitWindowSize(640, 480);&lt;br /&gt;   window = glutCreateWindow("");&lt;br /&gt;   glutDisplayFunc(&amp;amp;display);&lt;br /&gt;   glutKeyboardFunc(&amp;amp;keyPressed);&lt;br /&gt;   glutFullScreen();&lt;br /&gt;   glutIdleFunc(&amp;amp;display);&lt;br /&gt;   InitGL(640, 480);&lt;br /&gt;   glutMainLoop();&lt;br /&gt;   return 1;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5247244074427731365?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5247244074427731365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5247244074427731365' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5247244074427731365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5247244074427731365'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/opengl-example-rendering-cylinders.html' title='OpenGL example: Rendering Cylinders and Spheres, with Point-Cylinder Inside Test'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8623585982009284881</id><published>2008-08-13T09:41:00.000-07:00</published><updated>2008-08-14T05:55:01.705-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sphere'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='quadrics'/><title type='text'>Rendering a Sphere in OpenGL</title><content type='html'>There are a few little non-obvious OpenGL things you need for rendering a sphere. Here's a function which illustrates them:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;void renderSphere(float x, float y, float z, float radius,int subdivisions,GLUquadricObj *quadric)&lt;br /&gt;{&lt;br /&gt;  glPushMatrix();&lt;br /&gt;  glTranslatef( x,y,z );&lt;br /&gt;  gluSphere(quadric, radius, subdivisions,subdivisions);&lt;br /&gt;  glPopMatrix();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void renderSphere_convenient(float x, float y, float z, float radius,int subdivisions)&lt;br /&gt;{&lt;br /&gt;  //the same quadric can be re-used for drawing many spheres&lt;br /&gt;  GLUquadricObj *quadric=gluNewQuadric();&lt;br /&gt;  gluQuadricNormals(quadric, GLU_SMOOTH);&lt;br /&gt;  renderSphere(x,y,z,radius,subdivisions,quadric);&lt;br /&gt;  gluDeleteQuadric(quadric);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;A complete OpenGL example using this function can be found &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/opengl-example-rendering-cylinders.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-8623585982009284881?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8623585982009284881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8623585982009284881' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8623585982009284881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8623585982009284881'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/rendering-sphere-in-opengl.html' title='Rendering a Sphere in OpenGL'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1080470440032263363</id><published>2008-08-13T07:51:00.001-07:00</published><updated>2008-08-13T07:52:18.761-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code formatting'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Code to HTML</title><content type='html'>It's always a pain to put code snippets into pure html. I came across &lt;a href="http://formatmysourcecode.blogspot.com/2006/02/paste-your-text-here.html"&gt;this web app&lt;/a&gt; which does it for you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1080470440032263363?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1080470440032263363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1080470440032263363' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1080470440032263363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1080470440032263363'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/code-to-html.html' title='Code to HTML'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5855700195445925182</id><published>2008-08-13T07:44:00.000-07:00</published><updated>2008-08-14T05:49:46.028-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='inside test'/><category scheme='http://www.blogger.com/atom/ns#' term='cylinder'/><category scheme='http://www.blogger.com/atom/ns#' term='linear algebra'/><category scheme='http://www.blogger.com/atom/ns#' term='collision detection'/><title type='text'>Point Cylinder Inside Test</title><content type='html'>Here is code which tests whether a point is inside a cylinder defined by two endpoints and a radius (based on &lt;a href="http://www.flipcode.com/archives/Fast_Point-In-Cylinder_Test.shtml"&gt;this implementation&lt;/a&gt; by Greg James).&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric)&lt;br /&gt;{&lt;br /&gt;  float vx = x2-x1;&lt;br /&gt;  float vy = y2-y1;&lt;br /&gt;  float vz = z2-z1;&lt;br /&gt;&lt;br /&gt;  //handle the degenerate case of z1 == z2 with an approximation&lt;br /&gt;  if(vz == 0)&lt;br /&gt;      vz = .00000001;&lt;br /&gt;&lt;br /&gt;  float v = sqrt( vx*vx + vy*vy + vz*vz );&lt;br /&gt;  float ax = 57.2957795*acos( vz/v );&lt;br /&gt;  if ( vz &amp;lt; 0.0 )&lt;br /&gt;      ax = -ax;&lt;br /&gt;  float rx = -vy*vz;&lt;br /&gt;  float ry = vx*vz;&lt;br /&gt;  glPushMatrix();&lt;br /&gt;&lt;br /&gt;  //draw the cylinder body&lt;br /&gt;  glTranslatef( x1,y1,z1 );&lt;br /&gt;  glRotatef(ax, rx, ry, 0.0);&lt;br /&gt;  gluQuadricOrientation(quadric,GLU_OUTSIDE);&lt;br /&gt;  gluCylinder(quadric, radius, radius, v, subdivisions, 1);&lt;br /&gt;&lt;br /&gt;  //draw the first cap&lt;br /&gt;  gluQuadricOrientation(quadric,GLU_INSIDE);&lt;br /&gt;  gluDisk( quadric, 0.0, radius, subdivisions, 1);&lt;br /&gt;  glTranslatef( 0,0,v );&lt;br /&gt;&lt;br /&gt;  //draw the second cap&lt;br /&gt;  gluQuadricOrientation(quadric,GLU_OUTSIDE);&lt;br /&gt;  gluDisk( quadric, 0.0, radius, subdivisions, 1);&lt;br /&gt;  glPopMatrix();&lt;br /&gt;}&lt;br /&gt;void renderCylinder_convenient(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions)&lt;br /&gt;{&lt;br /&gt;  //the same quadric can be re-used for drawing many cylinders&lt;br /&gt;  GLUquadricObj *quadric=gluNewQuadric();&lt;br /&gt;  gluQuadricNormals(quadric, GLU_SMOOTH);&lt;br /&gt;  renderCylinder(x1,y1,z1,x2,y2,z2,radius,subdivisions,quadric);&lt;br /&gt;  gluDeleteQuadric(quadric);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;A complete OpenGL example using this function can be found &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/opengl-example-rendering-cylinders.html"&gt;here&lt;/a&gt;.&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://www.flipcode.com/archives/Fast_Point-In-Cylinder_Test.shtml"&gt;Original Implementation&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5855700195445925182?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5855700195445925182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5855700195445925182' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5855700195445925182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5855700195445925182'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/point-cylinder-inside-test.html' title='Point Cylinder Inside Test'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-8411181750059711148</id><published>2008-08-12T16:12:00.000-07:00</published><updated>2008-08-13T15:48:37.267-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='atom'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='feeds'/><category scheme='http://www.blogger.com/atom/ns#' term='feedparser'/><category scheme='http://www.blogger.com/atom/ns#' term='rss'/><title type='text'>Blog to Book</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;not finished - so far this is a guide for parsing feeds in Python using feedparser&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I want to create a program which will read an RSS feed (of blog posts) and translate it into a (book-formatted) LaTeX document, including all the pictures.&lt;br /&gt;&lt;br /&gt;My first step was to discover how to access the whole history of a blogger blog as a feed, which I found &lt;a href="http://www.google.com/support/feedburner/bin/answer.py?answer=79626"&gt;here&lt;/a&gt; - just add a "max-results" argument, like this:&lt;br /&gt;&lt;a href="http://lifeofahuman.blogspot.com/feeds/posts/default?max-results=500"&gt;http://lifeofahuman.blogspot.com/feeds/posts/default?max-results=500&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We could write a feed reader from scratch using minidom like &lt;a href="http://www.learningpython.com/2006/01/14/rss-reader-part-one/"&gt;this guy&lt;/a&gt;, but there is a nice Python library for reading feeds called &lt;a href="http://feedparser.org/"&gt;feedparser&lt;/a&gt;. To install it:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://feedparser.googlecode.com/files/feedparser-4.1.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;unzip feedparser-4.1.zip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo python setup.py install&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To extract the title of the blog, and the titles and contents of the first 5 entries:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;import feedparser&lt;br /&gt;d = feedparser.parse("http://lifeofahuman.blogspot.com/feeds/posts/default?max-results=5")&lt;br /&gt;print "Title: " + d.feed.title&lt;br /&gt;print "Entries:"&lt;br /&gt;for entry in d.entries:&lt;br /&gt;      print entry.title&lt;br /&gt;      print entry.content&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;If you copy this into &lt;span style="color: rgb(0, 0, 0);"&gt;readfeed&lt;/span&gt;.py, run it with&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;python readfeed.py&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's, so now we need to translate the HTML into Latex...coming soon!&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://feedparser.org/"&gt;feedparser&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.google.com/support/feedburner/bin/answer.py?answer=79626"&gt;tip about feed sizes from blogger&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-8411181750059711148?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/8411181750059711148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=8411181750059711148' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8411181750059711148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/8411181750059711148'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/blog-to-book.html' title='Blog to Book'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-7622309698054712141</id><published>2008-08-11T09:39:00.000-07:00</published><updated>2008-08-11T11:42:04.817-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jack'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='linux sound'/><title type='text'>Making Music live with a Computer?</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;not yet working&lt;/span&gt;&lt;br /&gt;I want to make the computer into a real instrument that one can play in a concert setting. I'm imagining a real time keyboard to midi mapping, with guitar, violin, or piano type layouts. Can it be done?&lt;br /&gt;&lt;br /&gt;Well, how can this be programmed in Linux? This question revealed to me that Linux sound is a big mess of interlocking components that's far from having a standard configuration - &lt;a href="http://www.alsa-project.org/"&gt;ALSA&lt;/a&gt;, &lt;a href="http://jackaudio.org/"&gt;JACK&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/TiMidity"&gt;Timidity&lt;/a&gt;, &lt;a href="http://fluidsynth.resonance.org/trac"&gt;FluidSynth&lt;/a&gt;, &lt;a href="http://dssi.sourceforge.net/"&gt;DSSI&lt;/a&gt;, &lt;a href="http://www.smbolton.com/whysynth.html"&gt;WhySynth&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A piano has already been implemented in the &lt;a href="http://pin.if.uz.zgora.pl/%7Etrasz/jack-keyboard/"&gt;Jack Keyboard&lt;/a&gt; project. Lets take a look at that. Here's how to install jack keyboard in Ubuntu:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://pin.if.uz.zgora.pl/~trasz/jack-keyboard/jack-keyboard-2.5.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;mkdir jack-keyboard&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;tar -zxvf jack-keyboard-2.5.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;cd jack-keyboard-2.5&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install build-essential libgtk-dev libjack-dev jackd -y&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;./configure&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;make&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo make install&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;For it to make any sound, you need to set up Jack to play midi. The README file recommends using Ghostess and WhySynth:&lt;br /&gt;Install Ghostess:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;wget http://www.smbolton.com/linux/ghostess-20061127.tar.gz&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;tar -zxvf ghostess-20061127.tar.gz&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;cd ghostess-20061127&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install dssi-dev liblo-dev -y&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;./configure&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;sudo make install&lt;br /&gt;&lt;/span&gt;Install WhySynth:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo su&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; echo deb &lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;http://&lt;wbr&gt;ppa.launchpad.&lt;wbr&gt;net/jaakko-&lt;wbr&gt;sipari/&lt;wbr&gt;ubuntu&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; hardy main &gt;&gt; /etc/apt/sources.list&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;apt-get update&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;apt-get install whysynth&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;/span&gt;&lt;br /&gt;To run it (according to the &lt;a href="http://pin.if.uz.zgora.pl/%7Etrasz/jack-keyboard/#Using"&gt;manual&lt;/a&gt;), we need to first start Jack&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;sudo apt-get install qjackctl&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt; qjackctl&lt;/span&gt;&lt;br /&gt;press "Start"&lt;br /&gt;ghostess whysynth.so&lt;br /&gt;Press "Insert"&lt;br /&gt;Press "z"&lt;br /&gt;&lt;br /&gt;nothing.&lt;br /&gt;WTF?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;DSSI_PATH=/usr/lib/dssi&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://pin.if.uz.zgora.pl/%7Etrasz/jack-keyboard/"&gt;Jack Keyboard&lt;/a&gt;&lt;br /&gt;&lt;a href="http://smbolton.com/linux.html"&gt;Ghostess&lt;/a&gt;&lt;br /&gt;&lt;a href="http://smbolton.com/whysynth.html"&gt;WhySynth&lt;/a&gt;&lt;br /&gt;&lt;a href="https://launchpad.net/%7Ejaakko-sipari/+archive"&gt;WhySynth Bleeding Edge Ubuntu Package&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-7622309698054712141?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/7622309698054712141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=7622309698054712141' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7622309698054712141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/7622309698054712141'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/making-music-live-with-computer.html' title='Making Music live with a Computer?'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-5605920368529129214</id><published>2008-08-10T06:21:00.000-07:00</published><updated>2008-08-13T07:50:51.606-07:00</updated><title type='text'>How to do web programming?</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;not yet working&lt;/span&gt;&lt;br /&gt;I want to write a 3D graph rendering web application, which takes a math function as input and displays the rendered function in the web page. I already have the parsing and rendering code, and I want to have it executed on the server side.&lt;br /&gt;&lt;br /&gt;In the web page I want just a text field and an image. When the user presses enter in the text field, I want some C function to be called on the server with the text in the page as an argument. The function will parse the text and render the image, then notify the client to update the image as soon as it is finished. I don't want to use polling anywhere. How would one do this?&lt;br /&gt;&lt;br /&gt;How do you put a text field into a web page? Use forms?&lt;br /&gt;How do you capture the enter key?&lt;br /&gt;How do you call a server side C function?&lt;br /&gt;How can server side C code send an update to the client?&lt;br /&gt;How can the server tell the client to update only the image, and NOT update the whole page? AJAX? JavaScript?&lt;br /&gt;Should the rendered image be saved as a public file on the server and read by the client? or can this step be bypassed, passing the image directly from server side RAM to the client somehow?&lt;br /&gt;&lt;br /&gt;I am totally new to web programming. Please let me know if you have any ideas of which direction to take. Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-5605920368529129214?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/5605920368529129214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=5605920368529129214' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5605920368529129214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/5605920368529129214'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/08/how-to-do-web-programming.html' title='How to do web programming?'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-1205097002791031344</id><published>2008-07-31T05:44:00.000-07:00</published><updated>2008-07-31T05:55:44.128-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='batch'/><category scheme='http://www.blogger.com/atom/ns#' term='batch rename'/><category scheme='http://www.blogger.com/atom/ns#' term='rename'/><category scheme='http://www.blogger.com/atom/ns#' term='file management'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='pipes'/><category scheme='http://www.blogger.com/atom/ns#' term='sed'/><title type='text'>Batch Rename</title><content type='html'>Unix magic always amazes me! I want to do a batch rename, where I replace "template" with "example" in all file names.&lt;br /&gt;&lt;br /&gt;There is a program called sed, which can process text streams with a search and replace syntax just like vim: &lt;span style="color: rgb(153, 51, 0);"&gt;/s/foo/bar/g&lt;/span&gt; - this means replace "foo" with "bar" in the whole line of text. We can use sed in combination with shell scripting and pipes to get the job done:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ls&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;bak  template.cu  template_gold.cpp  template_kernel.cu  template_utils.h&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;for file in *.*; do mv $file `echo $file | sed 's/template/example/g'` ; done&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;ls&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;bak  example.cu  example_gold.cpp  example_kernel.cu  example_utils.h&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Perfect!&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Sed"&gt;Sed&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lab.artlung.com/unix-batch-file-rename/"&gt;Batch Rename&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-1205097002791031344?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/1205097002791031344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6461387352629250590&amp;postID=1205097002791031344' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1205097002791031344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6461387352629250590/posts/default/1205097002791031344'/><link rel='alternate' type='text/html' href='http://lifeofaprogrammergeek.blogspot.com/2008/07/batch-rename.html' title='Batch Rename'/><author><name>curran</name><uri>http://www.blogger.com/profile/17464450838677227452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2160/2219803411_8e97ea9d71_o.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6461387352629250590.post-4117877619483871488</id><published>2008-07-30T10:14:00.000-07:00</published><updated>2011-03-29T06:16:49.681-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cylinder'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='trigonometry'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='quadrics'/><title type='text'>Rendering a Cylinder Between Two Points in OpenGL</title><content type='html'>&lt;span class="Apple-style-span"  &gt;This problem is more of a pain than one would think! Here is some code that does it, based on &lt;a href="http://home.neo.rr.com/jparris/OpenGL%20-%20draw%20cylinder%20between%202%20pts.htm"&gt;this implementation&lt;/a&gt; by Joel J. Parris.&lt;br /&gt;&lt;/span&gt;&lt;pre style="border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(153, 153, 153); border-right-color: rgb(153, 153, 153); border-bottom-color: rgb(153, 153, 153); border-left-color: rgb(153, 153, 153); padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; overflow-x: auto; overflow-y: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%; "&gt;&lt;code&gt;&lt;span class="Apple-style-span"  &gt;void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric)&lt;br /&gt;{&lt;br /&gt;float vx = x2-x1;&lt;br /&gt;float vy = y2-y1;&lt;br /&gt;float vz = z2-z1;&lt;br /&gt;&lt;br /&gt;//handle the degenerate case of z1 == z2 with an approximation&lt;br /&gt;if(vz == 0)&lt;br /&gt;    vz = .0001;&lt;br /&gt;&lt;br /&gt;float v = sqrt( vx*vx + vy*vy + vz*vz );&lt;br /&gt;float ax = 57.2957795*acos( vz/v );&lt;br /&gt;if ( vz &amp;lt; 0.0 )&lt;br /&gt;    ax = -ax;&lt;br /&gt;float rx = -vy*vz;&lt;br /&gt;float ry = vx*vz;&lt;br /&gt;glPushMatrix();&lt;br /&gt;&lt;br /&gt;//draw the cylinder body&lt;br /&gt;glTranslatef( x1,y1,z1 );&lt;br /&gt;glRotatef(ax, rx, ry, 0.0);&lt;br /&gt;gluQuadricOrientation(quadric,GLU_OUTSIDE);&lt;br /&gt;gluCylinder(quadric, radius, radius, v, subdivisions, 1);&lt;br /&gt;&lt;br /&gt;//draw the first cap&lt;br /&gt;gluQuadricOrientation(quadric,GLU_INSIDE);&lt;br /&gt;gluDisk( quadric, 0.0, radius, subdivisions, 1);&lt;br /&gt;glTranslatef( 0,0,v );&lt;br /&gt;&lt;br /&gt;//draw the second cap&lt;br /&gt;gluQuadricOrientation(quadric,GLU_OUTSIDE);&lt;br /&gt;gluDisk( quadric, 0.0, radius, subdivisions, 1);&lt;br /&gt;glPopMatrix();&lt;br /&gt;}&lt;br /&gt;void renderCylinder_convenient(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions)&lt;br /&gt;{&lt;br /&gt;//the same quadric can be re-used for drawing many cylinders&lt;br /&gt;GLUquadricObj *quadric=gluNewQuadric();&lt;br /&gt;gluQuadricNormals(quadric, GLU_SMOOTH);&lt;br /&gt;renderCylinder(x1,y1,z1,x2,y2,z2,radius,subdivisions,quadric);&lt;br /&gt;gluDeleteQuadric(quadric);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span class="Apple-style-span"  &gt;A complete OpenGL example using this function can be found &lt;a href="http://lifeofaprogrammergeek.blogspot.com/2008/08/opengl-example-rendering-cylinders.html"&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); line-height: 18px; "&gt;&lt;span class="Apple-style-span"  &gt;&lt;b&gt;Update 12/25/2010:&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); line-height: 18px; "&gt;&lt;span class="Apple-style-span"  &gt;Since it is getting some use I decided to create a GitHub repository for this little piece of useful code:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/curran/renderCyliner"&gt;https://github.com/curran/renderCyliner&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I would welcome any improvements!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;b&gt;Links:&lt;/b&gt;&lt;br /&gt;&lt;a href="http://home.neo.rr.com/jparris/OpenGL%20-%20draw%20cylinder%20between%202%20pts.htm"&gt;Original implementation&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6461387352629250590-4117877619483871488?l=lifeofaprogrammergeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeofaprogrammergeek.blogspot.com/feeds/4117877619483871488/comments/default' title='Post C
