<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>David Mohundro - Developer, Architect, Learner, Dad and more - software-development tag</title>
        <link>https://mohundro.com/tags/software-development</link>
        <description>Posts tagged with software-development</description>
        <lastBuildDate>Wed, 08 Apr 2026 14:46:21 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en-us</language>
        <image>
            <title>David Mohundro - Developer, Architect, Learner, Dad and more - software-development tag</title>
            <url>https://mohundro.com/static/images/me.jpeg</url>
            <link>https://mohundro.com/tags/software-development</link>
        </image>
        <copyright>All rights reserved 2026, David Mohundro</copyright>
        <atom:link href="https://mohundro.com/tags/software-development/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Finding Text in Files Revisited]]></title>
            <link>https://mohundro.com/blog/2014-10-04-finding-text-in-files-revisited/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2014-10-04-finding-text-in-files-revisited/</guid>
            <pubDate>Sat, 04 Oct 2014 00:00:00 GMT</pubDate>
            <description><![CDATA[If your career is anything like mine, you've dealt with a wide array of various code bases across multiple technologies. Some web, some client, etc. With...]]></description>
            <content:encoded><![CDATA[<p>If your career is anything like mine, you've dealt with a wide array of various code bases across multiple technologies.
Some web, some client, etc. With varying technologies, the tools change, the languages change, everything changes.</p>
<p>A few things have remained relatively constant, though, such as a command line.</p>
<p>And war... war never changes... (that's a <a href="http://fallout.wikia.com/wiki/Fallout_intro">Fallout reference</a>!)</p>
<p><img src="/static/images/blog/2014-10-04-fallout.gif" alt="War Never Changes" /></p>
<p>But I digress.</p>
<p>Given my love of all things command line, I still greatly prefer searching over the wide variety of code bases I've
worked with from the terminal. I've blogged about this before and have even written a PowerShell script to help with
this. Today, there are so many options available for text searching that I thought I'd share an updated list to help you
decide how best to find text in your source code.</p>
<p>My test case will be simple... recursively search for the term "jQuery" across the current directory, optionally
specifying the files to search in. Also, ideally show 3 lines of context after the match if possible.</p>
<h2>The Old Standards</h2>
<p>First off, I want to share the tools of the trade that have existed for years... decades even.</p>
<h3>grep (cross platform)</h3>
<p><a href="http://en.wikipedia.org/wiki/Grep">Grep</a> is the go to tool here. It's been around since at least the early 70s.</p>
<p>Often, you'll see <code>grep</code> used in conjuction with other tools, like <code>ps</code> to search for specific processes or other
command line tools. By default, it just returns any lines that match the search term from stdin.</p>
<pre><code># use in conjunction with the find command
find "directory" -name "*.js" | xargs grep "jQuery"

# or more succinctly without find usage
# options:
#   -r        = recursive
#   -n        = line numbers
#   -w        = match whole word
#   --include = to specify files to search (like *.js)
#   -e        = search term
#   -A        = context lines to show (after match)
#   -B        = context lines to show (before match)
#   -C        = context lines to show (before and after match)
grep -rnw "directory" --include "*.js" -e "jQuery" -A 3

# look in current directory for jQuery across all files
grep -rnw . -e jQuery -A 3
</code></pre>
<p>To install <code>grep</code>, you either have it installed already because you're on a *nix platform or you can install it
via <a href="http://gnuwin32.sourceforge.net/packages/grep.htm">Grep for Windows</a>.</p>
<h3>findstr (Windows)</h3>
<p>Windows doesn't come with <code>grep</code> installed by default, but it does come with
<a href="http://technet.microsoft.com/en-us/library/cc732459.aspx">findstr</a>.</p>
<p>In my humble opinion, while it can get the job done, you're much better off using one of the many other options out
there. I don't believe it has any options to show context lines in its results.</p>
<p>Usage:</p>
<pre><code>REM some relevant options:
REM   /p = skip files with non-printable characters
REM   /s = recursive searc
REM   /c = search term
findstr /p /s /c:"jQuery" *.js
</code></pre>
<p>No installation instructions - you're either on Windows and have it or you're not and don't need it.</p>
<h2>Replacing grep</h2>
<p>In the last 10 years or so, there have been a few stand out tools that have attempted to dethrone grep from its top spot
of text searching, at least in terms of searching for code.</p>
<h3>ack (cross platform)</h3>
<p><code>ack</code> is a perl script that whose original URL was actually
"betterthangrep.com" - now it lives at
<a href="http://beyondgrep.com/">beyondgrep.com</a>. Given the original URL, you can probably guess how it is positioned - it is "a
tool like grep, optimized for programmers." One of the key things for it is that it was built specifically for searching
over source code. Grep doesn't know to ignore VCS directories like ".git" or ".svn". You often have to specify quite a
few options to get to what you need.</p>
<p>Usage:</p>
<pre><code># relevant options:
#   --smart-case   = if set, ignores case unless the search term contains any upper case
#   -A             = context lines to show (after match)
#   -B             = context lines to show (before match)
#   -C             = context lines to show (before and after match)
#
# see also --help-types to see which file type groups ack supports
#   like --js, --csharp, --ruby, etc.

ack --js jQuery -A 3
</code></pre>
<p>To install, I'd recommend one of the following:</p>
<ul>
<li>Windows?
<ul>
<li>Install <a href="http://chocolatey.org/">Chocolatey</a></li>
<li>Run <code>choco install ack</code></li>
</ul>
</li>
<li>OSX?
<ul>
<li>Install <a href="http://brew.sh/">homebrew</a></li>
<li>Run <code>brew install ack</code></li>
</ul>
</li>
<li>Linux?
<ul>
<li>See <a href="http://beyondgrep.com/install/">list of packages</a></li>
</ul>
</li>
</ul>
<h3>Find-String (Windows)</h3>
<p>PowerShell was released in 2006. It shipped with a cmdlet called
<code>Select-String</code> that provided grep-like functionality; however, it didn't support context matches until version 2.
Multiple people built their own versions of wrappers around Select-String to make it more usable... I'm of course
partial to my own
<a href="https://github.com/drmohundro/find-string">Find-String</a> project.</p>
<p><code>ack</code> existed when I wrote <code>Find-String</code>, but it didn't perform as well for me at the time as using PowerShell (May
2009). Today, I'd guess <code>ack</code> and
<code>Find-String</code> are fairly comparable in terms of performance.</p>
<p>Usage:</p>
<pre><code># relevant options:
#   -context   = [x,y] where x is number of lines before and y is number of lines after
Find-String jQuery *.js -context 0,3
</code></pre>
<p>If you have access to PowerShell 5, I've got <code>Find-String</code> up on the
<a href="https://www.powershellgallery.com/packages/Find-String/">PowerShell Gallery</a>. You can install it by
running <code>Install-Module Find-String</code>.</p>
<p>If you're not yet on PowerShell 5, try installing <a href="http://psget.net/">PsGet</a>
and then you can just run <code>Install-Module Find-String</code>.</p>
<h2>The New Players</h2>
<p>In the last few years, there has been renewed interest in tools like <code>grep</code> and
<code>ack</code>, but with speed as a big focus.</p>
<h3>The Silver Searcher (ag) (cross platform)</h3>
<p>In 2011, the Silver Searcher (<code>ag</code>) was released. To my understanding, it was the first code search tool since <code>grep</code>
that was written in C. As a result, it performed faster than <em>any</em> of the competition. In the Linux and OSX communities,
it was quickly gaining ground over tools like <code>ack</code>. In Windows, however, it was far too difficult for most people to
get to compile in Windows. I used it when I was working in OSX, but I stuck with <code>Find-String</code> when I worked in Windows.
However, recently I discovered pre-built binaries of ag for Windows that work great and out-perform <code>Find-String</code> by
quite a bit.</p>
<pre><code># relevant options:
#   --smart-case   = if set, ignores case unless the search term contains any upper case
#   -A             = context lines to show (after match)
#   -B             = context lines to show (before match)
#   -C             = context lines to show (before and after match)
#   -G             = only search files that match regex
ag jQuery -G "\.js$" -A 3

# or if you want to search all files... it is fast enough it likely won't matter!
ag jQuery -A 3
</code></pre>
<p>To install, I'd recommend one of the following:</p>
<ul>
<li>Windows?
<ul>
<li>Check
out <a href="http://blog.kowalczyk.info/software/the-silver-searcher-for-windows.html">Krzysztof Kowalczyk's pre-built binaries</a></li>
</ul>
</li>
<li>OSX?
<ul>
<li>Install <a href="http://brew.sh/">homebrew</a></li>
<li>Run <code>brew install the_silver_searcher</code></li>
</ul>
</li>
<li>Linux?
<ul>
<li>See <a href="https://github.com/ggreer/the_silver_searcher">main project for details</a></li>
</ul>
</li>
</ul>
<h3>The Platinum Searcher (pt) (cross platform)</h3>
<p>The final one I'd like to share is the Platinum Searcher (<code>pt</code>). It is <em>very</em>
new, only having been released in early 2014. It is unique in that it is the only one written
in <a href="https://golang.org/">Go</a>. Go is nice in that it has the performance characteristics of C while also being cross
platform. Per the project site, it can search just as fast as <code>ag</code>.</p>
<p>You may notice that the command line options are almost identical to <code>ag</code>, which is nice.</p>
<pre><code># relevant options:
#   --smart-case   = if set, ignores case unless the search term contains any upper case
#   -A             = context lines to show (after match)
#   -B             = context lines to show (before match)
#   -C             = context lines to show (before and after match)
#   -G             = only search files that match regex
pt jQuery -G "\.js$" -A 3

# or if you want to search all files... it is fast enough it likely won't matter!
pt jQuery -A 3
</code></pre>
<p>To install, you can just grab one of
the <a href="https://github.com/monochromegane/the_platinum_searcher/releases">pre-built releases</a> or run <code>brew install pt</code> on
OSX.</p>
<h2>What do I recommend?</h2>
<p>Today, you have a lot of options with which to search... I'm not even going to try to mention all of the options you
have if you include GUI tools! I do have my favorites, though.</p>
<p>You might think I'd stick with <code>Find-String</code> given that I wrote it, but you'd be mistaken. I definitely keep it around,
but my go to at the moment is <code>pt</code>. Thus far, it is the fastest tool I've found at searching and it works across every
OS I use. I still fall back to <code>Find-String</code> in some cases, because I like having PowerShell and objects in the
pipeline, but for straight digging through code, <code>pt</code> wins hands down.</p>
<p>If you spot any inaccuracies or have other thoughts, let me know!</p>
<p><img src="/static/images/blog/2014-10-04-fallout-enjoy-your-stay.gif" alt="Enjoy Your Stay!" /></p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[Code review of randomness]]></title>
            <link>https://mohundro.com/blog/2012-04-10-code-review-of-randomness/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2012-04-10-code-review-of-randomness/</guid>
            <pubDate>Tue, 10 Apr 2012 00:00:00 GMT</pubDate>
            <description><![CDATA[Last week, prior to a weekly meeting, one of my team members had the idea to take a few minutes before the meeting to review some code. We already do code...]]></description>
            <content:encoded><![CDATA[<p>Last week, prior to a weekly meeting, one of my team members had the idea to
take a few minutes before the meeting to review some code. We already do code
reviews prior to deployments, but we've been wanting to improve the quality
of the code reviews... we wanted to really have good dialog about code quality
and be able to share that discussion with the whole team.</p>
<h2>Code reviews... but random</h2>
<p>So we were all on board with a more fully featured code review... but whose
code would we choose? We weren't exactly getting volunteers left and right to
offer up their code... probably because they knew that everyone else would
find <em>some</em> reason to skewer it. After all, no code is perfect... there is
almost always room for improvement.</p>
<p>Another problem with volunteered code is that it would typically be code that
had been seen recently. New code tends to be of higher quality than legacy
code; however, we have plenty of legacy code that could be greatly improved by
having the team take just 10 minutes to look over it.</p>
<p>The solution was a PowerShell script that I whipped together in about 15
minutes. Here it is:</p>
<pre><code>param (
    $fileType = "cs",
    $directoryToSearch = "c:\path\to\source\repo"
)

$scriptDir = (Split-Path $MyInvocation.MyCommand.Path -Parent)
$editor = 'C:\Program Files\Sublime Text 2\sublime_text.exe'

$excludedFilePaths =
    '\.Designer\.cs',
    '\.generated\.cs',
    '\\Service\sReferences\\'

function notIn($lookFor, $toSearch) {
    foreach ($toExclude in $toSearch) {
        if ($lookFor -match $toExclude) {
            return $false
        }
    }
    return $true
}

function allFilesOfType {
    ls -filter "*.$fileType" -recurse |
        where { notIn $_.FullName $excludedFilePaths }
}

Push-Location $directoryToSearch

"Drum roll, please..."

$randomlySelectedFile  = allFilesOfType | Get-Random -count 1 | select -expand FullName
&amp; $editor $randomlySelectedFile

Pop-Location
</code></pre>
<p>As you can see, it is pretty basic. Most of the complexity involves excluding
Designer or generated files. Once the script determines a random file, it
opens it in a text editor for the team to view. From there, we began looking
at it as a team and calling out issues... "we should use var here," "can we
rename that variable?," "I think we need to dispose of that object," etc. In a
short 15 minutes, we as a team were able to find all sorts of minor issues
with the code.</p>
<h2>Team Learning, Team Dialog, and Decreasing Technical Debt</h2>
<p>By reviewing the code together, it allowed us to share the learning about what
we <em>as a team</em> thought made for quality code. Often while pair programming,
these discussions come up, but they were only between 2 or 3 at most... by
doing this together, we could all benefit from the discussion.</p>
<p>Another benefit is that it forces us to become familiar with random parts of
our system. I'm confident that almost every development team has some aspect of
the "Train (or bus) Problem" as I call it... if someone on your team were hit
by a train (or bus), could the rest of the team pick up without them? If not,
then there is a potential liability there. By reviewing code as a group, the
team can become familiar with the code together.</p>
<p>From a technical debt perspective, we now have another tool in our arsenal
that we can use to slowly improve code. Ideally, if we continue improving our
core code in this way, in six months or so we'll have trouble finding issues.
We might have to go after specific sections of our code to review at that
point. Either way, we've got something started that seems to be very
beneficial.</p>
<p>Leave a comment if your team does something similar.</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[How I Got Started in Programming]]></title>
            <link>https://mohundro.com/blog/2008-07-15-how-i-got-started-in-programming/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2008-07-15-how-i-got-started-in-programming/</guid>
            <pubDate>Tue, 15 Jul 2008 00:00:00 GMT</pubDate>
            <description><![CDATA[Brian Sullivan tagged me with the latest ongoing meme. I'm really sort of excited because I've missed out on all the other memes going around. Jeff Atwood...]]></description>
            <content:encoded><![CDATA[<p><a href="http://www.sullivansoftdev.com/blog/">Brian Sullivan</a> <a href="http://www.sullivansoftdev.com/blog/post/How-I-Got-Started-in-Programming.aspx">tagged me with the
latest ongoing
meme</a>.
I'm really sort of excited because I've missed out on all the other memes going
around. <a href="http://www.codinghorror.com/blog/">Jeff Atwood</a> probably wouldn't even
consider me a real geek because of that. (I haven't updated a Wikipedia page
either! Gasp!)</p>
<h2>How old were you when you started programming?</h2>
<p>I didn't write my first "Hello World" until I was 18 in COMP 170. I created my
first personal website when I was 15 I think, but my primary tools were
<a href="http://en.wikipedia.org/wiki/Netscape_Composer">Netscape Composer</a> and <a href="http://en.wikipedia.org/wiki/Paint_Shop_Pro">Paint
Shop Pro</a>. :-) I think I had
figured out by that point some <em>very</em> basic Javascript, but I really had no
idea what I was doing.</p>
<h2>How did you get started in programming?</h2>
<p>I remember when my dad got a new PC with Windows 3.1 on it. Prior to that, I
knew how to 'cd' between directories and how to run 'dir'. All of these
commands were, of course, to get to the directory where my games were
installed. :-) I never really stayed in Windows at the time, because all the
games were still DOS-based. I didn't really have much to do with Windows
(except for the <a href="http://www.codinghorror.com/blog/archives/000341.html">Hot Dog
theme</a>), until Windows
95 came out. That's when I started becoming more of a computer enthusiast. I
remember troubleshooting <a href="http://www.annoyances.org/exec/show/article04-100">Dial Up
Networking</a> so that our 14.4
modem would connect up. I also remember buying my first piece of hardware, the
<a href="http://en.wikipedia.org/wiki/3dfx">3dfx Voodoo card</a>.</p>
<p>As I mentioned, I started doing some basic web pages when I was in high school.
This was the time of animated GIFs and tiled backgrounds, if you're interested.
This was also back when 56K modems first came out and there wasn't yet a clear
standard on how 56K modems would talk (you could either go with US Robotics or
the cheap brands) and I worked as tech support at a local ISP. It wasn't hard
to do tech support because I had been troubleshooting my own Dial Up Networking
problems for a few years already.</p>
<p>Coming from a tech support role, I didn't really have any programming
knowledge. I knew how to build a computer and I even knew about msconfig, but
programming??? Nah... not really. Just WYSIWYG HTML.</p>
<p>When I graduated high school, I either wanted to be a musician or work with
computers. Seeing as how I didn't really want to teach high school band, I
decided to go to school to learn about computers. I didn't really know what
Computer Science meant, but hey, my grades were pretty good so why not? So, I
chose a major of Computer Science and the rest is history.</p>
<h2>What was your first language?</h2>
<p>Unlike the rest of the programming populace, my first language was actually
<em>not</em> BASIC, but C++. I didn't actually write a line of BASIC until my junior
year of college! I would say that I currently prefer C# over VB.NET, but it has
more to do with terseness than it does with braces. For the same reason, I'm a
fan of Ruby as well.</p>
<h2>What was the first real program that you wrote?</h2>
<p>Are you saying Hello World doesn't count? C'mon!</p>
<p>I'm going to define "real program" in this case as something that I could show
my parents. I couldn't show them "Hello World" or a command line application to
create a binary search tree because they couldn't relate to it. However, I
<em>could</em> show them a GUI maze application that I wrote in Java. It had four
players (one of which could be human controllable) and then each player raced
to get to the exit. I also wrote a Solitaire program in C++, a networking Tic
Tac Toe game in C++, and a Paint program in C++ (using the Windows API).</p>
<p>My first team application, like Brian's, was created in the capstone course at
<a href="http://www.harding.edu/">Harding</a>. We wrote a version of Othello that had to
be networked with an AI. I wrote the networking code in C#. It even had
threading code, which of course was written completely wrong. I'm still not
entirely convinced that I can write threading code correctly today. :-)</p>
<h2>What languages have you used since you started programming?</h2>
<p>In college, I primarily used C++ and C#, but I also had some exposure to some
Assembler, Java, VB.NET, Perl, and even LISP! My work experience includes a
(thankfully short) period of COBOL and JCL on an IBM mainframe, but primarily
has been in VBScript (both classic ASP as well as scripts), Javascript,
PowerShell, C++, C#, and VB.NET.</p>
<p>In my personal projects, I've used C#, VB.NET, JavaScript, PowerShell, PHP,
Python, and Ruby. I'm sure I've missed something in there.</p>
<h2>What was your first professional programming gig?</h2>
<p>I got hired out of college to work at <a href="http://www.data-tronics.com/">Data-Tronics,
Corp</a>. where I still am to this day. My role has
changed significantly now, where I'm trying hard to push out 40 years of IT
practices with more modern methodologies (down Waterfall, down!) and
technologies (down Mainframe, down!).</p>
<h2>If you knew what you know now, would you have started programming?</h2>
<p>You bet. I'm a geek to the core.</p>
<h2>If there was one thing you learned along the way that you would tell new developers, what would it be?</h2>
<p>I'd have to agree completely with Brian - <em>get involved in the community</em>. Do
<strong><em>not</em></strong> let programming become just the job you perform. Like
<a href="http://blog.jpboodhoo.com/">JP</a>, get passionate about developing. If you don't
enjoy what you do, there isn't any point in doing it. Start reading blogs and
going to <a href="http://fsdnug.org/">user groups</a>. You'll be overwhelmed at how much
you didn't know, but remember that no one else knows it all either. We're all
<a href="/blog/2007/03/15/how-to-get-better-at-what-youre-doing/">learning together</a>.</p>
<h2>What's the most fun you've ever had... programming?</h2>
<p>I can't think of any one specific instance, but I think one of the best
feelings is, after having spent literally hours trying to debug some problem
and then giving up and going home, waking up the next day and having the light
bulb come on with the solution to this problem. I love solving problems with
software.</p>
<h2>Tag, you're it!</h2>
<p><a href="http://www.colinneller.com/blog/">Colin Neller</a>, come on down!</p>
<p><a href="http://mysoftwarestartup.com/blogs/">Randy Walker</a>, you too!</p>
<p>I've got other tags if anyone else is interested. I might even give some out!</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[Learning technologies outside (and inside) of the Microsoft ecosystem]]></title>
            <link>https://mohundro.com/blog/2008-01-30-learning-technologies-outside-and-inside-of-the-microsoft-ecosystem/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2008-01-30-learning-technologies-outside-and-inside-of-the-microsoft-ecosystem/</guid>
            <pubDate>Wed, 30 Jan 2008 00:00:00 GMT</pubDate>
            <description><![CDATA[In my post looking forward to 2008, I mentioned that I wanted to take more time this year to learn new technologies, particularly outside of the Microsoft...]]></description>
            <content:encoded><![CDATA[<p>In <a href="/blog/2008/01/01/welcome-2008-2007-in-review/">my post looking forward to
2008</a>, I mentioned that I wanted
to take more time this year to learn new technologies, particularly outside of
the Microsoft communities. With all of the push in .NET towards dynamic
languages right now, why not look to some of the dynamic languages that have
been out there being used for years?</p>
<p>I know what you're thinking - looks like David here decided to learn Ruby. I
mean, that's what everyone is using, right? Ruby and Ruby on Rails? Nahhh, I'm
actually learning Python! Probably the key factor for me was <a href="http://www.pythonchallenge.com/">the Python
Challenge</a>. I follow <a href="http://thepowershellguy.com/blogs/posh/default.aspx">MoW's Powershell
blog</a> and he's started up
a series on <a href="http://thepowershellguy.com/blogs/posh/archive/2008/01/09/posh-challenge-part-1.aspx">working through the Python Challenge using
Powershell</a>.
I had heard about the challenge before, but hadn't really looked into it much,
but this was enough to prompt me to get over there and try it out. (I am
planning on still learning Ruby, though - I'll just go through the challenges
with Ruby later)</p>
<p>I resisted the urge to try to find an IDE for Python and just code it up in a
text editor. It has forced me to get more familiar with the syntax as a result.
The Python site has a great tutorial for starters as well as some good
documentation on the available modules. The hardest part for me is to not write
the code like I write C# or VB. For one of the challenges, you have to take a
given string, a given mapping, and then translate the string to get the
instructions to move to the next challenge. I wrote a basic loop over the
characters in the string, converted them to their ordinal values, performed the
translation, and then converted them back to characters. It worked, but it
wasn't the best way to do it in Python. Python provides this great function
called string.maketrans. Also, the map function is amazing. It is sort of like
the List&lt;T&gt;.ForEach method except that it reads a lot better (though
lambda expressions in C# make it a little better). I'm <em>starting</em> to understand
the power behind the whole map/reduce idea that Google is so big on. List
comprehensions are really cool, too.</p>
<p>Anyway, so far, I'm to the 5th challenge (with some help from Google, the
Python tutorials, and the challenge forums at times) and it is pretty cool. One
of the most enlightening things about going through the challenge is that, as
you complete one, you can go look at submitted solutions on the wiki. It is a
great way to evaluate if you solved the challenge the "right" way or not. It is
a great learning experience. One way I'm trying to apply this knowledge is that
I'm running the challenges in both CPython (Python that runs on C, the standard
I think) and IronPython.</p>
<p>Another thing I've done to try to see how other development communities work is
that I've installed Ubuntu 8.04 (the alpha) on my laptop. I'm now dual booting
Vista x64 and Ubuntu and it is pretty nice. I have two favorite things about
Ubuntu so far - the ridiculous customization that you can do with it (compiz is
amazing) and the package manager. Seriously, the fact that you don't have to
pull up a browser to download apps and install them is a massive plus over
Windows. In fact, you can just run a simple apt-get command if you want. Don't
worry, though, I'm not planning on switching from Vista anytime, soon. Ubuntu
is great and I'll be keeping it on the laptop, but I still like Vista, too.
Right, right, blasphemy, I know. They're both great operating systems as far as
I'm concerned. One takes an entire DVD and seems like a resource hog (not as
bad anymore) and the other fits on a CD and requires editing conf files,
downloading "restricted" drivers, and sitting at the command line to get video
and wireless working :-) Seriously, neither are perfect. It has been nice
seeing both sides of the fence, though.</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[What code that you've written are you proud of?]]></title>
            <link>https://mohundro.com/blog/2007-09-26-what-code-that-youve-written-are-you-proud-of/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2007-09-26-what-code-that-youve-written-are-you-proud-of/</guid>
            <pubDate>Wed, 26 Sep 2007 00:00:00 GMT</pubDate>
            <description><![CDATA[Yesterday, I had a somewhat strange experience. I was helping someone with a problem they were having and, almost as a side note, this individual thought he...]]></description>
            <content:encoded><![CDATA[<p>Yesterday, I had a somewhat strange experience. I was helping someone with a
problem they were having and, almost as a side note, this individual thought he
would share some code with me that he was particularly proud of. He even
prefaced the story with the "not to brag or anything" phrase. He had written
some custom code to help text boxes grow or shrink depending on how the user
resized the window. If you know anything about WinForms, you'll know that some
simple anchoring techniques and good use of the SplitContainer will solve this
problem for you - please, please, please don't go writing custom mathematical
equations when the framework can take care of it for you.</p>
<p>At the time, I was pretty annoyed with it, because this individual was bragging
about something that I considered "the wrong way to do it." In retrospect, this
probably was the wrong response. Why? Because he was proud of some of the code
he had written. He actually cared about it enough to not just treat it as
something to toss off on to someone else when he moved to the next project.</p>
<p>The projects that have turned out best that I've worked on the ones where I was
really proud of the code. That doesn't mean I did it the right way. I'm
thinking of one example where I wrote this crazy elaborate dynamic menu system
in JavaScript. It even worked in both Firefox and Internet Explorer. It had a
full blown object model and made use of closures and more - it was great.
Here's a complete example of usage of the menu:</p>
<pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;clsNavBar&lt;/title&gt;
    &lt;script language="JavaScript" src="clsMenu.js"&gt;&lt;/script&gt;
    &lt;link href="styles.css" rel="stylesheet" type="text/css" /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;script language="JavaScript"&gt;
      var nav = new clsMenu()
      nav.setContainer(document.body)
      nav.setXMLUrl('NavBar.xml')
      //nav.setHorizontal(false)
      nav.buildMenu()
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>It had one problem. Maintenance. Maintenance on the system will be nigh
impossible for the next guy. From the very beginning, I should have used CSS
for the entire menu structure. When and if someone ever decides to change the
way the menus look, well... good luck. However, it was still a good experience.
I learned more about the inner workings of JavaScript from working with that
than I did from any blog post or book I've ever looked at. I would have never
learned what exactly 'this' references in JavaScript without that example (see
<a href="http://www.fitzblog.com/tabid/17782/bid/2127/Nine-Javascript-Gotchas.aspx">this post on JavaScript
gotchas</a>
and refer to the section on 'this').</p>
<p>In all of this, I have learned to be very careful of the code I'm proud of.
Inevitably, if you're growing as a developer by "<a href="http://www.codinghorror.com/blog/archives/000530.html">sucking less every
year</a>," you're not going
to be too proud of your code in a year or two anyway.</p>
<p>Do you have any code you're particularly proud of? If it turned out to be the
"wrong way to do it" but you learned a lot from the experience, you get bonus
points.</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[I wish I could be at the ALT.NET conference...]]></title>
            <link>https://mohundro.com/blog/2007-09-24-i-wish-i-could-be-at-the-altnet-conference/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2007-09-24-i-wish-i-could-be-at-the-altnet-conference/</guid>
            <pubDate>Mon, 24 Sep 2007 00:00:00 GMT</pubDate>
            <description><![CDATA[Reading posts like this one from Jeremy Miller really make me wish I could make it to the ALT.NET conference in Austin. There are almost too many good points...]]></description>
            <content:encoded><![CDATA[<p>Reading <a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/09/24/alt-net-in-austin-and-beyond.aspx">posts like this one from Jeremy
Miller</a>
really make me wish I could make it to the ALT.NET conference in Austin. There
are almost too many good points in his post for me to comment on, but I'll go
ahead and try.</p>
<p>I completely and wholeheartedly agree with his comments on the general lack of
knowledge that developers have regarding real OOP and software design concepts.
Many of the developers I work with are terrified of the upcoming releases of
the .NET framework. The thing is, they're just new releases in tools and
libraries. Sure, they provide value - I don't know how many times I realize
that some UI I'm trying to work with in WinForms would be ridiculously easy to
build in WPF. And WCF does a great job at abstracting the goo that connects all
of my objects. However, if I don't have a good background in solid OOP design
and separation of concerns, WCF won't help me at all anyway. These new tools
aren't going to do anything to make me a better developer. I'll still be able
to write awful code.</p>
<p>I commend these guys for trying to get to the heart of the issues in the .NET
community and I hope that the solution isn't to just move to Ruby and Ruby on
Rails. My opinion is that we have to fix the problems in our community - if we
just migrate to another community, the problems and lack of knowledge will
eventually follow us. I can still write bad code in Ruby, too.</p>
<p>Being one of the guys who won't be able to make it, I have a few requests. I
would really like to see the content from the conference posted online or made
accessible to those of us who won't be able to make it, particularly
considering the fact that the conference sold out. Microsoft did a good job in
posting content from both MiX and TechEd this year and I think that would be a
welcome addition from this conference as well.</p>
<p>Keep pushing this knowledge out - I'm optimistic that things will improve.</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[The Testing Continuum]]></title>
            <link>https://mohundro.com/blog/2007-07-05-the-testing-continuum/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2007-07-05-the-testing-continuum/</guid>
            <pubDate>Thu, 05 Jul 2007 00:00:00 GMT</pubDate>
            <description><![CDATA[In the few years that I've worked as a software developer, I've read and seen many examples of testing software. As a result, my own thinking regarding testing...]]></description>
            <content:encoded><![CDATA[<p>In the few years that I've worked as a software developer, I've read and seen
many examples of testing software. As a result, my own thinking regarding
testing has changed drastically over the past year or two. It seems that there
is a continuum behind the thinking that goes behind testing. I originally
titled this post "the Evolution of Testing Thought Processes" but evolution
doesn't describe this as well for me, because I find myself moving between the
different processes depending on the circumstances.</p>
<p>This post has a few goals:</p>
<ol>
<li>I want to gain a better understanding of where I stand regarding testing code.</li>
<li>I want to share some of these ideas with others, particularly my coworkers, who might not have encountered ideas like unit testing.</li>
<li>I want to get your input on this and see if anyone else struggles with these issues, too.</li>
</ol>
<p>Here are the different thought processes that I've seen regarding testing:</p>
<h2>No Testing (i.e. did it compile?)</h2>
<p>This one's easy to categorize, right? Basically, no testing happened
whatsoever. If it compiles, you're set. If you're working in a dynamic or
interpreted language, then good luck. Hopefully, you've never seen this one
before, but I wouldn't be surprised if you have.</p>
<p>I have a horror story to share regarding this. A few years ago, my team was on
track to install a fairly substantial update to a daily scheduled application.
The update unfortunately required some changes to the script that kicked off
the whole process. Because my team didn't own this script, we had to get
someone else to do it. What we didn't know is that a certainly individual who
will remain nameless decided to convert this script from REXX to VBScript. This
would have been a good change at the time, had we prepared for it. Needless to
say, this wasn't even the worst part.</p>
<p>This individual never even attempted to run this script.</p>
<p>You heard me - this individual converted a script from one language to another
one and never tested the script at all. How could I possibly know this when I
didn't even know the script was being converted? Because when the script was
scheduled to run the next day, it blew up. It blew up because of invalid
syntax. It blew up because there was VBScript code at the top... and REXX
script at the bottom. I spent the better part of two days attempting to fix
that problem.</p>
<p>The lesson here is to at least run your application <em>once</em> before installing. I
don't care if you're the best developer in the world. You can still make
mistakes.</p>
<p>Don't do this.</p>
<h2>Manual Testing (i.e. F5 testing)</h2>
<p>Manual testing is when developers run their application and attempt to test all
of the functionality themselves. If they don't spot any problems, then the
application is ready for production.</p>
<p>I used this technique the most while in college. If my professor could break
our application with invalid input, then our grade would drop. For each problem
the professor found, the grade would continue to drop. The majority of the
applications that I wrote during this time were command line applications, so
most of the user interaction was pretty easy to verify. I missed a few edge
cases sometimes, but I was able to test the basic functionality because the
application itself was so simple.</p>
<p>I consider having someone else test your application an example of this as
well. My experience is that usability problems are discovered here instead of
bugs. The problem is that most developers have their own projects to work on,
so testing your application isn't exactly at the top of their list of things to
do. In other words, their testing will likely be even less rigorous than your
testing.</p>
<h2>Manual Unit Testing</h2>
<p>This is a small variation on manual testing the whole application. At this
point, you are testing smaller units rather than an entire application, which
is a good thing. To do this, you typically have either a command line
interface, a small form or a small web page that uses the small unit from your
application. Your UI likely performs a few actions on your library and you then
examine the results for problems. Sometimes, you'll enter a few input details
to test different scenarios. Ideally, you'll test as much of the functionality
that the library provides as possible.</p>
<p>The most common place I see this is when someone has written a shared component
or created some external assembly that will potentially be used by someone
else. It doesn't have a UI of its own, so to test it, you have to create
something else to run it.</p>
<p>On the testing continuum, this is the first case where application testing is
broken up into pieces. Developers can test parts of the application separate
from the rest. As a result, there is less to distract developers.</p>
<h2>Unit Testing</h2>
<p>The problem with manually testing units of an application is that verification
of the results is still dependent upon the developer. Everyone makes mistakes
so it is only a matter of time before someone misses a problem. <a href="http://en.wikipedia.org/wiki/Unit_testing">Unit
Testing</a> takes the last approach and
expands upon it by letting the computer decide whether or not your library is
working correctly.</p>
<p>With a manual test application, you simply look at the results that your test
UI provides. Why not put those results (expectations) into code? The test can
then be much more precise about its results. For example, it is much easier to
determine if a returned numeric type is an integer or decimal value from code
than you can from a UI. In .NET, you can just check the type. Better yet, you
know immediately from code whether or not that is a "0" or an "O".</p>
<p>These tests provide value during development time, but particularly during
maintenance time. Imagine that a user of your system decides that they want to
change something. Crazy, right? Have you ever made a change to an existing
system and then broken existing functionality elsewhere in the application?
This is why <a href="http://en.wikipedia.org/wiki/Regression_testing">regression
testing</a> is necessary. Unit
testing makes regression testing even easier because the list of tests you have
stays with the application. As you find new bugs, you can write tests for those
so that they never show up again.</p>
<p>Tool support for unit testing is awesome, too. With tools like
<a href="http://www.mbunit.com/">MbUnit</a>, <a href="http://www.nunit.org/">NUnit</a>,
<a href="http://www.testdriven.net/">TestDriven.NET</a> and others, it is easier than ever
to write and use unit tests. The tools get better with each release, too. One
of the things that is nice about the unit testing libraries available is that
they all have test runners that generate reports. This allows you to automate
the testing and tie it into your build process or test your code nightly or
whatever. That is one of the ideas behind Continuous Integration. Every
check-in of an item into source control results in a build script running which
can also run tests. Not only do you find out if you broke the build, you also
find out if your tests now fail.</p>
<p>One of the problems that people have with unit tests is that they feel like
they spend twice as long on code because they're writing tests in addition to
the code that will run on a user's machine. Doesn't that increase development
time? In my experience, it adds to the time (though not twice as long) of the
first iteration of software development, but it can significantly cut down on
latter iterations. Have you ever maintained legacy code? I hate working with
legacy code because half the time I end up breaking existing functionality.
With unit tests, when I later have to come in to change a program, I can feel
confident knowing that I'm not breaking existing functionality.</p>
<h2>Test Driven Development</h2>
<p>How about writing your unit tests first? That will blow your mind the first
time you think about it. The idea behind <a href="http://en.wikipedia.org/wiki/Test-driven_development">Test-Driven
Development</a> isn't so
much that you're writing a test first as you are <em>designing the contract for
your class from the outside</em>. Proponents of test driven development very often
state that this development methodology helps drive their design more than
providing a good test framework. The test framework is an added benefit to good
and extensible design.</p>
<p>This is the hardest of the thought processes behind testing to really grasp, at
least for me, because it requires a change in the way you think about
developing software. Some don't see the benefits from it and others wouldn't
program without it. I certainly can see the value in it, but I haven't had
enough real world experience actually doing it to be effective with it yet.</p>
<p>So, did I miss anything? Where are you on the testing continuum? I find that I
move back and forth between Manual Unit Testing and Test Driven Development.
I'd like to move more towards &lt;acronym title="Test Driven
Development"&gt;TDD&lt;/acronym&gt;, because it is certainly beneficial and I find that
code <a href="http://weblogs.asp.net/rosherove/articles/Design4Tesatbility1.aspx">designed with
testability</a>
in mind is much easier to modify later.</p>
<p>One thing to remember is that all of these ideas play a part in testing an
application... except for the not testing idea. At some point, you'll need to
actually run your application to try it out. If you employ unit tests, they'll
simply provide more confidence in the application and provide future insurance
when the code changes - and it will change.</p>
<p>For more information, check out <a href="http://en.wikipedia.org/wiki/Software_testing">this software testing article on
Wikipedia</a>.</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[Books I'm trying to read right now]]></title>
            <link>https://mohundro.com/blog/2007-06-21-books-im-trying-to-read-right-now/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2007-06-21-books-im-trying-to-read-right-now/</guid>
            <pubDate>Thu, 21 Jun 2007 00:00:00 GMT</pubDate>
            <description><![CDATA[I have so many books I need to read right now, it isn't even funny. In my office at home, I've got about 8+ books which I need to read, and the majority...]]></description>
            <content:encoded><![CDATA[<p>I have so many books I need to read right now, it isn't even funny. In my
office at home, I've got about 8+ books which I need to read, and the majority
haven't even been started yet.</p>
<p>One of them is <a href="http://www.amazon.com/exec/obidos/ASIN/0201485672">Martin Fowler's
Refactoring</a>, which I'm
really looking forward to. I've started <a href="http://www.amazon.com/ASP-NET-2-0-Hacks-David-Yack/dp/0764597663">ASP.NET MVP
Hacks</a>, which
is pretty good. I'm only up to chapter 3 or 4, but I've already seen a decent
overview of the provider model that ASP.NET uses.</p>
<p>At work, <a href="http://www.amazon.com/Debugging-Microsoft-NET-2-0-Applications/dp/0735622027">John Robbins' Debugging Microsoft .NET 2.0
Applications</a>
and <a href="http://www.amazon.com/Windows-PowerShell-Action-Bruce-Payette/dp/1932394907">Bruce Payette's Windows PowerShell in
Action</a>
are sitting on my desk. I haven't yet started the PowerShell book yet, but I've
gotten a little ways into the debugging book.</p>
<p>I just read a funny story that John Robbins provides in his debugging book
about having what-if sessions during the project planning phase. He notes that
in his prior job as a member of the Green Berets, they would have what-if
sessions to plan for any and all contingencies. They're lives were on the line
after all.</p>
<p>He pointed out that, after moving to software development, he could get his
development team really uncomfortable by asking what-if questions like, "what
if Bob dies before we get through the requirements phase." I'll have to
remember to ask some "what-if-death" questions at my next team meeting...</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
        <item>
            <title><![CDATA[Classic Mistakes in Software Development]]></title>
            <link>https://mohundro.com/blog/2007-06-19-classic-mistakes-in-software-development/</link>
            <guid isPermaLink="false">https://mohundro.com/blog/2007-06-19-classic-mistakes-in-software-development/</guid>
            <pubDate>Tue, 19 Jun 2007 00:00:00 GMT</pubDate>
            <description><![CDATA[I just completed the Classic Mistakes survey from Construx. Thanks to Jeff Atwood for pointing this one out. The survey itself didn't seem particularly...]]></description>
            <content:encoded><![CDATA[<p>I just completed the <a href="https://vovici.com/wsb.dll/s/10431g2996e">Classic Mistakes survey from
Construx</a>. Thanks to Jeff Atwood for
<a href="http://www.codinghorror.com/blog/archives/000889.html">pointing this one out</a>.</p>
<p>The survey itself didn't seem particularly helpful, but the questions it poses
do help in enumerating many of the problems I've experienced by actually
putting them into words.</p>
<p>It also is beneficial to me because some of these mistakes stem from the
developers instead of the management. I've been guilty of developer
gold-plating and the silver-bullet syndrome many times, which is likely a
result of being a
<a href="http://www.google.com/search?q=site:mohundro.com+beta&amp;hl=en&amp;start=10&amp;sa=N">beta</a>
<a href="/blog/2006/01/26/the-a-to-z-of-programmer-predilictions/">junkie</a>. We're in
the process of moving to .NET 2.0 (no, not even .NET 3.0 or 3.5 yet) and I'm
already jumping to move to Visual Studio 2008 (formerly Orcas). I mean, surely
WPF, Linq, and WCF would solve all of our problems wouldn't they? Or, if we
suddenly went 100% with Test Driven Development, all of our problems would
disappear! Wouldn't they?</p>
<p>Sam Gentile's comments on <a href="http://codebetter.com/blogs/sam.gentile/archive/2007/06/17/writing-maintainable-code.aspx">writing maintainable
code</a>
are very relevant to silver-bullet syndrome. He points out that the XP
methodology revolves around 12 practices and not TDD by itself. TDD isn't a
silver bullet but instead is a tool to help document and protect your codebase.
You also have to work at refactoring your code and keep it clean and simple.</p>
<p>I haven't ever worked in an XP/Agile environment before, but I do like the
goals that it strives for. I'm really pushing my team to learn more about
architecture, design, and unit testing because I really do see the value. We
really have to just start using these tools. Otherwise, we'll keep talking
about them and never actually do anything.</p>
<p>Thank goodness for all these tech blogs. I've learned more from reading these
in the past couple of years than I have from just about anything else. It's
almost like I'm being mentored by all of the more experienced developers.</p>
]]></content:encoded>
            <author>david@mohundro.com (David Mohundro)</author>
        </item>
    </channel>
</rss>