<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>devjason</title>
	<atom:link href="http://www.devjason.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.devjason.com</link>
	<description>Code, Statistics, Data Visualization</description>
	<lastBuildDate>Sat, 07 Apr 2012 17:31:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Shakespeare Sonnet Sourced Markov Text Generation</title>
		<link>http://www.devjason.com/2010/12/28/shakespeare-sonnet-sourced-markov-text-generation/</link>
		<comments>http://www.devjason.com/2010/12/28/shakespeare-sonnet-sourced-markov-text-generation/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 21:39:32 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[markov]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=217</guid>
		<description><![CDATA[And play the mother&#8217;s part, kiss me, be kind; So will I pray that thou mayst prove me. Weary with toil, I haste me thence? Till I return, of posting is no remedy, It is the time with thoughts of &#8230; <a href="http://www.devjason.com/2010/12/28/shakespeare-sonnet-sourced-markov-text-generation/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<blockquote><p>
And play the mother&#8217;s part, kiss me, be kind;<br />
 So will I pray that thou mayst prove me.<br />
 Weary with toil, I haste me thence?<br />
 Till I return, of posting is no remedy,<br />
 It is the time with thoughts of love as oft as thou shalt find<br />
 Those children nursed, deliver&#8217;d from thy heart,<br />
 And take thou my love shall in these black lines be seen,<br />
 And they shall live, and he stole that word<br />
 From thy behaviour; beauty doth he give,<br />
 And found such fair assistance in my will no fair acceptance shine?<br />
 The sea, all water, yet receives rain still,<br />
 And then thou hast her it is built anew,<br />
 Grows fairer than at first, more strong, greater.
</p></blockquote>
<p><code><br />
Number of key tuples: 14916<br />
Mean Choices:         1.174175<br />
Min Choices:          1<br />
Max Choices:          27<br />
Sum of Squares:       13581.492357<br />
Standard Deviation:   116.539660<br />
</code></p>
<p>I have had a vague &#8220;todo&#8221; in my head for a while to do something with Markov text generation.  One of the things that I look forward to when I scan through my spam folders is finding interesting text that was obviously generated.  I was lazily browsing through some of my news feeds and following links when I came across this post titled <a href="http://www.codinghorror.com/blog/2008/06/markov-and-you.html">Markov and You</a> by Jeff Atwood.  I especially liked the Garkov reference he used to illustrate the usage.  I decided I would try to do something similar and found a basic markov implementation in python at this Usware <a href="http://uswaretech.com/blog/2009/06/pseudo-random-text-markov-chains-python/">blog post</a>.</p>
<p>After playing with the &#8221;quick brown fox&#8221; implementation and pulling in some CNN articles I decided to do something a bit more interesting and downloaded <a href="http://www.gutenberg.org/cache/epub/1041/pg1041.txt">Shakespeare&#8217;s Sonnets</a> from <a href="http://www.gutenberg.org/">Project Gutenberg</a>.</p>
<p>I modified my generator implementation to have output based on the number of lines emitted, and added a reseed function to select a new start tuple in the event that no keys matched my existing search tuple.  Finally, I added some simple output statistics to get a feel for how the constructed database looked when I tweaked the chain length parameter.  Having shorter chain lengths tended to make the text too random, while longer ones pulled in too much of an existing sonnet sequence.  Watching the number of key tuples and the summary statistics of the choices helped me tune the code for this corpus.</p>
<p>The code is available <a href="https://github.com/devjason/markov_poem">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2010/12/28/shakespeare-sonnet-sourced-markov-text-generation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple FSM Game in Prolog</title>
		<link>http://www.devjason.com/2010/11/28/simple-fsm-game-in-prolog/</link>
		<comments>http://www.devjason.com/2010/11/28/simple-fsm-game-in-prolog/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 21:38:35 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[fsm]]></category>
		<category><![CDATA[prolog]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=199</guid>
		<description><![CDATA[We have done some Prolog in my programming languages class recently, so I&#8217;ve been doing some additional reading this weekend for kicks. I actually have some background in rule-based system, primarily using Jess (look for my name in the credits &#8230; <a href="http://www.devjason.com/2010/11/28/simple-fsm-game-in-prolog/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We have done some Prolog in my programming languages class recently, so I&#8217;ve been doing some additional reading this weekend for kicks.  I actually have some background in rule-based system, primarily using <a href="http://jessrules.com">Jess</a> (look for my name in the credits of <a href="http://www.amazon.com/Jess-Action-Java-Rule-Based-Systems/dp/1930110898">Jess In Action</a>, I submitted a few bug reports/fixes so got to see my name in print ha).<br />
<span id="more-199"></span></p>
<p>I saw a reference to <a href="http://www.ai-junkie.com">ai-junkie</a> somewhere and read through the &#8220;Agents&#8221; section and thought I would have a go at building a simple finite state machine game in Prolog based on the Miner Bob example found <a href="http://www.ai-junkie.com/architecture/state_driven/tut_state2.html">here</a>, specifically in Figure 2.2.</p>
<p>I&#8217;m not sure if this is the best way to do this in Prolog, this approach will eventually fail for long enough games since the stack just keeps growing.</p>
<pre class="brush: plain; title: ; notranslate">
/*
  Simple FSM based on

http://www.ai-junkie.com/architecture/state_driven/tut_state1.html

  Player data structure looks like:
  player(wealth, thirst, banked).
*/

/* Game parameters */
goal(20).
maxThirst(3).
maxInventory(4).
rateThirst(1).
rateMine(2).

% debug helper which just dumps player information
debug(P) :-
  write(P),nl.

% The home state, where we start and end the game.
state(home, player(Wealth,Thirst,Banked)) :-
  write('Home'),nl,
  (Banked =:= 0 -&gt;
    fire(state(home), event(rested), player(Wealth,Thirst,Banked));
    write('Retirement!'),nl,
    debug(player(Wealth,Thirst,Banked))).

% The bank state, where wealth is deposited and our banked amount checked
state(bank, player(Wealth,Thirst,Banked)) :-
  write('Bank'),nl,
  B is Wealth + Banked,
  P = player(0,Thirst,B),
  goal(G),
  (B &lt; G -&gt;
    fire(state(bank), event(not_wealthy), P);
    fire(state(bank), event(wealth), P)).

% The mining state where we do our work, generating wealth and thirst
state(mine, player(Wealth,Thirst,Banked)) :-
  write('Mining'),nl,
  rateMine(Rm),
  rateThirst(Rt),
  W is Wealth+Rm,
  T is Thirst+Rt,
  P = player(W,T,Banked),
  maxThirst(MaxThirst),
  maxInventory(MaxInv),
  (T &gt;= MaxThirst -&gt; fire(state(mine), event(thirsty), P);
    (W &gt;= MaxInv -&gt;
      fire(state(mine), event(deposit), P);
      fire(state(mine), event(not_wealthy), P))).

% The quenching state, wherein we slake our thirst.
state(quench, player(Wealth,_,Banked)) :-
  write('Drinking'),nl,
  fire(state(quench), event(not_thirsty), player(Wealth,0,Banked)).

% Definitions of our state transitions and event
transition(state(home),   event(rested),      state(mine)).
transition(state(mine),   event(deposit),     state(bank)).
transition(state(mine),   event(thirsty),     state(quench)).
transition(state(mine),   event(not_wealthy), state(mine)).
transition(state(quench), event(not_thirsty), state(mine)).
transition(state(bank),   event(wealth),      state(home)).
transition(state(bank),   event(not_wealthy), state(mine)).

% Fires a state transition event and transfers us to the next state.
fire(state(S), event(E), P) :-
  write('\tStatus: '), debug(P),
  transition(state(S),event(E),state(NextState)),
  state(NextState, P).

% Starts the game!
start :-
  P = player(0, 0, 0),
  state(home, P).
</pre>
<p>Running it looks like:<br />
<code><br />
| ?- start.<br />
Home<br />
	Status: player(0,0,0)<br />
Mining<br />
	Status: player(2,1,0)<br />
Mining<br />
	Status: player(4,2,0)<br />
Bank<br />
	Status: player(0,2,4)<br />
Mining<br />
	Status: player(2,3,4)<br />
Drinking<br />
	Status: player(2,0,4)<br />
Mining<br />
	Status: player(4,1,4)<br />
Bank<br />
	Status: player(0,1,8)<br />
Mining<br />
	Status: player(2,2,8)<br />
Mining<br />
	Status: player(4,3,8)<br />
Drinking<br />
	Status: player(4,0,8)<br />
Mining<br />
	Status: player(6,1,8)<br />
Bank<br />
	Status: player(0,1,14)<br />
Mining<br />
	Status: player(2,2,14)<br />
Mining<br />
	Status: player(4,3,14)<br />
Drinking<br />
	Status: player(4,0,14)<br />
Mining<br />
	Status: player(6,1,14)<br />
Bank<br />
	Status: player(0,1,20)<br />
Home<br />
Retirement!<br />
player(0,1,20)<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2010/11/28/simple-fsm-game-in-prolog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Gephi for RDB Schema Visualization</title>
		<link>http://www.devjason.com/2010/11/22/using-gephi-for-rdb-schema-visualization/</link>
		<comments>http://www.devjason.com/2010/11/22/using-gephi-for-rdb-schema-visualization/#comments</comments>
		<pubDate>Mon, 22 Nov 2010 17:28:04 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[gephi]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=175</guid>
		<description><![CDATA[I spent a little bit of time this weekend looking at using Gephi for visualizing graphs and networks. I heard about Gephi from this post on the dataists web site. This is a directed graph of a relational database schema. &#8230; <a href="http://www.devjason.com/2010/11/22/using-gephi-for-rdb-schema-visualization/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.devjason.com/wp-content/uploads/2010/11/Gephi_Example-150x150.png" alt="" title="Gephi_Example" width="150" height="150" class="alignleft size-thumbnail wp-image-174" /><br />
I spent a little bit of time this weekend looking at using <a href="http://gephi.org">Gephi</a> for visualizing graphs and networks.  I heard about Gephi from <a href="http://www.dataists.com/2010/10/what-data-visualization-should-do-simple-small-truth/">this post</a> on the dataists web site.</p>
<p><span id="more-175"></span></p>
<p>This is a directed graph of a relational database schema.  The node size reflects the count of rows within the table, and the node color reflects the out-degree measurement of the node, that is the number of outgoing references the node has.  The node color is ramped from blue to red.  I&#8217;ve left off node labels for confidentiality.</p>
<p>The most central highly connected node has a large number of incoming edges because it is used for system wide auditing purposes.  Certain subsystems are able to be identified, and the ring of stand-alone nodes mainly represent setup and configuration tables that do not participate in cross-domain operations.</p>
<p>I investigated the filtering capabilities of Gephi and found them pretty easy to use, I was able to perform some basic k-core analysis of the node degrees to be able to identify the most linked tables in the schema.  I think making an animation of this could prove to be informative.</p>
<p>One feature that I would like but have not determined whether it is possible with Gephi is to identify dominators and cliques.</p>
<p><a href="http://www.devjason.com/wp-content/uploads/2010/11/Gephi_Example.png"><img src="http://www.devjason.com/wp-content/uploads/2010/11/Gephi_Example.png" alt="" title="Gephi_Example" width="595" height="764" class="aligncenter size-full wp-image-174" /></a></p>
<p>I used <a href="http://groovy.codehaus.org/">Groovy</a> + <a href="http://gexf.net/gexf4j/">gexf4j</a> to generate the <a href="http://gexf.net/format/">GEXF</a> XML graph.  The script is specific for Oracle, but should be able to be easily modified to interrogate the metadata of other relational database systems.</p>
<pre class="brush: groovy; title: ; notranslate">
/*
 Retrieve database metadata about table names and relationships.
 This information will be used to generate GEXL for use in Gephi.
*/

import groovy.sql.Sql
import com.ojn.gexf4j.core.data.*
import com.ojn.gexf4j.core.impl.*
import com.ojn.gexf4j.core.impl.data.*

def sql = Sql.newInstance(
	&quot;jdbc:oracle:thin:@server:port:sid&quot;,
	&quot;username&quot;,
	&quot;password&quot;,
	&quot;oracle.jdbc.OracleDriver&quot;
)

def query_tables_and_count(sql) {
	def tables = []
	sql.eachRow(&quot;select * from user_objects where object_type = 'TABLE'&quot;) {
		def name  = it.OBJECT_NAME
		def countQuery = &quot;select count(*) as cnt from ${name}&quot;.toString()
		def count = sql.firstRow(countQuery).cnt
		tables &lt;&lt; ['name': name, 'count' : count]
	}
	tables
}

/**
 	@see http://www.conandalton.net/2008/09/list-foreign-key-constraints-in-oracle.html
*/
def query_foreign_relationships(sql) {
	String foreignKeyQuery = &quot;&quot;&quot;
	select
		distinct col.table_name as key,
		rel.table_name as references
	from
		user_tab_columns col
		join user_cons_columns con
		  on col.table_name = con.table_name
		 and col.column_name = con.column_name
		join user_constraints cc
		  on con.constraint_name = cc.constraint_name
		join user_cons_columns rel
		  on cc.r_constraint_name = rel.constraint_name
		 and con.position = rel.position
	where
		cc.constraint_type = 'R'
	order by
		col.table_name, rel.table_name
	&quot;&quot;&quot;
	def results = []
	sql.eachRow(foreignKeyQuery) {
		results &lt;&lt; ['key':it.key, 'ref':it.references]
	}
	results
}

def write_xml(sql) {
	def gexf = new GexfImpl()

	// Metadata
	gexf.getMetadata()
		.setLastModified(Calendar.getInstance().getTime())
		.setCreator(&quot;Jason B. Smith&quot;)
		.setDescription(&quot;DB Graph&quot;)

	attrList = new AttributeListImpl(AttributeClass.NODE);
	gexf.getGraph().getAttributeLists().add(attrList);
	attrCount = attrList.createAttribute(&quot;0&quot;, AttributeType.INTEGER, &quot;count&quot;)

	// Nodes
	node_cache = [:]
	query_tables_and_count(sql).each { t -&gt;
		node = gexf.getGraph().createNode(t.name)
		node
			.setLabel(t.name)
			.getAttributeValues()
				.addValue(attrCount, &quot;${t.count}&quot;)	// convert from BigDecimal
		node_cache[t.name] = node
	}

	// Relationships
	query_foreign_relationships(sql).each { r -&gt;
		node_cache[r.key].connectTo(node_cache[r.ref])
	}

	// Write XML
	def writer = new StaxGraphWriter()
	writer.writeToStream(gexf, System.out)
}
write_xml(sql)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2010/11/22/using-gephi-for-rdb-schema-visualization/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MS Communicator(SIP) + Ubuntu 9.04</title>
		<link>http://www.devjason.com/2009/08/03/ms-communicatorsip-ubuntu-9-04/</link>
		<comments>http://www.devjason.com/2009/08/03/ms-communicatorsip-ubuntu-9-04/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 15:23:22 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=163</guid>
		<description><![CDATA[I found an interesting post this morning talking about using Pidgin on Fedora Core to communicate with a MS Communicator server. I was able to follow the instructions from Louis van der Merwe to get this working on 64-bit Ubuntu &#8230; <a href="http://www.devjason.com/2009/08/03/ms-communicatorsip-ubuntu-9-04/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I found an interesting <a href="http://kungfucodemonkey.blogspot.com/2009/06/ms-office-communicator-on-linux.html">post</a>  this morning talking about using Pidgin on Fedora Core to communicate with a MS Communicator server.  I was able to follow the  instructions from Louis van der Merwe to get this working on 64-bit Ubuntu 9.04.</p>
<p>First I downloaded the Pidgin client plugin sourceball from <a href="http://sipe.sourceforge.net/plugins/">the SIPE Project</a>, and started running <code>configure --prefix=/usr</code> to identify missing libraries.  I installed the missing dependencies using <code>sudo apt-get install intltool libpurple comerr-dev</code>, other systems may require more or less.  After configuring, making, and installing the plugin I fired up Pidgin.</p>
<p>The only modification I had to make to the configuration instructions was to use <code>SSL</code> instead of <code>TCP</code> for communications as we use a certificate at my workplace.  <del datetime="2009-09-22T17:02:09+00:00">Although contacts and groups were pulled in successfully, my presence notification doesn&#8217;t seem to work (I show up as offline).</del>  However, this is good enough for me right now and I&#8217;m really happy to be able to access the corporate communication channel in my primary development environment.</p>
<p><strong>*Updated to 1.6.3*</strong><br />
Presence notification seems to be working now, thank you SIPE team!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2009/08/03/ms-communicatorsip-ubuntu-9-04/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Moiré Curves</title>
		<link>http://www.devjason.com/2009/06/25/moire-curves/</link>
		<comments>http://www.devjason.com/2009/06/25/moire-curves/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 00:49:18 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=151</guid>
		<description><![CDATA[I wrote this during lunch to kill some time before a conference call. I liked the effect on the Moiré Pattern page and thought I would replicate a variation of it. Controls Left/Right Arrows or Mouse Buttons: Reverse direction or &#8230; <a href="http://www.devjason.com/2009/06/25/moire-curves/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.devjason.com/wp-content/uploads/2009/06/Moire-Circle-150x150.png" alt="Moiré Circle" title="Moiré Circle" width="150" height="150" class="alignleft size-thumbnail wp-image-157" /><br />
I wrote this during lunch to kill some time before a conference call.  I liked the effect on the <a href="http://en.wikipedia.org/wiki/Moiré_pattern">Moiré Pattern</a> page and thought I would replicate a variation of it.<br />
<span id="more-151"></span></p>
<h2>Controls</h2>
<p><b>Left/Right Arrows or Mouse Buttons</b>: Reverse direction or perform a step in that direction when in Step Mode.<br />
<b>Space or Middle Mouse Buttons</b>: Pause and enter Step mode<br />
<i>Note that after the circles pass each other, the left/right controls may seem counter-intuitive.</i></p>
<p><script src="http://java.com/js/deployJava.js"></script> <script type="text/javascript">// <![CDATA[
  var project_url = 'http://www.devjason.com/static/projects/processing/moire_circle/applet/';
  var attributes = {
    code:'moire_circle.class',
archive: project_url + 'moire_circle.jar',
    width:600,
    height:300
  };
  var parameters = {
    fontSize:12,
	 image: project_url + 'loading.gif'
  };
  var version = '1.5' ; // whichever minimum version you want to target, null works also
  deployJava.runApplet(attributes, parameters, version);
// ]]&gt;</script></p>
<p><a href="http://www.devjason.com/static/projects/processing/moire_circle/applet/moire_circle.pde">Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2009/06/25/moire-curves/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Processing Maze Generator/Solver</title>
		<link>http://www.devjason.com/2009/06/25/processing-maze-generatorsolver/</link>
		<comments>http://www.devjason.com/2009/06/25/processing-maze-generatorsolver/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 00:30:25 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=139</guid>
		<description><![CDATA[This is one of the first Processing projects I wrote a few months ago while I was waiting on a large database download and import. Requires a working Java plugin in your browser. The application has two phases: generating and &#8230; <a href="http://www.devjason.com/2009/06/25/processing-maze-generatorsolver/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-145" title="Maze" src="http://www.devjason.com/wp-content/uploads/2009/06/Maze-150x150.png" alt="Maze" width="150" height="150" /><br />
This is one of the first Processing projects I wrote a few months ago while I was waiting on a large database download and import.  Requires a working Java plugin in your browser.<br />
<span id="more-139"></span></p>
<p>The application has two phases: generating and solving.  You can restart the generation by clicking. After the maze has been generated click to begin solving from that point.</p>
<p><script src="http://java.com/js/deployJava.js"></script> <script type="text/javascript">// <![CDATA[
  var project_url = 'http://www.devjason.com/static/projects/processing/Maze/applet/';
  var attributes = {
    code:'Maze.class',
archive: project_url + 'Maze.jar',
    width:500,
    height:500
  };
  var parameters = {
    fontSize:12,
	 image: project_url + 'loading.gif'
  };
  var version = '1.5' ; // whichever minimum version you want to target, null works also
  deployJava.runApplet(attributes, parameters, version);
// ]]&gt;</script><br />
<a href="http://www.devjason.com/static/projects/processing/Maze/applet/Maze.pde">Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2009/06/25/processing-maze-generatorsolver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache Trailing Slash Problem</title>
		<link>http://www.devjason.com/2009/06/10/apache-trailing-slash-problem/</link>
		<comments>http://www.devjason.com/2009/06/10/apache-trailing-slash-problem/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 18:36:21 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=123</guid>
		<description><![CDATA[I was helping our IT guys out this past weekend configuring a reverse proxy load balancing environment for JBoss/Tomcat behind Apache. I kept running into problems where requests coming from Apache looked like: GET /foo//bar instead of GET /foo/bar Unfortunately &#8230; <a href="http://www.devjason.com/2009/06/10/apache-trailing-slash-problem/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was helping our IT guys out this past weekend configuring a reverse proxy load balancing environment for JBoss/Tomcat behind Apache.  I kept running into problems where requests coming from Apache looked like:<br />
<code>GET /foo//bar</code> instead of <code>GET /foo/bar</code><br />
<span id="more-123"></span><br />
Unfortunately this was causing NPEs and resource not found errors in a third party servlet filter we are using to combine some our static resources.  This is the Apache configuration that seems to have resolved the problem, I just wanted to post it here in case I ran up against it again.</p>
<pre class="brush: plain; title: ; notranslate">
# Placed in Apache conf for the site
&lt;Proxy balancer://app_cluster &gt;
BalancerMember http://app1/foo
BalancerMember http://app2/foo
BalancerMember http://app3/foo
&lt;/Proxy&gt;
ProxyPass /foo/ balancer://app_cluster/ stickysession=JSESSIONID
ProxyPassReverse /foo/ http://app1/foo/
ProxyPassReverse /foo/ http://app2/foo/
ProxyPassReverse /foo/ http://app3/foo/
</pre>
<p>The lesson here is attention to detail, especially your final slashes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2009/06/10/apache-trailing-slash-problem/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Visualizing Changes With Levelplot Heatmap</title>
		<link>http://www.devjason.com/2009/06/08/visualizing-changes-with-levelplot-heatmap/</link>
		<comments>http://www.devjason.com/2009/06/08/visualizing-changes-with-levelplot-heatmap/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 23:56:59 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[R]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=108</guid>
		<description><![CDATA[I recently worked on configuring and enabling Ehcache with our Hibernate objects for common domain objects we query on almost every page request. I was interested in whether this would improve performance, and how best to illustrate the effect of &#8230; <a href="http://www.devjason.com/2009/06/08/visualizing-changes-with-levelplot-heatmap/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a class="shutterset_" href="http://www.devjason.com/wp-content/gallery/r_generated/heatmap_diff.png"><br />
<img class="ngg-singlepic ngg-left" src="http://www.devjason.com/wp-content/gallery/r_generated/thumbs/thumbs_heatmap_diff.png" alt="heatmap_diff.png" /></a></p>
<p>I recently worked on configuring and enabling <a href="http://ehcache.sourceforge.net/">Ehcache</a> with our <a href="http://www.hibernate.org">Hibernate</a> objects for common domain objects we query on almost every page request.  I was interested in whether this would improve performance, and how best to illustrate the effect of the pages across threads and actions.<br />
<span id="more-108"></span></p>
<p>I had written some JMeter tests I am able to automatically run with different thread loads (5-60 threads stepping by 5) so I generated some response time data for before and after enabling the cache.  Although there is actually many more rows and columns, in general the data looks like:<br />
label elapsed threads<br />
<code><br />
Action    Elapsed  Threads<br />
NtSP      25    10<br />
DLgn      11   10<br />
FtDV       6   10<br />
NtMM      16   10<br />
NtSS      20   15<br />
SrfS     157   10<br />
</code></p>
<p>I then read the log files into two data frames, r1 for the pre-cache times and r2 for the post-cache times.  Using tapply I then generated two matrices of mean response times by thread and action (r1 becomes m1, r2 becomes m2).  From that point it is just a matter of subtracting the m1 matrix from m2 to obtain the differences measured.</p>
<pre class="brush: r; title: ; notranslate">
z &lt;- r1
m1 &lt;- tapply(z$elapsed, list(z$label, z$threads), mean)
z &lt;- r2
m2 &lt;- tapply(z$elapsed, list(z$label, z$threads), mean)
m.diff &lt;- m2 - m1
</pre>
<p>Because the final output of the previous calculations is a two-dimensional matrix, a heatmap or similar visualization style seemed like it might be appropriate.  In the real version the action names are not obfuscated.</p>
<pre class="brush: r; title: ; notranslate">
# Calculate breaks using midpoints of matrix histogram with initial extension
x &lt;- c(-20000, hist(m.diff)$mids)
levelplot(t(m.diff), scales=list(cex=0.7), aspect=&quot;iso&quot;, col.regions=heat.colors, pretty=F,at=x,xlab='Threads',ylab='Action',main=&quot;Time Difference With Cache&quot;)
</pre>
<p><img class="ngg-singlepic ngg-none" src="http://www.devjason.com/wp-content/gallery/r_generated/heatmap_diff.png" alt="heatmap_diff.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2009/06/08/visualizing-changes-with-levelplot-heatmap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Summary statistics by group with R</title>
		<link>http://www.devjason.com/2009/04/29/summary-statistics-by-group-with-r/</link>
		<comments>http://www.devjason.com/2009/04/29/summary-statistics-by-group-with-r/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 22:28:44 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[R]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=96</guid>
		<description><![CDATA[I was working on profiling some code today and wanted to obtain some summary statistics by groups with two factors. The original source was a log4j file that included entries from an aspect based logger I had enabled. I had &#8230; <a href="http://www.devjason.com/2009/04/29/summary-statistics-by-group-with-r/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was working on profiling some code today and wanted to obtain some summary statistics by groups with two factors.  The original source was a log4j file that included entries from an aspect based logger I had enabled.  I had already written a small perl script to extract the pertinent information and generate a CSV file with (clazz,method,elapsed) entries, so I was looking for some standard statistics like mean, median, etc. based on clazz+method combinations.<br />
<span id="more-96"></span><br />
My initial approach looked like:</p>
<pre class="brush: r; title: ; notranslate">
metrics &lt;- read.csv('some_metrics.csv',header=T)
aggregate(dce$elapsed, by=list(CLAZZ=dce$clazz,METHOD=dce$method), median) -&gt; medians
aggregate(dce$elapsed, by=list(CLAZZ=dce$clazz,METHOD=dce$method), mean) -&gt; means
aggregate(dce$elapsed, by=list(CLAZZ=dce$clazz,METHOD=dce$method), min) -&gt; mins
aggregate(dce$elapsed, by=list(CLAZZ=dce$clazz,METHOD=dce$method), max) -&gt; maxes
aggregate(dce$elapsed, by=list(CLAZZ=dce$clazz,METHOD=dce$method), length) -&gt; lengths
aggregate(dce$elapsed, by=list(CLAZZ=dce$clazz,METHOD=dce$method), sum) -&gt; sums
s &lt;- mins
s$MIN &lt;- s$x
s$x &lt;- NULL
s$MAX = maxes$x
s$MEAN = means$x
s$MEDIAN = medians$x
s$NUM = lengths$x
s$SUM = sums$x
rm(mins,means,maxes,medians,sums)
</pre>
<p>This was obviously less than ideal, although I could wrap this in a function it is a bit ugly and cumbersome.  I searched the R-help mailing list and found some references to the doBy package, which &#8220;grew out of a need to calculate groupwise summary statistics in a simple way&#8221;.  The summaryBy function in this package turned out to be exactly what I needed and simplified by code to:</p>
<pre class="brush: r; title: ; notranslate">
summarize &lt;- function(csvfile) {
	require(doBy)
	metrics.csv &lt;- read.csv(csvfile,header=T)
	metrics &lt;- summaryBy(elapsed ~ clazz + method, data=metrics.csv, FUN=c(mean,median,min,max,sum,length))
	write.csv(metrics, file='export.csv', quote=F, row.names=F)
	metrics
}
metrics &lt;- summarize('some_metrics.csv')
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2009/04/29/summary-statistics-by-group-with-r/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>More Quick R Maps: Country View of WHO Confirmed Cases</title>
		<link>http://www.devjason.com/2009/04/28/more-quick-r-maps-country-view-of-who-confirmed-cases/</link>
		<comments>http://www.devjason.com/2009/04/28/more-quick-r-maps-country-view-of-who-confirmed-cases/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 15:38:25 +0000</pubDate>
		<dc:creator>jsmith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cartography]]></category>
		<category><![CDATA[R]]></category>

		<guid isPermaLink="false">http://www.devjason.com/?p=87</guid>
		<description><![CDATA[I realized it should be pretty easy to use the approach as the previous R map I generated to make a smaller scale map at a country level. In this example I&#8217;m setting up an initial non-plotted map with limits &#8230; <a href="http://www.devjason.com/2009/04/28/more-quick-r-maps-country-view-of-who-confirmed-cases/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a class="shutterset_" href='http://www.devjason.com/2009/04/28/more-quick-r-maps-country-view-of-who-confirmed-cases/' title=''><img src='http://www.devjason.com/wp-content/gallery/r_generated/thumbs/thumbs_who_world_swineflu_04282009.png' alt='who_world_swineflu_04282009.png' class='ngg-singlepic ngg-right' /></a></p>
<p>I realized it should be pretty easy to use the approach as the previous R map I generated to make a smaller scale map at a country level.  In this example I&#8217;m setting up an initial non-plotted map with limits on the X and Y ranges I want to display.  Next I assign colors to the observations of this subset map, plot these filled areas, then plot all boundaries.<br />
<span id="more-87"></span><br />
I&#8217;m not really happy with this map because (1) I don&#8217;t really like just throwing out maps with just geographic coordinates, and (2) using area coloring can be a bit misleading about the magnitude and dispersal of the data presented: in this case there are really small clusters of reported cases, not country wide.  I think this map might be a good index map to get an overview of the spread and number of cases, but would need to be backed by more detailed maps that do not generalize the location of outbreaks as much.</p>
<p><img src='http://www.devjason.com/wp-content/gallery/r_generated/who_world_swineflu_04282009.png' alt='who_world_swineflu_04282009.png' class='ngg-singlepic ngg-none' /></p>
<p>Here&#8217;s the source:</p>
<pre class="brush: r; title: ; notranslate">
# load required libraries
require(maps)
require(RColorBrewer)

# Create a dataframe with the reported observations
loc &lt;- c('USA', 'Mexico', 'Canada', 'Spain')
cases &lt;- c(40, 26, 6, 1)
flu &lt;- data.frame(loc,cases)

# Setup the coordinate system
m &lt;- map('world',plot=F, xlim=c(-180,5),ylim=c(10,90), fill=T)

# Match up our observations
stm &lt;- match.map(m, flu$loc)

# Rank the cases and assign colors using the RColorBrewer YlOrRd palette
flu$rank &lt;- rank(flu$cases, ties='min')
pal &lt;- brewer.pal(max(flu$rank),'YlOrRd')
color &lt;- pal[flu$rank]
flu.color &lt;- color[stm]

# Do the drawing
map(m,col=flu.color,fill=T, lty=0,boundary=F,interior=F) # fill regions
map('world',interior=T,add=T,col='grey30') # plot boundaries
map.axes()
grid(col='grey50')
title('WHO Confirmed Cases of Swine Flu by Country (28 April 2009)')
legend('bottomleft', legend=paste(flu$loc,flu$cases),
	fill=color, bg='white', horiz=T, cex=0.75,
	title=paste('Jason B. Smith | 28 April 2009 | Source: CNN.com'))
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.devjason.com/2009/04/28/more-quick-r-maps-country-view-of-who-confirmed-cases/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

