tag:blogger.com,1999:blog-57203743717549764222024-03-13T17:21:30.013-05:00Gifford ConsultingExperiments in delivering softwareTim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.comBlogger58125tag:blogger.com,1999:blog-5720374371754976422.post-25113075361679819822015-12-29T15:16:00.000-06:002015-12-29T15:16:01.979-06:00Operations First Delivery<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
I've been involved with many projects that attempt to increase their delivery cadence after it has been deployed to production. This is met with severe resistance for multiple reasons; the manual testing effort takes too long, the environment is unstable, or it could result in downtime and customer impact. Since the business isn't asking for more frequent deliveries how can we justify the expense?</div>
<div>
<br /></div>
<div>
These reasons feel similar to the the resistance I receive when introducing test driven development. This got me thinking of an idea I've coined as "Operations First Delivery". The ideas is that the first delivery of a product should be a deployment to the production environment. This may seem ridiculous since nobody is using a non-existent product. I see that as a risk-free opportunity. This is the ideal time to release to production.</div>
<div>
<br /></div>
<div>
If we start every product were every changeset is deployed to production, we will start with Continuous Delivery. We will learn how to do zero-downtime deployments when it's appropriate. We will learn how to monitor our systems and resolve issues that generate support phone alerts. We will learn to evaluate and reduce risks in order to continuously deliver. This learning will be incremental and iterative from the beginning of the product. </div>
</div>
Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-76513070973687847642013-08-01T00:26:00.002-05:002013-08-01T00:49:15.702-05:00Daily Tally<div dir="ltr" style="text-align: left;" trbidi="on">
Have you attended (or participated) in this daily stand-up meeting?<br />
<blockquote class="tr_bq">
Q. What did I do yesterday?<br />
A. I worked on (pointing) this card yesterday. </blockquote>
<blockquote class="tr_bq">
Q. What am I doing today?<br />
A. I'll continue working on this card today. </blockquote>
<blockquote class="tr_bq">
Q. What's in my way?<br />
A. Nothing is in my way.</blockquote>
<br />
<div>
If this continues for an entire iteration the team looses credibility and trust with themselves and other stakeholders and teams. One technique my teams use to provide visibility to potential risks is a "Daily Tally" on every user story/defect card.</div>
<div>
<br /></div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiMrsxo7IVZbZtORIndSuWdTciQ2ed9EA_h_B95n6kyMXd7jF3U6Yh_bCy-CAfrEQoEcMbn8GaxGb8NJMCZfWy-sNlWxtbWJyy0NpTq_F-ka32vF5FwJ4oezIZphOi8R7wNtLnIui_98d3/s1600/DailyTally.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiMrsxo7IVZbZtORIndSuWdTciQ2ed9EA_h_B95n6kyMXd7jF3U6Yh_bCy-CAfrEQoEcMbn8GaxGb8NJMCZfWy-sNlWxtbWJyy0NpTq_F-ka32vF5FwJ4oezIZphOi8R7wNtLnIui_98d3/s400/DailyTally.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">5 Point User Story Card with Daily Tallies<br />Black - Developers<br />Orange - Testers<br />Red & Highlighter - Back Flow</td></tr>
</tbody></table>
</div>
<div>
Every day we place a tally mark on the card. Developers and testers have unique color markers and we tally from the the left to the right of the card to represent a timeline. The colors tell us how long we've been working on a card and how the time has been split between the developers and testers.</div>
<div>
<br /></div>
<div>
We also add a red tally when a card is returned to the developers from the testers. A red tally indicates that we missed an acceptance test scenario or introduced a defect.</div>
<div>
<br /></div>
<div>
The team uses the information from the daily tally in two primary ways:</div>
<div>
<ol style="text-align: left;">
<li><b>Retrospective Item</b> - A red tally mark shows when we have an opportunity to improve by reviewing the causes for the back flow and determine if we want to prevent it in the future.</li>
<li><b>Pushing help</b> - When the number of tally marks equal the card's point estimate it triggers the team to ask "How can we help?". This is not a failure of an individual or the team. It is a mechanism that makes the team aware to potential risks as early as possible.</li>
</ol>
<div>
We still use more traditional tracking methods, but we've found this technique effective for spotting trouble early and providing examples (with data) for retrospective meetings.</div>
</div>
</div>
Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-28905087025220637872013-02-21T22:59:00.002-06:002013-02-21T23:03:04.070-06:00Are all your changes included in the next release?<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
I'd like to share one technique I've used with teams to help error-proof their branching to verify the next release will include all their changes. This technique only applies to the "One Branch" strategy since a single code line will always contain all the changes.<br />
<h4 style="text-align: left;">
Error-proof Branching Strategies</h4>
<ul style="text-align: left;">
<li><b>One Branch (2 code lines) - main (of default) and release (or stable)</b></li>
<li>No Branches (1 code line) - main (or default)</li>
</ul>
<br />
The main error that occurs with branches is that developers forget to apply their changes to all branches. For example, a hot fix needs to be made to the release code line and the development code line to makes it in the next release. Like most errors, the developers aren't malicious and telling them to "do a better job next time" won't improve their behavior.<br />
<br />
One highly effective technique I use with teams is to run a script once a day to validate that all changes made to a release branch have been applied to the main (or default) code line. Since this happens daily, any merge conflicts are minimized.<br />
<br />
In this example using Mercurial, this batch script is called from a Jenkins job that runs once a day. If a commit exists on the release branch that hasn't been merged to the default branch it will fail the build. I hope you find it useful.<br />
<br />
<div>
<script src="https://gist.github.com/timgifford/5010638.js"></script>
</div>
</div>
</div>
Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-87804104840941628732013-02-21T22:55:00.000-06:002013-02-21T22:55:01.012-06:00Branching Strategies<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
I've stumbled across many creative and interesting branching strategies during my career. I'm going to categorize the branching strategies in to two categories: Error-prone and Error-proof.<br />
<h4>
Error-prone Branching Strategies</h4>
<ul>
<li>Branch per release per environment based on previous release</li>
<li>Branch per release</li>
<li>Branch from a previous release</li>
<li>Branch per environment</li>
</ul>
<h4>
Error-proof Branching Strategies</h4>
<ul>
<li>One Branch (2 code lines) - main (of default) and release (or stable)</li>
<li>No Branches (1 code line) - main (or default)</li>
</ul>
<div>
<br /></div>
</div>
Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-81758592482665763932012-07-14T16:00:00.001-05:002012-07-14T16:03:33.228-05:00My Mercurial Workflow (using Bookmarks)<div dir="ltr" style="text-align: left;" trbidi="on">
<h2 style="text-align: left;">
<span style="background-color: white;">The "master" branch...er...bookmark</span></h2>
<div>
I create a bookmark that always points to the latest changeset from the shared repository. I should call it "origin/master", but have been able to manage with a single 'master' bookmark. I update to the master bookmark before making changes or pulling changes,<br />
<br />
Any changesets that I want to push are ancestors of the 'master' bookmark. I put new commits on 'master' and defer the decision to create a branch when I have changes that need to be shared at different times. For example, when you start working on a new feature, but have to go back and fix a quick defect.<br />
<h2 style="text-align: left;">
Daily Flow:</h2>
</div>
hg update master<br />
<span style="background-color: white;">(edit, commit, edit, commit, edit, commit)</span><br />
<br />
** determine I need to move previous commits to a feature branch<br />
hg bookmark feature1<br />
<br />
** move the 'master' bookmark back to the last shareable/pushable changeset (rev 1234)<br />
hg bookmark -f master -r 1234<br />
(edit, commit, edit, commit, edit, commit)<br />
<br />
** Quit working on the non-sharable commits push the sharable changes<br />
hg update master<br />
hg pull --rebase<br />
<span style="background-color: white;">hg push -r master</span><br />
<br />
** Time goes by with dozens of changesets by other....<br />
<span style="background-color: white;">hg pull --update (--update will move the 'master' bookmark forward)</span><br />
<span style="background-color: white;">hg update feature1 (move my working directory to my feature1 branch)</span><br />
<span style="background-color: white;">hg rebase -d master (rebase my feature1 changeset on to the latest changes)</span><br />
<br />
** when these are ready to be shared<br />
hg bookmark master -f (move the master bookmark to the changesets we want to share)<br />
hg push -r master<br />
<h2 style="text-align: left;">
Pushing (The secret sauce)</h2>
If you have local changesets on bookmarked branches that haven't been merged in to master and you attempt a push you get the "abort: push creates new remote head" error.<br />
<br />
<b style="background-color: white;">Include the -r (or --rev) option to only push master changesets.</b><br />
<br />
-> <b>hg push -r master</b><br />
pushing to origin<br />
searching for changes<br />
1 changesets found<br />
adding changesets<br />
adding manifests<br />
adding file changes<br />
added 1 changesets with 1 changes to 1 files<br />
<h2 style="text-align: left;">
Tips for Bookmarks</h2>
Keep an eye on the active bookmark. The active bookmark is denoted with an asterisk (*). When you commit, the active bookmark will update to your new commit. This is most important when you're pulling in other changes. Switching the active bookmark is done by updating the bookmark (hg update feature_1). This can be done even when the bookmarks are point to the same revision.<br />
<br />
-> hg bookmark<br />
feature_1 3097:6757f51d7d1a<br />
* master 3101:0b0834be4897<br />
<br />
<br /></div>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-22313237088461128362012-05-03T23:36:00.000-05:002013-08-01T01:01:59.978-05:00Testing Boundaries<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
Many projects follow the same pattern for software testing. These projects test the entire system by running manual test cases through the user interface. When the number of manual test cases grow beyond the capacity of the current staff they introduce automation tools to execute the manual test cases. This testing strategy leads to discussions about data management, test maintenance cost and ever increasing execution times.<br />
<br />
While there are ways to improve the exist testing process, ultimately I think the strategy is wrong. More specifically the test boundaries are wrong. We can't effectively test a system using end-to-end tests exclusively. This is an example of an alternative testing strategy.<br />
<br />
Imagine we have a system with three Modules (A, B, C).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicSpplyLLoc9-nlASAJlPC84cPzlaGEThN39XJXQ4juX9PYCjQjj1JzOttDUZrDCaLR-y8P2HSn-93QI0YPOFhsDEXXvUSKhxk9Gaf2SFvsFPyvUtoH-UkWm2Cz6YijRnYFFZgyjEA3VaZ/s1600/TestingBoundary-Module.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="65" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicSpplyLLoc9-nlASAJlPC84cPzlaGEThN39XJXQ4juX9PYCjQjj1JzOttDUZrDCaLR-y8P2HSn-93QI0YPOFhsDEXXvUSKhxk9Gaf2SFvsFPyvUtoH-UkWm2Cz6YijRnYFFZgyjEA3VaZ/s320/TestingBoundary-Module.png" width="320" /></a></div>
<br />
For the sake of simplicity lets assume that each module has 10 paths. Every path in Module A depends on every path in Module B and every path in Module B depends on every path in Module C.</div>
<div>
<br /></div>
<div>
If we test the entire system across all the modules, we need 1000 tests to cover all the paths through the system.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv8__B4YxbBSL9Uth8GtkPVRAmJmwfJsga71OIstEr4b-wrdNwSRwxcSbdWTwoctadKqGO6PePh9jdGw3MMcG2gudyZY9jS64KVBKboiTpA6uvZpxEGwHCAwpl2U7DEAd08V29mZ5zVnk1/s1600/TestingBoundary-Blackbox.png" imageanchor="1"><img border="0" height="137" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv8__B4YxbBSL9Uth8GtkPVRAmJmwfJsga71OIstEr4b-wrdNwSRwxcSbdWTwoctadKqGO6PePh9jdGw3MMcG2gudyZY9jS64KVBKboiTpA6uvZpxEGwHCAwpl2U7DEAd08V29mZ5zVnk1/s320/TestingBoundary-Blackbox.png" width="320" /></a></div>
<br />
We can drastically reduce the testing effort by splitting our test boundaries.</div>
<div>
<br /></div>
<div>
When we unit test each module in isolation we'll need 10 tests per module, 1 for each path in the module. However these 30 tests don't cover the interactions between the modules. We need 200 integration tests between the modules. 100 tests to validate A and B plus 100 tests to cover B and C.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWKHgNXlyHTqWzSTQ9ZK8O7Byvo6X6-fm7r0p8KPHkvoJ_Um8-2DUOETWlaJwHB2Uu62mGzulLugWegqpJGtDPiHx61LQv0g4M5tppPz7V0K9g0lN8fbIaOW0tS4-fYotD6yblO6q-PqyK/s1600/TestingBoundary-Final.png" imageanchor="1"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWKHgNXlyHTqWzSTQ9ZK8O7Byvo6X6-fm7r0p8KPHkvoJ_Um8-2DUOETWlaJwHB2Uu62mGzulLugWegqpJGtDPiHx61LQv0g4M5tppPz7V0K9g0lN8fbIaOW0tS4-fYotD6yblO6q-PqyK/s320/TestingBoundary-Final.png" width="320" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
So if we change our test boundaries we can get the same test coverage for a system using 200 + 30 = 230 test cases.</div>
<div>
<br /></div>
<div>
The most powerful benefit of smaller test boundaries is the ability to quickly localize failures. If there is a single path in Module B that has a defect and we have a full system boundary we will have 100 failing test cases. This large number of failing tests makes it difficult to track down a single defect.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtHQfN-D9lsYMlpIU_BQt_DBzhpRrnRDAff5ZZ9PMyNXdXuly-VXR94zDaASJoPLSoUy62kAeg3E_2fdtjJ37-_WKMSeDKUfxfkMd15doCORo_7ScbleBVIYpPag8HJMprVRphIL3_LgZB/s1600/Testing+Boundary+-+Blackbox.png" imageanchor="1"><img border="0" height="137" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtHQfN-D9lsYMlpIU_BQt_DBzhpRrnRDAff5ZZ9PMyNXdXuly-VXR94zDaASJoPLSoUy62kAeg3E_2fdtjJ37-_WKMSeDKUfxfkMd15doCORo_7ScbleBVIYpPag8HJMprVRphIL3_LgZB/s320/Testing+Boundary+-+Blackbox.png" width="320" /></a></div>
<br /></div>
<div>
If we split our testing boundaries up, we have a single unit test failure for Module B and 10 broken integration tests between Module A and Module B and 10 broken tests between Module B and Module C. 21 failing tests is still a lot, but our single failing unit test will tell us the exact location of the defect and we can quickly discover the defect.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSNEId5FojlACVnjWlPAk0BMZX9wRw8RbO0wL-8IGvTeAWjFHQRUTHnyKgrv06d06VJBjoZhJnlCVBB4GGReJWHDV4bj2UX8gSevtw8014XXUXgYOzPTzsvyxodjowhNuVAt7em9wVxOnd/s1600/Testing+Boundary+-+Final+with+defect.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="229" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSNEId5FojlACVnjWlPAk0BMZX9wRw8RbO0wL-8IGvTeAWjFHQRUTHnyKgrv06d06VJBjoZhJnlCVBB4GGReJWHDV4bj2UX8gSevtw8014XXUXgYOzPTzsvyxodjowhNuVAt7em9wVxOnd/s320/Testing+Boundary+-+Final+with+defect.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
I realize this is a simple example, but I hope it illustrates the effects and impact of using smaller testing boundaries.</div>
</div>
Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com1tag:blogger.com,1999:blog-5720374371754976422.post-74751522918657720372012-04-29T11:21:00.001-05:002012-04-29T11:21:20.021-05:00Observations from a 2 day Hack-a-thonLast week I had the opportunity to participate in a two day "hack-a-thon". This is an event where engineers get to work on any interesting project and present their results to a panel of judges. The judges determine which projects are the most innovative and are awarded and promoted across the organization.<br />
<br />
In the past I've been skeptical of these types of events. Most of the proposed project are engineering improvements that should be worked on as part of their project deliverables and the majority of the projects for this event would fall into that category. However, I think the event gave the teams authority and permission to work on these projects and was impressed by the results the teams produced in two (more like 1.5 days to allow for demos).<br />
<br />
This lead me to ask a couple questions. One to the teams and one to the leaders/managers. To the team, I asked: How were the teams able to deliver such impressive results in 2 days? Some of the team's reasons included:<br />
<br />
<ul>
<li>Improved collaboration</li>
<li>Uninterrupted/focused work</li>
<li>Interesting projects</li>
<li>Competition with other teams</li>
<li>Scoping the work to two days</li>
<li>Food and snacks</li>
</ul>
<div>
The reason that I think contributed the most to the success of the projects is scoping the work to the time available. Most teams had two to three options for what they envisioned for their demo. They delivered the simplest demo first then worked on the next small improvement. Most demos were ready during the first day.</div>
<div>
<br /></div>
<div>
I saw another impressive behavior...The teams followed up on impediments instantly and would not take "no" or "tomorrow" as an answer. I don't know if I would call it Drive, Responsibility or Ownership, but was very happy to see it.</div>
<div>
<br /></div>
<br />
On Monday, I'll follow up with manager and leaders on how to replicate these outcomes on our real projects.Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-17700678864280202662011-11-03T23:25:00.000-05:002011-11-03T23:25:29.601-05:00Encapsulate Your ConstantsDoes your application have a "Constants" file? It's a class with a list of constants used across the application? It's a large file with a list of Strings that don't have any relationship to one another and has a bunch of comments and carriage returns to "organize" the file.Move them.<br />
<br />
Exposing a public constant allows developers to access state from all areas of the application. => Limit global variables and global constants. Move them into the class that is responsible for using the constant.<br />
<br />
Constant files grow over time => Don't introduce the constants file pattern. Your constants are related to some domain concept. Are they Roles? Are they keys for a cache or session storage? Move them to the correct class and make them private.<br />
<br />
Constants are an implementation detail => Don't force you teammates to find the correct key name to access some session variable. Create a method to get and set the value. The storage provider and index is an implementation detail and should be wrapped in a method that knows the storage key and provides appropriate casting.<br />
<br />
Do yourself and your team a favor and move the constants into the classes that need them.Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-43365525812735965772011-07-08T14:08:00.000-05:002011-07-08T14:08:58.289-05:00The Five Year RuleI have a rule that has guided my career since college. It has worked well for me and provided me a simple way to evaluate career opportunities.<br />
<br />
When people hear my rule for the first time, their initial reaction is to laugh. After further reflection they realize it contains truths about professional career development.<br />
<div style="margin-left: 40px;"><b>The Five Year Rule</b><br />
</div><div style="margin-left: 40px;">There are two reasons to have the same job for five (or more) years:<br />
</div><ol style="margin-left: 40px;"><li>You love your job.</li>
<li>Another company wouldn't hire you.</li>
</ol>There are a bunch of reasons to love your job, but make sure the reason you love your job isn't because you don't want to think about the second option.<br />
<br />
WARNING: Do not attempt to apply this rule to personal relationships!Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-16569316204310016232011-06-24T21:01:00.002-05:002011-06-24T21:04:50.411-05:00Mobile BloggingTwo enhancements to the blog.<br />
<br />
<ol><li>Mobile Theme - It looks ok on a phone</li>
<li>Mobile Posting - Just setup my phone to post directly to my blog. This could be a bad idea.</li>
</ol>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-43788036558920232402011-01-27T17:38:00.002-06:002011-01-27T17:38:52.974-06:00Leader or ManagerAs a Leader or a Manager we make decisions based on all of the available information at the time and the impact to stakeholders.<br />
<br />
I'm going to over simplify the difference between a Leader and a Manager by observing a single aspect in the decision making process.<br />
<blockquote>Managers make decisions based on the direction of a superior.</blockquote><blockquote>Leaders make decisions based on what why believe is best for their team.</blockquote>I have held both roles in my career. The tricky part is knowing when to be one over the other...yes there are times for both.Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-74630730336825132692010-12-08T21:58:00.002-06:002010-12-08T22:03:59.753-06:00How not to paint a fence<div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinEhoaQU9wpl2cXTA6V5q1lPlCqVQmJLJwojpfmNIJ1qvAW871ejhMem73nHIgPHeCvB1Cu_dmzX29NwWUfRYSW4VCynSOROqBjdDMkigYM2DYF810i31SFOnMYxRrCCTZ-ZKcfRIELewR/s1600/IMAG0097.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinEhoaQU9wpl2cXTA6V5q1lPlCqVQmJLJwojpfmNIJ1qvAW871ejhMem73nHIgPHeCvB1Cu_dmzX29NwWUfRYSW4VCynSOROqBjdDMkigYM2DYF810i31SFOnMYxRrCCTZ-ZKcfRIELewR/s400/IMAG0097.jpg" width="238" /></a><br />
This summer I spent a weekend staining the fence in my back yard with the kind help of my mother and father. Manual labor frees the mind to think and I started thinking about the application of the Theory of Constraints and Lean to the task of painting a fence...yes, I was in the sun too long.<br />
<br />
<h2>The Work</h2>My fence is a typical 4 ft cedar fence. It has 4x4 posts every 6 to 8 feet. Connecting the posts are a pair of 2x4s. One 6 inches above the ground the other is level with the post. The fencing is made of cedar planks that are drilled into the spanning 2x4s with a couple inch gap between each plank.<br />
There are two types of work when painting a fence. One type is the large brush (or painting pad) work to cover the the large wood planks. The second type is the trim work. The trim work on the outside of the fence is painless. A couple inches between each plank and the edges of each plank. The inside of the fence is another story. The trim work inside the fence includes the two 2x4s that span between the posts and the sections of the plank above and below those spanners.<br />
<br />
<h2>Estimating</h2>Before we started, I decided to time how long it took us to do the length of the outside of one side of the fence. I would use this sample duration to get a rough estimate on how long it would take to completed the entire fence. We’ll see how that worked out later...<br />
<br />
<h2>The Flow</h2>My father and I both started by worked on the large plank work. It took 30-45 minutes for my father and I to finish painting the large planks of the first side of the fence, however my poor mother was still finishing the trim work from the first 5 foot section. My Theory of Constraints brain kicked in and I started to think about the 5 Focusing Steps.<br />
<br />
The Theory of Constraints (ToC) defines the 5 Focusing Steps:<br />
<ol><li>Identify the constraint </li>
<li>Exploit the constraint </li>
<li>Subordinate everything else to the constraint </li>
<li>Elevate the constraint </li>
<li>Repeat </li>
</ol>It was obvious the trim work was the constraint in our system (step 1). When ToC talks about “Exploiting the constraint” it means to squeeze all the capacity out of the constraint that you can. Don’t allow the constraint to do anything activity that isn’t the constrained activity. In this case my mom was fully exploited. She wasn’t being distracted by the children or asked to grab drinks. She was just painting trim. My mom was fully exploited...from a ToC standpoint.<br />
<br />
What we should have done to subordinate everything else to trim work (step 3) is to have the large brush work only paint area where the trim work was done, but I knew it would be difficult to convince my dad. Having everyone do trim work wouldn’t “feel” like we were getting much done. I chose a compromise. I had a quick talk with my father to develop a new plan. He would continue to use the painting pad, but he should do as much of the trim work as possible. I would switch to a 2” brush and help my mother with the trim work.<br />
<br />
<h2>The Big Backside</h2>The outside of a fence is much easier to paint since it is mainly large panels. The structure inside the fence contains the top and bottom 2x4s that span between the posts. This side of the fence requires more trim work. The top, bottom and side of each of the 2x4s plus the sections above and below the spanners that aren’t large enough to get with the large paint pad.<br />
<br />
While working on the outside of fence, my father painted the front of the panel, the top and each of the half inch sides. On the backside of the fence, he was able to get the top and middle sections, but not the bottom section. He also did the spanners, but knew the “trimmers” would finish up the work.<br />
<br />
This division of labor caused a few problems:<br />
<ul><li>Buildup of Work in Progress (WIP) </li>
<li>Invalid estimates based on the duration of unfinished work </li>
<li>Quality </li>
</ul>Splitting the task into specializations of large brush work and trimming we created a large amount of work in progress (WIP). Nothing was “done”. Each section of fence required somebody to go back and “rework” the unfinished plank and trim.<br />
<br />
We could visualize how much work was left, but we needed to calculate the duration. We need to know that we had enough daylight to complete the work. Basing our duration estimates on how long it took us to partially complete a fixed length of fence didn’t give me much confidence.<br />
<br />
The final issue that was created by the division of labor was a lack of quality focus. Since my dad knew that I would be following him to do the detail trim work, he wasn’t too concerned about completing each plank. He was concerned about applying paint to the fence planks as fast as possible.<br />
<br />
While I was doing the large brush work, I had the same motivation. Getting the largest amount of square footage covered with paint meant the job was closer to being done. However, the job’s duration wasn’t strictly a function of square footage. It was a function of the duration to complete the trim work plus the duration to complete the large brush work.<br />
<br />
Ultimately we completed painting the fence. I would like to say that we had enough daylight left on Sunday to enjoy an ice cold lemonade on the deck and enjoy our work. I can’t. The sun was setting and we rushed to get everything done.<br />
<br />
<h2>Next Time...</h2>Next time I will start with a quality focus and limit the work in progress be removing the division of labor. We will have a two person team working each side of a section of fence. Both the trim and large brush work will be completed before moving to the next section. This simple change will allow us to estimate the remaining duration, reduce rework and improve quality.</div>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com1tag:blogger.com,1999:blog-5720374371754976422.post-57633782232074195522010-10-31T10:56:00.000-05:002010-10-31T10:56:28.216-05:00Continuous FeedbackThe Agile Manifesto states that we value “Individuals and interactions over processes and tools”; however we rarely discuss methods to improve the individuals on the team or their inter-personal soft skills. We need more practices that help develop the people on the team to increase the performance of the team. Improve the people and the process will take care if itself. For this reason, I want to introduce a practice I named “Continuous Feedback”.<br />
<br />
Continuous Feedback is a practice where the team provides praise and criticisms to other team members to allow them to understand how their performance or behavior is being perceived by other members of the team.<br />
<br />
<b>Differentiation</b><br />
The idea is based on Jack Welch’s concept of “Differentiation”. His concept is to split the organization into 3 segments: the top 20%, the middle 70% and the bottom 10%. <br />
<br />
The top 20% of the workforce are the stars of your organization. Lavish them with rewards and bonuses. They are smart, they get things done and they are your leaders. Reward, challenge and develop them or else someone else will!<br />
<br />
The middle 70% will require the most attention. Do not diminish the importance of the middle 70%. They are the heart and soul of your organization. The top performers in this segment will need to be developed to move into the top 20%. The people on the lower end of the 70% will need to know where they stand. People react differently when challenged. Some will “step up” others will “step down”. Either way, it is each person’s responsibility to make those decisions based on honest feedback and by knowing exactly where they stand. <br />
<br />
Finally, cut the bottom 10% out. By cutting out, I’m not talking about firing people unexpectedly. Let these people know where they stand. By knowing they are in the bottom 10% they may leave on there own. Nobody like to be were they are not wanted. Inversely, they might know where they stand and by understanding exactly where they stand they may be able to move into the 70% or higher! <br />
<br />
I know the idea of eliminating the bottom 10% sounds harsh, but most companies/teams never purge the weakest performers and this builds resentment within the other team members. <br />
<br />
We all know who these people are and we never provide feedback to let them know where they stand. It’s easier to avoid the situation than to confront them. Nobody wants to be “mean”. However, when layoffs happen they are surprised to find out they are first to be let go. Isn’t it fairer to let the weak performers know exactly where they stand? If you didn’t provide that feedback, aren’t you part of reason they were let go?<br />
<br />
Over time, cutting the bottom 10% becomes extremely difficult. Think about it. You can probably think of a few people on your team or in your department you wouldn’t mind if they were “released”. Now image if you had to go through a couple more rounds of cuts. The bottom 10% quickly becomes very qualified people! Your middle 70% doesn’t consist of people “hiding out” in the organization, waiting to collect a pension, those people are long gone. Your organization’s middle 70% are the best people in the industry!<br />
<br />
<b>The Game</b><br />
At the end of every iteration we hold a Retrospective meeting we, as a team, we discuss what went well, what we could improve on and how we could make the process better. As a part of this meeting, each member of the team must select the people who they believe to be in the bottom 10%. On our team 10% is one person. We do not publicly discuss why they were chosen. But they are encouraged to meet with the person to get feedback during the next iteration. After the exchange of the bottom 10%, each person must select the top 20% and during the meeting explain why they picked them as a top performer.<br />
<br />
We publicly select the top 20% and the bottom 10%, and publicly state why top performers are in the top 20%. We allow each member to privately receive feedback from members so they can improve and know where they stand within the team. Giving and receiving constructive criticism are important soft skills that now get practiced regularly.Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com8tag:blogger.com,1999:blog-5720374371754976422.post-42493692107222418572010-08-28T18:44:00.003-05:002010-08-29T09:52:19.823-05:00My Windows (with git) RVMI was disappointed to learn that <a href="http://rvm.beginrescueend.com/">RVM (Ruby Version Manager)</a> doesn't work on Windows, however I wasn't surprised. Windows and Ruby don't always play well with each other.<br />
<br />
I'm also a fan of <a href="http://mxcl.github.com/homebrew/">Homebrew</a> on my Mac. Homebrew is a command line package manager that downloads applications and creates symlinks so they are always on your path.<br />
<br />
I hate working with Windows environment variable since they don't always reload without logging off and back in again.<br />
<br />
For all of these reasons I started thinking about how I could configure my laptop to use multiple versions of Ruby without hacking my PATH environment variable.<br />
<br />
My solution was to create a C:\Ruby directory and initialized a git repository within that directory.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsGu1FqamxQ9f5mBtB4AwBHTw7MoCJboK0OvMq6N1z3EFu8NDxRWq6G7RkkEoyBOt5PFoXApgRs3oxWz5Ux-e8Z-SahOTdNjpNzzJcQFgf0vuEFF57NTRh5xlqhLHWycdf_Jnq6bk2tSU0/s1600/mkdir_ruby.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsGu1FqamxQ9f5mBtB4AwBHTw7MoCJboK0OvMq6N1z3EFu8NDxRWq6G7RkkEoyBOt5PFoXApgRs3oxWz5Ux-e8Z-SahOTdNjpNzzJcQFgf0vuEFF57NTRh5xlqhLHWycdf_Jnq6bk2tSU0/s320/mkdir_ruby.PNG" /></a></div>I downloaded the <a href="http://rubyforge.org/frs/download.php/72076/ruby-1.9.1-p430-i386-mingw32.7z">1.9.1 7-Zip package</a> from <a href="http://rubyinstaller.org/">rubyinstaller.org</a> and extracted it into C:\Ruby. Then I added/committed all the files to a branch named 'v191'.<br />
<br />
Finally I updated my PATH to include the C:\Ruby\bin directory.<br />
<br />
To install a different version of Ruby I created a new branch named "v192", delete all the files and committed the deletion of the files. Here are the commands:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE4eQ33YbDh7IWT6bYN-V9IxNut86Gu8pvPwDb6_k4imqWE81vZw_CU6nUgqBf12wZ_UYMNI8uAdaoqRiMVA0Rul_ATgdl96QFOm6h9Oz09bOocpHby5_rMSFuIzE54rEWaSXGRpQ2p9Fs/s1600/winrvm.PNG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE4eQ33YbDh7IWT6bYN-V9IxNut86Gu8pvPwDb6_k4imqWE81vZw_CU6nUgqBf12wZ_UYMNI8uAdaoqRiMVA0Rul_ATgdl96QFOm6h9Oz09bOocpHby5_rMSFuIzE54rEWaSXGRpQ2p9Fs/s320/winrvm.PNG" /></a><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">git checkout -b v192</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">rm -rf *</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">git add . -u && git commit -m "Cleared directory for next version"</span><br />
<br />
After I have a clean C:\Ruby directory, I extract the new version to C:\Ruby and add/commit them to the git repository.<br />
<br />
After installing I can do a git checkout {branchname} to switch my version of Ruby.Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com1tag:blogger.com,1999:blog-5720374371754976422.post-53714724646579483992010-08-16T23:54:00.000-05:002010-08-16T23:54:00.784-05:00Migrating the blog<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;">I don't know if any reads this anymore, but I am moving my blog from http://blogs.giffordconsulting.com/ to http://blog.giffordconsulting.com. Hopefully your reader didn't pick up all these posts as "new". They are not "new". They are, in fact, very, very, very old.</span></span><div><span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;">I had lofty aspirations when I started blogging back in 2005: </span></span></div><div><ol><li><span class="Apple-style-span" style="font-family: Arial; font-size: 13px;">I would blog </span><span class="Apple-style-span" style="font-size: 13px;">frequent</span></li>
<li><span class="Apple-style-span" style="font-family: Arial; font-size: 13px;">I would develop a community of bloggers under the giffordconsulting.com domain.</span></li>
<li><span class="Apple-style-span" style="font-family: Arial; font-size: 13px;">I would contribute to the SubText blogging software project</span></li>
</ol></div><div><span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;">I didn't do any of those things...I did join Twitter!</span></span></div><div><span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;">The new blog is hosted in the cloud:</span></span></div><div><ol><li><span class="Apple-style-span" style="font-family: Arial; font-size: 13px;">I don't have to pay anything</span></li>
<li><span class="Apple-style-span" style="font-family: Arial; font-size: 13px;">Upgrade or fix software bugs</span></li>
<li><span class="Apple-style-span" style="font-family: Arial; font-size: 13px;">Worry about bandwidth when I get on Hacker News</span><span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"> (Is that another lofty goal?)</span></li>
</ol></div><div><span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><br />
</span></span></div>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-1428975034757497912010-08-16T23:14:00.000-05:002010-08-16T23:14:25.927-05:00Testing Carriage Returns in FitNesse<p><a title="FitNesse" href="http://www.fitnesse.org" target="_blank">FitNesse</a> doesn't allow carriage returns in test fixture table. Normally, I replace carriage returns with a comma (or some other sentinel value) and pass it back to <a title="FitNesse" href="http://www.fitnesse.org" target="_blank">FitNesse</a>. I noticed a posting on the <a title="FitNesse" href="http://www.fitnesse.org" target="_blank">FitNesse</a> email group that recommended defining a variable and then using the variable in the table.</p><p>An Example:</p><p>!define multiLineAddress {Gifford Consulting<br /> Attn: Tim Gifford<br /> 123 Main Street<br /> Des Moines, IA 50266}</p><p>!|Check Address|<br /> |Address|<br /> |${multiLineAddress}|<br /></p>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-53070717628285841152010-08-07T11:23:00.218-05:002010-08-08T21:30:26.789-05:00Microsoft OPEN.NETLate last week we learned that Microsoft is de-funding the Iron projects (IronRuby, IronPython). Many have suggested that the community should take over the projects, but without access to the DLR, CLR and the compilers success would be limited.<br />
<br />
However if Microsoft opened up the DLR, CLR and compilers for what I'm going to call "Open .NET", we in the community could make some interesting things happen on .NET.<br />
<br />
I know it sounds crazy to open source the .NET platform, but I don't understand what competitive advantage Microsoft maintain by keeping it closed.<br />
<br />
I want to mention a couple advantages they would gain by opening it up.<br />
<br />
Allowing the community to create libraries and offer bug patches to the CLR, DLR and compiler we (the community) would feel involvement in the platform. This involvement would translate to more community created libraries and solutions.<br />
<br />
Microsoft wouldn't have to create tools and libraries that already exist (ala MsTest) and focus their efforts on expanding the platform.<br />
<br />
I'm not proposing that all products and innovation that is created by Microsoft shall be Open. They can build new technology within and around the open platform and release those changes to the community core projects after the product announcements.<br />
<br />
Create native extensions for Windows that increased performance and scalability. Create products that only run on IIS or SharePoint. Microsoft's current "enterprise" customers would continue to use the proprietary and supported versions of the compilers and runtime.<br />
<br />
Without an "Open.NET" Platform, projects like IronRuby and IronPython are not feasible outside of Microsoft. This innovation while secondary to Microsoft's corporate strategy is important to many of us in the community.Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-1456063746018764252010-06-09T22:13:00.000-05:002010-06-09T22:13:54.958-05:00Scheduled RestartI haven't been blogging for a while and have missed it. Twitter allows for quick quips and lunch/bar conversations allow for a deep introspection but I've been missing a venue to formalize my thoughts and to improve my writing ability.<div><br />
</div><div>Topics I will cover:<br />
<div><div><br />
<ul><li>Lean Software Development</li>
<li>Test Driven Development</li>
<li>Automated Acceptance Testing</li>
<li>Technology Reviews</li>
<li>Book Reviews</li>
<li>Experience Reports</li>
<li>...and random posts when I need more that 140 characters.</li>
</ul></div><div><br />
<br />
</div></div></div>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-25414758639988900722007-12-11T22:07:00.004-06:002010-08-17T00:00:38.269-05:00Team Foundation Server forces teams toward open source solutionsSource control is the lowest common denominator with software development. All (...ok...most) software development teams have a system in place to manage the version of their software source code.<br />
Within the Microsoft eco-system there are 2 options provided by Microsoft:<br />
<ul><li>Microsoft Source Safe</li>
<li>Microsoft Team Foundation Server</li>
</ul><a href="http://blog.giffordconsulting.com/2006/09/dear-sourcesafe-ive-found-another.html" target="_blank">SourceSafe has a bad reputation</a> so within the last couple years, teams that develop on the Microsoft stack have been forced to limp along with Source Safe or upgrade to Team Foundation Server.<br />
I don't want any one to get the impression that I don't like TFS; because I do. I like the integrated lifecycle, powerful reporting, task and project management tools. I like these things when they are needed. However, most mid-market software development shops don't need (or can't afford) all those tools.<br />
But what if you want the tools? Have you ever tried to determine the pricing for a Team Systems rollout? Can somebody tell me how much it will cost to roll out TFS for a development team of 10 developers? I've tried to do the pricing, but can't <a href="http://msdn2.microsoft.com/en-us/teamsystem/aa700832.aspx" target="_blank">navigate the licensing</a>.<br />
So what should you do if you need a source control tool? <br />
a.) Spend a couple days putting together a proposal to submit to your boss, who will submit it to her boss which will ultimately be rejected for "Budgeting Reasons". <br />
b.) Do you stick with Source Safe? Not because you want to or think it's the best solution but because it's the only other alternative from Microsoft? <br />
c.) Or do you install a Subversion Repository (free + time) on an existing server (free), install TortoiseSVN (free + time) on the developer workstations and hold a day of training with the development staff (time)?Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-49712532701533007012007-11-30T22:10:00.000-06:002010-08-16T22:11:54.466-05:00Agile defined with one photoI got this photo today at work when a co-worker recommend a couple alternative strategies. I love it and had to share!<br />
<img src="http://www.syslog.com/~jwilson/pics-i-like/kurios119.jpg" /> <br />
From: <a href="http://www.michaelsalamon.com/?p=20" title="http://www.michaelsalamon.com/?p=20">http://www.michaelsalamon.com/?p=20</a>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-54745656590456143842007-11-27T22:13:00.000-06:002010-08-16T22:14:23.048-05:00Full-time "Gig"After a short contract at a major financial company, I have accepted a full time job at <a href="http://www.tworiversmarketing.com/" target="_blank">Two Rivers Marketing</a>.<br />
We have a fairly large team (~15) of software developers, user interface designers, and Flash designers.<br />
Tools are not the most important part of a company, but they can tell you about the "development eco-system". What do these tools tell you about our eco-system?<br />
<a href="http://subversion.tigris.org/" target="_blank">Subversion</a> <br />
<a href="http://www.nhibernate.org/" target="_blank">NHibernate</a> <br />
<a href="http://www.nunit.org/" target="_blank">NUnit</a> <br />
<a href="http://logging.apache.org/log4net/" target="_blank">Log4Net</a> <br />
<a href="http://www.ayende.com/projects/rhino-mocks.aspx" target="_blank">Rhino Mocks</a> <br />
<a href="http://nant.sourceforge.net/" target="_blank">NAnt</a>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-71279139806662690812007-11-27T22:11:00.000-06:002010-08-16T22:13:07.754-05:00Twin$Jody, Sadie and I are expecting twins (one boy/one girl) in April. . We are excited and freaking out all at the same time.<br />
To prepare, we are building a new 4 bedroom home west of Jordan Creek Town Center.<br />
Wish us luck!Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-52243050118470053032007-06-27T22:15:00.001-05:002010-08-16T22:16:41.636-05:00One Simple MetricAt our last <a href="http://www.agileiowa.org/">Agile Iowa</a> meeting on Thursday, Jared Richardson, he was talking about Agile Testing Strategies. He mentioned a metric he used that I found very interesting. He took three variables and created a report that listed the top 10 method/assemblies that were at risk.<br />
Here is the (simple) equation:<br />
<blockquote>Cyclomatic Complexity (CC): <br />
Usage (U): How many other methods/classes rely on this code.<br />
Test Coverage Percentage (TC): The percentage of the code that is exercised by a unit test<br />
<strong>Risk Factor = CC x U x (1 - TC)</strong></blockquote>Let's look at a couple examples:<br />
This first table shows a method used by 50 other methods (Usage) with a Cyclomatic complexity (CC) of 20. I then vary the code coverage for this method. Without any unit tests, the risk factor is a cool "g" (or Grand). As the test coverage increases the Risk Factor decreases. When the test coverage reaches 100%, the Risk Factor is reduced to zero. The function is linear, so decreasing the usage or the complexity will also reduce the Risk Factor. So it make sense that if a method isn't used, it has a risk factor of zero.<br />
<table border="1" cellpadding="2"><tbody>
<tr> <th>CC</th> <th>Usage</th> <th>Code Coverage</th> <th>Risk Factor</th></tr>
<tr> <td>20</td> <td>50</td> <td>0</td> <td>1,000</td></tr>
<tr> <td>20</td> <td>50</td> <td>0.1</td> <td>900</td></tr>
<tr> <td>20</td> <td>50</td> <td>0.5</td> <td>500</td></tr>
<tr> <td>20</td> <td>50</td> <td>0.9</td> <td>100</td></tr>
</tbody></table>The following methods all have the same risk factor of 250. Do you think this is reasonable? Should one of these factors be weighted heavier?<br />
<table border="1" cellpadding="2"><tbody>
<tr> <th>CC</th> <th>Usage</th> <th>Code Coverage</th> <th>Risk Factor</th></tr>
<tr> <td>10</td> <td>50</td> <td>.5</td> <td>250</td></tr>
<tr> <td>50</td> <td>10</td> <td>0.5</td> <td>250</td></tr>
<tr> <td>50</td> <td>50</td> <td>0.9</td> <td>250</td></tr>
</tbody></table>For now I'm going to see how I can get the usage and the code coverage numbers automated... I can tweak the algorithm more later.Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-74135544886760244072007-06-21T22:14:00.000-05:002010-08-16T22:15:24.021-05:00Lean is the new Agile<p>I'm happy to see more people everyday are interested in Agile methods, however I'm saddened by the misinterpretation and perceptions of Agile by people who have never experienced it.</p><p>I've discovered that when I mention Agile to a group of IT Professionals, there is an initial reaction of shock and defensive posturing. </p><blockquote><p>"Agile isn't for us. We don't want the developers coding without any direction." </p><p>or </p><p>"If we're going to use XP, that's fine. I'll just find another team!"</p></blockquote><p>It's hard enough to have people listen about the spirit of agility when they have already made their minds up...which leads me to the topic of this post.</p><p><strong>Lean is the new Agile</strong></p><p>Recently I've been hearing more and more about Lean software development. It's not new, but I believe the agile community is looking for another way to market agility outside the software industry. And it makes sense to use Lean Manufacturing as the model. Every business person in the world has heard about lean manufacturing. Not only have they heard the term, there is an engrained positive feeling about it. Lean sounds like it costs less with more quality. They associate lean with Toyota which they associate with quality...Oh what a feeling!</p><p>Agile, on the other hand, is associated with XP (Extreme Programming). Nobody in business wants anything to do with anything that is extreme. Extreme equates to Risk and the business world is all about reducing risks (or as we say, "mitigating risks"). </p><p>So give it a shot. Next time someone is discussing your software development methodology, tell them you use a lean software development methodology based on the principles from the Toyota Production System and see how they react.</p>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0tag:blogger.com,1999:blog-5720374371754976422.post-67590772788138580612007-06-10T22:16:00.001-05:002010-08-16T22:18:11.822-05:00Single or Multi Threaded Projects<p>There are two strategies to complete the things you want to get done: </p><ol><li>Start them all at the same time </li><li>Work on one at a time until it is completed, then work on the next highest priority</li></ol><p>How do you do it in your daily life? If you have a list of tasks that you need to get done which approach do you use?</p><p>Let's think about how your company completes project. Which approach do they use? Are they the same?</p><p>Let's weigh the Pros and Cons of each approach. Let's assume your team needs to complete 3 similar sized projects (Project A, Project B, Project C) within 3 months.</p><h2>Start all the projects at the same time (Multi-threaded)</h2><h3>Pros:</h3><p>All project stakeholders are told their project has started</p><h3>Cons:</h3><p>Tracking each project's status is difficult</p><p>People on the project frequently have to switch thinking between each project</p><p>Each project will take 3 months duration to finish</p><p>Don't start earning returns on the projects</p><p>If there are overruns, each project is affected</p><h2>One project at a time (Single-threaded)</h2><h3>Pros:</h3><p>Only need to track a single project at a time</p><p>People on the project are focused</p><p>Each project should finish in one month</p><p>Project A will earn returns for 2 months</p><p>Project B will earn 1 month of returns</p><p>Overruns affect fewer projects</p><h3>Cons:</h3><p>Project stakeholders are told their project hasn't started</p><p> </p><p>Am I missing any Pro/Cons for either of these scenarios?</p>Tim Giffordhttp://www.blogger.com/profile/08110581704099555513noreply@blogger.com0