<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Software Artisan</title>
    <link>http://bloritsch.d-haven.net</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Design, Development, and Artisanship</description>
    <item>
      <title>Using Many Objects at Once</title>
      <description>&lt;p&gt;Last article was meant to introduce you to the terminology that is common to object oriented languages.  You should have a clear idea of what an Object is and what a Method is.  Today, we are going to learn about how to use more than one object at a time.  We&amp;#8217;ll start with simple variables, which are simply names for objects you are using so you can get to them again.  Then we&amp;#8217;ll talk about some special objects called containers, whose sole purpose is to organize a group of objects for you.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A container is an object that holds a bunch of other objects&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;Variables&lt;/h3&gt;


	&lt;p&gt;So there&amp;#8217;s a little more terminology here.  We can assign objects to individual variables fairly easily just by giving a name, using the equals sign, and the value.  For example:&lt;/p&gt;


&lt;pre&gt;
my_variable = 12345
&lt;/pre&gt;

	&lt;p&gt;As long as the first character of the variable name starts with a letter or an underscore &amp;#8220;&lt;em&gt;&amp;#8221; character, the rest of the characters can be letters, numbers, and underscores.  Almost all languages have this requirement, so that the computer doesn&amp;#8217;t get confused between what is supposed to be a number and what is supposed to be a variable.  Just a little helpful advice from someone with experience here, use variable names that make sense.  It is better to type a few extra keys than wonder whether _cntr&lt;/em&gt; meant &lt;em&gt;counter&lt;/em&gt; or &lt;em&gt;center&lt;/em&gt; later on.  It&amp;#8217;s also better to use names that reflect the variable&amp;#8217;s purpose rather than what it is made of.&lt;/p&gt;


&lt;pre&gt;
array = ['cero', 'uno', 'dos', 'tres']
ones_column = ['cero', 'uno', 'dos', 'tres']
&lt;/pre&gt;

	&lt;p&gt;The variable named &amp;#8216;array&amp;#8217; is kind of silly.  It describes what kind of object is assigned to the variable rather than what we are using the variable for.  The variable named &amp;#8216;ones_column&amp;#8217; describes the purpose for the variable better.  We are using an array of names to write out the ones column of a number.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Variables let us hold on to objects with a user friendly name so we can use them later&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;Arrays&lt;/h3&gt;


	&lt;p&gt;Since we already introduced how to create an array above, let&amp;#8217;s talk about how they are used.  Arrays hold a bunch of related values together so that we can use them in interesting ways.  Using the &amp;#8216;ones_column&amp;#8217; example above, we can use any single digit number to get the name of that number.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Arrays are lists of information&lt;/p&gt;
	&lt;/blockquote&gt;


&lt;pre&gt;
puts ones_column[2]

# prints 'dos'
&lt;/pre&gt;

	&lt;p&gt;Remember in the last lesson, when we had a number do something using the &lt;em&gt;times&lt;/em&gt; method?  The number passed back to our code started at zero.  The number inside the square brackets is an index number that starts at zero.  So the first element in the array is always 0, not 1.  That&amp;#8217;s why we started the array with &amp;#8216;cero&amp;#8217; (Spanish for zero) instead of &amp;#8216;uno&amp;#8217; (Spanish for one).&lt;/p&gt;


	&lt;p&gt;An Array is a Collection, so like all collections it has an &lt;em&gt;each&lt;/em&gt; method.  The &lt;em&gt;each&lt;/em&gt; method works just like the &lt;em&gt;times&lt;/em&gt; method on the number objects.  The method will pass back the elements (the objects) of the array one at a time in order.  So, if we wanted to count in Spanish, we would use our ones_column array like this:&lt;/p&gt;


&lt;pre&gt;
ones_column.each do |number|
  puts number
end
&lt;/pre&gt;

	&lt;h3&gt;Hash&lt;/h3&gt;


	&lt;p&gt;A Hash allows you to map one object as a key and another object as the value.  Other languages will call the Hash a Map or a Dictionary, essentially letting you look up one object (a definition) using another object (the word to look up).  Think of the word key in the terms of a map key.  A symbol represents a concept, so to speak.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Hash lets you associate key objects with value objects&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;In Ruby, Hashes are created using the curly braces, and the key/value pairs are marked with the phrase: &lt;code&gt;key =&amp;gt; value&lt;/code&gt; .  They can be quite handy when you have a lot of information to pass from one place to the next.  One variable would take all the name/value pairs.  If it helps, think of it as a collection of variables.  It is most common to see string names be the key, but in Ruby we also have something called a symbol.  Strings are surrounded by quotes, and they can change.  Symbols have a colon in front and they never change.&lt;/p&gt;


&lt;pre&gt;
my_map = {'string' =&amp;gt; 'surrounded by quotes',
          :symbol =&amp;gt; 'starts with colon',
          :string =&amp;gt; 'not the same as a string'}

puts my_map['string'] # shows 'surrounded by quotes'
puts my_map[:symbol]  # shows 'starts with colon'
puts my_map[:string]  # shows 'not the same as a string'
puts my_map[:string.to_s] # shows 'surrounded by quotes'
&lt;/pre&gt;

	&lt;p&gt;In the above code, we set up a map of keys to string values.  Just so you know, the objects don&amp;#8217;t have to be the same type.  In fact you&amp;#8217;ll see that we used one string and two symbols for keys.  You&amp;#8217;ll also see that the Hash object treats them differently.  The last lookup  call might cause a little confusion, so look at the method being called on the symbol.  The &lt;code&gt;to_s&lt;/code&gt; method is on every Ruby object, and it is a convenient way to get a string out of the object.  For a symbol, the &lt;code&gt;to_s&lt;/code&gt; returns the name of the symbol (everything except for the colon).  Because that happens to be the same name as a string key that is already in the map, it returns the value that belongs to the string.&lt;/p&gt;


	&lt;p&gt;This brings up a very important point, particularly for newbies.  Save yourself a lot of headaches, and only use keys of the same type until you know exactly what you are doing.  If you ever use many types of objects for different keys make sure you document your code with your comments.  You don&amp;#8217;t want to run the chance of spending hours tracking down a bug only to find it is the same thing I showed here.  Talk about your &amp;#8216;Doh!&amp;#8217; moments.&lt;/p&gt;


	&lt;h3&gt;Strings&lt;/h3&gt;


	&lt;p&gt;Ok, the Array and Map are good enough to get you going&amp;#8212;there are more collection types and more things you can do with these collections, but strings are pretty important in programming.  The string is your best tool for communicating with the user.  On web forms, your values are all strings, and when you add content onto a page, they are strings.  There are three ways of working with strings in Ruby, depending on how much power you need.  We will introduce them from the simplest to the most complex.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt; Strings hold text&lt;/p&gt;
	&lt;/blockquote&gt;


&lt;pre&gt;
simple_string = 'single quotes and no processing'
&lt;/pre&gt;

	&lt;p&gt;The above string is rather simple.  The single quotes mean to take the text &lt;span class="caps"&gt;AS IS&lt;/span&gt;, no escaped characters, no single quotes, and no formatting.  You&amp;#8217;d be surprised by how much you can use this simple declaration.  If we ever needed to stick two strings together, we can use the plus sign (&amp;#8217;+&amp;#8217;).&lt;/p&gt;


&lt;pre&gt;
hello = 'Hello'
world = 'World'

puts hello + ' ' + world

#shows 'Hello World'
&lt;/pre&gt;

	&lt;p&gt;Things can get messy when you have to show information your program has back to the user.  The &amp;#8217;+&amp;#8217; concatenation only works for strings, so each object that is not a string needs to call the &lt;code&gt;to_s&lt;/code&gt; method to be concatenated.  Oh, and then you still have the problem of formatting the text to be pretty.  There is a more powerful way to declare and use strings, and that is to use double quotes:&lt;/p&gt;


&lt;pre&gt;
number = 4

puts "Number:\t#{number}" 
&lt;/pre&gt;

	&lt;p&gt;In the string we sent directly to the &lt;code&gt;puts&lt;/code&gt; method, we see a bunch of stuff that might look confusing at first.  The first funny looking characters would be the &amp;#8221;\t&amp;#8221;.  The backslash (&amp;#8217;\&amp;#8217;) is an escape character, so you can access more special characters with it.  You can embed double quotes by adding a backslash in front, or in this case you can embed a tab character.  Essentially, we told the string to embed some white space.  The next set of funny looking characters would be &amp;#8221;#{number}&amp;#8221;, but when you realize that the &lt;code&gt;number&lt;/code&gt; inside the curly braces is the same name as the variable we defined before, it suddenly becomes a little less confusing.  Basically anything between the &amp;#8217;#{&amp;#8217; and &amp;#8216;}&amp;#8217; will be treated like regular ruby.  You can even do math in there if you really wanted.  It&amp;#8217;s best to keep it simple and only use it to display the value of variables in your string.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s all well and good, but what if I have a lot of text, I only need to embed a little bit of Ruby variables, and I
