<?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>Cale Dunlap &#187; Code</title>
	<atom:link href="http://www.caledunlap.com/tag/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.caledunlap.com</link>
	<description>Programmer and Hobbyist Game Developer</description>
	<lastBuildDate>Wed, 10 Mar 2010 21:30:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>LINQ Audit Trail v2 &#8211; DoddleAudit</title>
		<link>http://www.caledunlap.com/2009/12/linq-audit-trail-v2-doddleaudit/</link>
		<comments>http://www.caledunlap.com/2009/12/linq-audit-trail-v2-doddleaudit/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 04:29:17 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://www.caledunlap.com/?p=562</guid>
		<description><![CDATA[This looked like a link that was fairly re-post worthy. This is practically a must for any .NET + LINQ + MSSQL developer out there. Very neat way of doing audit trails in MSSQL with LINQ and C#.
A couple months ago I wrote a basic set of extension methods to handle automatic auditing in LINQ <a href="http://www.caledunlap.com/2009/12/linq-audit-trail-v2-doddleaudit/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>This looked like a link that was fairly re-post worthy. This is practically a must for any .NET + LINQ + MSSQL developer out there. Very neat way of doing audit trails in MSSQL with LINQ and C#.</p>
<blockquote><p>A couple months ago I wrote a basic set of extension methods to handle automatic auditing in LINQ to SQL. Well I have received a large number of emails regarding this particular project so I have decided to focus on cleaning up my v2 API and releasing it on CodePlex. There was a lot of room for improvement from version 1 and today I am going to post the all new LINQ Audit Trail code. This new version is significantly enhanced in the previous version.</p>
</blockquote>
<p>via <a href="http://www.matthidinger.com/archive/2009/01/12/linq-audit-trail-v2.aspx">LINQ Audit Trail v2 &#8211; DoddleAudit</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/12/linq-audit-trail-v2-doddleaudit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A few handy Javascript Methods</title>
		<link>http://www.caledunlap.com/2009/11/a-few-handy-javascript-methods/</link>
		<comments>http://www.caledunlap.com/2009/11/a-few-handy-javascript-methods/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 17:30:24 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://caledunlap.com/2009/11/a-few-handy-javascript-methods/</guid>
		<description><![CDATA[So I’ve been doing a LOT of Javascript programming in the last few days and I ran into a few limitations of the language or constructs within the language. For example, certain versions of IE do not support the Array.indexOf() method. Another problem I ran into is that the Javascript language does not contain a <a href="http://www.caledunlap.com/2009/11/a-few-handy-javascript-methods/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>So I’ve been doing a LOT of Javascript programming in the last few days and I ran into a few limitations of the language or constructs within the language. For example, certain versions of IE do not support the Array.indexOf() method. Another problem I ran into is that the Javascript language does not contain a method for performing deep copies on objects. So after some Googling I found a few ways around the aforementioned problems. The first one (indexOf) is as follows:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:26771b21-04fc-42a4-8226-2a6c06ce403e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap">Array.prototype.findObject = (<br /> &#160;&#160;&#160;&#160;!Array.indexOf ? <span style="color:#0000ff">function</span> (o) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">var</span> l = <span style="color:#0000ff">this</span>.length + 1;<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">while</span> (l&#8211;) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> (<span style="color:#0000ff">this</span>[l - 1] === o) <span style="color:#0000ff">return</span> l &#8211; 1;<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> -1;<br /> &#160;&#160;&#160;&#160;} : <span style="color:#0000ff">function</span> (o) { <span style="color:#0000ff">return</span> (<span style="color:#0000ff">this</span>.indexOf(o) !== -1); }<br /> );</div>
</p></div>
</p></div>
<p>The above code will add the ‘findObject’ method to your Array objects. Then you can use that instead of indexOf() and be guaranteed that it will work regardless if the browser supports indexOf or not.</p>
<p>The second one (deep copying) can be circumvented by creating a helper method which will perform the copy for you: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5f811a2f-8dd1-4896-a377-da22dd65ef42" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">var</span> ObjectHandler = {<br /> &#160;&#160;&#160;&#160;<span style="color:#006400">//public method</span><br /> &#160;&#160;&#160;&#160;getCloneOfObject: <span style="color:#0000ff">function</span>(oldObject) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">var</span> tempClone = {};</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> (<span style="color:#0000ff">typeof</span>(oldObject) == <span style="color:#800000">&quot;object&quot;</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">for</span> (prop <span style="color:#0000ff">in</span> oldObject)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#006400">// for array use private method getCloneOfArray</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> ((<span style="color:#0000ff">typeof</span>(oldObject[prop]) == <span style="color:#800000">&quot;object&quot;</span>) &amp;&amp;<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(oldObject[prop]).__isArray)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone[prop] = <span style="color:#0000ff">this</span>.getCloneOfArray(oldObject[prop]);<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#006400">// for object make recursive call to getCloneOfObject</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">else</span> <span style="color:#0000ff">if</span> (<span style="color:#0000ff">typeof</span>(oldObject[prop]) == <span style="color:#800000">&quot;object&quot;</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone[prop] = <span style="color:#0000ff">this</span>.getCloneOfObject(oldObject[prop]);<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#006400">// normal (non-object type) members</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone[prop] = oldObject[prop];</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> tempClone;<br /> &#160;&#160;&#160;&#160;},</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#006400">//private method (to copy array of objects) &#8211; getCloneOfObject will use this internally</span><br /> &#160;&#160;&#160;&#160;getCloneOfArray: <span style="color:#0000ff">function</span>(oldArray) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">var</span> tempClone = [];</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">for</span> (<span style="color:#0000ff">var</span> arrIndex = 0; arrIndex &lt;= oldArray.length; arrIndex++)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> (<span style="color:#0000ff">typeof</span>(oldArray[arrIndex]) == <span style="color:#800000">&quot;object&quot;</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone.push(<span style="color:#0000ff">this</span>.getCloneOfObject(oldArray[arrIndex]));<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone.push(oldArray[arrIndex]);</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> tempClone;<br /> &#160;&#160;&#160;&#160;}<br /> };</div>
</p></div>
</p></div>
</p>
</p>
<p>Just thought I’d share those with everyone. Credit for the majority of the deep copy code goes to <a href="http://blog.pramatiservices.com/deep-copy-in-javascript/">http://blog.pramatiservices.com/deep-copy-in-javascript/</a> and credit for the findObject code goes to someone other than me, but I didn’t bookmark the link so I can’t find it again. Sorry <img src='http://www.caledunlap.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/11/a-few-handy-javascript-methods/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Helpful Extension Methods to the System.String Class in C#</title>
		<link>http://www.caledunlap.com/2009/10/helpful-extension-methods-to-the-system-string-class-in-c/</link>
		<comments>http://www.caledunlap.com/2009/10/helpful-extension-methods-to-the-system-string-class-in-c/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 10:20:03 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[extension methods]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/2009/10/helpful-extension-methods-to-the-system-string-class-in-c/</guid>
		<description><![CDATA[I&#8217;ve been doing a decent amount of string manipulation lately and decided to combine that with my newfound knowledge about .NET extension methods. If you don&#8217;t know what extension methods are, they&#8217;re basically a way to extend a class without needing the source code to that particular class&#8211;hence why I can extend the System.String type <a href="http://www.caledunlap.com/2009/10/helpful-extension-methods-to-the-system-string-class-in-c/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing a decent amount of string manipulation lately and decided to combine that with my newfound knowledge about .NET extension methods. If you don&#8217;t know what extension methods are, they&#8217;re basically a way to extend a class without needing the source code to that particular class&#8211;hence why I can extend the System.String type by simply writing another class. The key is with the parameters of your methods. Here&#8217;s the basic gist of it:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:050e6608-4d1a-4fda-8b59-b3cc677f09bd" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> {Your Return Type} {Your Method Name} ( <span style="color:#0000ff">this</span> {Type/Class you want to extend} {Parameter Name} )<br /> {<br /> &#160;&#160;&#160;&#160;&#160;<span style="color:#008000">/* Your method body */</span><br /> }</div>
</p></div>
</p></div>
<pre class="code">&nbsp;</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>So the key here is the &#8220;this&#8221; keyword before the type identifier in the parameter list of the method.</p>
<p>I&#8217;ve wrapped all of my extension methods into a single class simply called &#8220;ExtensionMethods&#8221; and added it to my project. The namespace doesn&#8217;t matter, so I haven&#8217;t included it in this example. You can either use the global namespace (though I don&#8217;t recommend it) or just create your own namespace called whatever you want.</p>
<p>Without further adue, here&#8217;s the code:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0271f875-eb62-41fe-a74b-7958d98dab65" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">ExtensionMethods</span><br />
{<br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> Includes the trailing path delimiter.</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&quot;InputPath&quot;&gt;</span><span style="color:#008000">The input path.</span><span style="color:#808080">&lt;/param&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;returns&gt;</span><span style="color:#008000">The input path including a trailing path delimiter if it doesn&#39;t have one</span><span style="color:#808080">&lt;/returns&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> IncludeTrailingPathDelimiter(<span style="color:#0000ff">this</span> <span style="color:#0000ff">string</span> InputPath)<br />
&#160;&#160;&#160;&#160;{<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> (!InputPath.EndsWith(Path.DirectorySeparatorChar.ToString()) &amp;&amp;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;!InputPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> InputPath + Path.DirectorySeparatorChar;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> InputPath;<br />
&#160;&#160;&#160;&#160;}</p>
<p>&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> Asserts the trailing path delimiter.</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&quot;InputPath&quot;&gt;</span><span style="color:#008000">The input path.</span><span style="color:#808080">&lt;/param&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> AssertTrailingPathDelimiter(<span style="color:#0000ff">this</span> <span style="color:#0000ff">string</span> InputPath)<br />
&#160;&#160;&#160;&#160;{<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;InputPath = InputPath.IncludeTrailingPathDelimiter();<br />
&#160;&#160;&#160;&#160;}</p>
<p>&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> Trims the extension from a file name.</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&quot;InputFile&quot;&gt;</span><span style="color:#008000">The input file.</span><span style="color:#808080">&lt;/param&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> TrimExtension(<span style="color:#0000ff">this</span> <span style="color:#0000ff">string</span> InputFile)<br />
&#160;&#160;&#160;&#160;{<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">int</span> start, count;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> ((start = InputFile.LastIndexOf(<span style="color:#a31515">&quot;.&quot;</span>)) &gt; 0)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;count = InputFile.Length &#8211; start;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;InputFile = InputFile.Remove(start, count);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br />
&#160;&#160;&#160;&#160;}</p>
<p>&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> Gets a file extension of a filename.</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&quot;InputFile&quot;&gt;</span><span style="color:#008000">The input file.</span><span style="color:#808080">&lt;/param&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;returns&gt;</span><span style="color:#008000">The file extension</span><span style="color:#808080">&lt;/returns&gt;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> FileExtension(<span style="color:#0000ff">this</span> <span style="color:#0000ff">string</span> InputFile)<br />
&#160;&#160;&#160;&#160;{<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">int</span> start, count;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> ((start = InputFile.LastIndexOf(<span style="color:#a31515">&quot;.&quot;</span>)) &gt; 0)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;count = InputFile.Length &#8211; start;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> InputFile.Substring(start, count);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> <span style="color:#0000ff">string</span>.Empty;<br />
&#160;&#160;&#160;&#160;}</p>
<p>}</p></div>
</div>
</div>
<pre class="code">&nbsp;</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Now whenever you use a System.String object, you&#8217;ll be able to simply call these methods as if they were part of the System.String class. IE: string MyFileExtension = MyFilePath.FileExtension();</p>
<p>I&#8217;m sure I&#8217;ll add on to this as I go along.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/10/helpful-extension-methods-to-the-system-string-class-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TI-83 Addition</title>
		<link>http://www.caledunlap.com/2009/08/ti-83-addition/</link>
		<comments>http://www.caledunlap.com/2009/08/ti-83-addition/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 14:06:42 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[ti-83]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=366</guid>
		<description><![CDATA[I&#8217;ve added a section to the site called &#8220;TI-83&#8243; which contains just a couple of programs I&#8217;ve written for my graphing calculator over the years. A lot of these I wrote when I was in high school to assist me on quizzes and homework for algebra II and pre-calc. I&#8217;ve been finding myself relying more <a href="http://www.caledunlap.com/2009/08/ti-83-addition/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve added a section to the site called &#8220;TI-83&#8243; which contains just a couple of programs I&#8217;ve written for my graphing calculator over the years. A lot of these I wrote when I was in high school to assist me on quizzes and homework for algebra II and pre-calc. I&#8217;ve been finding myself relying more and more on my graphing calculator recently to solve complex equations&#8211;most recently was the Bernoulli Trials equation for my Discreet Mathematics class. Last session in school I damn near wrote a program that solved systems of equations using the Gauss-Jordan method, but then I realized that my graphing calculator already did this for me, so a program was not needed.</p>
<p>They&#8217;re all pretty small, but they might be worth grabbing. You&#8217;ll have to use your best judgement on using special math characters since keyboards and HTML don&#8217;t have them available for input/display. So for example instead of the square root sign that would normally be in a program or on a graphing calculator, I used &#8220;sqrt&#8221; and for something like the Greek letter Theta, i used &lt;THETA&gt; or (THETA). So the programs won&#8217;t port DIRECTLY into your calculator, you&#8217;ll have to use your discretion to make any modifications necessary.</p>
<p>Enjoy! *pushes glasses back up on nose with a single finger*</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/08/ti-83-addition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Templatize Tool</title>
		<link>http://www.caledunlap.com/2009/07/templatize-tool/</link>
		<comments>http://www.caledunlap.com/2009/07/templatize-tool/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 06:52:31 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[templatizer]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=345</guid>
		<description><![CDATA[I recently wrote up a template engine tool called Templatize. It started as a tool for my girlfriend so she could quickly generate HTML pages from CSV rows for use on eBay, but then quickly grew into a more robust template tool.
Basically it takes a set of input data, containing multiple entities (rows), each with <a href="http://www.caledunlap.com/2009/07/templatize-tool/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I recently wrote up a template engine tool called Templatize. It started as a tool for my girlfriend so she could quickly generate HTML pages from CSV rows for use on eBay, but then quickly grew into a more robust template tool.</p>
<p>Basically it takes a set of input data, containing multiple entities (rows), each with multiple properties (columns), formatted from some type of delimited text file. Then it takes in a master template file and spits out multiple &#8220;data-injected&#8221; versions of that template.</p>
<p>View the full page <a href="http://caledunlap.com/blog/c/templatize/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/07/templatize-tool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CTask-Lite on GitHub</title>
		<link>http://www.caledunlap.com/2009/07/ctask-lite-on-github/</link>
		<comments>http://www.caledunlap.com/2009/07/ctask-lite-on-github/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 23:49:07 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[ctask]]></category>
		<category><![CDATA[ctask-lite]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=295</guid>
		<description><![CDATA[Alright, I&#8217;ve finally put my open-source project website woes to rest. I successfully published the first version of CTask-Lite out on GitHub. It can be found here: http://github.com/cdunlap/ctask-lite
CTask-Lite is an easy to install, configure, theme, and use task management system. It is aimed at tiny teams working on &#8216;open&#8217; projects. What I mean by open is <a href="http://www.caledunlap.com/2009/07/ctask-lite-on-github/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Alright, I&#8217;ve finally put my open-source project website woes to rest. I successfully published the first version of CTask-Lite out on GitHub. It can be found here: <a href="http://github.com/cdunlap/ctask-lite">http://github.com/cdunlap/ctask-lite</a></p>
<p>CTask-Lite is an easy to install, configure, theme, and use task management system. It is aimed at tiny teams working on &#8216;open&#8217; projects. What I mean by open is that they don&#8217;t care who sees what (because there is no user/role management capability in it).</p>
<p>The Wiki for CTask-Lite is here:  <a style="text-decoration: none;" href="http://wiki.github.com/cdunlap/ctask-lite">http://wiki.github.com/cdunlap/ctask-lite</a></p>
<p>Spread the word! Download it, use it, mangle it, hack it, fork it, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/07/ctask-lite-on-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>1 little 2 little 3 little endians&#8230; er wait, is it 3 little 2 little 1 little endians?</title>
		<link>http://www.caledunlap.com/2009/06/1-little-2-little-3-little-endians-er-wait-is-it-3-little-2-little-1-littl-endians/</link>
		<comments>http://www.caledunlap.com/2009/06/1-little-2-little-3-little-endians-er-wait-is-it-3-little-2-little-1-littl-endians/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 17:50:42 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[confusion]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=286</guid>
		<description><![CDATA[Well, it depends on what encoding you&#8217;re using.
Lately I&#8217;ve been in &#8220;endian-ness&#8221; hell on a project I&#8217;m working on. Well, not really a &#8220;hell&#8221;, more of a hurdle that can easily be overcome. A friend of mine recently asked me the difference between the two binary encoding strategies and when I went to explain it <a href="http://www.caledunlap.com/2009/06/1-little-2-little-3-little-endians-er-wait-is-it-3-little-2-little-1-littl-endians/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Well, it depends on what encoding you&#8217;re using.</p>
<p>Lately I&#8217;ve been in &#8220;endian-ness&#8221; hell on a project I&#8217;m working on. Well, not really a &#8220;hell&#8221;, more of a hurdle that can easily be overcome. A friend of mine recently asked me the difference between the two binary encoding strategies and when I went to explain it to him (via cell phone txt messaging) I quickly realized that I will run up both our bills pretty quickly by doing so. So here&#8217;s the quick rundown, and an example as it applies to the project I am working on.</p>
<p>Big Endian means that value is stored &#8220;from left to right&#8221;. The most significant values (bytes) are stored in memory with the lowest address first. This is probably what many people are familiar with, especially those in the networking field.  Here&#8217;s an example of data stored as Big Endian:</p>
<p>Take for instance the 2-byte value 1325, equivalent to a short or unsigned short. Stored in Big Endian encoding, the value would look like this in binary: 00000101 00101101. Makes sense right?</p>
<p>Now here is the same 2-byte value, 1325, in Little Endian encoding: 00101101 00000101. The bytes are flipped and thus to make any sense of it, you must read the last set of bits first.</p>
<p>So for simplicity&#8217;s sake, Big Endian values are stored like so:</p>
<pre>&lt;byte1&gt; &lt;byte2&gt; &lt;byte3&gt; &lt;byte4&gt; ... &lt;byten&gt;</pre>
<p>Little Endian values are stored like so:</p>
<pre>&lt;byten&gt; ... &lt;byte4&gt; &lt;byte3&gt; &lt;byte2&gt; &lt;byte1&gt;</pre>
<p>Network devices use Big Endian, it is considered the network standard, or &#8220;network encoding&#8221;. Endian-ness varies from CPU to CPU depending on its architecture. <strong>Power</strong> Macs use Big Endian, network devices use Big Endian. Intel PC&#8217;s (and <strong>Intel</strong> Macs) use Little Endian. What does that mean? Well, it means that if a program running on a <strong>Power</strong> Mac sends data to a PC, the PC may not understand it correctly without some type of encoding change taking place.</p>
<p>In my situation, I&#8217;m reading a series of values off of the network, all coming in via a byte stream. So the client will send the following packet for example:</p>
<p>4 bytes, 2 bytes, 1 byte, &#8230; and some others but I won&#8217;t get into them</p>
<p>So when I read the first four bytes off the network (which uses Big Endian encoding, remember?) I must flip the entire set of 4 bytes before my Little Endian PC can understand it.  Same goes for the next 2 bytes. The single byte obviously doesn&#8217;t need to be flipped with anything, it stands alone. So an incoming set of data may look like:</p>
<pre>0x1A 0x2B 0x3C 0x4D 0x2A 0x2B 0xAD</pre>
<p>Now I must flip each set of values byte by byte (but not invert the entire thing; this is a packet, containing multiple values).</p>
<p>In Little Endian, the same set of data reads:</p>
<pre>0x4D 0x3C 0x2B 0x1A 0x2B 0x2A 0xAD</pre>
<p>Confused yet? You&#8217;ll figure it out. Here&#8217;s some reading that should help: <a href="http://en.wikipedia.org/wiki/Endianness">http://en.wikipedia.org/wiki/Endianness</a>. It even gets into the origins of the word, which is pretty interesting. Here&#8217;s a little tool that may help you understand the pattern: <a href="http://dlnova.com/reverseendian.htm">http://dlnova.com/reverseendian.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/06/1-little-2-little-3-little-endians-er-wait-is-it-3-little-2-little-1-littl-endians/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KnowIT RC2.1 Released</title>
		<link>http://www.caledunlap.com/2009/05/knowit-rc21-released/</link>
		<comments>http://www.caledunlap.com/2009/05/knowit-rc21-released/#comments</comments>
		<pubDate>Mon, 18 May 2009 14:02:37 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[knowit]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=265</guid>
		<description><![CDATA[I&#8217;ve completed the modifications and package builds for KnowIT releast candidate 2.1. They are available from the KnowIT Google Code site. Dare I say, this is one of the best peices of software I have written in a long time. And the best part is, its open source!
Check out the Screenshots.
KnowIT works with Windows ONLY. <a href="http://www.caledunlap.com/2009/05/knowit-rc21-released/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve completed the modifications and package builds for KnowIT releast candidate 2.1. They are available from the <a href="http://knowitaig.googlecode.com/" target="_blank">KnowIT Google Code site</a>. Dare I say, this is one of the best peices of software I have written in a long time. And the best part is, its open source!</p>
<p>Check out the <a href="http://code.google.com/p/knowitaig/wiki/Screenshots" target="_blank">Screenshots</a>.</p>
<p>KnowIT works with Windows ONLY. There is currently not a Linux/UNIX scanner available for KnowIT, and the database back-end is a Microsoft product (MSSQL 2005). However, I did add ODBC support this time around, so it may work on other database types as well. If anybody gets it to work on MySQL or Oracle, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/05/knowit-rc21-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VGL Math &#8211; 2D/3D Video Game Math Library</title>
		<link>http://www.caledunlap.com/2009/03/vgl-math-2d3d-video-game-math-library/</link>
		<comments>http://www.caledunlap.com/2009/03/vgl-math-2d3d-video-game-math-library/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 10:05:25 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[vgl]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=231</guid>
		<description><![CDATA[I decided to get bold and start another open source project. This time it is related to the math involved in developing 2D and 3D video games. The project is hosted at http://code.google.com/p/vglmath. I decided to deem it a &#8220;VGL community project&#8221;; VGL being the company I founded a few months ago.
I&#8217;m looking for any <a href="http://www.caledunlap.com/2009/03/vgl-math-2d3d-video-game-math-library/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I decided to get bold and start another open source project. This time it is related to the math involved in developing 2D and 3D video games. The project is hosted at <a href="http://code.google.com/p/vglmath" target="_blank">http://code.google.com/p/vglmath</a>. I decided to deem it a &#8220;VGL community project&#8221;; VGL being the company I founded a few months ago.</p>
<p>I&#8217;m looking for any pointers, contributors, or experts to make improvements or recommendations to the code. So please check it out. If you&#8217;re interested in contributing, please send me an email at cale@caledunlap.com so I can add your Google account to the members list.</p>
<p>And if you haven&#8217;t already, check out <a href="http://www.venomgamelabs.com" target="_blank">http://www.venomgamelabs.com</a>!</p>
<p>Now for your entertainment for the evening:<br />
<a href="http://www.youtube.com/watch?v=FRgYtp3HfvY"><!-- Smart Youtube --><span class="youtube"><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/FRgYtp3HfvY&amp;rel=1&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=&amp;fs=1&amp;hl=en&amp;autoplay=&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0" /><param name="allowFullScreen" value="true" /><embed wmode="transparent" src="http://www.youtube.com/v/FRgYtp3HfvY&amp;rel=1&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=&amp;fs=1&amp;hl=en&amp;autoplay=&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="355" ></embed><param name="wmode" value="transparent" /></object></span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/03/vgl-math-2d3d-video-game-math-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross-Tabulation (Pivot Tables) with MySQL</title>
		<link>http://www.caledunlap.com/2009/02/cross-tabulation-pivot-tables-with-mysql/</link>
		<comments>http://www.caledunlap.com/2009/02/cross-tabulation-pivot-tables-with-mysql/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 10:09:14 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[confusion]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pivot tables]]></category>
		<category><![CDATA[tabulation]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=191</guid>
		<description><![CDATA[I don&#8217;t really have any sections on my website related to MySQL, so I figured I&#8217;d just throw together a quick post about something I found incredibly helpful. I&#8217;m sure others will find it nice too.
So in my years being trained on data architecture and database design, I learned to &#34;normalize, normalize, normalize&#34;. Unfortunately, normalization <a href="http://www.caledunlap.com/2009/02/cross-tabulation-pivot-tables-with-mysql/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t really have any sections on my website related to MySQL, so I figured I&#8217;d just throw together a quick post about something I found incredibly helpful. I&#8217;m sure others will find it nice too.</p>
<p>So in my years being trained on data architecture and database design, I learned to &quot;normalize, normalize, normalize&quot;. Unfortunately, normalization doesn&#8217;t lend itself to very simple statistical calculations&#8211;such as those used to generate graphs or a statistical scorecard.</p>
<p>In the case of Angel, I&#8217;ve normalized the hell out of the data. Now it comes down to needing to report on that data. At first, my reporting attempts were terrible&#8211;tons of nested loops, many queries, etc. Well, when I spoke to a colleague of mine at work, he said that if I was running on an SAS Mainframe, the work would already be done for me using a function called &quot;PROC TABULATE&quot;. He sort of dated himself by saying that.</p>
<p>Then I broke the news to him: I&#8217;m not using SAS, or any other mainframe technology. He replied by suggesting I look into some sort of MySQL equivalent to that function. So I started hunting. I came across this very nice article: <a href="http://dev.mysql.com/tech-resources/articles/wizard/print_version.html" target="_blank">http://dev.mysql.com/tech-resources/articles/wizard/print_version.html</a></p>
<p>That article shows, very effectively, how to create a nice &quot;statistical&quot; report using cross-tabulation techniques with normalized source data. The queries are sort of monstrous if you have a large number of fields to report on, but at that point, you&#8217;d be using code to generate the parameters for the SELECT statement.</p>
<p>Here&#8217;s my example:</p>
<p>My source data looks like the following&#8211;please note that some results are truncated because the result set would be WAY too large for a blog:</p>
<p> <code>
<pre>mysql&gt; select uid, Email from players;
+-----+--------------------------+
| uid | Email                    |
+-----+--------------------------+
|  10 | brian@venomgamelabs.com  |
|   4 | cale@caledunlap.com      |
|   1 | cale@venomgamelabs.com   |
|   9 | daniel@venomgamelabs.com |
|  11 | dave@venomgamelabs.com   |
|   5 | jane@venomgamelabs.com   |
|   8 | janes@venomgamelabs.com  |
|  12 | jill@venomgamelabs.com   |
|   6 | john@venomgamelabs.com   |
|   7 | johns@venomgamelabs.com  |
+-----+--------------------------+
mysql&gt; select * from gamedata LIMIT 10;
+----------+---------+------+
| playerid | fieldid | data |
+----------+---------+------+
|        1 |       3 | 60   |
|        1 |       4 | 1    |
|        1 |       5 | 1    |
|        1 |       6 | 286  |
|        1 |       7 | 1    |
|        1 |       8 | 13   |
|        1 |       9 | 1    |
|        1 |      10 | 1    |
|        1 |      11 | 261  |
|        1 |      12 | 13   |
+----------+---------+------+

mysql&gt; select FieldID, FriendlyName, GameID, FieldTypeID FROM gamefields;
+---------+---------------------------------+--------+-------------+
| FieldID | FriendlyName                    | GameID | FieldTypeID |
+---------+---------------------------------+--------+-------------+
|       1 | Play Time                       |      1 |           2 |
|       2 | Last Character                  |      1 |           1 |
|       3 | Total Eggs                      |      4 |           2 |
|       4 | Total Playtime                  |      4 |           2 |
|       5 | Total King Of The Hill Captures |      4 |           2 |
|       6 | Total Kills                     |      4 |           2 |
|       7 | Total Deaths                    |      4 |           2 |
|       8 | Engineer Playtime               |      4 |           2 |
|      10 | Mongo Playtime                  |      4 |           2 |
|      11 | Grunt Playtime                  |      4 |           2 |
|      12 | Gladiator Playtime              |      4 |           2 |
|      13 | Total Powerup Uses              |      4 |           2 |
|      14 | Total Powerups Received         |      4 |           2 |
+---------+---------------------------------+--------+-------------+
mysql&gt; select typeid, typename from field_types;
+--------+------------------+
| typeid | typename         |
+--------+------------------+
|      1 | Text             |
|      2 | Numeric          |
|      3 | Game Coordinates |
|      4 | Boolean          |
|      5 | Physical Address |
|      6 | IP Address       |
+--------+------------------+</pre>
<p></code></p>
<p>What I want to know from that data is how many players have field values within specific ranges&#8211;to generate some input data for a chart output. The code I&#8217;m using does the following math (from a separate query):</p>
<ol>
<li>Find the minimum value out of all of the player data for each field (SQL Query) </li>
<li>Find the maximum value out of all of the player data for each field (Same SQL query) </li>
<li>Get a &quot;standard deviation&quot; between the number <code>$StandardDeviation = floor( ($High - $Low)/NUM_DEVIATION_RANGES );</code> </li>
<li>Begins a SQL query and assembles a list of parameters to select (based on the deviation ranges) <code>
<pre>for $i = 0 to NUM_DEVIATION_RANGES
$Min = $Low + ($StandardDeviation * $i)
$Max = ($Min + $StandardDeviation) – 1;
$Query .= “SUM( IF( CAST(gamedata.Data AS UNSIGNED) &gt;= $Min AND CAST(gamedata.Data AS UNSIGNED) &lt;= $Max, 1, 0) ) AS ‘$Min-$Max’,”;
end for</pre>
<p>    </code></li>
<li>Runs the query, obtains a single result per field and feeds it to the chart to render a per-field graphical analysis chart. </li>
</ol>
<p>The output of the query from step 4 is as follows:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0d8710e5-306b-41bd-9c98-3e3cec81dfee" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">SELECT</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 60 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 87<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;60-87&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 88 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 115<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;88-115&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 116 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 143<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;116-143&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 144 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 171<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;144-171&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 172 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 199<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;172-199&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 200 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 227<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;200-227&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 228 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 255<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;228-255&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 256 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 283<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;256-283&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 284 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 311<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;284-311&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 312 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 339<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;312-339&#39;</span><br />
<span style="color:#0000ff">FROM</span> gamedata<span style="color:#808080">,</span> gamefields<span style="color:#808080">,</span> field_types<br />
<span style="color:#0000ff">WHERE</span> gamedata<span style="color:#808080">.</span>fieldid <span style="color:#808080">=</span> gamefields<span style="color:#808080">.</span>FieldID<br />
&#160;&#160;&#160;&#160;<span style="color:#808080">AND</span> gamefields<span style="color:#808080">.</span>FieldTypeID <span style="color:#808080">=</span> field_types<span style="color:#808080">.</span>typeid<br />
&#160;&#160;&#160;&#160;<span style="color:#808080">AND</span> field_types<span style="color:#808080">.</span>typename <span style="color:#808080">=</span> <span style="color:#ff0000">&#39;Numeric&#39;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">AND</span> gamefields<span style="color:#808080">.</span>FriendlyName <span style="color:#808080">=</span> <span style="color:#ff0000">&#39;Total Eggs&#39;</span></div>
</div>
</div>
<p>Now that query runs once per number of fields requested. The above query was just a single query for a single field. Note how the code generated the SELECT statement parameters (min and max) and set them as the column header in the result?</p>
<p>The result of that query looks like this:</p>
<p><code></p>
<pre>+-------+--------+---------+---------+---------+---------+---------+---------+---------+---------+
| 60-87 | 88-115 | 116-143 | 144-171 | 172-199 | 200-227 | 228-255 | 256-283 | 284-311 | 312-339 |
+-------+--------+---------+---------+---------+---------+---------+---------+---------+---------+
|     2	|      0 |	 2 |	   0 |	     1 |      0	 |	2  |	   0 |	     1 |       0 |
+-------+--------+---------+---------+---------+---------+---------+---------+---------+---------+</pre>
<p></code></p>
<p>So the output is exactly what I need for my chart. The result fields represent the X axis of the chart, and the result values represent the Y axis of the chart, all from a single query against normalized data using cross-tabulation.</p>
<p>I urge you to click on the link I mentioned near the top of the article if you want to learn how to do this. My example is fairly specific to my situation. That article showed me exactly what I needed to do, but I needed to apply it to my data and my reports.&#160; You&#8217;ll notice that I&#8217;ve used CAST&#8217;s in my query. The reason being that in order to accept any type of data, I&#8217;ve used the &#8216;TEXT&#8217; type on my game data fields&#8211;that&#8217;s why I also have a type table and a type ID in the field types. I then query what types of fields is numeric, and only perform my calculations against them.</p>
<p>Doing cross-tabluation/pivot tables isn&#8217;t too bad once you know what you&#8217;re doing. I had a tough time wrapping my head around it, but after a few hours of tinkering, I finally got what I was looking for. Another thing to note is that I&#8217;m summing up 1&#8217;s and 0&#8217;s, basically a tally. If you want to sum up your real data, don&#8217;t use 1&#8217;s and 0&#8217;s; use your actual data field.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/02/cross-tabulation-pivot-tables-with-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
