<?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>ebmgh.com &#187; Computing</title>
	<atom:link href="http://ebmgh.com/blog/category/computing/feed/" rel="self" type="application/rss+xml" />
	<link>http://ebmgh.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 11 Jan 2011 00:27:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Making Excel/VBA random numbers more random with a seed</title>
		<link>http://ebmgh.com/blog/2010/04/making-excelvba-random-numbers-more-random-with-a-seed/</link>
		<comments>http://ebmgh.com/blog/2010/04/making-excelvba-random-numbers-more-random-with-a-seed/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 02:53:08 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/?p=282</guid>
		<description><![CDATA[I have a fairly simple user-defined function for Excel that I use to create random passwords. (I got kind of freaked out last year after someone hacked into my Facebook account. Trouble was, I used the same password for lots of sites. If this petty crook had been a little more savvy, he could have [...]]]></description>
			<content:encoded><![CDATA[<p>I have a fairly simple user-defined function for Excel that I use to create random passwords. (I got kind of freaked out last year after someone hacked into my Facebook account. Trouble was, I used the same password for lots of sites. If this petty crook had been a little more savvy, he could have done a lot more damage. At first, I immediately replaced a bunch of my passwords with strings like this: p9q4MF3nnX4B. The only problem now is that I can&#8217;t remember any of my passwords, and have to keep them in a file, which creates security concerns of its own&#8230;)</p>
<p>I noticed that my little password routine would repeatedly create the same password each time I used it anew, after re-starting the computer and re-launching Excel. It turns out that VBA&#8217;s RAND function is not as random as you&#8217;d think it might be. The way around this is</p>
<p>I saw this code that I found on the <a href="http://forums.techguy.org/business-applications/661639-excel-vba-random-number-generator.html">techguy forum</a>:</p>
<pre dir="ltr">  seed = TimeValue("00:" &amp; Format(Second(Time), "00") &amp; ":" &amp; Format(Minute(Time), "00"))
  Randomize (seed)
</pre>
<p>But according to the <a href="http://msdn.microsoft.com/en-us/library/ee177404%28PROT.10%29.aspx">RND entry</a> at the support site, you can just call Randomize on its own:</p>
<blockquote><p>Before calling Rnd, use the Randomize statement without an argument to  initialize the random-number generator with a seed based on the system  timer.</p></blockquote>
<p>I had never used Randomize before, and never knew that I needed to. In Python, a more sophisticated programming language, <a href="http://docs.python.org/library/random.html">seeding</a> is taken care of for you: &#8220;current system time is also used to initialize the generator when the  module is first imported.&#8221;</p>
<p>Lots more information at the Wikipedia article on <a href="http://en.wikipedia.org/wiki/Pseudo-random_number_generator">Pseudo-Random Number Generators</a>. From here I learned, &#8220;A PRNG can be started from an arbitrary starting state using a <a title="Random seed" href="http://en.wikipedia.org/wiki/Random_seed">seed  state</a>. It will always produce the same sequence thereafter when  initialized with that state.&#8221;</p>
<pre dir="ltr">
</pre>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/04/making-excelvba-random-numbers-more-random-with-a-seed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>US Army and USGS Topographic Maps in Google Earth</title>
		<link>http://ebmgh.com/blog/2010/04/us-army-and-usgs-topographic-maps-in-google-earth/</link>
		<comments>http://ebmgh.com/blog/2010/04/us-army-and-usgs-topographic-maps-in-google-earth/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 22:42:05 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[GIS]]></category>
		<category><![CDATA[Google Earth]]></category>
		<category><![CDATA[mapping]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/?p=100</guid>
		<description><![CDATA[So that I can find this again. A KML file that lets you view many old USGS and US Army maps in Google Earth: US Army and USGS Topographic Maps v 16, 9 Dec &#8217;08 at the Google Earth Forum. I&#8217;ve found the African maps and the historic topos to be especially interesting.]]></description>
			<content:encoded><![CDATA[<p>So that I can find this again. A KML file that lets you view many old USGS and US Army maps in Google Earth:</p>
<p><a href="http://bbs.keyhole.com/ubb/ubbthreads.php?ubb=showflat&#038;Number=922040">US Army and USGS Topographic Maps v 16, 9 Dec &#8217;08</a> at the Google Earth Forum.</p>
<p>I&#8217;ve found the African maps and the historic topos to be especially interesting.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/04/us-army-and-usgs-topographic-maps-in-google-earth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ArcGIS Extension: Tools for Graphics and Shapes</title>
		<link>http://ebmgh.com/blog/2010/03/arcgis-extension-tools-for-graphics-and-shapes/</link>
		<comments>http://ebmgh.com/blog/2010/03/arcgis-extension-tools-for-graphics-and-shapes/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 21:10:39 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/03/arcgis-extension-tools-for-graphics-and-shapes/</guid>
		<description><![CDATA[Jenness Enterprises, which appears to be a one-many GIS consultancy, offers some useful extensions for ArcGIS at: http://www.jennessent.com/arcgis/arcgis_extensions.htm Tools for Graphics and Shapes is &#8220;a large suite of tools for calculating geometric attributes of vector features and for selecting and naming graphics. All tools are available at the ArcView license level.&#8221; The extension gives you [...]]]></description>
			<content:encoded><![CDATA[<p>Jenness Enterprises, which appears to be a one-many GIS consultancy, offers some useful extensions for ArcGIS at:
</p>
<p><a href="http://www.jennessent.com/arcgis/arcgis_extensions.htm">http://www.jennessent.com/arcgis/arcgis_extensions.htm</a>
	</p>
<p>Tools for Graphics and Shapes is &#8220;a large suite of tools for calculating geometric attributes of vector features and for selecting and naming graphics. All tools are available at the ArcView license level.&#8221; The extension gives you lots of useful functions, like:
</p>
<p>
 </p>
<p><strong>Tools for Graphics<br />
</strong></p>
<ul>
<li>Graphic Elements to Shapes
</li>
<li>Select Graphic Elements by Type
</li>
<li>Select All Graphic Elements
</li>
<li>Unselect All Graphic Elements
</li>
<li>Flip Graphic Element Selection
</li>
<li>Zoom to Selected Graphic Elements
</li>
<li>Name Graphic Elements
</li>
</ul>
<p>
 </p>
<p><strong>Tools for Shapes<br />
</strong></p>
<ul>
<li>Convert Polygons to Label Points
</li>
<li>Convert Shapes to Centroids
</li>
<li>Convert Shapes to Spherical Centroids
</li>
<li>Convert Shapes to Vertices
</li>
<li>Convert Polylines to Polygons
</li>
<li>Convert Polygons to Polylines
</li>
<li>Build Polygons from Polylines
</li>
<li>Split Multipart Features
</li>
<li>Combine Features
</li>
<li>Calculate Geometry
</li>
</ul>
<p><img src="http://ebmgh.com/blog/wp-content/uploads/2010/03/032110_2108_ArcGISExten1.png" alt=""/></p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/03/arcgis-extension-tools-for-graphics-and-shapes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JOIN function for Excel</title>
		<link>http://ebmgh.com/blog/2010/03/join-function-for-excel/</link>
		<comments>http://ebmgh.com/blog/2010/03/join-function-for-excel/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 01:47:07 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/03/join-function-for-excel/</guid>
		<description><![CDATA[I wanted a simple function that works like CONCATENATE, but is simpler to use on a range of cells. If you want to join the contents of cells in A1 to D1, you&#8217;d need: =CONCATENATE(A1, B1, C1, D1) That&#8217;s kind of a pain. With this custom function, you can type: =JOIN(A1:D1) Better, no? You can [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted a simple function that works like CONCATENATE, but is simpler to use on a range of cells. If you want to join the contents of cells in A1 to D1, you&#8217;d need:</p>
<p>
<pre><code>=CONCATENATE(A1, B1, C1, D1)
</code></pre>
</p>
<p>That&#8217;s kind of a pain. With this custom function, you can type:</p>
<p><code><br />
=JOIN(A1:D1)<br />
</code></p>
<p>Better, no? You can also use an optional separator, e.g. if you want a comma-separated list. Here&#8217;s the code, to paste into a VBA module in Excel:
</p>
<p>
<pre><code>Function Join(rng As Range, Optional sep As String) As String
</code></pre>
</p>
<p>
<pre><code>'Kind of a more sophisticated concatenate
</code></pre>
</p>
<p>
<pre><code>'because it works with a range of cells, and it can use an optional separator
</code></pre>
</p>
<p>
<pre><code>'loosely based on Python's join method for arrays
</code></pre>
</p>
<p>
<pre><code>Dim cell As Range
</code></pre>
</p>
<p>
<pre><code>Dim str
</code></pre>
</p>
<p>
<pre><code>For Each cell In rng
</code></pre>
</p>
<p>
<pre><code>  If Not IsEmpty(cell) Then
</code></pre>
</p>
<p>
<pre><code>    str = str &amp; cell.Value &amp; sep
</code></pre>
</p>
<p>
<pre><code>  End If
</code></pre>
</p>
<p>
<pre><code>Next cell
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>'Strip off the trailing separator
</code></pre>
</p>
<p>
<pre><code>str = Left(str, Len(str) - Len(sep))
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>Join = str
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>End Function</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/03/join-function-for-excel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Returning an Error from an Excel User-Defined Function</title>
		<link>http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/</link>
		<comments>http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 18:00:34 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/</guid>
		<description><![CDATA[It&#8217;s often useful to write your own custom functions for Excel. These are often called User-Defined Functions, or UDFs. It&#8217;s actually not that hard if you know a bit of programming. It&#8217;s all done in VBA, or Visual Basic for Applications. I&#8217;ve probably written hundreds of these in the last 7 or 8 years, but [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s often useful to write your own custom functions for Excel. These are often called User-Defined Functions, or UDFs. It&#8217;s actually not that hard if you know a bit of programming. It&#8217;s all done in VBA, or Visual Basic for Applications. I&#8217;ve probably written hundreds of these in the last 7 or 8 years, but one trick I always forget is how to return a customized error message.
</p>
<p>If a line in your function produces a run-time error, you won&#8217;t get a popup message like you would for a Subroutine. Instead, code execution ends immediately, and you get the error #VALUE! in the cell on the worksheet.
</p>
<p>It is often useful to return a more descriptive error. To do this, you can use On Error to trap the error, and return one of Excel&#8217;s built in error types. To do this, use the VBA function CVErr and a constant to set the built-in error type. These are (via the online help under &#8220;Cell Error Values&#8221;):
</p>
<div>
<table style="border-collapse:collapse" border="0">
<colgroup>
<col style="width:78px"/>
<col style="width:92px"/>
<col style="width:122px"/></colgroup>
<tbody valign="top">
<tr style="background: #d9d9d9">
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt"><strong>Constant</strong></span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code><strong>Error number</strong></code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code><strong>Cell error value</strong></code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrDiv0</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2007</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#DIV/0!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrNA</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2042</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#N/A</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrName</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2029</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#NAME?</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrNull</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2000</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#NULL!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrNum</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2036</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#NUM!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrRef</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2023</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#REF!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrValue</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2015</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#VALUE!</code></pre>
</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>
 </p>
<p>For your UDF to return custom errors, you must declare the function so that it returns the data type Variant. See also this Microsoft knowldgebase article on Error <a href="http://support.microsoft.com/kb/146864">Trapping with Visual Basic for Applications</a>.
</p>
<p>Here&#8217;s an example of a UDF that returns the error #N/A. In this case, the function is a slightly more sophisticated version of the built-in function FIND, which returns the starting position of a one text string within another string. I wanted a function that would return the nth position, rather than just the first occurrence.
</p>
<p>
<pre><code>Function FindNth(find_text As String, within_text As String, n As Long) As Variant
</code></pre>
</p>
<p>
<pre><code>'Finding the nth occurrence of a text string within another text string
</code></pre>
</p>
<p>
<pre><code>'Uses Excel's built-in Worksheet Find function iteratively
</code></pre>
</p>
<p>
<pre><code>'(probably faster than a brute-force approach using a loop)
</code></pre>
</p>
<p>
<pre><code>'If find_text is not found, returns the error #N/A
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  Dim pos As Variant
</code></pre>
</p>
<p>
<pre><code>  Dim i As Long
</code></pre>
</p>
<p>
<pre><code>  Dim result As Long
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  i = 0
</code></pre>
</p>
<p>
<pre><code>  result = 0
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  Do
</code></pre>
</p>
<p>
<pre><code>    On Error GoTo ErrLine
</code></pre>
</p>
<p>
<pre><code>    pos = Application.WorksheetFunction.Find(find_text, within_text)
</code></pre>
</p>
<p>
<pre><code>    result = result + pos
</code></pre>
</p>
<p>
<pre><code>    i = i + 1
</code></pre>
</p>
<p>
<pre><code>    If i = n Then Exit Do
</code></pre>
</p>
<p>
<pre><code>    within_text = Right(within_text, Len(within_text) - pos)
</code></pre>
</p>
<p>
<pre><code>  Loop
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  FindNth = result
</code></pre>
</p>
<p>
<pre><code>  Exit Function
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>ErrLine: FindNth = CVErr(xlErrNA)
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>End Function
</code></pre>
</p>
<p>
 </p>
<p>For example:
</p>
<p>
<pre><code>=FINDNTH(" ", "Mira Vista Avenue", 2)
</code></pre>
</p>
<p>
 </p>
<p>Returns 11, the position of the second occurrence of a space in &#8220;Mira Vista Avenue&#8221;.
</p>
<p>
<pre><code>=FINDNTH("x", "Microsoft", 3)
</code></pre>
</p>
<p>
 </p>
<p>Returns #N/A, since it is looking for the 3<sup>rd</sup> letter x in &#8220;Microsoft&#8221;, and can&#8217;t find it.
</p>
<p>In this example, the function should probably return #VALUE! to copy the FIND function&#8217;s built-in behavior. But I wanted to differentiate between a VBA run-time error and an error returned by the function, and #N/A seemed to fit the bill.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learning SQL</title>
		<link>http://ebmgh.com/blog/2010/01/learning-sql/</link>
		<comments>http://ebmgh.com/blog/2010/01/learning-sql/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 22:24:51 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/01/learning-sql/</guid>
		<description><![CDATA[A former boss told me to spend a few hours working through the tutorials at SQLCourse.com several years ago. Funny advice to an environmental engineer? Probably not, since almost all modern engineering involves computing, and most non-trivial computer programs use databases to store and retrieve information. SQL, or &#8220;structured query language&#8221; is a standard way [...]]]></description>
			<content:encoded><![CDATA[<p>A former boss told me to spend a few hours working through the tutorials at SQLCourse.com several years ago. Funny advice to an environmental engineer? Probably not, since almost all modern engineering involves computing, and most non-trivial computer programs use databases to store and retrieve information.
</p>
<p>
		<a href="http://sqlcourse.com/"><img src="http://ebmgh.com/blog/wp-content/uploads/2010/01/012010_2223_LearningSQL1.png" alt="" border="0"/></a>
	</p>
<p>SQL, or &#8220;structured query language&#8221; is a standard way of interacting with a database. These free online courses are very good, and I still find myself referring back to them now and then. Learn how to select records, make updates, and join database tables…
</p>
<p>SQLCourse conents:
</p>
<ol>
<li><a href="http://sqlcourse.com/intro.html">What is SQL?</a>
		</li>
<li><a href="http://sqlcourse.com/table.html">Table basics</a>
		</li>
<li><a href="http://sqlcourse.com/select.html">Selecting data</a>
		</li>
<li><a href="http://sqlcourse.com/create.html">Creating tables</a>
		</li>
<li><a href="http://sqlcourse.com/insert.html">Inserting into a table</a>
		</li>
<li><a href="http://sqlcourse.com/update.html">Updating records</a>
		</li>
<li><a href="http://sqlcourse.com/delete.html">Deleting records</a>
		</li>
<li><a href="http://sqlcourse.com/drop.html">Drop a table</a>
		</li>
<li><a href="http://sqlcourse2.com/">Advanced Queries</a>
		</li>
</ol>
<p>SQLCourse2.com contents:
</p>
<ol>
<li><a href="http://sqlcourse2.com/intro2.html">Start Here &#8211; Intro</a>
		</li>
<li><a href="http://sqlcourse2.com/select2.html">SELECT Statement</a>
		</li>
<li><a href="http://sqlcourse2.com/agg_functions.html">Aggregate Functions</a>
		</li>
<li><a href="http://sqlcourse2.com/groupby.html">GROUP BY clause</a>
		</li>
<li><a href="http://sqlcourse2.com/having.html">HAVING clause</a>
		</li>
<li><a href="http://sqlcourse2.com/orderby.html">ORDER BY clause</a>
		</li>
<li><a href="http://sqlcourse2.com/boolean.html">Combining Conditions &amp; Boolean Operators</a>
		</li>
<li><a href="http://sqlcourse2.com/setoper.html">IN and BETWEEN</a>
		</li>
<li><a href="http://sqlcourse2.com/math.html">Mathematical Functions</a>
		</li>
<li><a href="http://sqlcourse2.com/joins.html">Table Joins, a must</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/01/learning-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing for String Membership in Excel VBA</title>
		<link>http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/</link>
		<comments>http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 01:31:57 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/</guid>
		<description><![CDATA[I found myself wishing that Excel or VBA had a simple way to test whether a string exists in another string. In Python you can type if substring in string: #Then do something… But Excel lacks this convenience. You can sort of hack the built in InStr function to do it for you. Since I [...]]]></description>
			<content:encoded><![CDATA[<p>I found myself wishing that Excel or VBA had a simple way to test whether a string exists in another string. In Python you can type
</p>
<p>
<pre><code>if substring in string:
</code></pre>
</p>
<p>
<pre><code>  #Then do something…
</code></pre>
</p>
<p>But Excel lacks this convenience. You can sort of hack the built in InStr function to do it for you. Since I always found this confusing (who can remember what the difference is between &#8220;text compare&#8221; and &#8220;binary compare&#8221;?), I created a simple function called Contains. On the spreadsheet, you can just type
<pre><code>=Contains(<span style="font-family:Calibri">"</span>abcdefg<span style="font-family:Calibri">"</span>, <span style="font-family:Calibri">"</span>a<span style="font-family:Calibri">"</span></code></pre>
<p>) and it returns TRUE. In VBA, it is useful in IF statements. Not as clean as Python, but a helpful convenience.
</p>
<p>
<pre><code>Function Contains(str As String, substr As String, _
</code></pre>
</p>
<p>
<pre><code>   Optional CaseSensitive As Boolean = False) As Boolean
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>'Does a simple test to see if str contains substr
</code></pre>
</p>
<p>
<pre><code>'Example: =Contains("abcd","a") returns TRUE
</code></pre>
</p>
<p>
<pre><code>'         =Contains("abcd","x") returns FALSE
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>'Set CaseSensitive flag to TRUE if you don't want "a" to find "A"
</code></pre>
</p>
<p>
<pre><code>'         =Contains("ABCD","a",True) returns FALSE
</code></pre>
</p>
<p>
<pre><code>'         =Contains("ABCD","a",False) returns TRUE (because the comparison is case sensitive)
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>Dim opt As Long
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>If CaseSensitive Then
</code></pre>
</p>
<p>
<pre><code>  opt = vbBinaryCompare
</code></pre>
</p>
<p>
<pre><code>Else
</code></pre>
</p>
<p>
<pre><code>  opt = vbTextCompare
</code></pre>
</p>
<p>
<pre><code>End If
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>If InStr(1, str, substr, opt) &gt; 0 Then
</code></pre>
</p>
<p>
<pre><code>  Contains = True
</code></pre>
</p>
<p>
<pre><code>Else
</code></pre>
</p>
<p>
<pre><code>  Contains = False
</code></pre>
</p>
<p>
<pre><code>End If
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>End Function</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing Excel’s SMALL and LARGE Functions</title>
		<link>http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/</link>
		<comments>http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 23:04:24 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/</guid>
		<description><![CDATA[Excel has a pair of useful built-in functions called SMALL and LARGE. Suppose you want to know the third-largest number in a column. Or you want to find the fourth-smallest. The function LARGE returns the kth largest value in a dataset. Entering =LARGE(A1:A9,3) returns the third largest value in the range A1 to A9. The [...]]]></description>
			<content:encoded><![CDATA[<p>Excel has a pair of useful built-in functions called SMALL and LARGE. Suppose you want to know the third-largest number in a column. Or you want to find the fourth-smallest.</p>
<p><img src="http://ebmgh.com/blog/wp-content/uploads/2010/01/011410_2303_FixingExcel1.png" alt="" /></p>
<p>The function LARGE returns the k<sup>th</sup> largest value in a dataset. Entering</p>
<pre><code>=LARGE(A1:A9,3) </code></pre>
<p>returns the third largest value in the range A1 to A9. The function is smart enough to ignore blank cells and text. However, if you have an error in a cells, the result of the formula will be an error.</p>
<p>Here are custom functions to replace the built-in ones, called MyLarge and MySmall. Their use is identical to the Excel version: just enter</p>
<pre><code>=MYLARGE(A1:A9,3).</code></pre>
<p>If you don&#8217;t know how to use these, check out the following: <a href="http://articles.techrepublic.com.com/5100-10878_11-5300300.html"><em>How do I… Create a user-defined function in Microsoft Excel</em></a> at Tech Republic. Or you can download an <a href="http://ebmgh.com/files/mylarge_demo.xls">example workbook</a> with the functions.</p>
<p><span id="more-123"></span></p>
<p>Note that these functions call a subroutine called <strong>QuickSort</strong>, which I copied from <a href="http://spreadsheetpage.com/">John Walkenbach</a>&#8216;s book <a href="http://www.amazon.com/Excel-Power-Programming-Spreadsheets-Bookshelf/dp/0470044012">Power Programming with Excel</a> VBA years ago. (Highly recommended if you use Excel a lot and want to learn to automate repetitive tasks or do more advanced stuff.)</p>
<pre><code>
Function MyLarge(x, k)
'Replicates Excel's LARGE function, but will not balk at errors
'Returns the k-th largest value in a data set.
'Usage: =MYLARGE(A1:A15,3), returns the third largest value in the range A1 to A15

Dim arr() As Double 'An array to hold the cell values
Dim i As Long  'counter for looping through the array
Dim n As Long  'n is the number of elements in array
Dim nrev As Long  'revised count of number of VALID elements in array x

nrev = -1
n = Int(x.Count)
ReDim arr(n) As Double

'Note that Excel ranges always start with an index = 1
For i = 1 To n
  If Not IsEmpty(x(i)) And Not IsError(x(i)) And IsNumeric(x(i)) Then
    nrev = nrev + 1
    arr(nrev) = x(i)
  End If
Next i

ReDim Preserve arr(nrev)
Call Quicksort(arr, 0, nrev)

On Error GoTo IndexError
  MyLarge = arr(nrev - k + 1)
  Exit Function

IndexError:
  MyLarge = CVErr(xlErrNum)

End Function

Function MySmall(x, k)
'Replicates Excel's SMALL function, but will not balk at errors
'Returns the k-th smallest value in a data set.
'Usage: =MYSMALL(A1:A15,3), returns the third smallest value in the range A1 to A15

Dim arr() As Double 'An array to hold the cell values
Dim i As Long  'counter for looping through the array
Dim n As Long  'n is the number of elements in array
Dim nrev As Long  'revised count of number of VALID elements in array x

nrev = -1
n = Int(x.Count)
ReDim arr(n) As Double

'Note that Excel ranges always start with an index = 1
For i = 1 To n
  If Not IsEmpty(x(i)) And Not IsError(x(i)) And IsNumeric(x(i)) Then
    nrev = nrev + 1
    arr(nrev) = x(i)
  End If
Next i

ReDim Preserve arr(nrev)
Call Quicksort(arr, 0, nrev)

On Error GoTo IndexError
  MySmall = arr(k - 1)
  Exit Function

IndexError:
  MySmall = CVErr(xlErrNum)

End Function

Sub Quicksort(values() As Double, ByVal min As Long, ByVal max As Long)

'A fairly efficient sort algorithm for sorting 1-dimensional arrays of numbers
'Source: Walkenbach, J., 1999, Power Programming for Excel/VBA

'values() is the 1-dimensional array to be sorted

'min is the array index for the beginning of slice of the array where the sort is to begin
'To sort the entire array, min = 0 or 1 (depending on what Base you are working in)

'max is the array index for the end of the part of the array to be sorted.
'To sort the entire array, use max = len(values)

'Note that this is an example of a *recursive algorithm*
'To understand recursive algorithms, first you have to understand recursive algorithms <img src='http://ebmgh.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> 

Dim med_value As String
Dim Hi As Long
Dim lo As Long
Dim i As Long

  ' If the list has only 1 item, it's sorted.
  If min &gt;= max Then Exit Sub

  ' Pick a dividing item randomly.
  i = min + Int(Rnd(max - min + 1))
  med_value = values(i)

  ' Swap the dividing item to the front of the list.
  values(i) = values(min)

  ' Separate the list into sublists.
  lo = min
  Hi = max
  Do
    ' Look down from hi for a value &lt; med_value.     Do While values(Hi) &gt;= med_value
      Hi = Hi - 1
      If Hi &lt;= lo Then Exit Do
    Loop

    If Hi &lt;= lo Then       ' The list is separated.       values(lo) = med_value       Exit Do     End If     ' Swap the lo and hi values.     values(lo) = values(Hi)     ' Look up from lo for a value &gt;= med_value.
    lo = lo + 1
    Do While values(lo) &lt; med_value       lo = lo + 1       If lo &gt;= Hi Then Exit Do
    Loop

    If lo &gt;= Hi Then
      ' The list is separated.
      lo = Hi
      values(Hi) = med_value
      Exit Do
    End If

    ' Swap the lo and hi values.
    values(Hi) = values(lo)
  Loop ' Loop until the list is separated.

  ' Recursively sort the sublists.
  Quicksort values, min, lo - 1
  Quicksort values, lo + 1, max

End Sub
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL vs PostgreSQL</title>
		<link>http://ebmgh.com/blog/2009/12/mysql-vs-postgresql/</link>
		<comments>http://ebmgh.com/blog/2009/12/mysql-vs-postgresql/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 14:35:47 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Bike Mapper]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/?p=96</guid>
		<description><![CDATA[Interesting head to head comparison&#8230; http://www.wikivs.com/wiki/MySQL_vs_PostgreSQL Lots of terminology I don&#8217;t quite understand, and probably don&#8217;t need to, but some good nuggets of information.]]></description>
			<content:encoded><![CDATA[<p>Interesting head to head comparison&#8230;</p>
<p><a href="http://www.wikivs.com/wiki/MySQL_vs_PostgreSQL">http://www.wikivs.com/wiki/MySQL_vs_PostgreSQL</a></p>
<p>Lots of terminology I don&#8217;t quite understand, and probably don&#8217;t need to, but some good nuggets of information.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2009/12/mysql-vs-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python &#8211; What makes a good dictionary key?</title>
		<link>http://ebmgh.com/blog/2009/12/python-what-makes-a-good-dictionary-key/</link>
		<comments>http://ebmgh.com/blog/2009/12/python-what-makes-a-good-dictionary-key/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 01:50:41 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[dictionary]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/?p=90</guid>
		<description><![CDATA[Python dictionaries are incredibly useful. In other programming languages, they&#8217;re called collections, hash tables, or associative arrays. If you&#8217;re an Excel user, think of what you normally do using a function like VLOOKUP or HLOOKUP. If your program needs to look up information that is indexed by some unique &#8220;key value, well, this what dictionaries [...]]]></description>
			<content:encoded><![CDATA[<p>Python dictionaries are incredibly useful. In other programming languages, they&#8217;re called collections, hash tables, or associative arrays. If you&#8217;re an Excel user, think of what you normally do using a function like VLOOKUP or HLOOKUP. If your program needs to look up information that is indexed by some unique &#8220;key value, well, this what dictionaries are good for.</p>
<p>Integers work well as dictionary keys, but you should use caution in using floating point numbers (i.e. decimals). From Section 6.8 in the manual:  Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.)&#8221;</p>
<div id="attachment_91" class="wp-caption alignnone" style="width: 310px"><a rel="attachment wp-att-91" href="http://ebmgh.com/blog/2009/12/python-what-makes-a-good-dictionary-key/dict/"><img class="size-medium wp-image-91 " title="dict" src="http://ebmgh.com/blog/wp-content/uploads/2009/12/dict-300x189.png" alt="" width="300" height="189" /></a><p class="wp-caption-text">Python dictionary with tuples as keys</p></div>
<p>Every item in a dictionary is a key:value pair. The key is what you&#8217;ll be using to do the lookup. Here&#8217;s an interesting and important concept: Keys must be immutable. In other words, they have to be a data type that can not be changed. Strings and numbers work. When you do some kind of string manipulation in Python, it creates a new copy in memory. Tuples work because they can&#8217;t be changed. For example,</p>
<p>T = (3, 4)</p>
<p>The tuple T does not have a method that you can call like T.append(5) or T.remove(4). If it&#8217;s a list like:</p>
<p>L = [3, 4]</p>
<p>you can use functions like .append(), .remove(), .insert() or .pop(). That means that it&#8217;s mutable, or changeable. And something that is mutable is not create a hash, or a unique identifier, for a list. Try it: hash(T) returns an integer, and hash(L) returns &#8220;TypeError: list objects are unhashable&#8221;.</p>
<p>Since dictionaries themselves are mutable (you can add and remove key-value pairs easily), you cannot use them as keys in other dictionaries.</p>
<p>More advanced stuff: If you want your own objects that you create to be dictionary keys, you have to define the method __hash__( self). See the manual section: Objects, values and types &gt; Basic Customization.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2009/12/python-what-makes-a-good-dictionary-key/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Served from: ebmgh.com @ 2012-02-05 10:18:07 -->