want to do all the spacing and carriage returns myself?  There is a way to define a big string by providing your own &amp;#8220;terminator&amp;#8221;.  The terminator is just so that Ruby can know when the string is done and it can go back to normal Ruby processing.&lt;/p&gt;


&lt;pre&gt;
really_big = &amp;lt;&amp;lt;-END
This string will keep going and going
on and on until I use the terminator
to make it end.
END

puts really_big
&lt;/pre&gt;

	&lt;p&gt;You can embed variables just like before using the &amp;#8217;#{}&amp;#8217; construct, but there really isn&amp;#8217;t a whole lot of need for escape characters and such.  When you have a big message you want to give to the user, this is usually the best way to get it done.  The important thing is that &lt;em&gt;you choose the terminator&lt;/em&gt; so it will never be text in your block.  The characters &amp;#8216;&amp;lt;&amp;lt;-&amp;#8217; basically tell ruby to keep adding lines to the string until we reach X where X is the terminator.  In my example, I chose the word &lt;span class="caps"&gt;END&lt;/span&gt; in all capital letters, but you could just as well use &lt;span class="caps"&gt;TERMINAR&lt;/span&gt; or &lt;span class="caps"&gt;BATTLE&lt;/span&gt;_FLAG or any other gibberish you want.  The string will start on the following line and continue until it hits the terminator you set up.  Just make sure it is clear what you are doing so that when you come back to the code later you aren&amp;#8217;t thinking What in the world did I do?&lt;/p&gt;</description>
      <pubDate>Wed, 06 Aug 2008 11:53:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:242f9095-b6c9-498c-bcd8-f40f2526d9c3</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/08/06/ruby-collections-and-other-fun-stuff</link>
      <category>programming</category>
      <category>ruby</category>
      <category>newbie</category>
      <category>containers</category>
      <category>using</category>
      <category>objects</category>
    </item>
    <item>
      <title>Intro to Programming with Ruby</title>
      <description>&lt;p&gt;First of all, &lt;a href="http://www.ruby-lang.org"&gt;Ruby&lt;/a&gt;  is a programming language that has become pretty popular with the advent of &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; .  That said, Ruby is a great first programming language to learn.  I won&amp;#8217;t bore you with it&amp;#8217;s history, even though the language has been in existence for over a decade.  For the summary about Ruby, check out &lt;a href="http://www.ruby-lang.org/en/about/"&gt;http://www.ruby-lang.org/en/about/&lt;/a&gt;  and also look at the different tutorials.  This tutorial is meant for people who don&amp;#8217;t know squat about programming.  If it&amp;#8217;s confusing at all, let me know in the comments.&lt;/p&gt;


	&lt;p&gt;Before we delve into objects and things like that, let&amp;#8217;s consider what happens when we have to use Ruby to help with other tasks.  Those tasks can be deployment scripts, test support, etc.  One of the most important things you will learn has nothing to do with actually making stuff work.  It&amp;#8217;s the comment.  Basically you want to leave notes for yourself so that you can get back into the swing of things after you leave something alone for a while.  To do that with Ruby, all you need is the &amp;#8217;#&amp;#8217; symbol.  It marks the beginning of a comment, and the comment is over at the end of the line.&lt;/p&gt;


&lt;pre&gt;
#
# A block of comments looks like this, with a '#' symbol
# at the beginning of every line.  Comments are supposed
# to help you remember things later on.
#
&lt;/pre&gt;

	&lt;p&gt;Start with good commenting habits, and keep them up.  Some things are pretty self explanatory so make sure you document the big things and not what every line is doing.  Remember that these are clues you leave to yourself, or anyone else who will work with the code about what&amp;#8217;s going on.&lt;/p&gt;


	&lt;p&gt;Now, Ruby is an object oriented language, but before I get into making objects let&amp;#8217;s look at what they can do for you.  In Ruby, everything is an object&amp;#8212;your numbers, ranges, collections, etc.  To help wrap your brain around objects, think of them as &amp;#8220;things&amp;#8221;.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Objects are things you can tell what to do.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Let&amp;#8217;s say you need something to be done five times.  The number five is an object, which means you can tell it to do something for you. &lt;a href="http://www.ruby-doc.org/core/"&gt;Core Ruby Doc&lt;/a&gt;  has all the standard objects that are part of the language, but it can be a little overwhelming at the beginning.  First of all, the number five is an Integer (there are no decimal points so math people tell us that the correct name is an Integer).  If you look up Integer in the Ruby docs, you&amp;#8217;ll find that a list of things that it can do.  There are two that look pretty interesting to us, but for now we just want to do something five times.  Here&amp;#8217;s how we do it:&lt;/p&gt;


&lt;pre&gt;
5.times do |num|
    puts 'Do something!'
end
&lt;/pre&gt;

	&lt;p&gt;Ok, what&amp;#8217;s going on here?  The number five is an object, and the &amp;#8221;.&amp;#8221; symbol means &amp;#8220;tell the object to do something&amp;#8221;.  The name after the &amp;#8221;.&amp;#8221; is what we are telling it to do.  So we are basically saying &amp;#8220;Number 5, I want you to .times&amp;#8221;.  OK, so we are missing part of the picture.  That part is the &lt;code&gt;do&lt;/code&gt; block.  Everything between the &lt;code&gt;do&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; is also being passed along with the message &amp;#8221;.times&amp;#8221;.  Let&amp;#8217;s call the &amp;#8221;.times&amp;#8221; message a method.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A method is something you can tell an object to do.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Continuing on, we have the &lt;code&gt;do&lt;/code&gt; block followed by some pipe symbols &amp;#8221;|&amp;#8221; and a name in the middle.  This is how the number 5 passes something back into your &lt;code&gt;do&lt;/code&gt; block so that you can use it.  The name you give this something is called a variable.  You can use it or ignore it, it&amp;#8217;s up to you.  We are ignoring it for now, but if we want to use it, we just have to use that name.&lt;/p&gt;


&lt;pre&gt;
5.times do |count|
    puts 'Do something on time ' + count
