<?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-2814339190488879140</id><updated>2012-02-01T22:43:15.717-08:00</updated><category term='web references'/><category term='constraint programming'/><category term='software python'/><category term='open source'/><category term='personal'/><category term='software testing'/><category term='python'/><category term='operations research'/><category term='software'/><category term='conferences'/><category term='coopr'/><title type='text'>William E. Hart's Blog</title><subtitle type='html'>Lessons learned and musing about software tools, software testing, computational experiments, optimization, operations research, and other interesting stuff that I run across...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-7545611097897864807</id><published>2012-02-01T22:41:00.000-08:00</published><updated>2012-02-01T22:43:15.724-08:00</updated><title type='text'>Science Fiction Comes to Life</title><content type='html'>One of my favorite authors is Vernor Vinge, who explores how the evolution of technology impacts future societies.&amp;nbsp; Vernor is a former professor of computer science, so it is perhaps no surprise that his tech focus appeals to me.&amp;nbsp; The novel &lt;a href="http://en.wikipedia.org/wiki/The_Peace_War"&gt;The Peace War&lt;/a&gt; imagines a post-apocalyptic society that is recovering from a world war that was prompted, in part, by a new force field generating device (called the Bobbler).&lt;br /&gt;&lt;br /&gt;There are all kinds of futuristic technologies described in this book, which is typical for Vinge's literature.&amp;nbsp; In one scene, the protagonist is about to be ambushed by a group of bad guys. He hands a gun to his teenage companion, who takes out the bad guys without hardly aiming the gun.&amp;nbsp; The trick is that the gun has computer-guided bullets, which the protagonist directed using his laptop.&lt;br /&gt;&lt;br /&gt;This sounded like standard sci-fi tech fantasy until I heard about the self-guided bullet that has been developed by &lt;a href="http://www.sandia.gov/"&gt;Sandia National Laboratories&lt;/a&gt;.&amp;nbsp; Mashable has a fun video describing the work (&lt;a href="http://news.yahoo.com/self-guided-bullet-strikes-target-mile-away-video-132957445.html"&gt;see Yahoo News&lt;/a&gt;).&amp;nbsp; Although I work at Sandia, the team working on this didn't invite me to the test range.&amp;nbsp; Perhaps I'll get to help test out the Bobbler.&amp;nbsp; &lt;span style="font-family: Verdana,sans-serif;"&gt;;)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-7545611097897864807?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/7545611097897864807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2012/02/science-fiction-comes-to-life.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/7545611097897864807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/7545611097897864807'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2012/02/science-fiction-comes-to-life.html' title='Science Fiction Comes to Life'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-8229453516441387848</id><published>2012-01-20T22:20:00.000-08:00</published><updated>2012-01-20T22:20:36.824-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><title type='text'>Testing Open Source Software</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Software_testing"&gt;Software testing&lt;/a&gt; is widely recognized as a &lt;a href="http://www.ibm.com/developerworks/websphere/library/techarticles/0306_perks/perks2.html"&gt;best practice for software development&lt;/a&gt;. Software tests define expected functionality, and they can focus developer efforts by providing an objective assessment of the state of a software project. Additionally, software testing data can provide evidence that a software package can be reliably used. For example, when evaluating whether to try out open source software, I routinely look for software testing data to confirm which platforms the software will run on, the versions of associated software that is used, and test coverage statistics that indicate how much of the the code is tested.&lt;br /&gt;&lt;br /&gt;Unfortunately, most open source software projects do not publish software test data.&amp;nbsp; I suspects that this indicates that a small fraction of OSS projects have robust test suites.&amp;nbsp; However, this also reflects another aspect of the OSS community:&amp;nbsp; hosting facilities for open source software do not support web-based testing facilities, like &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt;, that can be used by developers to remotely launch jobs on test machines with a variety of different configurations. This is not totally unexpected, since testing can be computationally intensive. &lt;br /&gt;&lt;br /&gt;Recently, I learned about &lt;a href="http://www.cloudbees.com/"&gt;CloudBees&lt;/a&gt;, which provides cloud services for building, running and managing Java applications. Happily &lt;a href="http://www.cloudbees.com/foss"&gt;CloudBees makes its Dev@cloud service freely available to open source projects&lt;/a&gt;! This includes the Jenkins testing service, which provides a limited number of CPU hours each month for testing an OSS project.&amp;nbsp; For example, the &lt;a href="http://cxxtest.com/"&gt;CxxTest&lt;/a&gt; project now hosts tests on a &lt;a href="https://cxxtest.ci.cloudbees.com/"&gt;CloudBees Jenkins server&lt;/a&gt;.&amp;nbsp; Cool!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-8229453516441387848?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/8229453516441387848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2012/01/testing-open-source-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8229453516441387848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8229453516441387848'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2012/01/testing-open-source-software.html' title='Testing Open Source Software'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-4301435118828461728</id><published>2012-01-08T07:34:00.000-08:00</published><updated>2012-01-08T07:34:48.579-08:00</updated><title type='text'>A Different Model for Writing Blog Posts</title><content type='html'>&lt;style&gt;&lt;!-- /* Font Definitions */@font-face {font-family:"ＭＳ 明朝"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 134676480 16 0 131072 0;}@font-face {font-family:"ＭＳ 明朝"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 134676480 16 0 131072 0;}@font-face {font-family:Cambria; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} /* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:Cambria; mso-ascii-font-family:Cambria; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"ＭＳ 明朝"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Cambria; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;}.MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-family:Cambria; mso-ascii-font-family:Cambria; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"ＭＳ 明朝"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Cambria; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;}@page WordSection1 {size:8.5in 11.0in; margin:1.0in 1.25in 1.0in 1.25in; mso-header-margin:.5in; mso-footer-margin:.5in; mso-paper-source:0;}div.WordSection1 {page:WordSection1;}--&gt;&lt;/style&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;This is a blog that I have been meaning to write for sometime.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;I occasionally take a look at thedownload statistics for this blog, and recently I was prompted to do this byother bloggers who were reporting their end-of-year statistics (e.g. see &lt;a href="http://punkrockor.wordpress.com/2012/01/02/year-in-review/"&gt;Laura McLay’s review of the Punk Rock OR blog&lt;/a&gt;). &lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Unlike Laura, I do not have impressive download statisticsto report about the many blogs I have written in 2011; frankly, I did notcreate many posts. However, an interesting pattern has emerged regarding thisblog’s readership:&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;there are a few keyblog posts that are frequently downloaded.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&lt;/span&gt;For example, my most frequently downloaded blog post is a survey ofPython plugin software, which I wrote in 2009.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&lt;/span&gt;I suspect that other bloggers have seen the same thing; they have a fewposts that are very popular because people do web searches on that topic.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;However, it is worth stepping back andthinking about the implications of this when writing a blog.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;When I first started blogging, I imagined that readers wouldview my blog the way that I view Laura’s blog.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&lt;/span&gt;They would use a RSS feeder to collect and view blog updates.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;These would be read shortly after they werepublished, and afterwards they might be used as a reference.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;This led me to create blogs that referencedeach other as part of a larger conversation on a topic.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;For example, after blogging about &lt;a href="http://wehart.blogspot.com/2009/01/python-plugin-frameworks.html"&gt;Python Plugin Frameworks&lt;/a&gt;, I had severalfollow-up blogs, including a brief description of &lt;a href="http://wehart.blogspot.com/2009/07/pyutilib-plugins.html"&gt;PyUtilib Plugins&lt;/a&gt; that I had developed.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;However, I have realized that my blogs are more likely to befound through internet searches focused on a topic.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;Consequently, the &lt;a href="http://wehart.blogspot.com/2009/01/python-plugin-frameworks.html"&gt;Python Plugin Frameworks&lt;/a&gt;post gets frequently read while the &lt;a href="http://wehart.blogspot.com/2009/07/pyutilib-plugins.html"&gt;PyUtilib Plugins&lt;/a&gt; post rarely getsread.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;Readers are finding my blog postsafter searching for “python plugins”. The narrower topic covered by the&lt;a href="http://wehart.blogspot.com/2009/07/pyutilib-plugins.html"&gt;PyUtilib Plugins&lt;/a&gt; post is not frequently referenced on the internet, andconsequently it is not strongly associated with the more general topic ofPython plugins; for example, I did not see it in the first three pages of agoogle search for “python plugin”.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;This suggests a different model for writing blog posts thathas already begun to affect my blogging.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&lt;/span&gt;Since blog posts are individual artifacts that may have enduring valueto readers, updating a blog post with new content makes more sense thancreating a new post that continues the previous discussion.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;For example, I’ve updated the &lt;a href="http://wehart.blogspot.com/2009/01/python-plugin-frameworks.html"&gt;Python PluginFrameworks&lt;/a&gt; post to include references to PyUtilib’s plugins.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;This may confuse readers of RSS feeds, and Ido not know that RSS feeds will automatically update their feed to capture updateslike this. I would assume not.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;However,this is clearly a strategy that will enhance the long-term impact of a blogpost on a specific topic.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-4301435118828461728?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/4301435118828461728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2012/01/different-model-for-writing-blog-posts.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4301435118828461728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4301435118828461728'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2012/01/different-model-for-writing-blog-posts.html' title='A Different Model for Writing Blog Posts'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-4183020730891467176</id><published>2012-01-07T22:09:00.000-08:00</published><updated>2012-01-22T13:52:36.632-08:00</updated><title type='text'>The Pyomo Book is Coming Soon</title><content type='html'>The Python Optimization Modeling Objects (Pyomo) package is an open source tool for modeling optimization applications in Python. Pyomo can be used to define symbolic problems, create concrete problem instances, and solve these instances with standard solvers. Pyomo provides a capability that is commonly associated with algebraic modeling languages such as AMPL, AIMMS, and GAMS, but Pyomo's modeling objects are embedded within a full-featured high-level programming language with a rich set of supporting libraries. Pyomo leverages the capabilities of the Coopr software library, which integrates Python packages for defining optimizers, modeling optimization applications, and managing computational experiments.&lt;br /&gt;&lt;br /&gt;Of course, there is very little online documentation describing Pyomo.&amp;nbsp; However, the first book on Pyomo is set to be published in February!&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://images.springer.com/cda/content/image/cda_displayimage.jpg?SGWID=0-0-16-1227219-0" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://images.springer.com/cda/content/image/cda_displayimage.jpg?SGWID=0-0-16-1227219-0" width="132" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;i&gt;Pyomo - Optimization Modeling in Python&lt;/i&gt;. William E. Hart, Carl Laird, Jean-Paul Watson and David L. Woodruff. Springer, 2012.&lt;/blockquote&gt;Here are some links if you want to learn more:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Pyomo-Optimization-Modeling-Springer-Applications/dp/1461432251"&gt;Amazon web page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springer.com/mathematics/book/978-1-4614-3225-8"&gt;Springer web page&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-4183020730891467176?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/4183020730891467176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2012/01/python-optimization-modeling-objects.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4183020730891467176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4183020730891467176'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2012/01/python-optimization-modeling-objects.html' title='The Pyomo Book is Coming Soon'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-4916609896022655675</id><published>2012-01-07T21:25:00.000-08:00</published><updated>2012-01-07T21:36:55.146-08:00</updated><title type='text'>A Pythonic C++ Parser</title><content type='html'>If you google for "python C++ parser", you will find a variety of internet discussions related to parsing C++ in Python.&amp;nbsp; C++ cannot be parsed by a LALR parser and it is well-known that parsing C++ is a nontrivial task.&amp;nbsp; Thus, these discussions generally fall into one of several categories:&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;It is too hard to parse C++ in Python, so use a package like &lt;a href="http://www.gccxml.org/HTML/Index.html"&gt;GCC_XML&lt;/a&gt; that does this for you.&amp;nbsp; If you really need to do something in Python, write a wrapper to GCC_XML.&lt;/li&gt;&lt;li&gt;It is too hard to perform a complete parse of C++ in Python, but we can use a LALR parser to collect gross structural information from C++ files.&amp;nbsp; The &lt;a href="http://pypi.python.org/pypi/CppHeaderParser/"&gt;CppHeaderParser&lt;/a&gt; is an example of this type of package, which uses the &lt;a href="http://www.dabeaz.com/ply/"&gt;ply&lt;/a&gt; parser to collect information about classes in header files. &lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;/ul&gt;In the recent release of &lt;a href="http://cxxtest.com/"&gt;CxxTest&lt;/a&gt;, I included a LALR C++ parser that is similar to &lt;a href="http://pypi.python.org/pypi/CppHeaderParser/"&gt;CppHeaderParser&lt;/a&gt;. CxxTest is a unit testing framework for C++ that is similar in spirit to JUnit, CppUnit, and xUnit. CxxTest is easy to use because it does not require precompiling a CxxTest testing library, it employs no advanced features of C++ (e.g. RTTI) and it supports a very flexible form of test discovery.&lt;br /&gt;&lt;br /&gt;CxxTest performs test discovery by searching C++header files for CxxTest test classes.  The default process fortest discovery is a simple process that analyzes each line in aheader file sequentially, looking for a sequence of lines thatrepresent class definitions and test method definitions.&lt;br /&gt;&lt;br /&gt;I added a new test discovery mechanism in CxxTest 4.0 that is basedon the a parser for the&lt;a href="http://www.computing.surrey.ac.uk/research/dsrg/fog/"&gt;Flexible ObjectGenerator (FOG)&lt;/a&gt; language, which is a superset of C++.  The grammarfor the FOG language was adapted to parse C++ header files toidentify class definitions and class inheritance relationships,class and namespace nesting of declarations, and class methods.This allows CxxTest to identify test classes that are definedwith complex inheritance relationships.&lt;br /&gt;&lt;p&gt;As I noted earlier, the CxxTest FOG parser is similar to the parser in CppHeaderParser.&amp;nbsp; Based on my limited knowledge of CppHeaderParser, here are some points of contrast between these two capabilities:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The FOG parser is embedded in CxxTest, while the CppHeaderParser is a stand-alone package.&amp;nbsp; Although I implemented the FOG parser as a separate component in CxxTest, I did not have specific design requirements that led me to make this a separate package.&amp;nbsp; (Interested parties should give me a buzz...)&lt;/li&gt;&lt;li&gt;The FOG parser is a specifically focused on the features required by CxxTest, and thus it does not parse out much of the information that CppHeaderParser provides (return values, argument types, etc).&lt;/li&gt;&lt;li&gt;The FOG parser was specifically designed to capture class inheritance relationships.&amp;nbsp; It is not clear to me that the CppHeaderParser does this.&lt;/li&gt;&lt;li&gt;The FOG parser is based on a superset of C++.&amp;nbsp; Thus, it can robustly parse C++ method and function definitions.&amp;nbsp; The examples provided by CppHeaderParser suggest that it can parser function and method declarations, but not headers that include their definitions.&amp;nbsp; (Of course, the FOG parser ignores these definitions, but that's the point.&amp;nbsp; The parser can do that.)&lt;/li&gt;&lt;li&gt;The FOG parser has been tested on a large set of C and C++ test files that are used to test the &lt;a href="http://scottmcpeak.com/elkhound/sources/elsa/"&gt;ELSA&lt;/a&gt; compiler.&amp;nbsp; This is a much more extensive test suite than is used to develop CppHeaderParser.&lt;/li&gt;&lt;/ol&gt;The point of this comparison is that the FOG parser may be of interest for other C++ parsing applications.&amp;nbsp; It has not been developed for general use, but it could easily be adapted to provide a more general capability. &amp;nbsp; &lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-4916609896022655675?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/4916609896022655675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2012/01/pythonic-c-parser.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4916609896022655675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4916609896022655675'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2012/01/pythonic-c-parser.html' title='A Pythonic C++ Parser'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-2132217907342810468</id><published>2011-10-05T23:14:00.000-07:00</published><updated>2011-10-05T23:14:22.796-07:00</updated><title type='text'>OptimJ is now free, but Ateji is closed</title><content type='html'>&lt;a href="http://www.ateji.com/"&gt;Atjei&lt;/a&gt;, the creater of OptimJ, is now closed. The OptimJ product is a Java extension that supports a simplified syntax for specifying optimization models. &amp;nbsp;It is sad to see this product be abandoned like this. &amp;nbsp;I do not know of any other optimization modeling tool that directly supports Java.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://yetanothermathprogrammingconsultant.blogspot.com/2011/10/ateji-defunct-optimj-now-free.html"&gt;Erwin Kalvelagen&lt;/a&gt; noted the demise of Ajeti, and commented that "&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, Arial, sans-serif; font-size: 13px; line-height: 16px;"&gt;I believe that some of the more complex data issues in practical modeling are often better (i.e. more efficiently) dealt with in a specialized language than in a traditional programming language."&lt;/span&gt; Pyomo is similar to OptimJ, in that it supports optimization modeling in Python. However, a premise that has guided Pyomo development is that users &lt;i&gt;will&lt;/i&gt; want to perform modeling in a full-featured programming language.&lt;br /&gt;&lt;br /&gt;Clearly, traditional programming languages are more verbose and complex than a domain-specific language. However, Python is arguably &lt;i&gt;much&lt;/i&gt; simpler to use than Java. In fact, I have gotten feedback from Pyomo users that suggests that they were not aware that they were developing models in Python; &amp;nbsp;they simply thought that it was another modeling language!&lt;br /&gt;&lt;br /&gt;Of course, I am a programmer who likes to do optimization. &amp;nbsp;My selfish reason for creating Pyomo is that I find domain-specific languages quite constraining. &amp;nbsp;In fact, I had thought that the use of Python for modeling and optimization would be attractive to optimization researchers. &amp;nbsp;Python is a great language for prototyping a complex idea, usually without losing too much performance. &amp;nbsp;I and other Pyomo developers have implemented complex optimizers in Python that directly interface with Pyomo models, and in most cases the runtime is dominated by LP subproblems. &amp;nbsp;Thus, there has been little motivation to develop custom, highly-optimized codes in languages like C++ based on these solvers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-2132217907342810468?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/2132217907342810468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2011/10/optimj-is-now-free-but-ateji-is-closed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2132217907342810468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2132217907342810468'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2011/10/optimj-is-now-free-but-ateji-is-closed.html' title='OptimJ is now free, but Ateji is closed'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-739589621014833433</id><published>2011-09-23T22:26:00.000-07:00</published><updated>2011-09-23T22:34:11.144-07:00</updated><title type='text'>Using AsciiDoc for Mathematical Publications</title><content type='html'>Technical writing is an integral part of my research in computer science and operations research. I have a long history using LaTeX, which is very well suited for writing technical articles that contain mathematical equations as well as code snippets.  Although LaTeX can readily generate postscript and PDF output files, I have been unimpressed with tools that generate HTML from LaTeX source.  Thus, I was intrigued by &lt;a href="http://www.methods.co.nz/asciidoc/"&gt;AsciiDoc&lt;/a&gt;, which promises to generate PDF, HTML and eBook formats. AsciiDoc is used to provide online documentation for software projects, and authors can publish book through  O'Rielly using this tool.  Thus, this is a well-developed document generation tool.&lt;br /&gt;&lt;br /&gt;I have successfully prototyped a draft book, &lt;i&gt;Getting Started with Coopr&lt;/i&gt;, and you can browse &lt;a href="https://software.sandia.gov/svn/public/coopr/coopr.doc/trunk/GettingStarted/current"&gt;the subversion repository for this document here&lt;/a&gt;. Note that the &lt;b&gt;Makefile&lt;/b&gt; file specifies build targets for PDF, HTML and eBook files.&lt;br /&gt;&lt;br /&gt;The advantage of AsciiDoc is that you can use a simple markup language to generate complex documents in a variety of formats.  Since this is a generic document-generation process, it is reasonable to expect that there will be limited control of document formatting.  (If you want a lot of control, you should just use LaTeX!) However, there are several major limitations to the document generation and format control that limit what you can do with AsciiDoc:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;Portable Mathematical Equations:&lt;/u&gt;&amp;nbsp; There is only limited support for generating eBook documents that contain mathematical equations.&amp;nbsp; I noticed that the ePUB standard was just updated this month to support MathML, so it is not clear that e-readers can handline MathML right now.&amp;nbsp; Additionally, AsciiDoc does not support the generation of the MathML XML from a high-level description (e.g. LaTeX math equations).&amp;nbsp; Thus, a user cannot easily prepare a document that generates both PDF (using LaTeX under the hood) and ePUB (using MathML under the hood).&amp;nbsp; I guess we will have to wait a few more years to see robust publishing of mathematics for eBooks.&lt;br /&gt;&lt;br /&gt; &lt;/li&gt;&lt;li&gt;&lt;u&gt;Formatting Mathematics:&lt;/u&gt;&amp;nbsp; For whatever reason, the default formatting of mathematical environments in HTML is not centered or indented (as it is in LaTeX).&amp;nbsp; Thus, it is much more difficult to read HTML documents containing mathematics.&amp;nbsp; I tried resolving this using an AsciiDoc filter, without luck.&amp;nbsp; I wound up rewriting the LatexMath macros to enforce this different formatting in HTML.&amp;nbsp; Unfortunately, these revised macros do not precisely match the syntax used by AsciiDoc.&amp;nbsp; {sigh}&lt;br /&gt; &lt;br /&gt; &lt;/li&gt;&lt;li&gt;&lt;u&gt;Document Authors:&lt;/u&gt;&amp;nbsp; The AsciiDoc markup language does not provide a convenient way to create a document with multiple authors.&amp;nbsp; Yes, I am not kidding.&amp;nbsp; There is a docbook configuration file that you can provide, which only works if the document generation process goes through docbook;&amp;nbsp; in my example, that works for ePUB and PDF files.&amp;nbsp; Thus, there does not appear to be a single, portable way for specifying multiple authors.&lt;/li&gt;&lt;li&gt;&lt;u&gt;Citations&lt;/u&gt;: It is noteworthy that none of the examples of online books referenced in the online AsciiDoc documentation contain citations or a bibliography.&amp;nbsp; The default format for bibliographies in AsciiDoc PDF files is as a numbered chapter or section, which differs from the normal convention in LaTeX (which I much prefer).&amp;nbsp; Thus, my AsciiDoc book uses the &lt;i&gt;colophon&lt;/i&gt; section, which is not numbered.&amp;nbsp; However, that means that it does not show up in the table of contents.&amp;nbsp; {sigh}&lt;br /&gt;&lt;br /&gt;Another issue with citations is that the examples provided by AsciiDoc do not correctly generate hyperlinks in the PDF file.&amp;nbsp; Basically, the &lt;i&gt;bibliography&lt;/i&gt; section type provided by AsciiDoc does not work well with the &lt;b&gt;dblatex&lt;/b&gt; tool used to generate the PDF.&amp;nbsp; My solution was to not use the &lt;i&gt;bibliography&lt;/i&gt; section type!&lt;br /&gt;&lt;br /&gt;Finally, the examples provided by AsciiDoc include citations in a list environment, which means that the PDF output contains a numbered list followed by a bracket citation reference.&amp;nbsp; Again, my solution was to avoid using the list;&amp;nbsp; the bibliography is simply a sequence of paragraphs, each of which is a citation with its associated anchor.&lt;/li&gt;&lt;/ul&gt;Despite these issues, I am planning to continue developing the Coopr documentation with AsciiDoc.&amp;nbsp; The lack of support for mathematical equations is a problem for ePUB documents, but most readers will be using this document to refer to the examples in python.&amp;nbsp; However, I would not consider using AsciiDoc for developing more complex documents, like a book intended for publication. There is too much customization that would be needed to get past the current limitations.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-739589621014833433?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/739589621014833433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2011/09/using-asciidoc-for-mathematical.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/739589621014833433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/739589621014833433'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2011/09/using-asciidoc-for-mathematical.html' title='Using AsciiDoc for Mathematical Publications'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-2315310923453885301</id><published>2011-08-05T06:03:00.000-07:00</published><updated>2011-08-05T06:04:22.982-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coopr'/><title type='text'>Coopr Download Fun</title><content type='html'>I stumbled across the following site, which provides download statistics for PyPI Python optimization packages:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://taichino.appspot.com/pypi_ranking/keyword/optimization"&gt;http://taichino.appspot.com/pypi_ranking/keyword/optimization&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It was fun to see the different download package statistics.  I'm quite curious that coopr.pysos has the highest number of downloads, since IMHO this package doesn't have much interesting functionality...  Hmmm...&lt;br /&gt;&lt;br /&gt;Another surprise for me is that so many optimization Python packages are _not_ on this list! &amp;nbsp;I am maintaining the following list of links for Python optimization packages:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="https://software.sandia.gov/trac/coopr/wiki/Documentation/RelatedProjects"&gt;https://software.sandia.gov/trac/coopr/wiki/Documentation/RelatedProjects&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Perhaps these packages were not tagged with the 'optimization' label ... or perhaps they were not downloaded enough to make the list?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-2315310923453885301?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/2315310923453885301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2011/08/coopr-download-fun.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2315310923453885301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2315310923453885301'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2011/08/coopr-download-fun.html' title='Coopr Download Fun'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1347065677438754084</id><published>2011-07-23T09:25:00.000-07:00</published><updated>2011-07-23T09:25:36.128-07:00</updated><title type='text'>Python Optimization Packages</title><content type='html'>I have been maintaining a list of Python optimization packages for a while now on the Coopr Trac pages:&amp;nbsp; see &lt;a href="https://software.sandia.gov/trac/coopr/wiki/Documentation/RelatedProjects"&gt;https://software.sandia.gov/trac/coopr/wiki/Documentation/RelatedProjects&lt;/a&gt;.Today, I noticed that if you google for "python optimization packages", this page does not show up right away.&amp;nbsp; Perhaps Trac pages are index differently?&amp;nbsp; I'm not sure.&lt;br /&gt;&lt;br /&gt;Anyway, I thought I'd add this reference here to help others find this list that I'm maintaining...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1347065677438754084?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1347065677438754084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2011/07/python-optimization-packages.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1347065677438754084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1347065677438754084'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2011/07/python-optimization-packages.html' title='Python Optimization Packages'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1037983974209475351</id><published>2011-07-23T09:21:00.000-07:00</published><updated>2011-07-23T09:26:17.393-07:00</updated><title type='text'>Coopr 3.0.4362 Release</title><content type='html'>We are pleased to announce the release of Coopr 3.0 (3.0.4362). Coopr is a collection of Python software packages that supports a diverse set of optimization capabilities for formulating and analyzing optimization models.&lt;br /&gt;&lt;br /&gt;The following are highlights of this release:&lt;br /&gt;&lt;br /&gt;- Solvers&lt;br /&gt;* More sophisticated logic for solver factory to find ASL and OS solvers&lt;br /&gt;* Various solver interface improvements&lt;br /&gt;* New Solver results object for efficient representation of variable values&lt;br /&gt;* New support for asynchronous progressive hedging&lt;br /&gt;&lt;br /&gt;- Modeling&lt;br /&gt;* Changes in rule semantics to limit rule return values&lt;br /&gt;* Changes in the expected order of rule arguments&lt;br /&gt;* Constant sums or products can now be used as constraint bounds&lt;br /&gt;* Added full support for the !ConstraintList modeling component.&lt;br /&gt;&lt;br /&gt;- Usability enhancements&lt;br /&gt;* More explicit output from runph and runef commands&lt;br /&gt;* Added support in runef to write the extensive form in NL format&lt;br /&gt;* Add controls for garbage collection in PH&lt;br /&gt;&lt;br /&gt;- Other&lt;br /&gt;* Efficiency improvements in generation of NL and LP files.&lt;br /&gt;* Significant efficiency improvements in parsing of Pyomo Data Files.&lt;br /&gt;* More robust MS Windows installer (does not use virtual python&lt;br /&gt;* environment)&lt;br /&gt;&lt;br /&gt;Note that this is a major release of Coopr that changes the expected formulation of Coopr models.  See the Coopr blog for further details about deprecated functionality, which will be disabled in future releases.&lt;br /&gt;&lt;br /&gt;See &lt;a href="https://software.sandia.gov/trac/coopr/wiki/GettingStarted"&gt;https://software.sandia.gov/trac/coopr/wiki/GettingStarted&lt;/a&gt; for instructions for getting started with Coopr.  Installers are available for MS Windows and Unix operating systems to simplify the installation of Coopr packages along with the third-party Python packages that they depend on.  These installers can also automatically install extension packages from Coin Bazaar.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;- Coopr Developer Team&lt;br /&gt;- &lt;a href="mailto:coopr-developers@googlecode.com"&gt;coopr-developers@googlecode.com&lt;/a&gt;&lt;br /&gt;- &lt;a href="https://software.sandia.gov/trac/coopr/wiki/Documentation/Developers"&gt;https://software.sandia.gov/trac/coopr/wiki/Documentation/Developers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-----------&lt;br /&gt;About Coopr&lt;br /&gt;-----------&lt;br /&gt;&lt;br /&gt;Coopr is a collection of Python software packages that supports a diverse set of optimization capabilities for formulating and analyzing optimization models.&lt;br /&gt;&lt;br /&gt;A key driver for Coopr development is Pyomo, an open source tool for modeling optimization applications in Python. Pyomo can be used to define symbolic problems, create concrete problem instances, and solve these instances with standard solvers. Thus, Pyomo provides a capability that is commonly associated with algebraic modeling languages like AMPL and GAMS.&lt;br /&gt;&lt;br /&gt;Coopr has also proven an effective framework for developing high-level optimization and analysis tools. For example, the PySP package provides generic solvers for stochastic programming.  PySP leverages the fact that Pyomo's modeling objects are embedded within a full-featured high-level programming language, which allows for transparent parallelization of subproblems using Python parallel communication libraries.&lt;br /&gt;&lt;br /&gt;Coopr development is hosted by Sandia National Laboratories and COIN-OR:&lt;br /&gt;&lt;br /&gt;* &lt;a href="https://projects.coin-or.org/Coopr"&gt;https://projects.coin-or.org/Coopr&lt;/a&gt;&lt;br /&gt;* &lt;a href="https://software.sandia.gov/coopr"&gt;https://software.sandia.gov/coopr&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;See &lt;a href="http://groups.google.com/group/coopr-forum/"&gt;http://groups.google.com/group/coopr-forum/&lt;/a&gt; for online discussions of Coopr.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1037983974209475351?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1037983974209475351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2011/07/we-are-pleased-to-announce-release-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1037983974209475351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1037983974209475351'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2011/07/we-are-pleased-to-announce-release-of.html' title='Coopr 3.0.4362 Release'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-3559117251908417223</id><published>2011-03-28T08:58:00.000-07:00</published><updated>2011-03-28T08:58:17.551-07:00</updated><title type='text'></title><content type='html'>&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:WordDocument&gt;   &lt;w:View&gt;Normal&lt;/w:View&gt;   &lt;w:Zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:TrackMoves/&gt;   &lt;w:TrackFormatting/&gt;   &lt;w:PunctuationKerning/&gt;   &lt;w:ValidateAgainstSchemas/&gt;   &lt;w:SaveIfXMLInvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:IgnoreMixedContent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:AlwaysShowPlaceholderText&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:DoNotPromoteQF/&gt;   &lt;w:LidThemeOther&gt;EN-US&lt;/w:LidThemeOther&gt;   &lt;w:LidThemeAsian&gt;X-NONE&lt;/w:LidThemeAsian&gt;   &lt;w:LidThemeComplexScript&gt;X-NONE&lt;/w:LidThemeComplexScript&gt;   &lt;w:Compatibility&gt;    &lt;w:BreakWrappedTables/&gt;    &lt;w:SnapToGridInCell/&gt;    &lt;w:WrapTextWithPunct/&gt;    &lt;w:UseAsianBreakRules/&gt;    &lt;w:DontGrowAutofit/&gt;    &lt;w:SplitPgBreakAndParaMark/&gt;    &lt;w:DontVertAlignCellWithSp/&gt;    &lt;w:DontBreakConstrainedForcedTables/&gt;    &lt;w:DontVertAlignInTxbx/&gt;    &lt;w:Word11KerningPairs/&gt;    &lt;w:CachedColBalance/&gt;   &lt;/w:Compatibility&gt;   &lt;w:DoNotOptimizeForBrowser/&gt;   &lt;m:mathPr&gt;    &lt;m:mathFont m:val="Cambria Math"/&gt;    &lt;m:brkBin m:val="before"/&gt;    &lt;m:brkBinSub m:val="&amp;#45;-"/&gt;    &lt;m:smallFrac m:val="off"/&gt;    &lt;m:dispDef/&gt;    &lt;m:lMargin m:val="0"/&gt;    &lt;m:rMargin m:val="0"/&gt;    &lt;m:defJc m:val="centerGroup"/&gt;    &lt;m:wrapIndent m:val="1440"/&gt;    &lt;m:intLim m:val="subSup"/&gt;    &lt;m:naryLim m:val="undOvr"/&gt;   &lt;/m:mathPr&gt;&lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"  DefSemiHidden="true" DefQFormat="false" DefPriority="99"  LatentStyleCount="267"&gt;   &lt;w:LsdException Locked="false" Priority="0" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Normal"/&gt;   &lt;w:LsdException Locked="false" Priority="9" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="heading 1"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 1"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 2"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 3"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 4"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 5"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 6"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 7"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 8"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 9"/&gt;   &lt;w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/&gt;   &lt;w:LsdException Locked="false" Priority="10" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Title"/&gt;   &lt;w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/&gt;   &lt;w:LsdException Locked="false" Priority="11" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/&gt;   &lt;w:LsdException Locked="false" Priority="22" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Strong"/&gt;   &lt;w:LsdException Locked="false" Priority="20" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="59" SemiHidden="false"   UnhideWhenUsed="false" Name="Table Grid"/&gt;   &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/&gt;   &lt;w:LsdException Locked="false" Priority="1" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/&gt;   &lt;w:LsdException Locked="false" Priority="34" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/&gt;   &lt;w:LsdException Locked="false" Priority="29" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Quote"/&gt;   &lt;w:LsdException Locked="false" Priority="30" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="19" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="21" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="31" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/&gt;   &lt;w:LsdException Locked="false" Priority="32" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/&gt;   &lt;w:LsdException Locked="false" Priority="33" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Book Title"/&gt;   &lt;w:LsdException Locked="false" Priority="37" Name="Bibliography"/&gt;   &lt;w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt; /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin;}&lt;/style&gt; &lt;![endif]--&gt;  &lt;br /&gt;&lt;div class="MsoPlainText"&gt;&lt;a href="https://software.sandia.gov/trac/coopr/blog/20110325-Coopr2.5.3890"&gt;Coopr 2.5(2.5.3890) has just been released&lt;/a&gt;! Coopr is a collection of Python software packages that supports a diverse set of optimization capabilities for formulating and analyzing optimization models.&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoPlainText"&gt;The following are highlights of this release:&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoPlainText"&gt;- Solvers&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* MIP solver interface updates to use appropriate objective names&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Added support for suffixes in GUROBI solver interface&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Improved diagnostic analysis of PH solver for the extensive form&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoPlainText"&gt;- Usability enhancements&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Improved robustness of coopr_install&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Fixed Coopr installation problem when using easy_install&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Added a script to launch the CooprAge GUI.&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* LP files now are written with the true objective name&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Rework of pyomo command line to create a concise output&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Many efficiency improvements during model generation!&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Many improvements to diagnostic output and error handling&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Expressions like "model.p &amp;gt; 1" can now be used within generation rules&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoPlainText"&gt;- Modeling&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Added support for generalized disjunctive programs (in coopr.gdp)&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Constraints can now be specified in "compound" form:&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;lb &amp;lt;= expr &amp;lt;= ub&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Significant robustness enhancements for model expressions&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Improved error handling for constraint generation&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoPlainText"&gt;- Other&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Python 2.5 is deprecated due to performance issues&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* Python versions 2.6 and 2.7 are supported&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;* New MS Windows installer is now available&lt;/div&gt;&lt;div class="MsoPlainText"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoPlainText"&gt;See the &lt;a href="https://software.sandia.gov/trac/coopr"&gt;Coopr wiki&lt;/a&gt; for further details!&lt;/div&gt;&lt;div class="MsoPlainText"&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-3559117251908417223?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/3559117251908417223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2011/03/normal-0-false-false-false-en-us-x-none.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/3559117251908417223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/3559117251908417223'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2011/03/normal-0-false-false-false-en-us-x-none.html' title=''/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-2530908316372809939</id><published>2010-11-26T16:59:00.000-08:00</published><updated>2010-11-26T16:59:22.895-08:00</updated><title type='text'>Getting Started with a Virtual Python Installation</title><content type='html'>Working with and developing Python software is complicated by several factors: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Many users do not have the administrative privileges that are  needed to install packages in the Python site packages directory, where  Python packages are most easily installed &lt;/li&gt;&lt;li&gt;Python developers often need to manage many Python projects in the same development environment &lt;/li&gt;&lt;/ul&gt;The Python &lt;a href="http://virtualenv.openplans.org/"&gt;virtualenv&lt;/a&gt; package resolves these issues by allowing users to generate a local Python installation.  Thus, a user can create a Python installation into which they can install Python packages using standard tools like  easy_install and pip.&lt;br /&gt;&lt;br /&gt;Unfortunately, getting started with virtualenv is complicated by the fact that you need to install this package to create virtual Python  installations.  But, if you do not have administrative privileges, then you are stuck.  This is the simplest process that I have seen:&lt;br /&gt;&lt;pre class="wiki"&gt;hg clone http://bitbucket.org/ianb/virtualenv&lt;br /&gt;virtualenv/virtualenv.py ENV&lt;/pre&gt;Unfortunately, the &lt;tt&gt;hg&lt;/tt&gt; command may not be preinstalled on your machine.  It is not available on any of mine...&lt;br /&gt;&lt;br /&gt;The &lt;a href="https://software.sandia.gov/trac/pyutilib/browser/pyutilib.virtualenv"&gt;pyutilib.virtualenv&lt;/a&gt; package contains the &lt;a href="https://software.sandia.gov/trac/pyutilib/export/HEAD/pyutilib.virtualenv/stable/scripts/vpy_install"&gt;vpy_install&lt;/a&gt; script, which can bootstrap the setup of virtualenv.  This script extends the functionality of the virtualenv driver script to allow direct, and it customization of this initial environment.  The &lt;a class="source" href="https://software.sandia.gov/trac/pyutilib/export/HEAD/pyutilib.virtualenv/stable/scripts/vpy_install"&gt;vpy_install&lt;/a&gt; script can be easily downloaded from the &lt;a href="https://software.sandia.gov/trac/pyutilib/wiki/Documentation/vpy"&gt;PyUtilib wiki&lt;/a&gt;, or it can be downloaded with commands like wget or curl:&lt;br /&gt;&lt;pre class="wiki"&gt;wget http://doiop.com/pyutilib/vpy_install&lt;br /&gt;vpy_install ENV&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-2530908316372809939?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/2530908316372809939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/11/getting-started-with-virtual-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2530908316372809939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2530908316372809939'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/11/getting-started-with-virtual-python.html' title='Getting Started with a Virtual Python Installation'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-7739185809188225690</id><published>2010-11-10T21:22:00.000-08:00</published><updated>2010-11-10T21:23:30.590-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Installing Python Software Packages: The Good, The Bad and the Ugly</title><content type='html'>I almost gave the following presentation at the INFORMS Annual Meeting:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.slideshare.net/WilliamHart1/10-11hart-installing-pythonsoftware"&gt;Installing Python Software Packages: The Good, The Bad and the Ugly&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;That is, I was scheduled to give this talk but my session co-organizer ran over and I had to summarize these slides in 5 minutes!&lt;br /&gt;&lt;br /&gt;Anyway, these slides describe different strategies for installing Python software.&amp;nbsp; Although I am a big fan of Python software development, robust strategies for software installation remains a challenge.&amp;nbsp; This talk describes several different installation scenarios:&lt;br /&gt;&lt;br /&gt;The Good: the user has administrative privileges&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Installing on Windows with an installer executable&lt;/li&gt;&lt;li&gt;Installing with Linux application utility&lt;/li&gt;&lt;li&gt;Installing a Python package from the PyPI repository&lt;/li&gt;&lt;li&gt;Installing a Python package from source&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;The Bad: the user does not have administrative privileges&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Using a virtual environment to isolate package installations&lt;/li&gt;&lt;li&gt;Using an installer executable on Windows with a virtual environment&lt;/li&gt;&lt;/ol&gt;&lt;ol&gt;&lt;/ol&gt;&lt;br /&gt;The Ugly: the user needs to install an extension package from source&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Installing a Python extension package from source&lt;/li&gt;&lt;li&gt;PyCoinInstall – Managing builds for Python extension packages&lt;/li&gt;&lt;/ol&gt;The last item referring to PyCoinInstall describes a utility being developed for the COIN-OR software, which is used within the operations research community.&amp;nbsp; COIN-OR includes a variety of Python and C++ software packages, and this script uses a simple plug-in system to support the management of package builds and installation.&amp;nbsp; Of course, this mostly does the easy packages right now...&lt;br /&gt;&lt;br /&gt;While preparing these slides I realized that the vpy_install script I use for setting up virtual environments is probably of broader interest.&amp;nbsp; I'll say more about this in a little bit.&amp;nbsp; In the meantime, checkout the slides!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-7739185809188225690?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/7739185809188225690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/11/installing-python-software-packages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/7739185809188225690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/7739185809188225690'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/11/installing-python-software-packages.html' title='Installing Python Software Packages: The Good, The Bad and the Ugly'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-6406895789385248519</id><published>2010-08-31T19:31:00.000-07:00</published><updated>2010-08-31T19:39:47.689-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='software python'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Reworking FAST</title><content type='html'>The role of the FAST software repository has evolved over the past few years, and it is time to rethink what the goal of FAST is.  See &lt;a href="https://software.sandia.gov/trac/fast/blog/20100815-RethinkingFast"&gt;Rethinking the goal of FAST&lt;/a&gt; for some perspective about FAST.  The upshot is that FAST has been reorganized to support an ensemble of independent software packages related to agile software development.&lt;br /&gt;&lt;br /&gt;One important change in this reorganization has been the decomposition of the FAST Python software into independent components.  Some elements of FAST are deprecated, and the rest have been spread out into various packages.  See the &lt;a href="https://software.sandia.gov/trac/fast/blog/20100815-RethinkingFast"&gt;FAST Blog&lt;/a&gt; for further details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-6406895789385248519?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/6406895789385248519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/08/reworking-fast.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6406895789385248519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6406895789385248519'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/08/reworking-fast.html' title='Reworking FAST'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-8519203005105814274</id><published>2010-08-29T13:20:00.000-07:00</published><updated>2010-08-31T19:55:51.897-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Update for gcovr</title><content type='html'>The &lt;a href="https://software.sandia.gov/trac/fast/wiki/Documentation/gcovr"&gt;gcovr&lt;/a&gt; command provides a utility for running the &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Gcov.html"&gt;gcov&lt;/a&gt; command and summarizing code coverage results.  This command is inspired by the Python &lt;a href="http://nedbatchelder.com/code/coverage/"&gt;coverage.py&lt;/a&gt; package, which provides a similar utility in Python.  Further, &lt;a href="https://software.sandia.gov/trac/fast/wiki/Documentation/gcovr"&gt;gcovr&lt;/a&gt; can be viewed as a command-line alternative of the &lt;a href="http://ltp.sourceforge.net/coverage/lcov.php"&gt;lcov&lt;/a&gt; utility, which runs gcov and generates an HTML output.&lt;br /&gt;&lt;br /&gt;Recently, the gcovr script has been broken out into a separate software package, which is managed at&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;https://software.sandia.gov/svn/public/fast/gcovr&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This package has been uploaded to the Python PyPI repository to facilitate it installation with easy_install:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;easy_install gcovr&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Alternatively, the gcovr script can be downloaded directly:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="https://software.sandia.gov/svn/public/fast/gcovr/trunk/scripts/gcovr"&gt;https://software.sandia.gov/svn/public/fast/gcovr/trunk/scripts/gcovr&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;See the &lt;a href="https://software.sandia.gov/trac/fast/wiki/gcovr"&gt;gcovr Trac page&lt;/a&gt; for further details about this tool. Although gcovr is increasingly used to generate coverage statistics within Hudson, the gcovr wiki documents a command-line text summary that I personally find very useful when developing tests to improve code coverage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-8519203005105814274?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/8519203005105814274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/08/update-for-gcovr.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8519203005105814274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8519203005105814274'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/08/update-for-gcovr.html' title='Update for gcovr'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1446884996654730502</id><published>2010-06-28T21:19:00.000-07:00</published><updated>2010-06-28T21:48:19.070-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>A New Python Package: pyutilib.autotest</title><content type='html'>A while back I developed &lt;a href="https://software.sandia.gov/trac/fast/wiki/Documentation/exact"&gt;EXACT&lt;/a&gt;, a Python package for executing computational experiments using an XML-defined process.  EXACT was designed to fill a particular niche in software testing:  performing computational tests that involve the application of solvers to a suite of test problems.  This sort of testing arises a lot when doing functionality testing for scientific software.&lt;br /&gt;&lt;br /&gt;Unfortunately, EXACT was too complex:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The XML specification was complex and difficult to read&lt;/li&gt;&lt;li&gt;Experiments with many factors were assigned generic experiment IDs&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It was hard to replication the execution of specific experiments&lt;/li&gt;&lt;li&gt;The experimental results were captured in XML results files that were difficult to browse&lt;/li&gt;&lt;/ul&gt;Even my close collaborators struggled to setup, run and analyze computational experiments!  {sigh}&lt;br /&gt;&lt;br /&gt;I have recently developed the &lt;a href="https://software.sandia.gov/trac/pyutilib/browser/pyutilib.autotest"&gt;pyutilib.autotest&lt;/a&gt; Python package to provide a simpler alternative to EXACT.  This package uses a &lt;a href="http://yaml.org/"&gt;YAML&lt;/a&gt; test configuration file to specify the solvers and problems that are exercised in a test.  The tests setup and executed with Python's unittest package, which allows the user to apply a rich set of testing methods.  The user can specify a test driver in Python that defines how each test is executed, using the solver and problem options that are specified in the configuration file.&lt;br /&gt;&lt;br /&gt;Here's a simple example of a YAML test specification, where the goal is to apply the UNIX cat command with different options to different test files:&lt;pre&gt;driver: example&lt;br /&gt;&lt;br /&gt;solvers:&lt;br /&gt;    cat:&lt;br /&gt;    cat2:&lt;br /&gt;        name: cat&lt;br /&gt;        cat_options: -n&lt;br /&gt;&lt;br /&gt;problems:&lt;br /&gt;    f1:&lt;br /&gt;        file: file1.txt&lt;br /&gt;    f2:&lt;br /&gt;        file: file2.txt&lt;br /&gt;&lt;br /&gt;suites:&lt;br /&gt;    suite1:&lt;br /&gt;        solvers:&lt;br /&gt;            cat:&lt;br /&gt;            cat2:&lt;br /&gt;        problems:&lt;br /&gt;            f1:&lt;br /&gt;            f2:&lt;br /&gt;&lt;/pre&gt;See the &lt;a href="http://pypi.python.org/pypi/pyutilib.autotest"&gt;pyutilib.autotest PyPI documentation&lt;/a&gt; for further details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1446884996654730502?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1446884996654730502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/06/new-python-package-pyutilibautotest.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1446884996654730502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1446884996654730502'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/06/new-python-package-pyutilibautotest.html' title='A New Python Package: pyutilib.autotest'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1923626041143451283</id><published>2010-06-21T14:24:00.000-07:00</published><updated>2010-06-21T14:40:03.731-07:00</updated><title type='text'>Dynamic Service Creation in the PyUtilib Component Architecture</title><content type='html'>The &lt;a href="https://software.sandia.gov/trac/pyutilib/export/1831/pyutilib.component.doc/trunk/doc/plugin/pca.pdf"&gt;PyUtilib Component Architecture (PCA)&lt;/a&gt; is a component architecture in Python that is derived from the &lt;a href="http://trac.edgewall.org/wiki/TracDev/ComponentArchitecture"&gt;Trac component framework&lt;/a&gt;.  One important extension was to support both singleton and non-singleton plugins.  Trac plugins are singletons that are created immediately when the plugin module is loaded (Python is a wonderful language for supporting this type of capability).  Singleton plugins are well-suited for Trac, since it is a persistent application, but many other applications need to employ plugins "on demand".  Consequently, the PCA supports non-singleton plugins, which need to be explicitly constructed by the end-user.&lt;br /&gt;&lt;br /&gt;The PCA is widely used in the &lt;a href="https://software.sandia.gov/trac/coopr"&gt;Coopr&lt;/a&gt; project, and most plugins are non-singletons.  Until recently, the PCA did not directly support plugin construction on demand.  That is, the user needed to know the plugin class name, and plugin construction was done explicitly by the user.  However, most plugins in Coopr can be best described as &lt;span style="font-style: italic;"&gt;named services&lt;/span&gt;.  For example, Coopr optimizers are implemented as plugins and each optimizer has a unique name.&lt;br /&gt;&lt;br /&gt;The PCA has recently been extended to support the &lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;alias&lt;/span&gt;&lt;/span&gt; function, which can be used to declare the name of a plugin with respect to a particular interface.  For example, consider the following definitions of the &lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;MyPlugin&lt;/span&gt;&lt;/span&gt; and &lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="font-weight: bold;"&gt;YourPlugin&lt;/span&gt;&lt;/span&gt; plugin classes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class ITask(Interface):&lt;br /&gt;&lt;br /&gt;  def print(self):&lt;br /&gt;&lt;br /&gt;class MyPlugin(Plugin):&lt;br /&gt;&lt;br /&gt;  implements(ITask)&lt;br /&gt;  alias('my', ITask)&lt;br /&gt;&lt;br /&gt;  def print(self):&lt;br /&gt;      print "My Plugin"&lt;br /&gt;&lt;br /&gt;class YourPlugin(Plugin):&lt;br /&gt;&lt;br /&gt;  implements(ITask)&lt;br /&gt;  alias('your', ITask)&lt;br /&gt;&lt;br /&gt;  def print(self):&lt;br /&gt;      print "Your Plugin"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These plugins are non-singletons, so they are only registered and used if they are constructed.  The &lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;alias&lt;/span&gt;&lt;/span&gt; function allows these plugins to be constructed with a factory class that is supported by the PCA.  For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;factory = CreatePluginFactory(ITask)&lt;br /&gt;&lt;br /&gt;p1 = factory('my')&lt;br /&gt;p2 = factory('your')&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;CreatePluginFactory&lt;/span&gt;&lt;/span&gt; class is provided by the PCA, and it provides a functor that manages the creation of plugins whose names are registered with the &lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;alias&lt;/span&gt;&lt;/span&gt; function.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1923626041143451283?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1923626041143451283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/06/pyutilib-component-architecture-pca-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1923626041143451283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1923626041143451283'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/06/pyutilib-component-architecture-pca-is.html' title='Dynamic Service Creation in the PyUtilib Component Architecture'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-8441589555640829290</id><published>2010-06-21T12:19:00.000-07:00</published><updated>2010-06-21T12:32:54.818-07:00</updated><title type='text'>Blogs for Coopr and PyUtilib</title><content type='html'>This is just a heads-up that I have setup blogs for the &lt;a href="https://software.sandia.gov/trac/coopr"&gt;Coopr&lt;/a&gt; and &lt;a href="https://software.sandia.gov/trac/pyutilib"&gt;PyUtilib&lt;/a&gt; software projects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Coopr:      &lt;a href="https://software.sandia.gov/trac/coopr/blog"&gt;https://software.sandia.gov/trac/coopr/blog&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;PyUtilib: &lt;a href="https://software.sandia.gov/trac/pyutilib/blog"&gt;https://software.sandia.gov/trac/pyutilib/blog&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;These blogs will document releases and end-user advice and examples.  Additionally, there will hopefully be other authors than just me adding content to these blogs.  But, I guess we'll see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-8441589555640829290?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/8441589555640829290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/06/blogs-for-coopr-and-pyutilib.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8441589555640829290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8441589555640829290'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/06/blogs-for-coopr-and-pyutilib.html' title='Blogs for Coopr and PyUtilib'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-4827494093945626699</id><published>2010-04-16T14:19:00.000-07:00</published><updated>2010-04-16T14:20:40.344-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>PyUtilib Component Architecture</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I earlier mentioned that I developed a plugin framework within my PyUtilib software.  This is now called the PyUtilib Component Architecture (PCA).  The PCA is derived from the Trac component architecture, and it supports advanced features like nonsingleton components, namespaces and caching of component interactions. The PCA includes an independent, self-contained framework core that can be easily integrated into other applications, as well as a variety of extension packages with commonly used components.&lt;br/&gt;&lt;br/&gt;See &lt;a href='https://software.sandia.gov/trac/pyutilib/export/1754/pyutilib.component.doc/trunk/doc/plugin/pca.pdf'&gt;The PyUtilib Component Architecture&lt;/a&gt; for further details.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-4827494093945626699?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/4827494093945626699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/04/pyutilib-component-architecture.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4827494093945626699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4827494093945626699'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/04/pyutilib-component-architecture.html' title='PyUtilib Component Architecture'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-6537299099574285248</id><published>2010-04-16T14:07:00.001-07:00</published><updated>2010-04-16T14:12:38.896-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='software python'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>Recent Coopr Developments</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;Coopr is a collection of Python optimization-related packages that supports a diverse set of optimization capabilities for formulating and analyzing optimization models.   The following are key Coopr capabilities that are driving Coopr development:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Pyomo: Formulate algebraic models within Python's modern programming language &lt;/li&gt;&lt;li&gt;PySP: Generic solvers for stochastic programming problems&lt;br /&gt;&lt;/li&gt;&lt;li&gt;COLIN: Scripts that simplify IO between optimizers and black-box applications&lt;br /&gt;&lt;/li&gt;&lt;li&gt;SUCASA: Customize MIP solvers to expose model structure to the MIP solver engine&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;See &lt;a href="http://www.google.com/url?sa=D&amp;amp;q=https://software.sandia.gov/trac/coopr/wiki/GettingStarted&amp;amp;usg=AFQjCNEl3LOuH9LxcoSunA8gz8nBbnErxQ" rel="nofollow" target="_blank"&gt;https://software.sandia.gov/trac/coopr/wiki/GettingStarted&lt;/a&gt; for instructions for getting started with Coopr.  An installation script, coopr_install, is provided to simplify the installation of Coopr packages along with the third-party Python packages that they depend on.  This installer can also automatically install extension packages from Coin Bazaar. See &lt;a href="http://www.google.com/url?sa=D&amp;amp;q=http://groups.google.com/group/coopr-forum/topics&amp;amp;usg=AFQjCNFFSWBlpKNbsrQmtMHWpjfNHfETGA" rel="nofollow" target="_blank"&gt;http://groups.google.com/group/coopr-forum/topics&lt;/a&gt; for online discussions of Coopr. &lt;/p&gt;&lt;p&gt;Two recent Coopr developments are noteworthy:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I. Coopr development is now co-hosted by Sandia National Laboratories and COIN-OR: &lt;a href="http://www.google.com/url?sa=D&amp;amp;q=https://projects.coin-or.org/Coopr&amp;amp;usg=AFQjCNGgFCHw6GkTl8G5lGR6cgIxf-rhFg" rel="nofollow" target="_blank"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.google.com/url?sa=D&amp;amp;q=https://projects.coin-or.org/Coopr&amp;amp;usg=AFQjCNGgFCHw6GkTl8G5lGR6cgIxf-rhFg" rel="nofollow" target="_blank"&gt;https://projects.coin-or.org/Coopr&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/url?sa=D&amp;amp;q=https://software.sandia.gov/coopr&amp;amp;usg=AFQjCNFxxg1bUmeJduZIXfzrpYm6TPS_cw" rel="nofollow" target="_blank"&gt;https://software.sandia.gov/coopr&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Coopr includes wrappers for COIN-OR solvers, and Coopr directly leverages the COIN-OR Coin&lt;br /&gt;Bazaar project to host plug-in packages for Coopr (e.g., see the coopr.neos package in Coin Bazaar).&lt;br /&gt;&lt;br /&gt;II. We have recently released Coopr 2.3. This release includes&lt;br /&gt;&lt;ul&gt;&lt;li&gt;  A preliminary Gurobi solver interface&lt;br /&gt;&lt;/li&gt;&lt;li&gt;  Extended syntax for data command files:&lt;br /&gt;        o 'include' command to load other data command files&lt;br /&gt;        o 'import' command to load data from other sources&lt;br /&gt;        o namespaces to next data declarations&lt;br /&gt;&lt;/li&gt;&lt;li&gt;  The coopr_install script can install packages from Coin Bazaar&lt;br /&gt;&lt;/li&gt;&lt;li&gt;  New conversion scripts to generate LP or NL files from Pyomo models&lt;br /&gt;&lt;/li&gt;&lt;li&gt;  Solvers now extract standard suffix information&lt;br /&gt;&lt;/li&gt;&lt;li&gt;  Various fixes to PySP solvers&lt;br /&gt;&lt;/li&gt;&lt;li&gt;  Full support for PyPI. You can install from PyPI using the 'Coopr' package name.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Enjoy!&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-6537299099574285248?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/6537299099574285248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2010/04/recent-coopr-developments.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6537299099574285248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6537299099574285248'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2010/04/recent-coopr-developments.html' title='Recent Coopr Developments'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-2510660870317459069</id><published>2009-10-21T05:06:00.001-07:00</published><updated>2009-10-21T05:06:43.664-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>MINLP Test Problems</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Ignacio Grossmann and Jon Lee recently announced the &lt;a href='http://www.minlp.org/'&gt;CMU-IBM Cyberinfrastructure Collaborative site for MINLP&lt;/a&gt;.  The goal of this web site is to create a library of optimization problems in different application areas in which one or several alternative models are presented with their derivation. In addition, each model has one or several instances that can serve to test various algorithms. This effort is different from other test problem collections by requiring a description of the problem, and encouraging the contribution of alternate modeling formulations.  Thus, the actual models in this collection may be MILP or NLP formulations that simplify a nonlinear problem, including simplifications of other MINLP formulations.&lt;br/&gt;&lt;br/&gt;As it happens, Cindy Phillips, Regan Murray and I are working on a paper that describes our work on sensor placement for water security, where we describe various MILP formulations for this nonlinear application.  I guess we should try to add our models to this repository!&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=2884f2e4-f199-8044-a440-9ec0df4ddc76' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-2510660870317459069?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/2510660870317459069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/10/minlp-test-problems.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2510660870317459069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2510660870317459069'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/10/minlp-test-problems.html' title='MINLP Test Problems'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1559529888423543947</id><published>2009-10-20T15:16:00.001-07:00</published><updated>2009-10-20T15:17:47.326-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Using easy_install to download source files</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Python's &lt;a href='http://pypi.python.org/pypi/setuptools/'&gt;setuptools &lt;/a&gt;package includes the &lt;font face='Courier New'&gt;easy_install&lt;/font&gt; script, which provides a convenient mechanism for installing a Python package from the &lt;a href='http://pypi.python.org/pypi'&gt;PyPi &lt;/a&gt;repository.  Normally, &lt;font face='Courier New'&gt;easy_install &lt;/font&gt;installs a Python package in the Python site packages directory.  However, I recently discovered that &lt;font face='Courier New'&gt;easy_install&lt;/font&gt; can download the source for Python package.  For example, the following command downloads the &lt;a href='http://pypi.python.org/pypi/Coopr/'&gt;Coopr &lt;/a&gt;optimization package into the &lt;font face='Courier New'&gt;coopr &lt;/font&gt;directory:&lt;br/&gt;&lt;br /&gt;&lt;blockquote&gt;easy_install -q --editable --build-directory . Coopr&lt;/blockquote&gt;&lt;br/&gt;I had to browse a variety of web pages before I figured this syntax out.  Enjoy!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1559529888423543947?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1559529888423543947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/10/using-easyinstall-to-download-source.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1559529888423543947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1559529888423543947'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/10/using-easyinstall-to-download-source.html' title='Using easy_install to download source files'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1858745639235921239</id><published>2009-10-14T19:04:00.001-07:00</published><updated>2009-10-14T19:04:15.021-07:00</updated><title type='text'>Book Recommendation: Software IP</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I have been working with software-related intellectual property issues for several years now.  I finally broke down and bought a book to help me get the big picture.  The following book has been remarkably helpful:&lt;br/&gt;&lt;blockquote&gt;Intellectual Property and Open Source: A practical guide to protecting code&lt;br/&gt;Van Lindberg&lt;br/&gt;O'Reilly, 2008&lt;br/&gt;&lt;/blockquote&gt;I have been quite surprised how well Lindberg describes the complex legal issues related to intellectual property law.  Lindberg is a lawyer and software developer, and he uses computer science analogies that are quite straightforward.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=90f3125e-a924-84ee-b750-2b13888ebe41' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1858745639235921239?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1858745639235921239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/10/book-recommendation-software-ip.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1858745639235921239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1858745639235921239'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/10/book-recommendation-software-ip.html' title='Book Recommendation: Software IP'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-3962167558031786563</id><published>2009-10-05T20:44:00.001-07:00</published><updated>2009-10-05T20:44:52.919-07:00</updated><title type='text'>Applying the CBC Presolver</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Here's a fun fact that I wanted to archive...   In a recent COIN-OR email exchange on coin-discuss, John Forrest suggested the following command-line for applying the CBC preprocessor to an MPS file:&lt;br/&gt;&lt;br/&gt;     cbc xxxxx.mps -preprocess save -heuristic off -maxnode -1 -solve&lt;br/&gt;&lt;br/&gt;This command will save the cbc-presolved model in the file presolved.mps. The -heuristic off and -maxnode -1 options make cbc stop as quickly as possible.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-3962167558031786563?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/3962167558031786563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/10/applying-cbc-presolver.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/3962167558031786563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/3962167558031786563'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/10/applying-cbc-presolver.html' title='Applying the CBC Presolver'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-2834889847493320818</id><published>2009-07-17T11:15:00.000-07:00</published><updated>2009-07-17T11:18:11.871-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><title type='text'>Using Open-Source Tools to Manage Software Quality</title><content type='html'>&lt;font face="sans-serif"&gt;At PyCon 2009, Aaron Maxwell gave a presentation about the use of &lt;a href="http://buildbot.net/trac"&gt;BuildBot&lt;/a&gt; to support an automated software QA infrastructure. Listening to his talk (&lt;a href="http://us.pycon.org/2009/conference/schedule/event/22/"&gt;online&lt;/a&gt;) made me think more carefully about the reasons I am not using BuildBot, which I took a look at several years ago.&amp;nbsp; After working with a custom automated build tool for a few years, I have recently begun using &lt;a href="https://hudson.dev.java.net/"&gt;Hudson &lt;/a&gt;to automate software quality processes for a variety of open source software packages.&amp;nbsp; Hudson automates the following QA activities for these packages:&lt;br /&gt;&lt;/font&gt;&lt;ul&gt;&lt;li&gt;&lt;font face="sans-serif"&gt;portability tests - building packages with different compilers, language versions and compute platforms&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face="sans-serif"&gt;continuous integration - rapid builds and software tests to provide developers continuous feedback&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face="sans-serif"&gt;integration tests - builds that test the integration of different software tools&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face="sans-serif"&gt;archiving QA statistics - test histories, code coverage statistics, build times, etc.&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face="sans-serif"&gt;managing third-party builds - building third-party libraries that my codes depend on&lt;br /&gt;&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;&lt;font face="sans-serif"&gt;Although I am reasonably happy with Hudson, I must admit that I did not immediately decide that it was perfect for my needs the first time I looked at it.&amp;nbsp; However, as the scope of my QA needs has grown, it has become critical to have a flexible, extensible strategy for automating software QA activities. The following high-level issues have proven to be major considerations when assessing the viability of tools like BuildBot and Hudson:&lt;ul&gt;&lt;li&gt;&lt;u&gt;GUI/web interface&lt;/u&gt;&lt;br /&gt;GUI and web interfaces are key to ensuring that developers regularly use the QA data that is being generated.  Interactive interrogation of QA current data facilitates effective use of this data, and GUI interfaces are very important when developers do not all have access to the same computing platforms.  These interfaces can also convey valuable QA in a concise manner, such as graphical representations of QA history (e.g test failure/successes of time).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;Extensibility&lt;/u&gt;&lt;br /&gt;Any automation framework is going to need to be customized to adapt to local operating constraints.  Thus, the extensibility of the automation framework is a key issue for end-users.  A particularly effective strategy for supporting this flexibility is with plugin components, which are supported in Hudson.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;Loosely Coupled QA Tools&lt;/u&gt;&lt;br /&gt;Hudson uses a &lt;i&gt;standards-based approach&lt;/i&gt; for integrating QA information.  QA activities can be initiated in a very generic manner, using shell commands whose scope is not restricted.  If the QA information is provided in a standard format, then Hudson can integrate it into its QA summaries.  For example, Hudson recognizes testing results that are documented with the xUnit XML format, and code coverage results that are documented with the Cobertura XML format.  This strategy supports a loose coupling between the QA processes and the use of Hudson, which allows for the application of a heterogeneous set of QA tools, including tools for different test harnesses and programming languages!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;Compute Resource Management&lt;/u&gt;&lt;br /&gt;Coordinating of a large number of QA activities requires scalable strategies for managing computing resources.  Frameworks like Hudson provide basic resource management strategies, including dynamic scheduling of continuous integration builds on a build farm.  More generally, scalable automated testing tools need to support strategies like fractional factorial test designs, which test many build options (configuration, platform, compiler, etc) with a small number of builds.  Also, management of daemon clients also becomes an issue for large build farms (e.g. notification of exceptional events like running out of disk space).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;Ease of Use&lt;/u&gt;&lt;br /&gt;It is worth restating that ease-of-use is a major factor in practice.  Developers will not use QA frameworks unless they add value to the development process.  Further, it can be difficult to convince an organization to support the maintenance of automated QA frameworks on a large build farm.&lt;/li&gt;&lt;/ul&gt;As a final note, the &lt;a href="https://software.sandia.gov/trac/acro/wiki/Development/Resources"&gt;Acro Developer Resources page&lt;/a&gt; summarizes the QA tools that the Acro project is using with Hudson to support software development.  It is noteworthy that this effort includes QA processes for both C/C++ software and Python software.  On another project, we have also used Hudson to summarize tests of Matlab code.&lt;br /&gt;&lt;br /&gt;P.S.  I want to thank John Siirola for brainstorming about this blog.  John has done most of the work setting up the Hudson server that we are using for Acro and related open source software development.&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-2834889847493320818?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/2834889847493320818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/07/using-open-source-tools-to-manage.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2834889847493320818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2834889847493320818'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/07/using-open-source-tools-to-manage.html' title='Using Open-Source Tools to Manage Software Quality'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-6631430256582009603</id><published>2009-07-17T09:48:00.000-07:00</published><updated>2009-07-17T09:49:55.881-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><title type='text'>Summarizing gcov Coverage Statistics with gcovr</title><content type='html'>The &lt;a href="https://software.sandia.gov/trac/fast/wiki/Documentation/gcovr"&gt;gcovr&lt;/a&gt; command provides a utility for running the &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Gcov.html"&gt;gcov&lt;/a&gt; command and summarizing code coverage results.  This command is inspired by the Python &lt;a href="http://nedbatchelder.com/code/coverage/"&gt;coverage.py&lt;/a&gt; package, which provides a similar utility in Python.  Further, &lt;a href="https://software.sandia.gov/trac/fast/wiki/Documentation/gcovr"&gt;gcovr&lt;/a&gt; can be viewed as a command-line alternative of the &lt;a href="http://ltp.sourceforge.net/coverage/lcov.php"&gt;lcov&lt;/a&gt; utility, which runs gcov and generates an HTML output.&lt;br /&gt;&lt;br /&gt;The gcovr command currently generates two different types of output:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;Text Summary&lt;/u&gt;&lt;br /&gt;For each file that generates gcov statistics, gcovr will summarize the number of lines covered, the percentage of coverage and enumerate the lines that are not covered.&lt;/li&gt;&lt;li&gt;&lt;u&gt;Cobertura XML&lt;/u&gt;&lt;br /&gt;An XML summary of the coverage statistics can be generated in a format that is consistent with Cobertura.&lt;/li&gt;&lt;/ul&gt;I find the text summary quite convenient for interactive assessment of coverage, especially as I design tests to improve coverage.  The Cobertura summary can be used by continues build tools like &lt;a href="https://hudson.dev.java.net/"&gt;Hudson&lt;/a&gt;.  For example, see the &lt;a href="https://software.sandia.gov/hudson/view/_coverage_/job/acro-utilib_trunk_coverage/"&gt;acro-utilib coverage report&lt;/a&gt; that was generated with gcovr, using the Cobertura XML output option.&lt;br /&gt;&lt;br /&gt;See the &lt;a href="https://software.sandia.gov/trac/fast/wiki/Documentation/gcovr"&gt;gcovr Trac page&lt;/a&gt; for further details about this tool. The gcovr command is currently bundled with the &lt;a href="https://software.sandia.gov/trac/fast"&gt;FAST&lt;/a&gt; Python package, which you can download from the &lt;a href="https://software.sandia.gov/trac/fast"&gt;FAST Trac site&lt;/a&gt;.&amp;nbsp; However, gcovr is a stand-alone Python script.&amp;nbsp; Thus, it is also convenient to download the latest development version &lt;a href="https://software.sandia.gov/trac/fast/export/HEAD/fast/trunk/scripts/gcovr"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-6631430256582009603?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/6631430256582009603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/07/summarizing-gcov-coverage-statistics.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6631430256582009603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6631430256582009603'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/07/summarizing-gcov-coverage-statistics.html' title='Summarizing gcov Coverage Statistics with gcovr'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-6447708761289425440</id><published>2009-07-17T06:16:00.000-07:00</published><updated>2009-07-17T06:25:24.797-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software python'/><title type='text'>Videos for PyCon2009!</title><content type='html'>I just discovered that the talks at &lt;a href="http://us.pycon.org/2009/about/"&gt;PyCon&lt;/a&gt; 2009 were video taped!  Excellent!  I had fun browsing them last night, looking for clues to the challenges that I face managing several complex Python packages.&lt;br /&gt;&lt;br /&gt;I am not sure how the PyCon organizers justified the cost for doing this, but I think that this was an excellent idea.  I would love to see other conferences adopt this idea (or at least support online publishing of electronic slides).  I suspect that this would discourage some people from attending a conference.  However, people like me are already traveling too much.  Thus, the PyCon organizers did not lose anything with me; I was already unable to attend.  Further, having access to the presentations makes me more likely to adopt the techniques/approaches that they are presenting!  This sounds like a win-win to me!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-6447708761289425440?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/6447708761289425440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/07/videos-for-pycon2009.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6447708761289425440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6447708761289425440'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/07/videos-for-pycon2009.html' title='Videos for PyCon2009!'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-4770034450495492507</id><published>2009-07-02T12:33:00.001-07:00</published><updated>2009-07-02T12:37:49.038-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>PyUtilib Plugins</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;After blogging about Python plugin frameworks earlier this year, I wound up implemented a new framework in the &lt;a href='https://software.sandia.gov/trac/pyutilib/wiki'&gt;PyUtilib&lt;/a&gt; software package.  The PyUtilib wiki provides a detailed description of the &lt;a href='https://software.sandia.gov/trac/pyutilib/wiki/Documentation/Plugins'&gt;PyUtilib Plugin Framework&lt;/a&gt;, but here's a brief summary:&lt;br/&gt;&lt;ul class='simple'&gt;&lt;li&gt;This framework is derived from the Trac plugin framework (a.k.a. component architecture)&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Provides support for both singleton and non-singleton plugin instances&lt;/li&gt;&lt;li&gt;Includes utilities for managing plugins within namespaces&lt;/li&gt;&lt;li&gt;The core framework is defined in a single Python module, which can be used independently from PyUtilib&lt;br/&gt;&lt;/li&gt;&lt;li&gt;PyUtilib also includes commonly use plugins, such as&lt;br/&gt;&lt;ul&gt;&lt;li&gt;A config-file reader/writer based on ConfigParser&lt;/li&gt;&lt;li&gt;Loading utilities for eggs and modules&lt;/li&gt;&lt;li&gt;A file manager for temporary files&lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;/ul&gt;Although I initially resisted the urge to develop my own framework, I was led to develop this because (1) I wanted a light-weight framework like that provided by Trac, but (2) Trac's framework is not particularlly modular within the Trac software repository.  Also, I really needed a plugin framework that supported non-singleton plugins.  Development of the PyUtilib Plugin Framework is mostly motivated by my work with &lt;a href='https://software.sandia.gov/trac/coopr'&gt;Coopr&lt;/a&gt;, which extensively leverages plugins to support a flexible, extensible optimization tools.&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-4770034450495492507?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/4770034450495492507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/07/pyutilib-plugins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4770034450495492507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4770034450495492507'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/07/pyutilib-plugins.html' title='PyUtilib Plugins'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-862575500907244803</id><published>2009-01-26T18:18:00.000-08:00</published><updated>2009-01-26T18:22:56.476-08:00</updated><title type='text'>Another Discussion of Python Plugins</title><content type='html'>Here's a nice discussion and comparison of Python plugin frameworks that I ran across today: &lt;a href=" http://www.pitivi.org/wiki/Design_Docs_Plugins"&gt;Design Docs Plugins - PiTiViWiKi&lt;/a&gt;.  This notes that a big difference between Zope and Trac plugins is that Zope defines interfaces which allows for checking interface implementation/definition, as well as facilities for plugin adapters.  In this respect, the Envisage Core plugins are similar  to Zope.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-862575500907244803?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/862575500907244803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/01/another-discussion-of-python-plugins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/862575500907244803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/862575500907244803'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/01/another-discussion-of-python-plugins.html' title='Another Discussion of Python Plugins'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-7963574898419282330</id><published>2009-01-26T09:37:00.001-08:00</published><updated>2011-02-19T14:21:06.097-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python Plugin Frameworks</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;i&gt;Updated to include pointers to the PyUtilib Component Architecture and PnP.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Various Python projects I am working on could benefit from the use of a Plug-in framework.&amp;nbsp; However, there does not appear to be a standard Python plug-in framework, though there are some mature packages that support plug-ins.&lt;br /&gt;&lt;br /&gt;Here's a summary of my recent web research:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://yapsy.sourceforge.net/"&gt;yapsy&lt;/a&gt; - This is a simple plug-in framework that was designed specifically to support plug-ins with no external dependencies.&lt;/li&gt;&lt;li&gt;Mary Alchin describes a &lt;a href="http://martyalchin.com/2008/jan/10/simple-plugin-framework/"&gt;simple plugin framework&lt;/a&gt;, with a similar goal.&amp;nbsp; His classes provide an API for the plugins, with few supporting features (e.g. searching for plugins).&lt;/li&gt;&lt;li&gt;&lt;a href="http://aroberge.blogspot.com/2008/12/plugins-part-1-application.html"&gt;André Roberge&lt;/a&gt; has a series of posts that describe the application of plugins to refactor a simple calculator application.&amp;nbsp; The goal of this is to illustrate the requirements for plugin frameworks, with the goal of identifying best practices for plugins. There are some interesting replies to this post, which consider implementations of the plugins he proposes in &lt;a href="http://www.plope.com/Members/chrism/pluginizing_an_app"&gt;zope &lt;/a&gt;and &lt;a href="http://regebro.wordpress.com/2008/12/19/the-plugin-architecture-bashout-grok/"&gt;grok&lt;/a&gt;. Both of these pull in quite a few libraries, which begs the question of whether it makes sense for external users to rely on these components for only plugin support.&lt;/li&gt;&lt;li&gt;Enthought's &lt;a href="http://pypi.python.org/pypi/EnvisageCore/3.0.1"&gt;Envisage&lt;/a&gt; project includes a framework for building extensible, pluggable applications.&amp;nbsp; The enthough.envisage package defines these capabilities, and there is nice documentation &lt;a href="https://svn.enthought.com/enthought/wiki/EnvisageThree/core.html"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Trac and Zope are frameworks that incorporate plug-ins, and these capabilities may be modular enough for use in other applications. Trac's &lt;a href="http://trac.edgewall.org/wiki/TracDev/ComponentArchitecture"&gt;component architecture&lt;/a&gt; is detailed in the Trac wiki pages. Zope's plug-ins appear to be called &lt;a href="http://www.contentmanagementsoftware.info/zope"&gt;products&lt;/a&gt; (see also &lt;a href="http://www.linuxjournal.com/article/5687"&gt;here&lt;/a&gt;). &lt;a href="http://www.martinaspeli.net/articles/writing-trac-plugins"&gt;Martin Aspeli&lt;/a&gt; describes his experience writing Trac plug-ins and contrasts them with Zope.&lt;/li&gt;&lt;li&gt;The &lt;a href="https://software.sandia.gov/trac/pyutilib/export/1831/pyutilib.component.doc/trunk/doc/plugin/pca.pdf"&gt;PyUtilib Component Architecture (PCA)&lt;/a&gt; is a component architecture in Python that is derived from the &lt;a href="http://trac.edgewall.org/wiki/TracDev/ComponentArchitecture"&gt;Trac component framework&lt;/a&gt;.  One important extension was to support both singleton and non-singleton plugins.  Singleton plugins are created immediately when the plugin module is loaded, which is well-suited for persistent applications like Trac.  However, many other applications need to employ plugins "on demand", which need to be explicitly constructed by the end-user.  &lt;a href="https://software.sandia.gov/trac/pyutilib"&gt;(See the PyUtilib wiki for further details.)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/daltonmatos/plugnplay#readme"&gt;Plug n' PLay (PnP)&lt;/a&gt; is a Generic plug-in system inspired by Trac's internal component management. PnP is roughly a implementation of the Observer pattern (&lt;a href="http://en.wikipedia.org/wiki/Observer_pattern"&gt;http://en.wikipedia.org/wiki/Observer_pattern&lt;/a&gt;).&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;These resources highlight one reason why there is not a standard Python plug-in framework: there are a variety of different capabilities that a user may want, and the complexity of the framework generally increases as these new capabilities are added (e.g. security, API validation, etc).  Another item that seems clear is that while a variety of packages support plug-ins, many of them do not use them in a modular fashion.&amp;nbsp; Thus, it is difficult to reuse sophisticated plug-in frameworks without incorporating a lot of extraneous code.   &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-7963574898419282330?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/7963574898419282330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/01/python-plugin-frameworks.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/7963574898419282330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/7963574898419282330'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/01/python-plugin-frameworks.html' title='Python Plugin Frameworks'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1651633691990855073</id><published>2009-01-20T09:38:00.001-08:00</published><updated>2009-01-20T09:41:38.511-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>A Python Trick: Adding a Lambda Method to a Class</title><content type='html'>It does not take much to add a lambda function to a Python class. For example, consider the following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &gt;&gt;&gt; class A: pass&lt;br /&gt;  &gt;&gt;&gt; f = lambda self,x:x&lt;br /&gt;  &gt;&gt;&gt; setattr(A,"f",f)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This code adds the method &lt;font face="Courier New"&gt;f &lt;/font&gt;to class &lt;font face="Courier New"&gt;A&lt;/font&gt;.  For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &gt;&gt;&gt; a=A()&lt;br /&gt;  &gt;&gt;&gt; a.f(1)&lt;br /&gt;  1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, the &lt;font face="Courier New"&gt;f &lt;/font&gt;method created this way does not have the expected Python name:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &gt;&gt;&gt; A.f.__name__&lt;br /&gt;  '&lt;lambda&gt;'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Further, defining this value is not possible; the instancemethod &lt;font face="Courier New"&gt;f &lt;/font&gt;does not have a &lt;font face="Courier New"&gt;__name__&lt;/font&gt; attribute.&lt;br /&gt;&lt;br /&gt;The trick is to name the lambda function &lt;i&gt;before &lt;/i&gt;defining the class method:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &gt;&gt;&gt; class A: pass&lt;br /&gt;  &gt;&gt;&gt; f = lambda self,x:x&lt;br /&gt;  &gt;&gt;&gt; f.__name__ = "f"&lt;br /&gt;  &gt;&gt;&gt; setattr(A,"f",f)&lt;br /&gt;  &gt;&gt;&gt; f.__name__&lt;br /&gt;'f'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is simple, but it took too long to figure this out...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1651633691990855073?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1651633691990855073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/01/python-trick-adding-lambda-method-to.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1651633691990855073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1651633691990855073'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/01/python-trick-adding-lambda-method-to.html' title='A Python Trick: Adding a Lambda Method to a Class'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-8349204839951779182</id><published>2009-01-20T09:05:00.001-08:00</published><updated>2009-01-20T11:35:04.275-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Interrupting the UNIX time command</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Consider the following use of the standard Unix time command:&lt;br /&gt;&lt;pre&gt;/usr/bin/time ls -R /&lt;/pre&gt;&lt;br /&gt;If the SIGTERM signal is sent to the time process, then the &lt;span style="font-family:Courier New;"&gt;ls&lt;/span&gt; process will continue! This is an unexpected behavior, which is not well-documented.&lt;br /&gt;&lt;br /&gt;Normally, this is not much of an issue; the process that is monitored will simply terminate quietly. However, when the &lt;span style="font-family:Courier New;"&gt;time &lt;/span&gt;utility is used in interactive applications, process interrupts can lead to many unexpected rogue processes.&lt;br /&gt;&lt;br /&gt;The &lt;a href="https://software.sandia.gov/trac/utilib/wiki/Documentation/timer"&gt;&lt;b&gt;timer&lt;/b&gt;&lt;/a&gt; command is a modification of the UNIX timing utility that behaves as expected. When using &lt;b&gt;timer&lt;/b&gt;, the SIGTERM signal is sent to the process, which terminates it as expected. The &lt;a href="https://software.sandia.gov/trac/utilib/wiki/Documentation/timer"&gt;&lt;b&gt;timer&lt;/b&gt;&lt;/a&gt; command is available in the &lt;a href="https://software.sandia.gov/trac/utilib"&gt;UTILIB&lt;/a&gt; software library, but it can be compiled independently.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-8349204839951779182?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/8349204839951779182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/01/interrupting-unix-time-command.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8349204839951779182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8349204839951779182'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/01/interrupting-unix-time-command.html' title='Interrupting the UNIX time command'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1736698869510762609</id><published>2009-01-19T22:39:00.001-08:00</published><updated>2009-01-20T11:38:56.864-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Monitoring Maximum Memory Usage in Linux</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;There are many tools available that can be used to monitor memory usage in computer programs. However, there are few tools that can be applied to monitor the memory usage of a specific process in an automated manner. Most memory monitoring tools provide a gui that a user can monitor.&lt;br /&gt;&lt;br /&gt;However, these tools are not useful in contexts where memory must be monitored repeatedly. For example, automated software tests may require checks to validate that the memory usage does not exceed expected limits.&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;&lt;a href="https://software.sandia.gov/trac/utilib/wiki/Documentation/memmon"&gt;memmon&lt;/a&gt;&lt;/b&gt; command is a new memory monitoring tool that is included in the &lt;a href="https://software.sandia.gov/trac/utilib"&gt;UTILIB&lt;/a&gt; software library. &lt;b&gt;memmon &lt;/b&gt;provides a convenient mechanism to report the maximum amount of memory that a process uses.&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;memmon&lt;/b&gt; command requires the absolute path to the command that will be executed.  Beyond that, its default syntax is quite simple:&lt;br /&gt;&lt;pre&gt;$ ./memmon /bin/sleep 1&lt;br /&gt;53768 Kb used&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;memmon&lt;/b&gt; command can also be used to terminate a process whose memory exceeds a specified threshold:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ./memmon -k 10 /bin/sleep 1&lt;br /&gt;./memmon: Error: memory exceeded&lt;br /&gt;53764 Kb used&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At present, &lt;b&gt;memmon&lt;/b&gt; only supports memory monitoring on Linux platforms. However, it is not clear how its capability could be ported to other operating systems.  I am particularly interested in this capability on MS Windows, if anyone has ideas for how to do that...&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1736698869510762609?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1736698869510762609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/01/monitoring-maximum-memory-usage-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1736698869510762609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1736698869510762609'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/01/monitoring-maximum-memory-usage-in.html' title='Monitoring Maximum Memory Usage in Linux'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-5255302370987629602</id><published>2009-01-19T22:01:00.001-08:00</published><updated>2009-01-19T22:38:37.068-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Software Releases</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I have not blogged much this fall because I have been busy managing a variety of software releases.  I plan to include further details in upcoming blogs, but I thought I would summarize these releases here:&lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='https://software.sandia.gov/trac/acro'&gt;acro 2.0&lt;/a&gt; - Acro is &lt;i&gt;A Common Repository for Optimizers&lt;/i&gt; that integrates a rich variety of optimization libraries and solvers that have been developed for large-scale engineering and scientific applications. Acro was developed to facilitate the design, development, integration and support of optimization software libraries. Thus, Acro includes both individual optimization solvers as well as optimization frameworks that provide abstract interfaces for flexible interoperability of solver components. Furthermore, many solvers included in Acro can exploit parallel computing resources to solve optimization problems more quickly. &lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href='https://software.sandia.gov/trac/utilib'&gt;utilib 4.0&lt;/a&gt; - Utilib is a library of general-purpose C++ utilities, similar in spirit to the Boost libraries. While generally treated as an Acro package, Utilib is hosted in a separate subversion repository to facilitate use by projects outside of Acro. &lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href='https://software.sandia.gov/trac/pyutilib'&gt;PyUtilib  1.0&lt;/a&gt; - PyUtilib is yet another a Python utility library. PyUtilib supports several Python projects under development at Sandia National Laboratories, including Acro, Coopr and FAST.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href='https://software.sandia.gov/trac/fast'&gt;FAST 2.0&lt;/a&gt; - FAST provides a collection of Python tools that support software testing. In it's current form, this does not really constitute a framework, but the plan is to develop a set of tools that support comprehensive testing of software tools.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href='https://software.sandia.gov/trac/coopr'&gt;Coopr 1.0&lt;/a&gt; - The Coopr Python package integrates a variety of Python optimization-related packages. Most of these packages rely on externally built optimization solvers. In particular, the Acro software builds many optimizers used by Coopr packages.&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;The Trac wikis for these packages contain a variety of tools that I'll describe in more detail later...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-5255302370987629602?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/5255302370987629602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2009/01/software-releases.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/5255302370987629602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/5255302370987629602'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2009/01/software-releases.html' title='Software Releases'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-8146400181787398651</id><published>2008-10-28T07:06:00.001-07:00</published><updated>2008-10-28T07:13:16.314-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Generating tests in Python unittest</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;There are many applications where you want to apply a code to a variety of data sets, and verify that you get the correct output.  In this context, what you want is a test generator, which can dynamically create tests, based on the set of data sets that are available for testing.&lt;br /&gt;&lt;br /&gt;Unfortunately, this does not appear to be a feature of &lt;span style="font-family:Courier New;"&gt;unittest&lt;/span&gt;.  The closest I have seen to this, is the support for test generators in the &lt;a href="http://somethingaboutorange.com/mrl/projects/nose"&gt;nose&lt;/a&gt; package, which extends &lt;span style="font-family:Courier New;"&gt;unittest &lt;/span&gt;to provide test discovery mechanisms.  However, that test generation feature is somewhat limited; it only applies to test functions that are Python generators, and not to similar class methods.&lt;br /&gt;&lt;br /&gt;The following example shows how to directly insert new test methods into a &lt;span style="font-family:Courier New;"&gt;unittest.TestCase class&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;&lt;br /&gt;#&lt;br /&gt;# A simple example for generating tests in the Python unittest framework&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;import glob&lt;br /&gt;import unittest&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Defining the class that will contain the new tests&lt;br /&gt;#&lt;br /&gt;class TestCases(unittest.TestCase): pass&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# A generic function that performs a test on a particular file&lt;br /&gt;#&lt;br /&gt;def perform_test(self,file):&lt;br /&gt;  if len(file) &gt; 20:&lt;br /&gt;      self.fail("Failing in file \""+file+"\" because its name is too long.")&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Insert test methods into the TestCases class&lt;br /&gt;#&lt;br /&gt;for file in glob.glob("*")+glob.glob("*/*"):&lt;br /&gt;  tmp = file.replace("/","_")&lt;br /&gt;  tmp = tmp.replace("\\","_")&lt;br /&gt;  tmp = tmp.replace(".","_")&lt;br /&gt;  setattr(TestCases, "test_"+tmp, lambda self,x=file: perform_test(self,x))&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Apply these unittests&lt;br /&gt;#&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;  unittest.main()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this example, the files in the current directory and in all subdirectories are used to create new test methods.  For each file, a new test method is added to the &lt;span style="font-family:Courier New;"&gt;TestCases &lt;/span&gt;class, which does a silly check to see if the file is &lt;i&gt;too long&lt;/i&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-8146400181787398651?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/8146400181787398651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/10/generating-tests-in-python-unittest.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8146400181787398651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8146400181787398651'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/10/generating-tests-in-python-unittest.html' title='Generating tests in Python unittest'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-6100893298678272534</id><published>2008-10-03T07:43:00.001-07:00</published><updated>2008-10-03T07:43:42.810-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='constraint programming'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>Constraint Programming</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Nick Berger pointed me to the &lt;a href='http://www.emn.fr/x-info/sdemasse/gccat/index.html'&gt;Global Constraint Catalog&lt;/a&gt;, a collection of constraints that are can be used for constraint programming formulations.  This looks like a nice reference!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-6100893298678272534?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/6100893298678272534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/10/constraint-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6100893298678272534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6100893298678272534'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/10/constraint-programming.html' title='Constraint Programming'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-5314976134164395859</id><published>2008-10-01T06:54:00.001-07:00</published><updated>2008-10-01T06:55:43.562-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>New Journal: Mathematical Programming Computation</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;I have recently joined the editorial board of the new journal &lt;a href="http://www2.isye.gatech.edu/%7Ewcook/mpc/index.html"&gt;Mathematical Programming Computation&lt;/a&gt;, which publishes original research articles that are at the intersection of math programming and computing.  This journal reflects the growing role of computation in operations research, where real-world applications often require the application of complex software packages to analyze mathematical models.&lt;br /&gt;&lt;br /&gt;This journal will include articles that report on innovative software, comparative tests, modeling environments, libraries of data, and/or applications. A main feature of the journal is the inclusion of accompanying software and data with submitted manuscripts. The journal's review process includes the evaluation and testing of the accompanying software. Where possible, the review will aim for verification of reported computational results.&lt;br /&gt;&lt;br /&gt;Topics covered in Mathematical Programming Computation include linear programming, convex optimization, nonlinear optimization, stochastic optimization, robust optimization, integer programming, combinatorial optimization, global optimization, network algorithms, and modeling languages. &lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-5314976134164395859?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/5314976134164395859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/10/new-journal-mathematical-programming.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/5314976134164395859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/5314976134164395859'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/10/new-journal-mathematical-programming.html' title='New Journal: Mathematical Programming Computation'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-8599433615204122658</id><published>2008-09-24T07:24:00.001-07:00</published><updated>2008-09-24T07:37:55.266-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='web references'/><title type='text'>Online Video Tutorials</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;By necessity, I have become quite adept at digging through webspace with search engines like google to figure out "how to do X".  But occasionally, it is difficult to get a sense of whether something is &lt;i&gt;easy &lt;/i&gt;from written instructions.  For example, I recently tried to install PyQT, a Python interface to the popular QT application interface library, and here's the error that I got when trying to use nmake to build the SIP library (which PyQT uses):&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:Courier New;"&gt;&lt;small&gt;C:\Python25\sip-4.7.6\sip-4.7.6\siplib&amp;gt;nmake&lt;br /&gt;&lt;br /&gt;Microsoft (R) Program Maintenance Utility Version 8.00.50727.762&lt;br /&gt;Copyright (C) Microsoft Corporation.  All rights reserved.&lt;br /&gt;&lt;br /&gt;      cl -c -nologo -Zm200 -O2 -MD -W0 -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -I. -IC:\Python25\include -Fo @C:\DOCUME~1\wehart\LOCALS~1\Temp\nm271.tmp&lt;br /&gt;NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.EXE"' : return code '0xc0000135'&lt;br /&gt;Stop.&lt;/small&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;I had more than a little difficulty figuring out what the return code &lt;span style="font-family:Courier New;"&gt;&lt;small&gt;0xc0000135&lt;/small&gt;&lt;/span&gt; meant, especially since this is turned out to be an nmake return error and not an error generated by cl.  Go figure.&lt;br /&gt;&lt;br /&gt;In many cases, it is much easier to look over someone's shoulder and have them show you the ropes.  That is why I have been so impressed with the &lt;a href="http://showmedo.com/videos/all"&gt;ShowMeDo&lt;/a&gt; tutorial site.  This site provides video tutorials where someone walks you through common installation, setup and configuration examples.&lt;br /&gt;&lt;br /&gt;I think that this site is particularly useful for an "average" computer user, who is not familiar with manual software installation and configuration. I work with a variety of such users in my work, and I have found that these tutorials provide a convenient reference that it quite accessible.  If they cannot look over &lt;i&gt;my &lt;/i&gt;shoulder, then at least they can view a video that provides a similar experience!&lt;br /&gt;&lt;br /&gt;The site also includes video tutorials for how to create video tutorials!  I have not tried this myself, but I hope this type of tutorial catches on.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-8599433615204122658?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/8599433615204122658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/09/online-video-tutorials.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8599433615204122658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/8599433615204122658'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/09/online-video-tutorials.html' title='Online Video Tutorials'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-387019686510217155</id><published>2008-09-22T07:09:00.000-07:00</published><updated>2008-09-24T07:35:38.427-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Why Python?</title><content type='html'>In the past year, I have increasingly been using Python to develop a variety of OR-related scientific software.  In particular, the &lt;a href="https://software.sandia.gov/svn/public/coopr/"&gt;Coopr &lt;/a&gt;library has been a major focus of this software development.&lt;br /&gt;&lt;br /&gt;Recently, I have written a paper that will appear in the proceedings of the &lt;a href="http://ics09.meetings.informs.org/"&gt;INFORMS Computing Society Conference 2009&lt;/a&gt;:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:arial;"&gt;W. Hart, &lt;/span&gt;&lt;span style="font-style: italic;font-family:arial;" &gt;Python Optimization Modeling Objects (Pyomo)&lt;/span&gt;&lt;span style="font-family:arial;"&gt;, Proc. INFORMS Computing Society Conference, 2009, (to appear).&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;In this paper, I describe Pyomo, an open-source tool for modeling optimization applications in Python.  A key goal of Pyomo is to provide an open-source math programming modeling capability.  Although open-source optimization solvers are widely available in packages like &lt;a href="http://www.coin-or.org/"&gt;COIN-OR&lt;/a&gt;, surprisingly few open-source tools have been developed to model optimization applications.&lt;br /&gt;&lt;br /&gt;Pyomo has been developed in Python because it is a well-used modern programming language that provides a robust foundation for developing and applying scientific software.  In this paper, I noted that Python meets some basic criteria that relate to how Pyomo will be used and managed:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Open Source License:&lt;/span&gt; Python is freely available, and its liberal open source license lets you modify and distribute a Python-based application with few restrictions.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Features:&lt;/span&gt; Python has a rich set of datatypes, support for object oriented programming, namespaces, exceptions, and dynamic loading.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Support and Stability:&lt;/span&gt; Python is highly stable, and it is well supported through newsgroups and special interest groups.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Documentation:&lt;/span&gt; Users can learn about Python from extensive online documentation, and a number of excellent books that are commonly available.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Standard Library:&lt;/span&gt; Python includes a large number of useful modules.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Extendability and Customization:&lt;/span&gt; Python has a simple model for loading Python code developed by a user.  Additionally, compiled code packages that optimize computational kernels can be easily used.  Python includes support for shared libraries and dynamic loading, so new capabilities can be dynamically integrated into Python applications.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Portability:&lt;/span&gt; Python is available on a wide range of compute platforms, so portability is typically not a limitation for Python-based applications.&lt;/li&gt;&lt;/ul&gt;Another factor, not to be overlooked, is the increasing acceptance of Python in the scientific community.  Large Python projects like &lt;a href="http://www.scipy.org/"&gt;SciPy &lt;/a&gt;and &lt;a href="http://www.sagemath.org/"&gt;SAGE &lt;/a&gt;strongly leverage a diverse set of Python packages.&lt;br /&gt;&lt;br /&gt;Several other popular programming languages were also considered for Pyomo.  However, in most cases Python appears to have distinct advantages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;.Net&lt;/span&gt;: As mentioned earlier, the .Net languages are not portable to Linux platforms, and thus they were not suitable for Pyomo.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Ruby: &lt;/span&gt;At the moment, Python and Ruby appear to be the two most widely recommended scripting languages that are portable to Linux platforms, and comparisons suggest that their core functionality is similar.  Our preference for Python is largely based on the fact that it has a nice syntax that does not require users to type weird symbols(e.g. \$, \%, @).  Thus, we expect this will be a more natural language for expressing math programming models.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Java:&lt;/span&gt; Java has a lot of the same strengths as Python, and it is arguably as good a choice for Pyomo.  However, two aspects of Python recommended it for Pyomo instead of Java.  First, Python has a powerful interactive interpreter that allows realtime code development and encourages experimentation with Python software.  Thus, users can work interactively with Pyomo models to become familiar with these objects and to diagnose bugs.  Second, it is widely acknowledged that Python's dynamic typing and compact, concise syntax makes software development quick and easy.  Although some very interesting optimization modeling tools have been developed in languages like C++ and Java, there is anecdotal evidence that users will not be as productive in these languages as they will when using tools developed in languages like Python (see &lt;a href="http://www.ferg.org/projects/python_java_side-by-side.html"&gt;Python vs Java&lt;/a&gt;).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;C++:&lt;/span&gt; Models formulated with the &lt;a href="https://projects.coin-or.org/FlopC++"&gt;FlopC++&lt;/a&gt; package are similar to models developed with Pyomo.  They are be specified in a declarative style using classes to represent model components (e.g. sets, variables and constraints).  However, C++ requires explicit compilation to execute code, and it does not support an interactive interpreter.  Thus, we believe that Python will provide a more flexible language for users.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-387019686510217155?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/387019686510217155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/09/why-python.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/387019686510217155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/387019686510217155'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/09/why-python.html' title='Why Python?'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-4354871975903351100</id><published>2008-09-21T21:16:00.001-07:00</published><updated>2008-09-24T07:33:43.302-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='conferences'/><title type='text'>INFORMS ICS Meeting</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;If you are interested in the intersection of operations research and computing, then the &lt;a href="http://www.blogger.com/%20http://ics09.meetings.informs.org/" target="_blank"&gt;INFORMS ICS Meeting&lt;/a&gt; will be of interest to you!  I am organizing a session on open-source software for operations research.  &lt;a href="mailto:wehart@sandia.gov"&gt;Contact me&lt;/a&gt; if you are interested in giving a presentation!&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-4354871975903351100?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/4354871975903351100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/09/informs-ics-meeting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4354871975903351100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/4354871975903351100'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/09/informs-ics-meeting.html' title='INFORMS ICS Meeting'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-1408533554330506913</id><published>2008-09-08T15:39:00.001-07:00</published><updated>2008-09-24T07:34:17.952-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='web references'/><title type='text'>Why open-source software?</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Much of my work involves the development of open-source software.  Recently, I have been challenged to justify this in several different projects.&lt;br /&gt;&lt;br /&gt;I recently stumbled across &lt;a href="http://www.dwheeler.com/oss_fs_why.html"&gt;Dave Wheeler's paper&lt;/a&gt;, which provides a nice &lt;i&gt;quantitative&lt;/i&gt; analysis of the advantages of open-source software.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-1408533554330506913?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/1408533554330506913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/09/why-open-source-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1408533554330506913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/1408533554330506913'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/09/why-open-source-software.html' title='Why open-source software?'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-2620707532773026824</id><published>2008-09-06T14:58:00.001-07:00</published><updated>2008-09-24T07:34:30.181-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web references'/><title type='text'>Testing ScribeFire</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;I'm going to try using &lt;a href="http://blog.scribefire.com/"&gt;ScribeFire&lt;/a&gt; to generate these posts.  This seems highly recommended. Also, I can work with it offline, which is a definite plus for me!&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-2620707532773026824?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/2620707532773026824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/09/testing-scribefire.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2620707532773026824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/2620707532773026824'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/09/testing-scribefire.html' title='Testing ScribeFire'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2814339190488879140.post-6443766962135928171</id><published>2008-08-27T19:13:00.000-07:00</published><updated>2008-09-24T07:34:40.402-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Starting to blog...?</title><content type='html'>OK, this is really my second blogging experience.  I'm currently the 'blogger in residence' for the &lt;a href="http://computing.society.informs.org/"&gt;INFORMS Computing Society&lt;/a&gt;.  Though I'm still trying to figure out what that means, I blogged the last &lt;a href="http://computing.society.informs.org/serendipity/"&gt;INFORMS Annual Meeting&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;So, why this blog?  I do a lot of software development at Sandia National Laboratories, mostly focused on scientific computing and optimization.  The more I work with open-source projects, the more I realize that I should archive some of my 'lessons learned'.  Although I like to publish papers, a blog is a better way to informally share information!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2814339190488879140-6443766962135928171?l=wehart.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wehart.blogspot.com/feeds/6443766962135928171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wehart.blogspot.com/2008/08/starting-to-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6443766962135928171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2814339190488879140/posts/default/6443766962135928171'/><link rel='alternate' type='text/html' href='http://wehart.blogspot.com/2008/08/starting-to-blog.html' title='Starting to blog...?'/><author><name>Bill Hart</name><uri>http://www.blogger.com/profile/10166929153462801784</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
