<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-34747147</id><updated>2011-11-27T15:40:38.992-08:00</updated><category term='release tests'/><category term='i18n'/><category term='release plan'/><category term='refactoring'/><category term='debugging'/><category term='planning'/><category term='code smell'/><category term='security'/><category term='defect prevention'/><category term='measurement'/><category term='unit tests'/><category term='deployment'/><category term='cmmi'/><category term='version control'/><category term='test-driven development'/><category term='requirements'/><category term='duplication'/><category term='maturity'/><title type='text'>Task Coach</title><subtitle type='html'>About developing an open source task manager.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-34747147.post-5850295115222420759</id><published>2010-09-06T13:41:00.000-07:00</published><updated>2010-09-06T13:41:47.282-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maturity'/><category scheme='http://www.blogger.com/atom/ns#' term='measurement'/><category scheme='http://www.blogger.com/atom/ns#' term='cmmi'/><title type='text'>Measurement and Analysis for Task Coach</title><content type='html'>&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;As announced in a&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;a href="http://taskcoach.blogspot.com/2010/07/maturity-of-open-source-projects.html" style="color: #992211; text-decoration: none;"&gt;previous posting&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;, I am investigating which of the&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;a href="http://www.sei.cmu.edu/cmmi" style="color: #992211; text-decoration: none;"&gt;CMMI&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;goals are achieved by the Task Coach project. The fifth process area I am looking at is Measurement and Analysis (MA). MA is a support process area at level two of the CMMI for Development. Because MA is part of the core model foundation, it is also part of the other two CMMI constellations, CMMI for Services and CMMI for Acquisition. But here, I'll be looking at MA from a development perspective.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;According to the CMMI, "&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;The purpose of Measurement and Analysis (MA) is to develop and&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;sustain a measurement capability that is used to support management&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;information needs." The first question is who "management" is in an open source project. CMMI doesn't define management. It does define "manager" however, as "...&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;a person who provides technical&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;and administrative direction and control to those performing&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;tasks or activities within the manager’s area of responsibility." &amp;nbsp;I guess management in the case of the Task Coach project equals the developers. So the purpose of MA in our case is to develop and sustain a measurement capability that is used to support the information needs of the developers. Well, let's see.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;MA has two specific goals and, like all CMMI process areas, five generic goals. For now, I'll only be looking at specific goals.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The first specific goal of MA states "&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;Measurement objectives and activities are aligned with identified&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;information needs and objectives." To achieve this goal, CMMI expects us to perform four specific practices.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The first specific practice (SP1.1) of MA is to "&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;Establish and maintain measurement objectives that are&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;derived from identified information needs and objectives." We as a project don't have any formally identified and documented information needs and objectives. I guess one implicit objective is to have as many happy Task Coach users as possible, but we have no measurement objectives derived from this objective that are "established and maintained".&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The second specific practice (SP1.2) of MA reads "Specify measures to address the measurement objectives." We have no specified measures.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The third specific practice (SP1.3) states "Specify how measurement data will be obtained and stored." Again, we have no specifications on how to obtain and store measurement data.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The fourth specific practice (SP1.4) of MA expects us to "Specify how measurement data will be analyzed and reported." It gets boring, but we don´t have specifications on how to analyze and report measurement data.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The conclusion is clear: since we don´t do any of the practices, the first goal of MA is not satisfied.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The second goal of MA states "&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;Measurement results, which address identified information needs and&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;objectives, are provided." To achieve this goal, CMMI expects us to perform four specific practices.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;The first specific practice (SP2.1) of the second goal of MA is to "Obtain specified measurement data." Measurement data we obtain include&amp;nbsp;&lt;a href="http://sourceforge.net/downloads/taskcoach/stats_timeline"&gt;number of downloads&lt;/a&gt;, &lt;a href="http://www.fraca7.net:8010/waterfall"&gt;build status&lt;/a&gt;, &lt;a href="http://www.fraca7.net/TaskCoach-coverage/win32-trunk/index.html"&gt;test coverage&lt;/a&gt;, &lt;a href="http://www.ohloh.net/p/taskcoach/analyses/latest"&gt;source code volume&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://translations.launchpad.net/taskcoach/"&gt;translation completeness&lt;/a&gt;. However, which measures we collect is partly determined by what different tools and websites collect for us automatically. I think the intent of this practice is to obtain measurement data that fulfills the specified information needs as discussed in SG1 of MA. However, if we would have made our information needs explicit I think these measurement data would still be in line with those information needs, so I´d judge this practice as largely implemented.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;The second specific practice (SP2.2) expects us to "Analyze and interpret measurement data." We do analyze some of the data, but mostly on an ad hoc basis. For example, we changed the coverage measurement when analysis showed that third party software included in the Task Coach source code repository was included in the coverage measurement. One analysis is always done, and that is when the build bot fails at building one or more of the distributions. However, other measurements like number of downloads and source code volume are not analysed at all. Conclusion: this practice is only implemented a little bit.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;The third specific practice of SG2 of MA says that we should " &lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;Manage and store measurement data, measurement&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;specifications, and analysis results." Due to the open nature of the project and the tools used, all measurement data is stored and available. However, measurement specifications and analysis results are not explicitly stored, except maybe in emails between the developers. Practice partly implemented.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;The fourth and last specific practice of SG2 reads "&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 20px;"&gt;Report results of measurement and analysis activities to all&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;relevant stakeholders." Some of the measurements are reported (emailed) automatically, such as build failures. Other measurements are available via the web on demand. Since we report (actively or passively) all measurement activities that we do, I guess that makes this practice largely implemented. By the way, it is interesting to note that the intent of this practice is to "t&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;o support decision making and assist in taking corrective action", but that this expectation is not part of the mandatory or expected content of the model.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;Conclusion, the second goal is only partly achieved since most of the practices are only partly implemented.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-5850295115222420759?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/5850295115222420759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=5850295115222420759' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/5850295115222420759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/5850295115222420759'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2010/09/measurement-and-analysis-for-task-coach.html' title='Measurement and Analysis for Task Coach'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-8557589623284886768</id><published>2010-08-15T03:52:00.000-07:00</published><updated>2010-08-15T05:16:27.682-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maturity'/><category scheme='http://www.blogger.com/atom/ns#' term='planning'/><category scheme='http://www.blogger.com/atom/ns#' term='cmmi'/><title type='text'>Project Monitoring and Control for Task Coach</title><content type='html'>As announced in a &lt;a href="http://taskcoach.blogspot.com/2010/07/maturity-of-open-source-projects.html"&gt;previous posting&lt;/a&gt;, I am investigating which of the &lt;a href="http://www.sei.cmu.edu/cmmi"&gt;CMMI &lt;/a&gt;goals are achieved by the Task Coach project. The fourth process area I am looking at is Project Monitoring and Control (PMC). PMC is a project management process area at level two of the CMMI for Development. Because PMC is part of the core model foundation, it is also part of the other two CMMI constellations, CMMI for Services and CMMI for Acquisition. But here, I'll be looking at PMC from a development perspective.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;According to the CMMI, "The purpose of Project Monitoring and Control (PMC) is to provide an understanding of the project’s progress so that appropriate corrective actions can be taken when the project’s performance deviates significantly from the plan." When we were&lt;a href="http://taskcoach.blogspot.com/2010/07/project-planning-for-task-coach.html"&gt; investigating Project Planning&lt;/a&gt; (PP), we saw that the Task Coach project doesn't really do much project planning and that it doesn't have an established project plan. That probably means the PMC goals and practices won't be implemented either, but let's investigate that more closely before we draw conclusions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PMC has two specific goals and, like all CMMI process areas, five generic goals. For now, I'll only be looking at specific goals. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first specific goal (SG1) of PMC states "Actual performance and progress of the project are monitored against the project plan." To achieve this first goal, CMMI expects us to implement seven specific practices.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first specific practice (SP1.1) of PMC reads "Monitor the actual values of the project planning parameters against the project plan." Since there is no project plan and there are no project planning parameters, this practice cannot be, and is not, implemented. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second specific practice (SP1.2) of PMC expects us to "Monitor commitments against those identified in the project plan." Since we don't have a project plan, don't have documented commitments and we don't monitor (implicit) commitments, this practice is not implemented.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The third specific practice (SP1.3) of PMC says "Monitor risks against those identified in the project plan." Again, we don't have a project plan and we don't explicitly identify risks, so we cannot and do not monitor risks.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The fourth specific practice (SP1.4) of PMC wants us to "Monitor the management of project data against the project plan." Almost all project data is in some online repository (Subversion repository, bug tracker, feature request tracker, etc.) and these are monitored by means of automated emails when something gets changed. However, CMMI expects us to monitor the &lt;i&gt;management &lt;/i&gt;of project data. I'm not sure monitoring the data itself is the same as monitoring the management of the data. Probably not, but then I don't know how to interpret this practice in the context of this project.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The fifth specific practice (SP1.5) of SG1 of PMC reads "Monitor stakeholder involvement against the project plan." As explained in the discussion of Project Planning, we do involve stakeholders (users mostly) but this is not monitored against a plan.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The sixth specific practice (SP1.6) of SG1 of PMC expects us to "Periodically review the project's progress, performance, and issues." This is something that is not done on a periodic basis, but could be a nice additional practice for the project.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last specific practice (SP1.7) of SG1 of PMC is "Review the accomplishments and results of the project at selected project milestones." Like SP1.6, this not done, but would be good to do, probably in the form of post-release retrospectives.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, the conclusion is simple. The Task Coach project does not achieve the first specific goal of PMC.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second specific goal (SG2) of PMC reads "Corrective actions are managed to closure when the project's performance or results deviate significantly from the plan." Again, without a plan, this goal is hard to achieve. But let's look briefly at the practices anyway.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first specific practice (SP2.1) of SG2 expects us to "Collect and analyze the issues and determine the corrective actions necessary to address the issues." We don't collect issues other than bugs. That doesn't mean there are no issues besides bugs of course, but these don't get collected and analyzed in a repeatable manner. It could be a good idea to keep track of other issues somewhere. Sourceforge allows for creating additional "trackers", so it wouldn't be hard to create a separate "issue tracker".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second specific practice (SP2.2) of SG2 wants us to "Take corrective action on identified issues." Since we don't explicitly identify issues we also don't explicitly take corrective actions. At least not in a structured manner.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The third specific practice (SP2.3) of SG2 then expects us to "Manage corrective actions to closure." Again, we don't do this. Having an issue tracker would greatly help us do this.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Again, the conclusion is simple. This second goal of PMC hasn't been achieved either.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-8557589623284886768?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/8557589623284886768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=8557589623284886768' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/8557589623284886768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/8557589623284886768'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2010/08/project-monitoring-and-control-for-task.html' title='Project Monitoring and Control for Task Coach'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-1772481603952586222</id><published>2010-08-13T11:46:00.000-07:00</published><updated>2010-08-13T12:28:58.154-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Tricks for debugging a wxPython GUI</title><content type='html'>The other day, it took me quite some time to debug an issue that would have taken much less time had I used these two tools sooner:&lt;div&gt;&lt;ul&gt;&lt;li&gt;The wxPython &lt;a href="http://wiki.wxpython.org/Widget%20Inspection%20Tool"&gt;Widget Inspection Tool&lt;/a&gt; that shows how GUI elements are related, and,&lt;/li&gt;&lt;li&gt;The &lt;a href="http://docs.python.org/library/traceback.html"&gt;traceback module&lt;/a&gt; that makes it easy to see who is calling a method by putting this line in a method: &lt;span class="Apple-style-span"&gt;import traceback; traceback.print_stack()&lt;/span&gt;.&lt;/li&gt;&lt;/ul&gt;Hopefully writing this down makes it easier to remember these tools for the next occasion.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-1772481603952586222?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/1772481603952586222/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=1772481603952586222' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/1772481603952586222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/1772481603952586222'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2010/08/tricks-for-debugging-wxpython-gui.html' title='Tricks for debugging a wxPython GUI'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-6999670711795399163</id><published>2010-07-14T08:16:00.000-07:00</published><updated>2010-08-04T06:12:06.606-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maturity'/><category scheme='http://www.blogger.com/atom/ns#' term='planning'/><category scheme='http://www.blogger.com/atom/ns#' term='cmmi'/><title type='text'>Project Planning for Task Coach</title><content type='html'>As announced in a &lt;a href="http://taskcoach.blogspot.com/2010/07/maturity-of-open-source-projects.html"&gt;previous posting&lt;/a&gt;, I am investigating which of the &lt;a href="http://www.sei.cmu.edu/cmmi"&gt;CMMI&lt;/a&gt; goals are achieved by the Task Coach project. The third process area I am looking at is Project Planning (PP). PP is a Project Management process area at level two of the CMMI for Development. Because PP is part of the core model foundation, it is also part of the other two CMMI constellations, CMMI for Services and CMMI for Acquisition. But here, I'll be looking at PP from a development perspective.&lt;br /&gt;&lt;br /&gt;According to the CMMI, "The purpose of Project Planning (PP) is to establish and maintain plans that define project activities."  Unfortunately, CMMI doesn't define the word &lt;span style="font-style: italic;"&gt;plan&lt;/span&gt;. However, CMMI defines &lt;span style="font-style: italic;"&gt;project plan&lt;/span&gt; as "A plan that provides the basis for performing and controlling the project’s activities, which addresses the commitments to the project’s customer."  We'll assume that the plans mentioned in the purpose statement of PP are meant to be project plans.&lt;br /&gt;&lt;br /&gt;PP has three specific goals and, like all CMMI process areas, five generic goals. For now, I'll only be looking at specific goals.&lt;br /&gt;&lt;br /&gt;The first specific goal (SG1) of PP reads "Estimates of project planning parameters are established and maintained."  In the explanation of this goal, CMMI states that "Project planning parameters include all information needed by the project to perform the necessary planning, organizing, staffing, directing, coordinating, reporting, and budgeting." For a small open source project like Task Coach, the amount of necessary planning, organizing, staffing, etc., is probably much lower than is needed for commercial software development projects. To achieve this first PP goal, CMMI expects organisations to implement four specific practices. Let's see how these apply to the Task Coach project.&lt;br /&gt;&lt;br /&gt;The first specific practice (SP1.1) of PP says "Establish a top-level work breakdown structure (WBS) to estimate the scope of the project." CMMI, in the informative part of the practice, explains that the WBS typically provides a scheme for organizing the work in logical units, called work packages. The Task Coach project does not have a WBS. I guess a very abstract version of a WBS would contain top-level work packages like: develop new features, fix bugs, release software, write documentation, and provide user support. However, we haven't documented this, so I guess this practice isn't implemented.&lt;br /&gt;&lt;br /&gt;The second specific practice (SP1.2) of PP reads "Establish and maintain estimates of the attributes of the work products and tasks." The idea here is to estimate the size of work products and tasks, and then use those size estimates as a basis for estimating resource requirements (described in PP SP1.4). However, since this is a project with only volunteers (committed volunteers, but volunteers still), our resources are basically fixed. We also have no fixed deadlines, so there is no immediate need to make these estimates. Anyhow, this practice is not implemented.&lt;br /&gt;&lt;br /&gt;The third specific practice (SP1.3) says "Define the project lifecycle phases on which to scope the planning effort." I guess the lifecycle phases of Task Coach are: developing new features, followed by bug fixing (we're not producing bug free software, yet :-)  These phases usually overlap, i.e. while bugs are fixed in the latest x.y version, resulting in release x.y.1, x.y.2, etc., work starts on x.y+1.  This is not explicitly documented. Again, this practice is not implemented.&lt;br /&gt;&lt;br /&gt;The fourth specific practice (SP1.4) of the first PP goal reads "Estimate the project effort and cost for the work products and tasks based on estimation rationale."  We don't estimate effort and cost. Practice not implemented.&lt;br /&gt;&lt;br /&gt;Since all four practices of the SG1 of PP are not implemented, the goal is not achieved.&lt;br /&gt;&lt;br /&gt;The second specific goal (SG2) of PP requires that "A project plan is established and maintained as the basis for managing the project." There are seven specific practices that CMMI expects us to implement to reach this goal.&lt;br /&gt;&lt;br /&gt;The first specific practice (SP2.1) of SG2 is "Establish and maintain the project’s budget and schedule." The Task Coach project has no budget, other than the time its developers and other volunteers put into it. We do have an implicit schedule of frequent releases. This is evidenced by the &lt;a href="http://www.taskcoach.org/all_changes.html"&gt;117 releases in 5,5 years&lt;/a&gt; (assuming I counted correctly). However, I am not sure this counts as an established schedule. Practice partly implemented at most.&lt;br /&gt;&lt;br /&gt;The second specific practice (SP2.2) is "Identify and analyze project risks." We don't do this.&lt;br /&gt;&lt;br /&gt;The third practice (SP2.3) reads "Plan for the management of project  data." Like most open source projects, we keep almost all project data  in on-line repositories, see the discussion of &lt;a href="http://taskcoach.blogspot.com/2010/07/configuration-management-for-task-coach.html"&gt;Configuration  Management&lt;/a&gt;. Practice implemented.&lt;br /&gt;&lt;br /&gt;SP2.4 says "Plan for  necessary resources to perform the project." Project resources include  labor and equipment, materials and methods. Labor is a given. Other  resources such as our Subversion repository, bug tracker, email lists,  etc., all are present, but haven't really been planned explicitly.  Practice not implemented.&lt;br /&gt;&lt;br /&gt;In SP2.5 of PP, CMMI expects you to "Plan for knowledge and skills needed to perform the project." We work with the knowledge and skills that are available and do not explicitly plan to acquire knowledge and skills.&lt;br /&gt;&lt;br /&gt;The sixth specific practice (SP2.6) of SG2 reads "Plan the involvement of identified stakeholders." We do involve stakeholders, users mostly, via the UserVoice website and the users mailinglist, but there is no explicit plan for this.&lt;br /&gt;&lt;br /&gt;The last specific practice (SP2.7) of SG2 expects us to "Establish and maintain the overall project plan content." We don't have a documented project plan so this practice is not implemented.&lt;br /&gt;&lt;br /&gt;Of the seven practice of SG2, we haven't implemented the majority so this goal is clearly not achieved.&lt;br /&gt;&lt;br /&gt;The third specific goal (SG3) of PP is "Commitments to the project plan are established and maintained."  We have already established that the Task Coach project doesn't have a project plan, so it doesn't seem this goal can be satisfied. We look at the three specific practices for this goal anyway.&lt;br /&gt;&lt;br /&gt;The first specific practice (SP3.1) for this goal reads "Review all plans that affect the project to understand project commitments." The idea here is that plans for other process areas (e.g. for Configuration Management, Requirements Management, etc.) may affect the project plan. Since we don't have a project plan, this practice cannot be, and is not, performed.&lt;br /&gt;&lt;br /&gt;The second specific practice (SP3.2) states that we should "Reconcile the project plan to reflect available and estimated resources." This is the basis for how we work; adapting all activities to the amount of time the developers have/make available for the project. However, we do not capture the reconciliation in a project plan.&lt;br /&gt;&lt;br /&gt;The third specific practice (SP3.3) of the third goal of PP reads "Obtain commitment from relevant stakeholders responsible for performing and supporting plan execution."  We do have commitment from the two developers as shown by their involvement in the project for more than five years. Commitment of other stakeholders, like translators or documentation writers, is not secured. This is evidenced by &lt;a href="https://translations.launchpad.net/taskcoach/"&gt;incomplete translations&lt;/a&gt; and slow progress on writing a &lt;a href="http://taskcoach.wikispaces.com/Task+Coach+Manual"&gt;Task Coach user manual&lt;/a&gt;. Practice partly implemented.&lt;br /&gt;&lt;br /&gt;The practices of the third specific PP goal are only partly implemented, so this goal is not achieved.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-6999670711795399163?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/6999670711795399163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=6999670711795399163' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6999670711795399163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6999670711795399163'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2010/07/project-planning-for-task-coach.html' title='Project Planning for Task Coach'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-6776979067858079518</id><published>2010-07-13T09:12:00.000-07:00</published><updated>2010-07-13T12:23:53.922-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maturity'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='cmmi'/><title type='text'>Configuration Management for Task Coach</title><content type='html'>As announced in a &lt;a href="http://taskcoach.blogspot.com/2010/07/maturity-of-open-source-projects.html"&gt;previous posting&lt;/a&gt;, I am investigating which of the &lt;a href="http://www.sei.cmu.edu/cmmi"&gt;CMMI&lt;/a&gt; goals are achieved by the Task Coach project. The second process area I am looking at is Configuration Management (CM). CM is a Support process area at level two of the CMMI for Development. Because CM is part of the core model foundation, it is also part of the other two CMMI constellations, CMMI for Services and CMMI for Acquisition. But here, I'll be looking at CM from a development perspective.&lt;br /&gt;&lt;br /&gt;According to the CMMI, "The purpose of Configuration Management (CM) is to establish and maintain the integrity of work products using configuration identification, configuration control, configuration status accounting, and configuration audits." Work products are defined as "In the CMMI Product Suite, a useful result of a process. This can include files, documents, products, parts of a product, services, process descriptions, specifications, and invoices. A key distinction between a work product and a product component is that a work product is not necessarily part of the product." So, work products for Task Coach are obviously product components like source code and tests, but also include things like the &lt;a href="http://www.taskcoach.org/"&gt;Task Coach website&lt;/a&gt; and &lt;a href="http://tech.groups.yahoo.com/group/taskcoach/message/2009"&gt;announcement emails&lt;/a&gt;. The purpose of CM is to establish and maintain the integrity of these work products.&lt;br /&gt;&lt;br /&gt;CM has three specific goals and, like all CMMI process areas, five generic goals. For now, I'll only be looking at specific goals.&lt;br /&gt;&lt;br /&gt;The first specific goal (SG1) of CM reads "Baselines of identified work products are established." CMMI defines a baseline as "A set of specifications or work products that has been formally reviewed and agreed on, which thereafter serves as the basis for further development, and which can be changed only through change control procedures."  CMMI expects organisations to perform three practices to achieve this goal.&lt;br /&gt;&lt;br /&gt;The first specific practice (SP1.1) is to "Identify the configuration items, components, and related work products that will be placed under configuration management."  Almost all Task Coach work products are placed under some form of configuration management:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Source code, including automated tests, third party sources, and release scripts, are put in the &lt;a href="http://taskcoach.svn.sourceforge.net/viewvc/taskcoach/"&gt;Sourceforge Subversion repository&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The &lt;a href="http://taskcoach.svn.sourceforge.net/viewvc/taskcoach/trunk/taskcoach/website.in/"&gt;website sources&lt;/a&gt; are in the Subversion repository as well.&lt;/li&gt;&lt;li&gt;Bug reports are kept in the &lt;a href="https://sourceforge.net/tracker/?group_id=130831&amp;amp;atid=719134"&gt;Sourceforge bug tracker&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Feature requests are tracked using the &lt;a href="http://taskcoach.uservoice.com"&gt;UserVoice &lt;/a&gt;website.&lt;/li&gt;&lt;li&gt;Support requests are tracked with the &lt;a href="https://sourceforge.net/tracker/?group_id=130831&amp;amp;atid=719135"&gt;Sourceforge support request tracker&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Translations are both in the Subversion repository and &lt;a href="https://translations.launchpad.net/taskcoach"&gt;Launchpad &lt;/a&gt;so that translators can edit them.&lt;/li&gt;&lt;li&gt;Mailinglist discussions are &lt;a href="http://groups.yahoo.com/group/taskcoach/messages"&gt;archived&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Old releases of Task Coach are &lt;a href="http://www.taskcoach.org/download_old_releases.html"&gt;archived&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;This seems pretty complete to me, so I'd say this practice is fully implemented by the Task Coach project.&lt;br /&gt;&lt;br /&gt;The second specific practice (SP1.2) for SG1 is "Establish and maintain a configuration management and change management system for controlling work products."  Subversion is the configuration management system for source code and the website. For bug reports and support requests we use the Sourceforge trackers. For feature requests we use UserVoice. For translations we use Launchpad. For mailinglists we use Yahoo Groups  and its archives. Old releases of Task Coach are archived at Sourceforge. I think we've got this one covered as well.&lt;br /&gt;&lt;br /&gt;The third specific practice (SP1.3) is "Create or release baselines for internal use and for delivery to the customer." As specified in our &lt;a href="http://www.taskcoach.org/devinfo.html"&gt;developer info&lt;/a&gt;, under the Subversion  usage conventions heading, we create branches in Subversion for each feature (x.y) release and tag each bug fix (x.y.z) release. The &lt;a href="http://www.taskcoach.org/changes.html"&gt;change history&lt;/a&gt; details for each release (=baseline) which features are added and which bugs are fixed. CMMI says that baselines have to be formally reviewed. That's not something we do. Instead, we make sure Task Coach is always ready for release. The head of a release branch is always ready for release. The trunk most of the time. The reason for this approach is that users can benefit from fixed bugs and new features as soon as possible. I guess that makes this practice largely implemented.&lt;br /&gt;&lt;br /&gt;Since SP1.1 and SP1.2 are fully implemented and SP1.3 largely, I would say that the first specific goal of CM is achieved.&lt;br /&gt;&lt;br /&gt;The second specific goal of CM is "Changes to the work products under configuration management are&lt;br /&gt;tracked and controlled."  CMMI expects organisations to implement two practices to achieve this goal.&lt;br /&gt;&lt;br /&gt;The first practice of the second goal (SP2.1) of CM says "Track change requests for the configuration items." Change requests include changed or new requirements as well as bug reports. As mentioned above, we track change requests in the UserVoice system and the Sourceforge bug tracker. For each change request we keep track of the status, closing it when a new release of Task Coach is available that includes the new feature or fix. Conclusion, this practice is implemented by the Task Coach project.&lt;br /&gt;&lt;br /&gt;The second practice of the second goal (SP2.2) is "Control changes to the configuration items." CMMI explains that control means: "Control is maintained over the configuration of the work product baseline. This control includes tracking the configuration of each of the configuration items, approving a new configuration if necessary, and updating the baseline." We track changes to the Subversion repository by means of a &lt;a href="https://sourceforge.net/mailarchive/forum.php?forum_name=taskcoach-commits"&gt;commit-message mailinglist&lt;/a&gt;. Whenever a developer checks in changes to the repository, an email message is mailed to that mailinglist, notifying the other developer (and possible other interested parties) of the changes. Only developers are allowed to make changes to the source code. Users are allowed to submit bug reports and feature requests, but the status is monitored and updated by the developers. The baseline is updated as part of the &lt;a href="http://taskcoach.svn.sourceforge.net/viewvc/taskcoach/trunk/taskcoach/release.py?revision=3327&amp;amp;view=markup"&gt;release process&lt;/a&gt;. Practice fully implemented, I'd say.&lt;br /&gt;&lt;br /&gt;Since both specific practices of SG2 are implemented, this must mean SG2 is achieved.&lt;br /&gt;&lt;br /&gt;The third specific goal (SG3) of CM says that "Integrity of baselines is established and maintained." To achieve this goal, CMMI expects organisations to implement another two specific practices.&lt;br /&gt;&lt;br /&gt;The first specific practice (SP3.1) of the third goal is "Establish and maintain records describing configuration items." CMMI suggests, in the subpractices of SP3.1, to record configuration management actions and ensure that relevant stakeholders have access to and knowledge of the configuration status of the configuration items. We do this via Subversion and the commit-messages mailinglist mentioned above for the source code and via the Sourceforge bug tracker, UserVoice feature requests, and the change history. CMMI also suggests to specify the latest version of the baselines. This is done quite prominently on the &lt;a href="http://www.taskcoach.org"&gt;Task Coach website&lt;/a&gt;, by means of announcements via the Task Coach users mailinglist and via &lt;a href="http://twitter.com/taskcoach"&gt;twitter&lt;/a&gt;. CMMI also suggests to identify the versions of configuration items that constitute a particular baseline. We do this by tagging each release in Subversion. Differences between baselines are described in the change history mentioned before. And finally, CMMI advices us to revise the status and history of configuration items as necessary. Again, Subversion supports this for source code. For other configuration items, such as bug reports and feature requests, the status is updated by the developers using the administrative user interface provided by the Sourceforge and UserVoice websites. Conclusion, practice fully implemented.&lt;br /&gt;&lt;br /&gt;The second specific practice (SP3.2) of SG3 reads "Perform configuration audits to maintain integrity of the configuration baselines." CMMI defines configuration audit as "An audit conducted to verify that a configuration item, or a collection of configuration items that make up a baseline, conforms to a specified standard or requirement."  This something we do not do on a regular basis. We probably should, because we often run into bug reports that should be closed because the reported bug has been fixed, or feature requests that should be closed because the feature has been implemented. Often, this is caused by duplicate bug reports and feature requests. Anyhow, this practice is not implemented by the Task Coach project.&lt;br /&gt;&lt;br /&gt;Since one practice of SG3 is fully implemented and one is not, SG3 is not satisfied.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-6776979067858079518?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/6776979067858079518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=6776979067858079518' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6776979067858079518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6776979067858079518'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2010/07/configuration-management-for-task-coach.html' title='Configuration Management for Task Coach'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-9135857864778443147</id><published>2010-07-12T11:41:00.000-07:00</published><updated>2010-08-15T05:16:54.085-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements'/><category scheme='http://www.blogger.com/atom/ns#' term='maturity'/><category scheme='http://www.blogger.com/atom/ns#' term='cmmi'/><title type='text'>Requirements management for Task Coach</title><content type='html'>As announced in a &lt;a href="http://taskcoach.blogspot.com/2010/07/maturity-of-open-source-projects.html"&gt;previous posting&lt;/a&gt;, I am investigating &lt;a href="http://taskcoach.blogspot.com/2010/07/maturity-of-open-source-projects.html"&gt;which of the CMMI goals are achieved by the Task Coach project&lt;/a&gt;. The first process area I am looking at is Requirements Management (REQM). REQM is an Engineering process area at level two of the CMMI for Development. Because REQM is part of the core model foundation, it is also part of the other two CMMI constellations, CMMI for Services and CMMI for Acquisition. But here, I'll be looking at REQM from a development perspective.&lt;br /&gt;&lt;br /&gt;According to the CMMI, "The purpose of Requirements Management (REQM) is to manage the &lt;span style="font-style: italic;"&gt;requirements &lt;/span&gt;of the &lt;span style="font-style: italic;"&gt;project&lt;/span&gt;’s &lt;span style="font-style: italic;"&gt;products and product components&lt;/span&gt; and to identify inconsistencies between those requirements and the project’s &lt;span style="font-style: italic;"&gt;plans and work products&lt;/span&gt;." (emphasis mine).  The purpose has four interesting concepts:  (a) a project, (b) the project's products and product components, (c) requirements of the project's products and product components that need to be managed and (d) the project's plans and work products that need to be kept consistent with the requirements.&lt;br /&gt;&lt;br /&gt;(a) We need to decide what the project is. Since we're using Task Coach as a guinea pig, the project must be the Task Coach project. The Task Coach project is staffed by two developers (Jérôme and myself) and supported by dozens of translators, beta testers, bug reporters, etc.&lt;br /&gt;&lt;br /&gt;(b) The Task Coach project has two main products: the desktop version of Task Coach and the iPhone/iPod/iPad version of Task Coach. Because Jérôme is the only one working on the iPhone/iPod/iPad version at the moment, I'll limit the scope of this investigation to the desktop version of Task Coach, currently at release 1.0.7.&lt;br /&gt;&lt;br /&gt;(c) Now on to the requirements. CMMI defines requirements as "(1) A condition or capability needed by a user to solve a problem or achieve an objective. (2) A condition or capability that must be met or possessed by a product or product component to satisfy a contract, standard, specification, or other formally imposed documents. (3) A documented representation of a condition or capability as in (1) or (2)." Obviously, (2) doesn't apply for Task Coach since there are no formally imposed documents. (1) does apply. We collect requirements on &lt;a href="http://taskcoach.uservoice.com/"&gt;UserVoice&lt;/a&gt;, a website that allows users to request features and vote for existing feature requests.&lt;br /&gt;&lt;br /&gt;(d) The final concept in the purpose of REQM is the project's plans and work products that need to be kept consistent with the requirements. Since this is an open source project, there is not much planning going on.  Progress is mostly determined by the amount of time the developers have available and are willing to spend on the project. Work products are defined as "In the CMMI Product Suite, a useful result of a process. This can include files, documents, products, parts of a product, services, process descriptions, specifications, and invoices. A key distinction between a work product and a product component is that a work product is not necessarily part of the product." So, work products for Task Coach are obviously product components like source code and tests, but also include things like the &lt;a href="http://www.taskcoach.org/"&gt;Task Coach website&lt;/a&gt; and &lt;a href="http://tech.groups.yahoo.com/group/taskcoach/message/2009"&gt;announcement emails&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Having determined how to interpret the main concepts from REQM in the light of Task Coach, we move on to the goals and practices of REQM. REQM has one specific goal and, like all CMMI process areas, five generic goals. For now, I'll only be looking at specific goals.&lt;br /&gt;&lt;br /&gt;The specific goal (SG1) of REQM is quite similar to the purpose and reads "Requirements are managed and inconsistencies with project plans and work products are identified."  CMMI expects organisations to perform five practices to achieve this goal.&lt;br /&gt;&lt;br /&gt;The first specific practice (SP1.1) is "Develop an understanding with the requirements providers on the meaning of the requirements." As mentioned before, Task Coach uses &lt;a href="http://taskcoach.uservoice.com/"&gt;UserVoice &lt;/a&gt;to collect feature requests. UserVoice also allows for &lt;a href="http://taskcoach.uservoice.com/forums/26465-desktop-version-windows-linux-mac-of-task-coach/suggestions/289130-task-status-and-start-dates-based-on-task-dependen"&gt;discussing feature requests&lt;/a&gt;. In the subpractices of SP1.1, CMMI suggests establishing criteria for determining appropriate requirements providers and criteria for evaluating and accepting requirements.  The first we don't need at this time; everybody is allowed to submit feature requests. The second might be good to have so that people submit feature requests that have a higher chance of getting implemented. However, since the subpractices are informative material we don't have to implement them. My conclusion is that the Task Coach project has implemented this practice.&lt;br /&gt;&lt;br /&gt;The second practice (SP1.2) of REQM is "Obtain commitment to the requirements from the project participants." Since there are only two developers, volunteering to work on a feature request is the main form of commitment. By starting to work on a specific requirement, a developer shows commitment to that requirement. Practice implemented, I conclude.&lt;br /&gt;&lt;br /&gt;The third practice (SP1.3) is "Manage changes to the requirements as they evolve during the project." New and changed requirements are tracked on &lt;a href="http://taskcoach.uservoice.com/"&gt;UserVoice&lt;/a&gt; by means of feature requests. The status of requirements (started, completed, declined) is tracked there as well. Released features are listed in the &lt;a href="http://www.taskcoach.org/changes.html"&gt;change history&lt;/a&gt; of the product, with links to the originating requests on UserVoice. Again, practice implemented, I think.&lt;br /&gt;&lt;br /&gt;The fourth practice (SP1.4) of REQM is "Maintain bidirectional traceability among the requirements and work products." The idea of this practice is that by maintaining bidirectional traceability, the project is able to check that all requirements have been properly addressed in work products and that all work products can be traced to a valid source requirement. This is particularly important when doing impact analyses of changing requirements. Task Coach doesn't maintain requirements traceability, other than links from the &lt;a href="http://www.taskcoach.org/changes.html"&gt;change history&lt;/a&gt; to the feature requests on  &lt;a href="http://taskcoach.uservoice.com/"&gt;UserVoice&lt;/a&gt;. But that limited traceability doesn't help with impact analysis. So this practice is not implemented.&lt;br /&gt;&lt;br /&gt;The fifth and last specific practice (SP1.5) is "Identify inconsistencies between the project plans and work products and the requirements."   Task Coach doesn't have much of a project plan, so there can't be many inconsistencies there. Inconsistencies between requirements and work products are identified via the feature request submission "process". When people submit a feature request, we are notified by email and check whether the requested feature hasn't &lt;a href="http://taskcoach.uservoice.com/forums/26465-desktop-version-windows-linux-mac-of-task-coach/suggestions/885831-estimated-tasktime?ref=title"&gt;been implemented already&lt;/a&gt;. We also check for &lt;a href="http://taskcoach.uservoice.com/forums/26465-desktop-version-windows-linux-mac-of-task-coach/suggestions/730212-manager-for-reminders-instead-of-just-a-box-?ref=title"&gt;duplicate requests&lt;/a&gt;. When a features is completed, the corresponding feature request is &lt;a href="http://taskcoach.uservoice.com/forums/26465-desktop-version-windows-linux-mac-of-task-coach/suggestions/641157-task-names-for-displaying-task-window-?utm_campaign=ShortUrls&amp;amp;utm_medium=generic&amp;amp;utm_source=taskcoach.uservoice.com"&gt;marked as completed&lt;/a&gt;. Is this enough to identify inconsistencies between work products and requirements? I think for us it is.&lt;br /&gt;&lt;br /&gt;To summarize, SP1.1, SP1.2 and SP1.3 have been implemented by the Task Coach project. SP1.4 has not. SP1.5 has been implemented partly, for the part that is relevant. Now, does the Task Coach project achieve the specific goal of REQM: "Requirements are managed and inconsistencies with project plans and work products are identified."? My judgement is that yes, we do. But, IANAL (I Am Not A Lead Appraiser) so comments are welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-9135857864778443147?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/9135857864778443147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=9135857864778443147' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/9135857864778443147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/9135857864778443147'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2010/07/requirements-management-for-task-coach.html' title='Requirements management for Task Coach'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-6987042301607217259</id><published>2010-07-12T08:56:00.000-07:00</published><updated>2010-07-12T11:41:27.107-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit tests'/><category scheme='http://www.blogger.com/atom/ns#' term='maturity'/><category scheme='http://www.blogger.com/atom/ns#' term='cmmi'/><title type='text'>Maturity of open source projects</title><content type='html'>In my work as an IT consultant I sometimes use open source projects as reference for judging the quality and maturity of in-house or commercial software projects. Task Coach, for example, has more than 3500 automated unit tests that cover 63% of the  &lt;a href="http://www.ohloh.net/p/taskcoach/analyses/latest"&gt;100.000 Python lines of code&lt;/a&gt;. Since Task Coach is just a hobby project, this in my mind makes it a lower boundary for assessing the amount and coverage of unit tests in other projects.&lt;br /&gt;&lt;br /&gt;Last week I was attending the official Introduction to the &lt;a href="http://www.sei.cmu.edu/cmmi"&gt;CMMI &lt;/a&gt;course taught by André Heijstek (of &lt;a href="http://www.improvementfocus.com/pages/en/home.php?lang=EN"&gt;Improvement Focus&lt;/a&gt;). While we were discussing the different process areas in the CMMI for Development, I started wondering if and how CMMI would apply to open source organizations and projects. Maybe the CMMI doesn't apply to open source projects at all. However, if a project like Task Coach does achieve a significant portion of the CMMI goals, then that would be another stick in the ground to compare other organization and projects against.&lt;br /&gt;&lt;br /&gt;So, the plan is to investigate which of the CMMI for Development v1.2 (and Services too probably; user support is an integral part of open source projects) goals are met by the Task Coach organization and project. Since there are many CMMI process areas I will assess each of the CMMI process areas in a separate posting. As I'm obviously biased, I'll invite André, who is a certified lead appraiser for CMMI, to review my assessments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-6987042301607217259?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/6987042301607217259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=6987042301607217259' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6987042301607217259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6987042301607217259'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2010/07/maturity-of-open-source-projects.html' title='Maturity of open source projects'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-6439562594301658279</id><published>2009-11-22T08:45:00.000-08:00</published><updated>2009-11-22T09:46:43.407-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='i18n'/><category scheme='http://www.blogger.com/atom/ns#' term='release tests'/><category scheme='http://www.blogger.com/atom/ns#' term='defect prevention'/><title type='text'>A bug caused by "make clean"</title><content type='html'>A Task Coach user reported today that one of the translations (Simplified Chinese) was not working. Not working meaning that instead of the translated texts in the user interface, the original English texts would be shown. A little investigation showed that most translations were OK, but a few were not.&lt;br /&gt;&lt;br /&gt;Now, it is necessary to know how Task Coach deals with translations. Task Coach uses Launchpad for translations. Launchpad provides the translations as .po files. These .po files are transformed into Python sources files that are in turn bundled with the different Task Coach installers/packages.&lt;br /&gt;&lt;br /&gt;I noticed that a few of these generated Python source files were missing from the folder where the translations are stored. Asking myself how some of these could be missing while others were not, I decided that one possible explanation would be the Makefile not removing all files. So I checked the "clean" target in the Makefile and indeed, it would only remove the "??_??.py" files and not the "??.py" files. That means zh_CN.py would get removed, but nl.py not. So that explains why some translations, such as Simplified Chinese (zh_CN) and Brazilian Portuguese (pt_BR),  were missing and others, such as Dutch (nl) and French (fr), not.&lt;br /&gt;&lt;br /&gt;The final question is, of course, how to prevent this from happening ever again. We already have a set of release tests. I guess that adding a release test that checks whether all translations are included in the Task Coach installers and packages should do it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-6439562594301658279?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/6439562594301658279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=6439562594301658279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6439562594301658279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/6439562594301658279'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2009/11/bug-caused-by-make-clean.html' title='A bug caused by &quot;make clean&quot;'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-7919698572604314711</id><published>2008-06-27T13:27:00.000-07:00</published><updated>2008-06-27T13:50:49.432-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='deployment'/><title type='text'>Automating .deb building</title><content type='html'>Some time ago, Stani helped me to create a Task Coach package in Debian package format (.deb). This is the package format that is also used by Linux distributions derived from Debian, such as Ubuntu. Since I want the release process of Task Coach to be as easy as possible, I decided to automate the package build process as much as possible. &lt;br /&gt;&lt;br /&gt;I wrote a distutils command that creates a Debian package from a source distribution, as created by &lt;tt&gt;python setup.py sdist&lt;/tt&gt;. This new distutils command, called &lt;tt&gt;bdist_deb&lt;/tt&gt;, copies the source distribution, unpacks it, adds the necessary Debian control files and compiles the package using the regular packaging tools. &lt;br /&gt;&lt;br /&gt;The &lt;tt&gt;bdist_deb&lt;/tt&gt; command takes a large number of parameter since it needs a lot of information to create the .deb. For example, application title, description, version, license information, copyright, author, maintainer, etc. In the case of Task Coach, most of the information is already available in a meta data source file, and easily passed to the &lt;tt&gt;bdist_deb&lt;/tt&gt; command from the distutils setup script. &lt;br /&gt;&lt;br /&gt;Since this was specifically developed for Task Coach it is probably not completely generalized. Nevertheless, I hope it provides a starting point for other developers that want to create proper Debian packages for their Python applications.&lt;br /&gt;&lt;br /&gt;Check out the &lt;tt&gt;&lt;a href="http://taskcoach.svn.sourceforge.net/viewvc/taskcoach/branches/Release0_70_Branch/buildlib/bdist_deb.py?view=markup"&gt;bdist_deb&lt;/a&gt;&lt;/tt&gt; command and the invocation of the command in the distutils &lt;tt&gt;&lt;a href="http://taskcoach.svn.sourceforge.net/viewvc/taskcoach/branches/Release0_70_Branch/make.py?view=markup"&gt;setup&lt;/a&gt;&lt;/tt&gt; script (called &lt;tt&gt;make.py&lt;/tt&gt;), starting at line 109.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-7919698572604314711?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/7919698572604314711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=7919698572604314711' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/7919698572604314711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/7919698572604314711'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2008/06/automating-deb-building.html' title='Automating .deb building'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-9212326862679824908</id><published>2008-04-06T11:24:00.000-07:00</published><updated>2008-04-06T11:46:45.746-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><title type='text'>Migrating from CVS to Subversion</title><content type='html'>I recently migrated the Task Coach source code from its Sourceforge CVS repository to a &lt;a href="https://sourceforge.net/svn/?group_id=130831"&gt;Subversion repository&lt;/a&gt;, also on Sourceforge. I followed the &lt;a href="http://alexandria.wiki.sourceforge.net/Subversion+-+Version+Control+for+Source+Code#tocSubversion%20-%20Version%20Control%20for%20Source%20Code6"&gt;migration instructions&lt;/a&gt; at the Sourceforge website and all went smoothly. &lt;br /&gt;&lt;br /&gt;Because the &lt;tt&gt;cvs2svn&lt;/tt&gt; script needs the CVSROOT module present, you can only remove it after &lt;tt&gt;cvs2svn&lt;/tt&gt; has run, i.e. you need remove it from the svndump file that &lt;tt&gt;cvs2svn&lt;/tt&gt; creates. &lt;tt&gt;svndumpfilter&lt;/tt&gt; does do that for you. Unfortunately, the CVSROOT module is present in the svndump file multiple times: not only in the trunk folder, but also in all branch and version folders of the svndump. A script to help with finding all those CVSROOT occurences would be nice. &lt;br /&gt;&lt;br /&gt;Marcin Zajączkowski helped me out with a shell script. I used it as the basis for a little python script that removes specific folders or files from your svndump file. Use as you like.&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;&lt;br /&gt;import os, optparse&lt;br /&gt;&lt;br /&gt;usage = '''Usage: %prog dumpfile path [path...]&lt;br /&gt;Remove path(s) from &amp;lt;dumpfile&amp;gt; and write new dump file to &amp;lt;dumpfile&amp;gt;.out'''&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class PathRemoverOptionParser(optparse.OptionParser):&lt;br /&gt;    def __init__(self):&lt;br /&gt;        optparse.OptionParser.__init__(self, usage)&lt;br /&gt;&lt;br /&gt;    def parse_args(self):&lt;br /&gt;        options, args = optparse.OptionParser.parse_args(self)&lt;br /&gt;        if len(args) &lt; 2:&lt;br /&gt;            self.error('provide both dumpfile and path to remove')&lt;br /&gt;        dumpFile, paths = args[0], args[1:]&lt;br /&gt;        if not os.path.exists(dumpFile):&lt;br /&gt;            self.error('dumpfile (%s) does not exist'%dumpFile)&lt;br /&gt;        return dumpFile, paths&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def branches(dumpFile, paths, pathPrefix='Node-path: '):&lt;br /&gt;    ''' Find branches in the dumpFile that contain the paths. '''&lt;br /&gt;    for line in file(dumpFile):&lt;br /&gt;        if line.startswith(pathPrefix):&lt;br /&gt;            for path in paths:&lt;br /&gt;                if line.endswith(path+'\n'):&lt;br /&gt;                    yield line[len(pathPrefix):-1] # yield branch&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;parser = PathRemoverOptionParser()&lt;br /&gt;dumpFile, paths = parser.parse_args()&lt;br /&gt;excludes = ' '.join(branches(dumpFile, paths))&lt;br /&gt;if not excludes:&lt;br /&gt;    parser.error('path(s) (%s) not found'%', '.join(paths))&lt;br /&gt;&lt;br /&gt;os.system('svndumpfilter exclude %s &lt; %s &gt; %s.out'%(excludes, dumpFile, dumpFile))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-9212326862679824908?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/9212326862679824908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=9212326862679824908' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/9212326862679824908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/9212326862679824908'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2008/04/migrating-from-cvs-to-subversion.html' title='Migrating from CVS to Subversion'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-5706024626180925251</id><published>2007-10-09T12:01:00.000-07:00</published><updated>2007-10-09T12:25:00.935-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='deployment'/><title type='text'>Installing with or without administrator privileges</title><content type='html'>To create the installer for Task Coach on Windows, I use the excellent &lt;a href="http://www.jrsoftware.org/isinfo.php"&gt;Innosetup&lt;/a&gt; tool. I upgraded to the latest version of Innosetup a while ago but didn't notice immediately that the installer created by this new version of Innosetup required the user to have administrator privileges. Because Task Coach is aimed at ordinary users, that is not acceptable. &lt;br /&gt;&lt;br /&gt;It took me some time to find out how to have the installer work for both users with and without administrator privileges. I'm recording the solution here so that other developers may benefit from it. &lt;br /&gt;&lt;br /&gt;In the registry section of the Innosetup script I included two versions of the lines that associate the ".tsk" extension with Task Coach. The first four lines (*) are used if the user has administrator privileges (Check: IsAdminLoggedOn), but the last four lines are used if the user has no administrator rights (Check: not IsAdminLoggedOn). &lt;br /&gt;&lt;br /&gt;(*) I had to split the lines to prevent them from being clipped. The line continuations are indented.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[Registry]&lt;br /&gt;Root: HKCR; Subkey: ".tsk"; ValueType: string; ValueName: "";&lt;br /&gt;   ValueData: "TaskCoach"; Flags: uninsdeletevalue; &lt;br /&gt;   Check: IsAdminLoggedOn&lt;br /&gt;Root: HKCR; Subkey: "TaskCoach"; ValueType: string; ValueName: ""; &lt;br /&gt;   ValueData: "Task Coach File"; Flags: uninsdeletekey; &lt;br /&gt;   Check: IsAdminLoggedOn&lt;br /&gt;Root: HKCR; Subkey: "TaskCoach\DefaultIcon"; ValueType: string; &lt;br /&gt;    ValueName: ""; ValueData: "{app}\TaskCoach.EXE,0"; &lt;br /&gt;    Check: IsAdminLoggedOn&lt;br /&gt;Root: HKCR; Subkey: "TaskCoach\shell\open\command"; &lt;br /&gt;    ValueType: string; ValueName: ""; &lt;br /&gt;    ValueData: """{app}\TaskCoach.EXE"" ""%%1"""; &lt;br /&gt;    Check: IsAdminLoggedOn&lt;br /&gt;Root: HKCU; Subkey: "Software\Classes\.tsk"; ValueType: string; &lt;br /&gt;    ValueName: ""; ValueData: "TaskCoachFile"; &lt;br /&gt;    Flags: uninsdeletevalue; Check: not IsAdminLoggedOn&lt;br /&gt;Root: HKCU; Subkey: "Software\Classes\TaskCoachFile"; &lt;br /&gt;    ValueType: string; ValueName: ""; ValueData: "Task Coach File"; &lt;br /&gt;    Flags: uninsdeletekey; Check: not IsAdminLoggedOn&lt;br /&gt;Root: HKCU; Subkey: "Software\Classes\TaskCoachFile\DefaultIcon"; &lt;br /&gt;    ValueType: string; ValueName: ""; &lt;br /&gt;    ValueData: "{app}\TaskCoach.EXE,0"; Check: not IsAdminLoggedOn&lt;br /&gt;Root: HKCU; Subkey: "Software\Classes\TaskCoachFile\shell\open\command"; &lt;br /&gt;    ValueType: string; ValueName: ""; &lt;br /&gt;    ValueData: """{app}\TaskCoach.EXE"" ""%%1"""; &lt;br /&gt;    Check: not IsAdminLoggedOn&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-5706024626180925251?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/5706024626180925251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=5706024626180925251' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/5706024626180925251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/5706024626180925251'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2007/10/installing-with-or-without.html' title='Installing with or without administrator privileges'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-7120427708163224044</id><published>2007-08-26T13:50:00.000-07:00</published><updated>2007-08-26T14:31:56.118-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit tests'/><category scheme='http://www.blogger.com/atom/ns#' term='i18n'/><title type='text'>Testing translations</title><content type='html'>A &lt;a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1772019&amp;group_id=130831&amp;atid=719134"&gt;recent bug&lt;/a&gt; in Task Coach was caused by one of the translations being incorrect. So, I decided it was time to unittest the translations. For each translated string I wanted to check that certain conditions hold. For example, if the original string has a formatting operator (e.g. '%d' for digits) the translated string should contain the same formatting operator. These tests are relatively simple:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for formatter in '%s', '%d', '%.2f':&lt;br /&gt;  self.assertEqual(self.englishString.count(formatter), &lt;br /&gt;                   self.translatedString.count(formatter))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The challenge is how to create one unittest for each (language, string)-pair. This is not a good solution:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def testMatchingFormatting(self):&lt;br /&gt;  for language in getLanguages():&lt;br /&gt;    for english, translated in language.dictionary():&lt;br /&gt;      ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;because this unittest stops as soon as one translation is incorrect. &lt;br /&gt;&lt;p&gt;My first thought was that I could use decorators to unfold the loop, but after a few feeble attempts I decided  I am not smart enough to wrap my head around decorators. After some more experimenting I ended up with the code below. I put the loop outside the test class and explicitly create a new TestCase class for each (language, string)-pair. This generates a lot of unittests (over 7600 for the current version of Task Coach), but they run in less than 0.5 seconds, so that's a small price to pay for increased test coverage.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import test, i18n, meta, string&lt;br /&gt;&lt;br /&gt;class TranslationIntegrityTests(object):&lt;br /&gt;  ''' Unittests for translations. This class is &lt;br /&gt;      subclassed below for each translated string &lt;br /&gt;      in each language. '''&lt;br /&gt;      &lt;br /&gt;  def testMatchingFormatting(self):&lt;br /&gt;    for formatter in '%s', '%d', '%.2f':&lt;br /&gt;      self.assertEqual(self.englishString.count(formatter), &lt;br /&gt;                      self.translatedString.count(formatter))&lt;br /&gt;            &lt;br /&gt;  def testMatchingAccelerators(self):&lt;br /&gt;    # snipped&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def getLanguages():&lt;br /&gt;  return [language for language in \&lt;br /&gt;          meta.data.languages.values() \&lt;br /&gt;          if language is not None]&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;def createTestCaseClassName(language, englishString, &lt;br /&gt;  prefix='TranslationIntegrityTest'):&lt;br /&gt;  ''' Generate a class name for the test case class based &lt;br /&gt;      on the language and the English string. '''&lt;br /&gt;&lt;br /&gt;  # Make sure we only use characters allowed in Python &lt;br /&gt;  # identifiers:&lt;br /&gt;  englishString = englishString.replace(' ', '_')&lt;br /&gt;  allowableCharacters = string.ascii_letters + \&lt;br /&gt;                        string.digits + '_'&lt;br /&gt;  englishString = ''.join([char for char in englishString \&lt;br /&gt;                           if char in allowableCharacters])&lt;br /&gt;  className = '%s_%s_%s'%(prefix, language, englishString)&lt;br /&gt;  count = 0&lt;br /&gt;  while className in globals(): # Make sure className is unique&lt;br /&gt;      count += 1&lt;br /&gt;      className = '%s_%s_%s_%d'%(prefix, language, &lt;br /&gt;                                 englishString, count)&lt;br /&gt;  return className&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def createTestCaseClass(className, language, englishString, &lt;br /&gt;                        translatedString):&lt;br /&gt;  class_ = type(className, &lt;br /&gt;                (TranslationIntegrityTests, test.TestCase), &lt;br /&gt;                {})&lt;br /&gt;  class_.language = language&lt;br /&gt;  class_.englishString = englishString&lt;br /&gt;  class_.translatedString = translatedString&lt;br /&gt;  return class_&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;for language in getLanguages():&lt;br /&gt;  translation = __import__('i18n.%s'%language, &lt;br /&gt;                           fromlist=['dict'])&lt;br /&gt;  for english, translated in translation.dict.iteritems():        &lt;br /&gt;    className = createTestCaseClassName(language, english)&lt;br /&gt;    class_ = createTestCaseClass(className, language, &lt;br /&gt;                                 english, translated)&lt;br /&gt;    globals()[className] = class_&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-7120427708163224044?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/7120427708163224044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=7120427708163224044' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/7120427708163224044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/7120427708163224044'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2007/08/blog-post.html' title='Testing translations'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-8160778832010382972</id><published>2007-05-26T09:35:00.000-07:00</published><updated>2007-05-26T09:46:51.690-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>False positive</title><content type='html'>A few days ago AVG Anti-virus started reporting a trojan horse in Task Coach (0.63.2). A &lt;a href="http://sourceforge.net/mailarchive/forum.php?thread_name=67dd1f930705250854j13424e18ub11c827c546e1f40%40mail.gmail.com&amp;forum_name=py2exe-users"&gt;little investigation&lt;/a&gt; with the help of other py2exe users indicates that AVG detects a trojan in a specific part of py2exe. Py2exe is a program that is used to bundle python source code and the python interpreter into an executable that can be easily installed on Windows machines and doesn't require users to install python. It seems that someone wrote a trojan in python and bundled it with py2exe. Apparently, AVG is now triggered by py2exe instead of a signature that is specific for that trojan horse. It probably means that all applications bundled with py2exe are affected as well. What a bummer. But also kind of interesting to see how other applications, that have nothing to do with Task Coach itself, can cause &lt;a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1726048&amp;group_id=130831&amp;atid=719134"&gt;bug reports&lt;/a&gt; about Task Coach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-8160778832010382972?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/8160778832010382972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=8160778832010382972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/8160778832010382972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/8160778832010382972'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2007/05/false-positive.html' title='False positive'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-3345789326622593517</id><published>2006-10-14T07:52:00.000-07:00</published><updated>2006-10-14T08:16:54.076-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='release plan'/><title type='text'>The need for branches</title><content type='html'>Until now, I have tried to create a new release of Task Coach every two to four weeks. Each release would contain a mixture of bugfixes and new features. The nice thing of this release strategy is that I don't need to create multiple branches in the version control system. And simple is good, right?&lt;br /&gt;&lt;br /&gt;However, the feature I'm working on right now (hierarchical categories) turns out to be harder than I thought. At the same time, people have been reporting some bugs on the latest release that are pretty easy to fix. But, since I'm halfway the development of the hierarchical categories feature, the code is not in a releaseable state. So, I cannot release those bugfixes although they are in the version control system. And that is a waste, right?&lt;br /&gt;&lt;br /&gt;So, how to resolve this situation? The classical solution is to add a separate branch for the latest release, apply the bugfixes to that branch, and release a bugfix release from that branch. After that, one only needs to merge those bugfixes into the mainline and everything is fine again. Except for the added complexity of having to deal with multiple branches and merging, that is. The alternative solution, the one I have been using so far, is to add functionality in much smaller steps. Steps that are so small that the code is never 'not in a releaseable state' for more than, say, two weeks. Apparently, I have been not applying that strategy successfully lately, leading to the need for branching.&lt;br /&gt;&lt;br /&gt;Anyway, I'll try the branching, see how it works out, and then decide on how to proceed in the long run.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-3345789326622593517?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/3345789326622593517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=3345789326622593517' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/3345789326622593517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/3345789326622593517'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2006/10/until-now-i-have-tried-to-create-new.html' title='The need for branches'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-9157404811083938947</id><published>2006-09-21T06:52:00.000-07:00</published><updated>2006-09-21T06:53:52.282-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='duplication'/><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Duplication smells</title><content type='html'>Duplication. A programmer's worst nightmare. Does that sound over the top? Maybe it does, but I guess most programmers would agree that duplication is one of the worst code smells around. So, a programmer should do everything to prevent and reduce duplication, right? Well, I think that in the case of simple duplication we all agree on that. With simple I mean that two pieces of code are textually equal or very similar, e.g.:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;patterns.Publisher().registerObserver(self.onMatchAllChanged,&lt;br /&gt;   eventType='view.taskcategoryfiltermatchall')&lt;br /&gt;patterns.Publisher().registerObserver(self.onFilteredCategoriesChanged,&lt;br /&gt;   eventType='view.taskcategoryfilterlist')&lt;br /&gt;patterns.Publisher().registerObserver(self.onAddCategoryToTask,&lt;br /&gt;   eventType='task.category.add')&lt;br /&gt;patterns.Publisher().registerObserver(self.onRemoveCategoryFromTask,&lt;br /&gt;   eventType='task.category.remove')&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is actual code from Task Coach (&lt;span style="color: rgb(255, 153, 0);"&gt;blush&lt;/span&gt;) and represents a component registering itself as observer for different event types. Of course, this type of duplication is rather easy to fix, e.g.:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;callbacks = {'view.taskcategoryfiltermatchall': self.onMatchAllChanged, ...}&lt;br /&gt;publisher = patterns.Publisher()&lt;br /&gt;for eventType, callback in callbacks.items():&lt;br /&gt;   publisher.registerObserver(callback, eventType)&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;But then there's also duplication that's not strictly textual, but more structural. For example, two for-loops looping over the same datastructure but with a different body. An example from Task Coach again. These two event handlers update a check-listbox (a list with items that can be checked and unchecked by the user) when categories are added to or removed from a task:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;def onAddCategoryToTask(self, event):&lt;br /&gt;   for category in event.values():&lt;br /&gt;       if self._checkListBox.FindString(category) == wx.NOT_FOUND:&lt;br /&gt;           self._checkListBox.Append(category)&lt;br /&gt;   self.Enable(len(self.__taskList.categories()) &gt; 0)&lt;br /&gt;&lt;br /&gt;def onRemoveCategoryFromTask(self, event):&lt;br /&gt;   for category in event.values():&lt;br /&gt;       if category not in self.__taskList.categories():&lt;br /&gt;           self._checkListBox.Delete(self._checkListBox.FindString(category))&lt;br /&gt;   self.Enable(len(self.__taskList.categories()) &gt; 0)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Removing this type of duplication is more tricky. Refactoring to something like the following should work (untested):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;def updateCategoriesListbox(self, categories, updateNeeded, updateListbox):&lt;br /&gt;   for category in categories:&lt;br /&gt;       if updateNeeded(category):&lt;br /&gt;           updateListbox(category)&lt;br /&gt;   self.Enable(len(self.__taskList.categories()) &gt; 0)&lt;br /&gt;&lt;br /&gt;def onAddCategoryToTask(self, event):&lt;br /&gt;   def updateNeeded(category):&lt;br /&gt;       return self._checkListBox.FindString(category) == wx.NOT_FOUND&lt;br /&gt;&lt;br /&gt;   def updateListbox(category):&lt;br /&gt;       self._checkListBox.Append(category)&lt;br /&gt;&lt;br /&gt;   self.updateCategoriesListbox(event.values(), updateNeeded, updateListbox)&lt;br /&gt;&lt;br /&gt;def onRemoveCategoryFromTask(self, event):&lt;br /&gt;   def updateNeeded(category):&lt;br /&gt;       return category not in self.__taskList.categories()&lt;br /&gt;&lt;br /&gt;   def updateListbox(category):&lt;br /&gt;       self._checkListBox.Delete(self._checkListBox.FindString(category))&lt;br /&gt;&lt;br /&gt;   self.updateCategoriesListbox(event.values(), updateNeeded, updateListbox)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But this raises the question: is the increase in lines of code and number of functions worth the reduction of duplication? Or did I miss a more simple solution?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-9157404811083938947?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/9157404811083938947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=9157404811083938947' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/9157404811083938947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/9157404811083938947'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2006/09/duplication-smells.html' title='Duplication smells'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-1623057287574156362</id><published>2006-09-20T14:42:00.000-07:00</published><updated>2006-09-20T14:55:04.989-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements'/><category scheme='http://www.blogger.com/atom/ns#' term='release plan'/><title type='text'>Steering open source development</title><content type='html'>So far, steering the development of Task Coach has been very easy. Since I'm basically the only developer and it's a hobby project that I work on after hours, I've been adding functionality that &lt;span style="font-weight: bold;"&gt;I&lt;/span&gt; thought would be a good idea to add. Judging from reactions by users and on websites I think I did pick valuable features most of the time so far.&lt;br /&gt;&lt;br /&gt;However, the &lt;a href="https://sourceforge.net/tracker/?group_id=130831&amp;amp;atid=719137"&gt;list of feature requests&lt;/a&gt; has been growing much faster than I have been able to develop them. So, unless I get more people to work on Task Coach, I need to prioritize between features. I have been thinking about different possible ways to do that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Developing a release plan with a different focus per release. For example, the focus for a 1.0 release could be to add all functionality that would make Task Coach a full fledged stand-alone task manager. Then the 2.0 release could focus on integrating Task Coach with e-mail and calendar software (e.g. using vCal).&lt;/li&gt;&lt;li&gt;Letting people vote on features. Features with the most votes get implemented first. Unfortunately, Source Forge doesn't support anything like this, as far as I know.&lt;/li&gt;&lt;li&gt;Donation driven development. The features that gets the most donations is implemented first.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Maybe a combination of the above could work too. I'll have to ponder this issue some more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-1623057287574156362?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/1623057287574156362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=1623057287574156362' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/1623057287574156362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/1623057287574156362'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2006/09/steering-open-source-development.html' title='Steering open source development'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34747147.post-115878711372678986</id><published>2006-09-20T14:04:00.000-07:00</published><updated>2006-12-07T12:37:44.010-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit tests'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>About this blog</title><content type='html'>Software development is fun and hard at the same time. This blog discusses my experience with developing an open source desktop application called &lt;a href="http://www.taskcoach.org/"&gt;Task Coach.&lt;/a&gt; Task Coach is a task manager that supports hierarchical tasks, budget and time registration, categories, and more. For me, Task Coach is also a vehicle to experiment with software development, tools, and techniques. For example, I try to use test-driven development to steer the development of the software. So far, I like the way test-driven development allows me to add new functionality in a safe and gradual manner. I also like how having an extensive set of automated unit tests (+/- 1700  at the moment, that run in about 30 seconds) allows me to refactor the source code without (too much) fear of seriously breaking the application. Anyway, the plan is to use this blog to talk about ideas about software development, and as much as possible, discuss experience with applying this ideas to Task Coach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34747147-115878711372678986?l=taskcoach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taskcoach.blogspot.com/feeds/115878711372678986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34747147&amp;postID=115878711372678986' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/115878711372678986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34747147/posts/default/115878711372678986'/><link rel='alternate' type='text/html' href='http://taskcoach.blogspot.com/2006/09/software-development-is-fun-and-hard.html' title='About this blog'/><author><name>Frank</name><uri>http://www.blogger.com/profile/03326284039453250115</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KCOBbNfACPM/TDyQQhv1E_I/AAAAAAAAAXE/q1JQU67S1HM/s1600-R/57b9a115445b838fe078a88aec6e569d.png'/></author><thr:total>4</thr:total></entry></feed>