end
&lt;/pre&gt;

	&lt;p&gt;What you see will change based on the value of the variable &amp;#8220;count&amp;#8221; that the number 5 is giving us.  The documentation tells us that the number will start at 0 and go to just under our number.  So we will see five lines counting up from 0 to 4.  A lot of programming languages do this, so it&amp;#8217;s just something you have to get used to.  Everything between the &lt;code&gt;do&lt;/code&gt; and the &lt;code&gt;end&lt;/code&gt; markers gets run each time.  The important thing is that the variable you named inside the &amp;#8221;|&amp;#8221; symbols is how you use that variable.&lt;/p&gt;


	&lt;p&gt;OK, we are taking some baby steps here, but I&amp;#8217;ll stop for today.  First of all, we learned that things are called Objects and we tell Objects what to do by calling Methods (some people call them messages, but other languages use the word Method so we are just being consistent).  We also learned that you could pass in a whole block into a method and have that object run that block for us.  We learned that when we pass in a block to an object&amp;#8217;s message, it can pass something back into our block so that we can use it.  I want to point out that the whole &amp;#8220;pass a block of code&amp;#8221; thing is something that not every language can do.  For instance at the time I am writing this, Java, C#, and C++ can&amp;#8217;t do that.&lt;/p&gt;


	&lt;p&gt;Lastly, I want to start you thinking about something.  The best code is self documenting, but it will never read like a book.  As long as the details are clear, all you have to worry about in your comments is &lt;em&gt;why&lt;/em&gt; you are doing something five times.  With the last snippet of code above, it almost reads like English.  We are saying &amp;#8220;five times do something using &amp;#8216;count&amp;#8217;&amp;#8221;.  The word &amp;#8220;puts&amp;#8221; is actually a method on the text console object.  Ruby makes some assumptions to make the code a little more readable.&lt;/p&gt;</description>
      <pubDate>Mon, 28 Jul 2008 12:12:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f653b593-6812-41bc-a976-ad86be060d71</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/07/28/intro-to-programming-with-ruby</link>
      <category>ruby</category>
      <category>tutorial</category>
      <category>loops</category>
      <category>intro</category>
      <category>objects</category>
      <category>methods</category>
      <category>blocks</category>
    </item>
    <item>
      <title>What's the Minimum Requirement for a Successful Project?</title>
      <description>&lt;p&gt;This is in preparation for a newbie series on the Ruby language; however, it&amp;#8217;s included for your benefit here.  There are certain things that any project needs to keep track of if it is going to be successful:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;What needs to be done?&lt;/li&gt;
		&lt;li&gt;What was done?&lt;/li&gt;
		&lt;li&gt;And how close are we to being done?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I&amp;#8217;m going to avoid all the project management and tech speak as much as possible.  For you college students, pay attention, if you aren&amp;#8217;t doing these things you are writing a recipe for disaster.  So let&amp;#8217;s look at these things one by one.&lt;/p&gt;


	&lt;h2&gt;What needs to be done?&lt;/h2&gt;


	&lt;p&gt;To answer the question you need to ask yourself, &amp;#8220;if I get nothing else done what will make me successful?&amp;#8221;  These things are called &lt;em&gt;requirements&lt;/em&gt; and every project has a different focus, so the requirements will not be the same.  The next thing you have to ask yourself, &amp;#8220;what is standing in between me and something I am proud to show off?&amp;#8221;  These things are called &lt;em&gt;issues&lt;/em&gt; and they can be your own doing, or they can be external forces.  Now, you can lump everything together, because you have to address both your requirements and your issues in any given release.  A &lt;em&gt;release&lt;/em&gt; is a version of what you are doing that addresses a list of things&amp;#8212;whether they are requirements or issues.  It&amp;#8217;s kind of a package deal.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve managed a few projects where we put everything in an issues list, and assigned version numbers to those things.  The issues could be further classified into requirements, enhancements (aka new requirements), bugs (mistakes we made), configuration problems (environment problems), and risks (something that may or may not happen that we need to be aware of).  The important thing is that you assign these things to a version so that you can have an idea of what the package is.  The complete list of things to be done is your release, and as you knock them off, you can see how close you are to making a release.  The list can grow as your are working and new bugs come up, or the people you are writing the application for come up with something new.&lt;/p&gt;


	&lt;h2&gt;What was done?&lt;/h2&gt;


	&lt;p&gt;To track what was done, you not only need to track how you are doing in your issues list, but you also need to make sure that your workspace (source code, etc.) matches what you said is done.  You need to make sure that when you have a number of people working together on the same project, that no one accidentally deletes someone else&amp;#8217;s work or added something extra.  For software projects, the chief tool to keep track of what was in older releases and merging multiple people&amp;#8217;s work together is called a version control system.  Some common free version control systems include &lt;acronym title="Concurrent Versioning System"&gt;CVS&lt;/acronym&gt; and Subversion.  For software projects, there really is no excuse for not using a tool for version control.  The two listed are free open source projects, and the second one is a little better to manage.  There are commercial software projects, but the important thing is that you are using something other than people to manage the process.  Your version control software has to support the following functions:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Tagging (marking a set of code at a version in history so you can say what was done for a previous release)&lt;/li&gt;
		&lt;li&gt;Merging (when more than one person is working, their work should be merged into the controlled version and not just replacing the whole file)&lt;/li&gt;
		&lt;li&gt;Logging (every commit should have a message summarizing what was included in the change)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Document management systems usually don&amp;#8217;t support tagging and merging.  They just keep a history of versions of a document.  They also usually require you lock a file so that no one else can touch it while the changes are happening.  While that may be necessary when you are working with word processor documents, with source code it is an unnecessary restriction that gets in the way of doing work.&lt;/p&gt;


	&lt;p&gt;So how do we make sure we did what we said we did?  You test.  Testing is essentially checking the application is doing what we expect it to do.  You can do testing manually, automatically, or some combination of the two.  The best option is to combine automated testing with manual testing.  The automated testing will always check the &amp;#8220;blessed path&amp;#8221; or expected way to use an application.  That way you make sure you don&amp;#8217;t accidentally break something with new changes.  The manual testing (people actually using the application) will have people trying to break it or abuse the system.  If they succeed in breaking it in an unexpected way you have a new bug and a new automated test to deal with.&lt;/p&gt;


	&lt;h2&gt;How close are we?&lt;/h2&gt;


	&lt;p&gt;Hopefully, the list of open issues is getting smaller and the number of passing tests is increasing.  Eventually, the number of open issues for a release will reach zero, and all the new stuff will be fully tested and given the green light.  That&amp;#8217;s when you know you are ready to cut a new release.  It helps to chunk up the work so that you can get a feel for how close we are getting a little at a time.  Let&amp;#8217;s say you have a long list of things for a release, and you think it&amp;#8217;s going to take about six months to get it all done.  If you wait until the end of those six months to begin checking your work, you are probably going to get overwhelmed with the list of things that went wrong.  It&amp;#8217;s better to break up the work into smaller chunks.&lt;/p&gt;


	&lt;p&gt;I find that one or two week cycles give a good balance between getting the work done and testing early.  If you do too much work before testing, it will take a lot of work to fix the problems.  If you do too little work before testing the work becomes tedious and unpleasant.  It&amp;#8217;s best to have a good battle marching speed to do little mini releases so that people testing will be able to catch and report problems before they get too big.&lt;/p&gt;


	&lt;p&gt;For any project where money is involved (i.e. just about anything other than an open source project) it&amp;#8217;s important to see how close you are to your estimate.  Unexpected problems can really affect when you get the work done.  Let&amp;#8217;s say you are marching along really well and it looks like you might even beat your 6 month deadline, but suddenly the database is imploding under the work load.  Now you have to find out why it&amp;#8217;s misbehaving and fix it.  The problem might be a configuration problem, or it might be that you have too little database for your application, or it might be that you are doing too much with the application.  Finding the problem and fixing might set you back a month, so meeting that six month deadline is starting to look like a pipe dream.  Now you have to figure out how you are going to handle the schedule problem.  You can move the schedule, change what&amp;#8217;s required for the release, change the way you are doing things to speed it up, or make people work longer.  There&amp;#8217;s a physical limit to how long people can work, and the longer the work the exponentially more inefficient they become.  If you can work smarter instead of harder, go for it.  It will help you with the next release.&lt;/p&gt;


	&lt;p&gt;With open source projects, the schedule is less of an issue, and things are released when they are ready.  However, if someone wants to help out and start helping, it&amp;#8217;s always best to give a clear answer of what you are trying to do.  If they can see the list of issues and help get it done quicker, more power too them.&lt;/p&gt;</description>
      <pubDate>Mon, 21 Jul 2008 15:15:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:e84caccd-e9fd-46df-989e-680bce038e54</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/07/21/whats-the-minimum-requirement-for-a-successful-project</link>
      <category>process</category>
      <category>development</category>
      <category>simplified</category>
      <category>easy</category>
      <category>required</category>
    </item>
    <item>
      <title>Testing and Choosing Your Process</title>
      <description>&lt;p&gt;&lt;em&gt;Process&lt;/em&gt; .  It&amp;#8217;s a dirty word around some people.  All it means is &amp;#8220;A way to get something done&amp;#8221;.  Nothing more, nothing less.  However, we have things like &lt;span class="caps"&gt;ISO 9001&lt;/span&gt;, &lt;acronym title="I"&gt;CMM&lt;/acronym&gt;, Agile, XP, Scrum, etc. all presenting themselves as &lt;em&gt;the way&lt;/em&gt; to develop your software.  Each has it&amp;#8217;s benefits and drawbacks, and each works with a different kind of client.  If you hear anyone tell you that their way to do things is better, faster, etc. than anything you are doing without knowing the details you know you are dealing with a snake oil salesman.  Even within the &lt;span class="caps"&gt;CMMI&lt;/span&gt; framework, there is a lot of leeway for you to have a heavy process or an agile process.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&lt;em&gt;Process&lt;/em&gt; is just a way to get things done.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I&amp;#8217;ve heard of some people&amp;#8217;s software development process as &amp;#8220;write a little code, run the app, write a little more code, and so on.&amp;#8221;  That process can work for some people, but not for everyone.  I happen to be a fan of Test Driven Development coupled with Continuous Design&amp;#8212;a fairly Agile approach.  However, I know there is a lot of people who just can&amp;#8217;t think that way.  That&amp;#8217;s fine.  We just probably won&amp;#8217;t be working on the same projects.&lt;/p&gt;


	&lt;h2&gt;Manual Process vs. Automatic Process&lt;/h2&gt;


	&lt;p&gt;The first aspect software development process is finding the right ratio between things you do manually, and things that the process takes care of for you&amp;#8212;as a side effect of just doing the process.  We programmers tend to be lazy, and so we do whatever is easiest on us to do.  Ironically, we are so lazy sometimes that we would rather not invest the time to set up the automation unless there is a clear reason to do so.  It&amp;#8217;s actually a good thing because too much automation can get in the way of making changes.  Of course, manual processes don&amp;#8217;t scale very well.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Anything you do manually is something you have to remember to tell someone else.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;When you are working alone, you can take all the shortcuts you want because you don&amp;#8217;t have to explain what you are doing.  The problem comes when you add someone to your team.  All the things you were doing you now have to explain to someone else and get them to do it, or it won&amp;#8217;t get done.  Heck, sometimes you either forget a step even when you are by yourself.  It&amp;#8217;s for that reason we even consider automation.  The places where we have the best benefit from using tools include configuration management and creating builds.  I wouldn&amp;#8217;t imagine writing any code without version control software of some sort even if I&amp;#8217;m by myself.  The versions are managed for you so you can go back to a release to reproduce issues if necessary, the code is backed up and managed beyond your own hard drive, and as soon as you add more people to the team it takes care of merging code for you.  The benefits far out way the alternative.  Creating a build might be easy or difficult depending on the structure of the complete application.  The build process will create your distributables and run any tests you have included.  Tools include Make, Rake, Ant, etc. and have differing levels of complexity.  The important aspect is that you aren&amp;#8217;t relying on someone else to make the identical configuration settings in their &lt;span class="caps"&gt;IDE&lt;/span&gt; to get the same executable.  It&amp;#8217;s all taken care of by the script.&lt;/p&gt;


	&lt;p&gt;There are other areas where automation can help out, but it does depend on the culture of the project, and the ease of setting it up.  How do you manage your issues?  Many tools generate reports just from how you use the application.  You can show how quickly you are burning through your issues, and you can see how fast or slowly you are approaching the completed release.  Sometimes you can add flags to the tool to notify you if values are outside a certain set of parameters.&lt;/p&gt;


	&lt;h2&gt;Testing your Process&lt;/h2&gt;


	&lt;p&gt;In any software project there are number of things you have to keep track of, and your process (the way you get things done) should make it easier.  So how do we know if the process is working or not?  You have to start by identifying what&amp;#8217;s important.  What is going to make your client lose confidence in you?  If you do nothing else, what has to be done?  Do you really need full Earned Value Management (EVM) or can you get away with proving you are making progress at the expected rate.  Many times it&amp;#8217;s enough just to know when you are falling behind.  One thing that&amp;#8217;s a must in any process is that you produce the deliverables.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt; If anything important slips through the cracks, your process is broken.  Period.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Once you&amp;#8217;ve identified the important stuff you can&amp;#8217;t miss, you keep track of it.  So how do I do that?  You do your process.  If you can ensure your process takes care of tracking the important stuff, all the better.  Keeping track of something is what some people call &amp;#8220;metrics&amp;#8221;.  The thing I don&amp;#8217;t like about metrics is that you are essentially associating numbers to parts of your process.  Numbers people like metrics because they have something to play with.  The reality is that numbers don&amp;#8217;t mean anything at all.  Trends mean something, numbers don&amp;#8217;t.  If you are getting better, (i.e. your trend is going in the right direction), your process is working.  If you are getting worse, (i.e. your trend is going in the wrong direction), your process needs to be fixed.&lt;/p&gt;


	&lt;p&gt;So how do you track trends, and when does a change really mean something?  The tricky thing with trends is that if your sample is too short you might make adjustments that are not warranted, but if the sample is too long you won&amp;#8217;t make the adjustments soon enough.  There is no substitute for your gut feeling when you are just starting to track how well your process is working.  The trick is not to be alarmist, and make proper adjustments.  It&amp;#8217;s like learning to drive for the first time.  You either make too many large adjustments and overcompensate, or you make too many small adjustments.  The good news is that you aren&amp;#8217;t going to crash right away.&lt;/p&gt;


	&lt;p&gt;There are a few things that process people (you know those heavy process proponents) forget to look at while they are testing their process.  How much work is needed to feed the process, vs. how much work is spent actually making deliverables?  If you need 5 people that do nothing other than track the project&amp;#8217;s progress when you have a team of 3 developers generating code, there&amp;#8217;s something a little off-kilter.  Notice that I said the 5 people are feeding process.  Ensuring you have a quality product is work that&amp;#8217;s done for the deliverable.  Ensuring you have a quality code review is not.  That&amp;#8217;s &amp;#8220;meta-work&amp;#8221; or work about work.  It&amp;#8217;s stuff done to feed the process.  Even the discipline of code reviews can be brought into question as long as you gain the benefit another way.  A cod review is merely a means to both mentor other team members and ensure the quality of the product.  If your process handles those benefits in other ways, then you don&amp;#8217;t need a formal code review.&lt;/p&gt;


	&lt;h2&gt;Fixing a Broken Process&lt;/h2&gt;


	&lt;p&gt;If you are like me, then you really won&amp;#8217;t wonder about how you fix a broken process.  You just make the changes on the fly and the process evolves.  You know these &amp;#8220;lessons learned&amp;#8221; meetings people have that dig up all the surprises and issues that we ran across?  Are you merely identifying lessons, or are you actually learning them?  If a technology choice turned out to be bad, how can you make sure the same mistake doesn&amp;#8217;t happen again?&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;You haven&amp;#8217;t really learned a lesson unless you did something to correct it.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;If you discover that something you are doing isn&amp;#8217;t lending any value whatsoever, you shouldn&amp;#8217;t be doing it anymore.  The advantage of changing your ways vs. logging issues is that it actually fixes the cause of your heartburn.  Logging an issue helps you vent and get things off your chest, but it&amp;#8217;s still there until you actually do something about it.  That&amp;#8217;s why the traditional &amp;#8220;lessons learned&amp;#8221; meetings don&amp;#8217;t work.  They let people vent, and then nothing is done about it.  &amp;#8220;Yeah, that was painful.  We&amp;#8217;ll be doing it again next go &amp;#8216;round too.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;One of the biggest lessons I learned is that waiting until a &amp;#8220;lessons learned&amp;#8221; meeting to vent is waiting too long.  If you are experiencing some heartburn now, fix it now.  If you spend more time collecting numbers than you do using those numbers (um, I mean metrics), then just how important are those numbers in the grand scheme of things?  Can you find another way of collecting those numbers?  It&amp;#8217;s funny, but machines are much better about collecting them than people are.  There&amp;#8217;s probably some way of making those numbers be a byproduct of how you do things.  In essence, if you can make your tools support the way you do things and keep track of the numbers for you, you are better off.  As long as you are depending on people to actually log numbers, you are depending on the most unreliable source for numbers.  It&amp;#8217;s a pain to keep track of them.  Even if we only need to type them into a form, it&amp;#8217;s still a pain to keep track of them.  Let your tools do all the data entry for you.&lt;/p&gt;


	&lt;p&gt;The bottom line is prove you need to change, change, and then prove your change is helping.  It&amp;#8217;s &lt;span class="caps"&gt;TDD&lt;/span&gt; for process.  If you see a bad trend and the process is the culprit, prove it.  Then decide what a good trend would be.  Make your changes and see how close you are to the results you want.  You may find that your change is &amp;#8220;close enough&amp;#8221;, in which case you are done.  Of course, you may find that you just introduced more work than the way of doing things, in which case you revert back or make a different change.&lt;/p&gt;</description>
      <pubDate>Wed, 09 Jul 2008 13:27:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:003d3436-d41e-4c3c-81a1-95b10012cadd</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/07/09/testing-and-choosing-your-process</link>
      <category>process</category>
      <category>testing</category>
      <category>fixing</category>
      <category>tracking</category>
    </item>
    <item>
      <title>Test Driven Development 101</title>
      <description>&lt;p&gt;I&amp;#8217;m back after a long hiatus, and I&amp;#8217;m probably talking to the air right now, but that&amp;#8217;s OK.  For the two or three of you actually listening to me, listen on.  We have a number of projects of different sorts at the company I work for, and you&amp;#8217;d be surprised at how few do test driven development&amp;#8212;and how few even write unit tests.  In this day and age, not writing tests that can be automated at all is inexcusable.  At the very least, the tricky stuff should be thoroughly tested.  This article is for anyone who is either skeptical about or interested in Test Driven Development.  That includes managers as well as developers.&lt;/p&gt;


	&lt;h2&gt;What&amp;#8217;s the Problem, Man?&lt;/h2&gt;


	&lt;p&gt;We all ( at least &lt;em&gt;should&lt;/em&gt; ) want to write quality software, and we will take this as the &amp;#8220;given&amp;#8221; in geometry.  Since we want to write quality software, how do we do it?  In the early cowboy days of software engineering, it was painful to write code.  First you did all your planning, wrote what you hoped would work, printed the stacks of punch cards, and then loaded it on the main frame.  Which explains all the texts on the huge design up front methodology.  However, that was before my time.  When I first started, we wrote a little, ran the software, and debugged.  Which explains why debuggers were so important at that time.  However, times have changed.  We now have a &lt;a href="http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks"&gt;plethora of unit testing frameworks&lt;/a&gt;  and maintainable build scripts to incorporate the tests into the build process.&lt;/p&gt;


	&lt;p&gt;As soon as we ran into some hard problems that really couldn&amp;#8217;t be completely designed up front (like &lt;span class="caps"&gt;TCP&lt;/span&gt;/IP stacks), we developers had to figure out a way to make sure things worked properly.  I mean, the spec is pretty complete, but there are a lot of details and practical limitations imposed by hardware that you won&amp;#8217;t find in the spec.  If you attempted to alter the spec to include all these corner cases, you would also lose any way of understanding how it is supposed to work.  This is how the automated unit test was born.  All these corner cases had to be accounted for so that future changes to the code won&amp;#8217;t break the existing functionality.  I think everyone recognizes the importance of testing.  It&amp;#8217;s just how, when, and where testing happens that people disagree on.&lt;/p&gt;


	&lt;p&gt;Another problem that is often brushed under the table is code slipping in that doesn&amp;#8217;t need to be there.  How often have you tracked down a problem only to discover code that was never supposed to exist be the culprit.  You remove the offending code, and &lt;em&gt;viol&#225;&lt;/em&gt; it works!  The code could have been there from old legacy requirements that no longer apply, or it could be a developer without experience over thinking a problem.  Nevertheless the code is there and it is causing problems.&lt;/p&gt;


	&lt;p&gt;If you adopt a clean as you go philosophy to developing software, you had better make sure you don&amp;#8217;t accidentally breaking anything as you refactor your code.  Even with &amp;#8220;safe&amp;#8221; refactoring, there is an inherent risk that you can inadvertently break something you didn&amp;#8217;t think you would.  If only there was a way to make sure all the important functionality keeps working&amp;#8230;.  Oh yeah, you do have a full test suite don&amp;#8217;t you?  Oh, it didn&amp;#8217;t get written because you were under the gun and you were on a roll?  Too bad.&lt;/p&gt;


	&lt;p&gt;Test Driven Development (TDD) was designed to not only address these issues, but to instill a discipline so that your unit tests would get written.  Let&amp;#8217;s face it, all people are lazy.  It&amp;#8217;s in our nature to not do anything we think is a waste of time.  Sure we&amp;#8217;ll do a little work now to avoid a bunch of work later, but we need to know it really is going to avoid a bunch of work later.  What some people fail to realize about &lt;span class="caps"&gt;TDD&lt;/span&gt; is that the time will be spent somewhere.  Either you write your tests up front or you spend time in a debugger later.  Either you prove that your approach will work now, or you do it later.  Either you break up your work into testable chunks now, or you attempt to do it later and fail at it.&lt;/p&gt;


	&lt;h2&gt;OK, So How Does It Work?&lt;/h2&gt;


	&lt;p&gt;At its heart, &lt;span class="caps"&gt;TDD&lt;/span&gt; is pretty simple&amp;#8212;you simply perform a prove, fix, prove cycle.  First you &lt;em&gt;prove it doesn&amp;#8217;t work&lt;/em&gt; .  Then you &lt;em&gt;fix&lt;/em&gt; the problem.  Finally, you &lt;em&gt;prove your fix worked&lt;/em&gt; .  If you are lucky, your first &amp;#8220;prove&amp;#8221; step will prove the code already handles what you were thinking about.  Write the test anyway, because you need to make sure that any changes will still support that test case.  It&amp;#8217;s fairly easy to see how to perform the mechanics of &lt;span class="caps"&gt;TDD&lt;/span&gt;, but less about it&amp;#8217;s design implications without a little more explanation.&lt;/p&gt;


	&lt;p&gt;One of the side-effects of writing your tests before you write code is that it makes your code easier to test.  Remember, people are lazy?  Since a proper unit test sets up the environment and checks the effect of the call after, we make it easy to set up the environment.  In fact, the less we rely on network connectivity or environment variables, the better.  If a bit of code can be tested just by passing objects into it and examining the return value, then you aren&amp;#8217;t going to be overly clever in your implementation.  Easily testable code, also happens to be more modular.  If you can pass in a mock object for something that would normally talk to the network so that you can have the mock imitate the situations you would encounter there, you can more easily test just the small unit you are working on.&lt;/p&gt;


	&lt;h3&gt;Unit Tests vs. Integration Tests&lt;/h3&gt;


	&lt;p&gt;In the best of all worlds, a project would have both.  Unit tests make sure that the smallest unit (such as a method on a class) is doing what we expect it to do.  A proper unit test also tests only one aspect of that method.  It&amp;#8217;s not uncommon to have several tests for the same method to make sure that all the corner cases are taken care of.  Integration tests make sure all the different units work together like we thought they would.  A unit test uses mock objects to isolate the thing we are testing from everything else.  An integration test sets up the complete environment and runs the test against that environment.  They are different tools for different problems.  To do &lt;span class="caps"&gt;TDD&lt;/span&gt;, unit tests are required, but additional testing is a plus.&lt;/p&gt;


	&lt;p&gt;More often than not, code that is properly unit tested will work just fine.  However, there are some issues that only crop up when the whole system is put together.  Perhaps there is some race condition, or some complicated event loop that only appears in certain conditions.  Once you track down the cause of the problem, you can write a unit test to reproduce the condition that caused the mess in the first place.  With the new unit test, you fix the code, and everything should work in integration again.&lt;/p&gt;


	&lt;p&gt;Many times, the integration tests are all done manually.  The challenge is that it is hard to set up a complete environment, test the user interface or system messaging, and evaluate the results automatically.  The problem is that over time the number of tests that people have to do for a release becomes daunting.  People are less picky than machines.  If there is a tool to support integration testing like &lt;a href="http://selenium.openqa.org/"&gt;Selenium&lt;/a&gt;  or some other testing framework, use it to at least catch regression issues.  You know those issues where you accidentally break something that used to work when you add a new feature?  Anything that was working and gets broken needs to be tested every time.  Machines are good at doing rote repetition like that.&lt;/p&gt;


	&lt;h3&gt;Battle Rhythm&lt;/h3&gt;


	&lt;p&gt;When you sit down and start &lt;em&gt;doing&lt;/em&gt; TDD, you&amp;#8217;ll develop a battle rhythm.  Most IDEs these days have support for running your unit tests without going through the whole build process.  It&amp;#8217;s pretty convenient, and it makes &lt;span class="caps"&gt;TDD&lt;/span&gt; a lot easier to do.  So, you&amp;#8217;ve got a new requirement and you need to get it working.  It&amp;#8217;s good to have a general idea of where you want to go, or how it is supposed to work, but don&amp;#8217;t be a slave to that idea.  We start writing the unit test at the easiest place it is to begin&amp;#8212;whatever that may be.  I personally find it is best to start with the &lt;em&gt;happy path&lt;/em&gt; (the path where everything works as expected).  For example, look at the pseudo code below:&lt;/p&gt;


&lt;pre&gt;
Test String is a URL
--------------------
1. Use the string "http://bloritsch.d-haven.net" 
2. Pass the string to the String Utility "isURL" method
3. Assert the response is "true" 
&lt;/pre&gt;

	&lt;p&gt;Of course, it&amp;#8217;s pretty easy to make this one test pass.  All we have to do is write the &lt;code&gt;StringUtility.isURL()&lt;/code&gt; method to simply return true.  No evaluation or anything.  When we run the test, we prove that solution is good enough for now.  So we need to start thinking about the next test.  What if the string is not a &lt;span class="caps"&gt;URL&lt;/span&gt;?  So we add the next test:&lt;/p&gt;


&lt;pre&gt;
Test String is NOT a URL
------------------------
1. Use the string "I'm not a URL, ignoramus!" 
2. Pass the string to the String Utility "isURL" method
3. Assert the response is "false" 
&lt;/pre&gt;

	&lt;p&gt;Now we&amp;#8217;ve proven we have some work to do.  So we change StringUtility to return true if the string starts with &amp;#8220;http:&amp;#8221;.  It&amp;#8217;s the simplest thing, right?  But what if we want to include &lt;span class="caps"&gt;SSL&lt;/span&gt; encrypted URLs, or mailto URLs?  So you add tests for them, and make them pass&amp;#8212;without breaking the other tests you&amp;#8217;ve written.  All these tests are cumulative, so while they may have been extra work at the beginning, they can save your bacon later.  Don&amp;#8217;t forget about those corner cases, what if the string is &lt;code&gt;null&lt;/code&gt; ?  Etc.&lt;/p&gt;


	&lt;p&gt;By the time you are done with this method, you&amp;#8217;ll have done the following things without even realizing it:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Documented what you consider a &lt;span class="caps"&gt;URL&lt;/span&gt; and what is not a &lt;span class="caps"&gt;URL&lt;/span&gt; (design documentation side-effect)&lt;/li&gt;
		&lt;li&gt;Proven the design works (design proof side-effect)&lt;/li&gt;
		&lt;li&gt;Tested the implementation (implementation proof)&lt;/li&gt;
		&lt;li&gt;Provided a safety net to do refactoring (supporting implementation malleability)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Sure the method is just a part of the overall design, but you&amp;#8217;ve thought about and decided how the method is going to be used from the perspective of someone using the method.  It&amp;#8217;s a shift in thinking from being the &amp;#8220;implementer&amp;#8221; of the method, which usually results in code that is easier to use elsewhere.  You&amp;#8217;ve also introduced a level of trust in this method that you wouldn&amp;#8217;t have if you just reached for that regular expression you found on the net to determine if something is a &lt;span class="caps"&gt;URL&lt;/span&gt; or not.  You&amp;#8217;ve also introduced a boundary where the implementation can be as simple or complex as you want&amp;#8212;but code that uses the method won&amp;#8217;t care about those details.&lt;/p&gt;


	&lt;p&gt;The battle rhythm of proving, fixing, and proving actually improves your development speed.  It may not seem like it at first, but by testing all along the way we&amp;#8217;ve minimized the time we will have to spend in a debugger.  The ramp up time is a little slower, but as you get your battle rhythm going, you stay at a constant pace.  Without &lt;span class="caps"&gt;TDD&lt;/span&gt;, I find myself working with bursts of productivity interrupted by long periods of finding out exactly where I went wrong in a debugger.  With &lt;span class="caps"&gt;TDD&lt;/span&gt;, I find myself working at a steady pace, and those occasions where I missed something I spend much less time in the debugger.  Once I&amp;#8217;ve discovered the culprit, I add the test case that reproduces the error condition and then make it work.  Now, when I refactor code I can make sure I don&amp;#8217;t reintroduce the problem accidentally.&lt;/p&gt;


	&lt;h2&gt;Silver Bullet?&lt;/h2&gt;


	&lt;p&gt;There is no silver bullet, and no golden hammer that will make things work perfectly the first time.  There are only tools that help you get closer to the ideal.  &lt;span class="caps"&gt;TDD&lt;/span&gt; is a tool that helps improve quality from the start.  Most detractors of &lt;span class="caps"&gt;TDD&lt;/span&gt; look at the claims of documenting your design as being false&amp;#8212;or at least unreadable to normal people.  I may give them that argument, but &lt;span class="caps"&gt;TDD&lt;/span&gt; isn&amp;#8217;t about documenting design, it&amp;#8217;s about building a better quality product with the minimal amount of investment.  It&amp;#8217;s about improving your productivity over the course of a software project.  It&amp;#8217;s about reducing the number of &amp;#8220;doh!&amp;#8221; bugs to virtually none saving your brain cells for the more complex problems.  Finally, it&amp;#8217;s about minimizing the risk involved in refactoring or even rewriting your software.&lt;/p&gt;


	&lt;p&gt;All of these benefits are things that the text books say are a good thing.  It&amp;#8217;s also done in a way that is less painful to developers.  Writing documentation is a pain in the butt, however, writing test cases is something that directly benefits the developer.  It benefits the project over it&amp;#8217;s period of performance.  Bottom line?  More bang for the buck.&lt;/p&gt;</description>
      <pubDate>Thu, 03 Jul 2008 11:47:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:790038c5-b23f-43bc-8054-d49ee5e8eb31</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/07/03/test-driven-development-101</link>
      <category>TDD</category>
      <category>test</category>
      <category>driven</category>
      <category>development</category>
      <category>methodology</category>
      <category>software</category>
    </item>
    <item>
      <title>No Fear</title>
      <description>&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/bloritsch/2444042108/" title="No Fear (1949-dektol-oriental-fb-0002) by Berin Loritsch, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3085/2444042108_4193079c4f.jpg" width="357" height="500" alt="No Fear (1949-dektol-oriental-fb-0002)" /&gt;&lt;/a&gt;&lt;br/&gt;&lt;em&gt;No Fear&lt;/em&gt;&lt;/div&gt;

	&lt;p&gt;How often do you see something cool, and take a picture of it?  How often does it resurface 60 years later?  Yep, this picture is another from the set of pictures my grandparents took around 1949.  I think it is quite telling how no one thought it strange to take a camera to a pool back in the day, but now it&amp;#8217;s an international crime.&lt;/p&gt;


	&lt;p&gt;No doubt this gentleman was showing off for the ladies.  No matter how strong you are, you can only hold a pose like that for so long.  Without all the modern gadgetry of today, my grandma was able to take this picture quickly enough.  When photographing people you do have to be ready.  The camera was loaded, and probably set for a reasonable exposure given the time of day.  All that was needed was to cock the shutter (if it wasn&amp;#8217;t a press type shutter that was self cocking) and release it.  Advance the film and be ready for the next one.&lt;/p&gt;


	&lt;p&gt;Is there anything that could have done better?  Absolutely, but what&amp;#8217;s done is done.  I think in this instant age where everything is done for you, the effort to retry is so little that people tend not to be as critical as they should be before pulling the trigger.  The really good picture is lost in a sea of mediocre pictures, and will likely never see the light of paper.&lt;/p&gt;


	&lt;p&gt;Quite frankly, quantity is the enemy of excellence.  I&amp;#8217;ve taken literally thousands of pictures, and more than half of them are really good&amp;#8212;some excellent.  However, the pain of going through them all will likely cause them to never really get any special treatment.  Wall space is more precious than album space, which is in turn more precious than hard drive space or negative storage space.  While I publish far fewer pictures and take far fewer pictures now, the ones I do take are on average better than when I took several at a time.  This fact doesn&amp;#8217;t change whether I shoot digital or film.&lt;/p&gt;


	&lt;p&gt;Don&amp;#8217;t be afraid &lt;em&gt;not&lt;/em&gt; to take a picture if you can&amp;#8217;t make it special.  Have you ever taken a picture of something you thought was amazing, but after you took the picture it looked so-so?  I know I have.  Have you ever taken a step to either side or gotten lower or higher to reveal on film (or digital frame) what you were experiencing?  Do your walkabout quickly to get in position if you can.  A mediocre picture of a spectacular event is is more frustrating to me than not having the right picture of the event.  I&amp;#8217;ve not taken pictures because the moment passed before I found the right position&amp;#8212;but I&amp;#8217;ve also learned from that experience.  I can better anticipate the right perspective now.&lt;/p&gt;


	&lt;p&gt;Don&amp;#8217;t be afraid to make your own decisions about what you like and don&amp;#8217;t like.  There&amp;#8217;s lots of opinions and guidelines about what makes a good picture.  However, if you don&amp;#8217;t like a picture that follows the rules then you don&amp;#8217;t like it.  Break the rules and make something you do like.  That&amp;#8217;s when you develop your own style.&lt;/p&gt;


	&lt;p&gt;Don&amp;#8217;t be afraid to try something different.  Whether it&amp;#8217;s going old school or new school, you can only grow by incorporating new tools or processes.  Just make sure you don&amp;#8217;t try too much too quickly.  Introduce yourself one bit at a time to the new stuff.  Build on what you&amp;#8217;ve learned so far and go a step further.  Don&amp;#8217;t spend thousands of dollars on equipment you&amp;#8217;ll never get around to using.  As you add to your equipment, learn to use the new stuff properly before you get the next thing.&lt;/p&gt;


	&lt;p&gt;Lastly, don&amp;#8217;t be afraid to enjoy what you do.  If all you are doing is worrying about how to make your equipment pay for itself with jobs then it&amp;#8217;s only a matter of time before you get burned out.  Find something that you enjoy, that relaxes you, and don&amp;#8217;t worry about trying to make it pay for itself.  Just have fun.&lt;/p&gt;</description>
      <pubDate>Thu, 01 May 2008 00:24:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:d696b44a-f78a-45d3-8e68-01f13d4bdda3</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/05/01/no-fear</link>
      <category>process</category>
      <category>pictures</category>
      <category>composition</category>
      <category>fun</category>
      <category>film</category>
      <category>digital</category>
    </item>
    <item>
      <title>Printing Family History</title>
      <description>&lt;div style="text-align:center"&gt;
&lt;a href="http://www.flickr.com/photos/bloritsch/2438074792/" title="Test Strips (1949-dektol-oriental-fb-0001) by Berin Loritsch, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2270/2438074792_78f440df08.jpg" width="500" height="354" alt="Test Strips (1949-dektol-oriental-fb-0001)" /&gt;&lt;/a&gt;&lt;br/&gt;
&lt;em&gt;Test Strips on Oriental &lt;span class="caps"&gt;VC FB&lt;/span&gt; Paper&lt;/em&gt;
&lt;/div&gt;

	&lt;p&gt;I got it stuck in my head that I would print all the negatives that I inherited from my grandparents.  These are a treasure trove of years gone by that capture a world we have forgotten about.  Along with these negatives comes some inherent problems.  The negatives are pretty near 60 years old already, and were made before the film base was standardized on something that doesn&amp;#8217;t deteriorate so quickly.  The film is either Kodak Plus-X or Kodak Tri-X (they had several rolls of each).  None of it is &lt;a href="http://en.wikipedia.org/wiki/Safety_film"&gt;safety-film&lt;/a&gt;  which means it isn&amp;#8217;t.  The film format is 127 film.  That means it is not quite as big as modern day medium format or as small as 35mm film.  The negatives are about 4cm wide with some frames 6cm, some 4cm, and some 3cm.  I can&amp;#8217;t find proper sleeves, and the film has a nasty curl due to being stored rolled up in a plastic baggy.&lt;/p&gt;


	&lt;p&gt;Archivists will tell you to make sure you store the film in archivally safe sleeves that are acid-free, buffered, lignin-free, etc.  Lignin is found in paper, cardboard, etc.  Rubber-bands deteriorate and the byproducts also help break down the negatives.  These negatives were stored in a plastic baggy with the original cardboard boxes when available (which is where I got the dates from), or wrapped with rubber bands that were disintegrating.  I can&amp;#8217;t say it&amp;#8217;s archivally safe, but there is no more cardboard or rubber bands anymore.  Due to the storage conditions, some of the negatives are damaged, but most are OK for now.  I really need to find out how to copy the negatives on to standard film.  I&amp;#8217;d rather step up a size rather than down, because I don&amp;#8217;t want to lose any more information than I have to.&lt;/p&gt;


	&lt;p&gt;All that said, several of the negatives are in good shape and almost all are printable.  The picture at the top of this article is one of those pictures.  As you might expect when the person taking the picture (my grandma) is not a professional photographer, many of the negatives present significant challenges.  This negative is losing contrast to the shadow detail, so I have to bump it up on the paper.  This picture requires a #4 contrast filter to bring out any definition.  I may have to go up even more than that, but I think I&amp;#8217;ll live with this.  The quality going to limit how much I can enlarge the picture.  The picture would have been even more striking if grandma thought to reflect a little light up underneath this gentleman.  A large sheet of white paper would do the trick nicely.  Based on the angle of the highlights and the shadow under this guy, it was probably taken around noon.&lt;/p&gt;


	&lt;p&gt;In my insanity to grow my darkroom skills, I decided to use fiber based (FB) papers.  They are similar to resin coated (RC) paper in the sense that it is paper, and it uses a gelatin based emulsion.  Other than that they are completely different.  When RC paper gets wet, it doesn&amp;#8217;t feel any different.  The chemicals only penetrate the emulsion, and thanks to the resin or plastic coating on the paper it does not penetrate the paper.  RC papers are therefore much more convenient in that the process is a whole lot quicker.  FB papers feel different once they are in the solutions.  The paper actually gets wet, and you can feel the fiber of the paper much better.  Glossy also looks different.  The gloss on a FB print is virtually unnoticeable until the print dries, where on RC paper it is ever before you.  It seems that FB paper is more susceptible to dry-down effects.  However, FB paper does take toning better than the RC paper cousins.&lt;/p&gt;


	&lt;p&gt;Bottom line, this will be a good learning process and I will be able to pass on my personal family history to another generation.  Part of the process will be making digital copies as well as copies of the negatives.&lt;/p&gt;</description>
      <pubDate>Thu, 24 Apr 2008 02:42:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:00734cb4-4041-44d2-8886-a16ea318b7b2</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/04/24/printing-family-history</link>
      <category>print</category>
      <category>paper</category>
      <category>resin</category>
      <category>fiber</category>
      <category>history</category>
      <category>family</category>
      <category>archival</category>
      <category>127</category>
    </item>
    <item>
      <title>Presque Isle Lighthouse</title>
      <description>&lt;div style="margin-bottom: 10px;text-align:center;"&gt;
&lt;a href="http://www.flickr.com/photos/bloritsch/2420316647/" title="Presque Isle Lighthouse (lf7-Efke-25-WD2D+-0001) by Berin Loritsch, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2030/2420316647_92015350c7.jpg" width="400" height="500" alt="Presque Isle Lighthouse (lf7-Efke-25-WD2D+-0001)" /&gt;&lt;/a&gt;&lt;br/&gt;
&lt;em&gt;Presque Isle Lighthouse&lt;/em&gt;
&lt;/div&gt;
Out of only three hours of photography, I got four pictures with my large format and a roll of small format pictures.  The trip was primarily to support my son&amp;#8217;s basketball team, but I was able to get some time aside.  Even in the winter you can find some truly wonderful pictures.  You just need to be able to look properly.

	&lt;p&gt;This particular subject was a bit challenging.  If I went to the beach my view was obstructed by dense dead trees.  However, here I had the sun coming through gray clouds, almost backlighting my subject.  The bright spot in the upper right corner is where the sunlight was coming from.  My Rodenstock 26cm super-aplanat lens was made in 1935, so it doesn&amp;#8217;t have all the improvements in lens manufacturing made since then.  It still resolves an incredible amount of detail.&lt;/p&gt;


	&lt;p&gt;This particular picture is not a scan of a print, but of the negative.  In order to overcome some of the problem areas of the picture I had to do some digital dodging and burning.  I have to say that I don&amp;#8217;t enjoy doing these things digitally because I think in terms of stops, not percentages.  Nevertheless the light refractions in the lens obscured the top of the lighthouse so I had to do something.  I dodged it about 30% which was enough to make it more substantial without making it look fake.  I dodged the edges of the picture slightly differently for each edge due to the way the tones lay.  The right side with the tree didn&amp;#8217;t need as much burning as the left side.  Additionally the sky required more dodging than the ground.  Lastly, the sky where the sun was peaking through required some more control so I burned that top corner in an additional 40%.  The tree in the middle had a bit too much weight, so I had to dodge it.  Unfortunately, the scan didn&amp;#8217;t have any more detail to give me.  An optical print will help me out there.&lt;/p&gt;


	&lt;p&gt;I played around with different toning options and I found that selenium just didn&amp;#8217;t suit it very well.  I wanted a cooler look to it, so I went for a simulated gold tone.  I did try a sepia tone as an alternative, and I was pleasantly surprised at how nice that would look&amp;#8212;but went with a straight gold tone.&lt;/p&gt;


	&lt;p&gt;Sometimes playing with a scan of a negative digitally will help with visualizing what you can do with the optical print.  Looking at this picture, I can see how I should have changed my angle a little bit.  I wanted the large tree on the right to help frame the picture, but the tree in front of the light house is not at a good angle.  I probably should have set up in the brush on the right side of the large tree.  Sometimes you have to choose between personal safety and the perfect shot.  Traversing snow and ice while carrying several pounds of equipment isn&amp;#8217;t the best idea.&lt;/p&gt;


	&lt;p&gt;When I print this optically, I will definitely have to put it on 11&amp;#215;14 or larger paper.  It needs the breathing room of the larger area so you can get up close and see the detail.  The 11&amp;#215;14 also might cut off the little bit of the sign on the right.&lt;/p&gt;</description>
      <pubDate>Thu, 17 Apr 2008 14:01:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:0cee291e-3210-437e-994b-954d511473f6</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/04/17/presque-isle-lighthouse-lf7-efke-25-wd2d-0001</link>
      <category>Presque Isle</category>
      <category>monochrome</category>
      <category>wd2d</category>
      <category>Efke25</category>
      <category>lighthouse</category>
      <category>process</category>
    </item>
    <item>
      <title>How much does it really cost to do film?</title>
      <description>&lt;p&gt;I&amp;#8217;m not going to argue about quality, process, etc.  It&amp;#8217;s just a pure look at the cost of film vs. the cost of digital.  Let&amp;#8217;s be honest, there are some real gear junkies out there so we aren&amp;#8217;t going to talk about the people who change their camera every week for half of a megapixel more resolution.  We&amp;#8217;re going to talk about real people and real situations.  So first off there are certain costs that are the same.  Your lenses and your flash units are not likely to be any different with film vs. digital at any format size.  Medium and large format cameras where the shutter is in the lens use a standard cable release for remote operation.  Small format cameras like to get you to spend more money for the same thing so a remote for your film camera may not work for your digital camera.  What&amp;#8217;s worse is that a remote for one model of a company&amp;#8217;s camera won&amp;#8217;t necessarily work with a different model of the same company&amp;#8217;s camera.  It&amp;#8217;s still a constant expense, so go figure.&lt;/p&gt;


	&lt;p&gt;OK, so now that we got that out of the way, what&amp;#8217;s different about digital vs. film (other than the fact that one is digital and the other is film)?  First off, the cost of the sensor for a digital camera is very high in comparison to the &amp;#8220;sensor&amp;#8221; for a film camera.  One is several hundred (or thousand depending on format) dollars, and the other is less than $10.  That&amp;#8217;s right, film is a light sensitive material, hens it is a film camera&amp;#8217;s sensor.  The big difference of course, is that you can only use film once and you can use a digital sensor several times.  That&amp;#8217;s the rub.  Your up front costs are going to be higher with digital, but over a given time your consumable costs will overtake that initial investment.  That&amp;#8217;s a fact no matter how you slice it.  Digital also has consumables in the form of compact flash cards and hard drives.  They are convenient in that they can store large amounts of photos, but dangerous because if the device fails you lose everything.  That&amp;#8217;s why you need more than one, and to back them up on other drives.  With film, the negative is your storage device and it requires physical damage to lose pictures.&lt;/p&gt;


	&lt;p&gt;Small format cameras are a little worse than medium and large format cameras in the sense that you have to replace the entire camera when you upgrade.  Medium and large format cameras have changeable backs where you can use the same camera for both film and digital, depending on the client and your budget.  By the way, a digital back for a medium format camera is several thousand dollars.  You can purchase several small format digital &lt;span class="caps"&gt;SLR&lt;/span&gt; cameras for the same price.  For the sake of argument, let&amp;#8217;s keep things in the realm of the small format &lt;span class="caps"&gt;SLR&lt;/span&gt; cameras.&lt;/p&gt;


	&lt;p&gt;A used small format film camera can be had for $25-$400 depending on the model you buy (consumer/pro, age, etc.).  You can buy a small format digital camera for about $500-$900 depending on the model you buy.  Add to that a compact flash card for $20-$50 depending on the size and speed you buy.  So just how many rolls of film will it take to overtake the initial plunge?  Again, it depends on what kind of film you use.  Slide film is near $10 a roll, but if you do black and white film is around $3 a roll.  The price of lab development also varies based on the lab and the type of film.  Slide film can cost near $10 a roll to develop at a pro shop, regular color film can cost about $4 a roll at a pro shop or $1.50 a roll at Target.  If you develop black and white film yourself it will cost you pennies a roll&amp;#8212;definitely worth it.  So you can see that the answer depends on a lot of different things.&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s say you are the extravagant type and you shoot Fuji Astia 100.  It costs $5 a roll, but to get it developed unmounted it costs $6 a roll (mounted is $10).  That&amp;#8217;s $11 a roll.  Now, let&amp;#8217;s say you also you skimped on the body knowing you were going to upgrade to digital later.  So that&amp;#8217;s $25 for a cheap used camera.  Slide film is typically very low grain and very rich colors.  To produce equivalent pictures you&amp;#8217;ll need a nice digital.  Let&amp;#8217;s go for the $900 model (roughly what I paid for my used Canon 30D).  The difference between the $925 (camera and compact flash card) digital and the $25 film camera is $900, so it would take roughly 82 rolls (just under 3000 pictures) to hit the break even point where the up front cost of digital equals the same cost in film.&lt;/p&gt;


	&lt;p&gt;Now, let&amp;#8217;s say you are shooting sporting events and you need to take several pictures in a row quickly.  You&amp;#8217;ll need a better film body so your up front cost is something like $400 for a used top of the line model (roughly what I paid for my used Canon 1N).  You&amp;#8217;ll also need high &lt;span class="caps"&gt;ISO&lt;/span&gt; film if you are shooting indoors, which means you are working with normal color negative film.  You have a choice between Fuji Press 800 for $3.50 a roll or Fuji Pro-Z 800 for $5.50 a roll.  Developing costs for a pro shop is about $4 without prints.  Let&amp;#8217;s call it an even $8 for simple math.  Using the same digital camera from the last example, your difference is only $525.  You can shoot 65 rolls (2300 pictures) before you hit the break even point.  In sports photography that number comes up really quick.  Digital is a clear winner here.&lt;/p&gt;


	&lt;p&gt;For the aspiring fine art photographer, black and white is king.  You&amp;#8217;ll want the nicest camera you can afford because you want to enjoy the process, but you are now shooting black and white film and developing it yourself.  Fomapan 100 (a very nice film) is about $3 a roll, and to develop it yourself costs about $0.50 or cheaper a roll depending on the chemicals you use.  That&amp;#8217;s $3.50 total per roll, and for the sake of argument we will compare the same two cameras in our last example.  You will have to shoot 150 rolls of film (5400 pictures) before you break even.  Since this style of photography is slower paced, your digital gear might need an upgrade before you reach that mark.  The film gear will be just fine for years to come.  My personal belief is that film renders a better black and white image than you can get from digital.  That&amp;#8217;s my opinion, and you can take it for what it&amp;#8217;s worth.  If we took the cheapy film camera and the expensive digital camera the difference is even more drastic at 257 rolls (9252 pictures).&lt;/p&gt;


	&lt;p&gt;For the casual shooter, film provides a great starting point as you get your equipment together.  For the more prolific types of photography such as sports and event photography, digital is a clear winner.  It will pay for itself rather quickly.  For the fine art photographer, you can&amp;#8217;t go wrong with film.  There is no real demand on quantity of pictures, and the archival quality of film has been proven based on history rather than simulated projections.  There are plenty of other reasons to choose film, but those are all personal choices.  The truth is that digital cameras (not the cheap point and shoot variety) cost a lot more in the initial investment, and film has a continual cost you need to incur as you take pictures.  Eventually, digital will become cheaper as long as you don&amp;#8217;t keep upgrading your body.  I use both, personally.&lt;/p&gt;</description>
      <pubDate>Thu, 10 Apr 2008 23:34:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:fd39a96c-1926-43d7-8c24-7dce22a9e1c1</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/04/10/how-much-does-it-really-cost-to-do-film</link>
      <category>film</category>
      <category>digital</category>
      <category>cost</category>
      <category>camera</category>
      <category>photography</category>
    </item>
    <item>
      <title>Pyro Based Film Processing</title>
      <description>&lt;div style="text-align: center;width:*"&gt;&lt;a href="http://www.flickr.com/photos/bloritsch/2368882689/" title="Ice Dunes (lf6-Efke-25-WD2D+-0004) by Berin Loritsch, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2375/2368882689_fe57df6a11.jpg" width="500" height="400" alt="Ice Dunes (lf6-Efke-25-WD2D+-0004)" /&gt;&lt;/a&gt;&lt;br/&gt;&lt;em&gt;Ice Dunes&lt;/em&gt;&lt;/div&gt;

	&lt;p&gt;One of my favorite combos is Efke 25 and &lt;span class="caps"&gt;WD2D&lt;/span&gt;+, a pyrogallol based developer.  Pyro (what we darkroom nuts call pyrogallol) based developers stain the film, and the staining action increases with the density of the silver.  What this means in layman&amp;#8217;s terms is that you get nice, clean sharp edges and your open spaces are smoothed out.  You&amp;#8217;ll notice that there is almost no grain.&lt;/p&gt;


	&lt;p&gt;Let me give a little more technical information before I dive into the fun stuff.  Efke is a traditional emulsion film that has &lt;a href="http://en.wikipedia.org/wiki/Orthochromatic"&gt;orthochromatic&lt;/a&gt; characteristics, although I&amp;#8217;m not sure if it is classified as an ortho film.  Basically, it&amp;#8217;s not that sensitive to red light.  At &lt;span class="caps"&gt;ISO 25&lt;/span&gt;, you may think it&amp;#8217;s pretty slow but my 4&amp;#215;5 Calumet has to be mounted on a tripod anyway.  You&amp;#8217;d be surprised how easy it is to find a good exposure setting even when the &lt;span class="caps"&gt;ISO&lt;/span&gt; is so slow.  Wimberly&amp;#8217;s Developer #2, Version D+ (WD2D+) is a staining developer with a hardener built in.  Unlike other pyro based developers, &lt;span class="caps"&gt;WD2D&lt;/span&gt;+ provides an orange stain.  All pyro developers are more toxic than regular developers, but if you take reasonable care you&amp;#8217;ll be fine.  If you have good darkroom habits you&amp;#8217;ll be just fine.&lt;/p&gt;


	&lt;p&gt;Not every scene lends itself to pyro, and sometimes you actually want more of that good, honest grit.  Typically, I reach for the pyro when I want delicate highlights and clean edges.  I commonly use it for snow scenes, or if I have smooth curves like silk sheets or something of that nature.  I find that a negative can have a tremendous amount of detail that the enlarger picks up but your eyes don&amp;#8217;t.  Again, it&amp;#8217;s not a magic bullet.  After using it yourself, you&amp;#8217;ll get a better feel for how it develops your pictures.  &lt;span class="caps"&gt;WD2D&lt;/span&gt;+ tends to make things &amp;#8220;cleaner&amp;#8221;, and perhaps a little more sterile&amp;#8212;but not in a bad way.  Contrast this with Rodinal which also has great acutance (sharpness) but gives a grittier, more honest feel.&lt;/p&gt;


	&lt;p&gt;This particular scene, &lt;em&gt;Ice Dunes&lt;/em&gt; , was shot at Presque Isle in Erie, Pennsylvania.  I took meter readings on the darkest spot and the brightest spots and found that there really wasn&amp;#8217;t a whole lot of contrast.  I placed the shadow reading on Zone &lt;span class="caps"&gt;III&lt;/span&gt; and the highlights fell on Zone &lt;span class="caps"&gt;VII&lt;/span&gt;.  Yes, I use the zone system&amp;#8212;but I&amp;#8217;ve tailored it to the way I think.  It&amp;#8217;s a tool to help get what you visualize to reality.  I could have done N+2 development, but pyro really isn&amp;#8217;t made for pushing film.  I figured that there might be some detail that would have more shadow and more highlight than my meter would pick up.&lt;/p&gt;


	&lt;p&gt;The picture was scanned in using my Microtek i800 flatbed scanner, scanned at 16 bits.  Once I got in the computer I played with it in &lt;a href="http://gimp.org"&gt;the Gimp&lt;/a&gt;  giving it some levels adjustments, burning the sky a lot, and the ledge a little bit.  I dodged the open area in ice to make things stand out a bit.  Finally, I gave it some digital toning of my own.  I consider this a practice round for the darkroom which I have yet to use in a long time.&lt;/p&gt;</description>
      <pubDate>Wed, 02 Apr 2008 02:21:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:086fce7b-3654-47dd-992c-3b74806aaef4</guid>
      <author>Berin Loritsch</author>
      <link>http://bloritsch.d-haven.net/articles/2008/04/02/pyro-based-film-processing</link>
      <category>wd2d</category>
      <category>pyro</category>
      <category>developer</category>
      <category>film</category>
      <category>efke</category>
    </item>
  </channel>
</rss>
