    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Generating Lists for C++ in Python</title>
        <link>https://members.accu.org/index.php/articles/1217</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 15, #3 - Jun 2003</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c108/">153</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-108/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+108/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Generating Lists for C++ in Python</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 June 2003 13:15:57 +01:00 or Tue, 03 June 2003 13:15:57 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>In this, the second article in my Practical Uses for Python in C++ Series, I explore and provide examples of using Python [python] to generate lists for C++. </p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p><span class="inlinemediaobject"><img src=
"resources/python%20lists.jpg" align="right"></span>In this, the
second article in my Practical Uses for Python in C++ Series, I
explore and provide examples of using Python [<a href=
"#python">python</a>] to generate lists for C++. The particular
example I am going to use is the loading of country names into a
Combo Box (see figure 1). Most of my GUI development experience has
been with the Microsoft Visual C++ (MSVC) Graphical User Interface
(GUI) libraries. For this article I decided I would try out a new
cross-platform GUI framework library, with the idea that it may
help the article appeal to more people. I initially looked at Qt
[<a href="#qt">qt</a>] but found various problems with it. I then
tried WxWindows [<a href="#wxwindows">wxwindows</a>] and found it
much easier to work with, after the initial set-up and
compilation.</p>
<p>At the time of writing the latest stable release of WxWindows is
2.4.0 and can be downloaded from the WxWindows Download [<a href=
"#download">download</a>] page. There are versions available for
Windows, Unix (including Linux), MacOS and OS/2. Full installation
and build instructions come with each package and are beyond the
scope of this article. I would also recommend the wizard [<a href=
"#wizard">wizard</a>] for MSVC and Windows users.</p>
<p>Before writing the necessary Python script we need a test
application with a Combo Box. This is quite easy with WxWindows and
only requires two new classes - an application class and a dialog
class. The dialog class holds the combo box and is defined as
follows:</p>
<pre class="programlisting">
// PythonListsDialog.h (include guards omitted)
#include &quot;wx/dialog.h&quot;
#include &quot;wx/combobox.h&quot;
#include &quot;wx/textctrl.h&quot;
class PythonListsDialog : public wxDialog {
public:
  PythonListsDialog(wxWindow *parent);
private:
  virtual void InitDialog();
  void OnComboTextChanged(wxCommandEvent &amp;event);
private:
  wxComboBox *m_pCombo;
  wxTextCtrl *m_pText;
private:
  DECLARE_EVENT_TABLE()
};
</pre>
<p><tt class="literal">PythonListsDialog</tt> is implemented in the
following way:</p>
<pre class="programlisting">
// PythonListsDialog.cpp
#include &quot;PythonListsDialog.h&quot;
#include &quot;wx/icon.h&quot;
#include &quot;wx/msgdlg.h&quot;
#include &lt;memory&gt;
const wxWindowID comboId = 1000;
const wxWindowID textId = 1001;
BEGIN_EVENT_TABLE(PythonListsDialog, wxDialog)
  EVT_TEXT(comboId,
           PythonListsDialog::OnComboTextChanged)
END_EVENT_TABLE()
PythonListsDialog::PythonListsDialog(wxWindow
                                     *parent) :
  wxDialog(parent, -1, _T(&quot;Python Lists&quot;),
  wxDefaultPosition, wxSize(200,100),
  wxDEFAULT_DIALOG_STYLE),
  m_pCombo(0),
  m_pText(0) {}

void PythonListsDialog::InitDialog() {
  try {
    wxString comboContents[] = {&quot;&quot;};
    m_pCombo = new wxComboBox(this,
               comboId,
               &quot;&quot;,
               wxPoint(10,40),
               wxDefaultSize,
               0,
               comboContents,
               wxCB_DROPDOWN | wxCB_READONLY);
    // Extra check for implementations
    // where new does not throw.
    if (m_pCombo == 0) {
      throw std::bad_alloc(&quot;Failed to create
                     combo box: new failed.&quot;);
    }
    m_pText = new wxTextCtrl(this,
                             textId,
                             &quot;&quot;,
                             wxPoint(10,10),
                             wxDefaultSize,
                             wxTE_READONLY);
    // Extra check for implementations
    // where new does not throw.
    if (m_pText == 0) {
      throw std::bad_alloc(&quot;Failed to create
      text box: new failed.&quot;);
    }
  }
  catch(const std::bad_alloc&amp; e) {
    wxMessageBox(e.what(),
    wxString(&quot;Dialog Error&quot;),wxOK,this);
  }
}

void PythonListsDialog::OnComboTextChanged(
                    wxCommandEvent &amp;event) {
  m_pText-&gt;SetValue(event.GetString());
}
</pre>
<p>The second class is the application class and is defined as
follows:</p>
<pre class="programlisting">
// PythonListsApp.h (include guards omitted)
#include &quot;wx/wxprec.h&quot;
class PythonListsApp : public wxApp {
private:
  virtual bool OnInit();
};
DECLARE_APP(PythonListsApp)
</pre>
<p>The application class implements its single override in the
following way:</p>
<pre class="programlisting">
// PythonListsApp.cpp
#include &quot;PythonListsApp.h&quot;
#include &quot;PythonListsDialog.h&quot;
IMPLEMENT_APP(PythonListsApp)
bool PythonListsApp::OnInit() {
  // This will be deleted by the framework.
  PythonListsDialog* pDialog =
                  new PythonListsDialog(0);
  pDialog-&gt;ShowModal();
  return false;
}
</pre>
<p>Now that we have an application with a Combo Box we need to fill
it with country names. The <tt class="literal">wxComboBox</tt>
method for adding strings to the combo box is <tt class=
"literal">Append()</tt>. Therefore the code to add countries would
look something like this:</p>
<pre class="programlisting">
m_pCombo-&gt;Append(&quot;Afghanistan&quot;);
m_pCombo-&gt;Append(&quot;Albania&quot;);
m_pCombo-&gt;Append(&quot;Algeria&quot;);
....
m_pCombo-&gt;Append(&quot;Zimbabwe&quot;);
</pre>
<p>This would take some time to format and enter into the code by
hand and if the list ever changed significantly (unlikely for
countries, of course) it would need doing again. This is where
Python comes in handy. If you have a list of countries in a text
file, Python can be used to generate a function which will load all
the countries into the combo box.</p>
<p>Start with a header file that declares the function which will
load the countries:</p>
<pre class="programlisting">
// LoadCountries.h
#ifndef LOADCOUNTRIES_H
#define LOADCOUNTRIES_H
#include &quot;wx/combobox.h&quot;
void LoadCountries(wxComboBox* pComboBox);
#endif // LOADCOUNTRIES_H
</pre>
<p>Then create a template for the cpp file. Call it something like
'<tt class="literal">LoadCountries_template.cpp</tt>':</p>
<pre class="programlisting">
// LoadCountries.cpp
#include &quot;LoadCountries.h&quot;
void LoadCountries(wxComboBox* pComboBox) {
  if (pComboBox != 0) {
    // Countries Here
  }
}
</pre>
<p>The template file will be used to generate C++ along with the
text file containing the list of countries. The comment:</p>
<pre class="programlisting">
// Countries Here
</pre>
<p>is used to tell the Python script where to write the countries
in the generated C++ file.</p>
<p>Now it's time to write a Python script. Assuming that the list
of countries is in a flat text file called 'countries.txt' and the
C++ template is in a file called '<tt class=
"literal">LoadCountries_template.cpp</tt>', the first thing we want
the script to do is take the two input files and an output file as
command line arguments:</p>
<pre class="programlisting">
# CountriesList.py
import sys
import string
print &quot;\nCountriesList.py\n&quot;
# Check Command Line Parameters
if len(sys.argv) &lt; 4:
  print &quot;CountriesList.py requires three filenames \
                       as command line parameters: &quot;
  &quot;Countries, Template, OutputFile&quot;
else:
  print &quot;Countries Filename:\t&quot; + sys.argv[1]
  print &quot;Template Filename:\t&quot; + sys.argv[2]
  print &quot;Output Filename:\t&quot; + sys.argv[3] + &quot;\n&quot;
</pre>
<p>Then open, read in and store the list of countries and the
template:</p>
<pre class="programlisting">
#Open and store Countries
CountriesFile = open(sys.argv[1],&quot;r&quot;)
CountriesStore = CountriesFile.readlines()
CountriesFile.close
#Open and store Template
TemplateFile = open(sys.argv[2],&quot;r&quot;)
TemplateStore = TemplateFile.readlines()
TemplateFile.close
</pre>
<p>This list of countries I have is all in upper case and each
country is followed by its abbreviation. For example:</p>
<pre class="programlisting">
AFGHANISTAN AF
ALBANIA AL
ALGERIA DZ
AMERICAN SAMOA AS
</pre>
<p>Therefore as the Python script writes the C++ it not only needs
to be able to spot the &quot;<tt class="literal">// Countries Here</tt>&quot;
comment, it must also case the countries and remove the
abbreviation. Also, each country must be wrapped in quotes (&quot;) as
well as the <tt class="literal">Append</tt> method.</p>
<p>The &quot;<tt class="literal">// Countries Here</tt>&quot; comment must be
detected during the writing of the output file. This can be done as
follows:</p>
<pre class="programlisting">
#Write Output File
OutputFile = open(sys.argv[3],&quot;w&quot;)
for templateline in TemplateStore:
  if templateline == &quot;// Countries Here\n&quot;:
    # write countries here
    print &quot;Countries Comment Found.\n&quot;
  else:
    OutputFile.write(templateline)
OutputFile.close()
print sys.argv[3] + &quot; written Ok.&quot;
</pre>
<p>Finally the countries must be formatted and written to the
output file. Python makes this easy:</p>
<pre class="programlisting">
# loop through countries
for line in CountriesStore:
  # Remove country abbreviation
  line = line [:line.rfind(&quot; &quot;)]
  # Case country
  line = string.capwords(line)
  # Write combo box loading country code to
  # output file
  OutputFile.write('\t\tpComboBox-&gt;Append(&quot;' + \
                                  line + '&quot;);\n')
</pre>
<p>The complete Python script looks like this:</p>
<pre class="programlisting">
# CountriesList.py
import sys
import string
print &quot;\nCountriesList.py\n&quot;
# Check Command Line Parameters
if len(sys.argv) &lt; 4:
  print &quot;CountriesList.py requires three filenames \
                       as command line parameters: &quot;
  &quot;Countries, Template, OutputFile&quot;
else:
  print &quot;Countries Filename:\t&quot; + sys.argv[1]
  print &quot;Template Filename:\t&quot; + sys.argv[2]
  print &quot;Output Filename:\t&quot; + sys.argv[3] + &quot;\n&quot;
  #Open and store Countries
  CountriesFile = open(sys.argv[1],&quot;r&quot;)
  CountriesStore = CountriesFile.readlines()
  CountriesFile.close
  #Open and store Template
  TemplateFile = open(sys.argv[2],&quot;r&quot;)
  TemplateStore = TemplateFile.readlines()
  TemplateFile.close
  #Write Output File
  OutputFile = open(sys.argv[3],&quot;w&quot;)
  for templateline in TemplateStore:
    if templateline == &quot;// Countries Here\n&quot;:
      # loop through countries
      for line in CountriesStore:
        # Remove country abbreviation
        line = line [:line.rfind(&quot; &quot;)]
        # Case country
        line = string.capwords(line)
        # Write combo box loading country code
        # to output file
        OutputFile.write('\t\tpComboBox-&gt;Append(&quot;' + \
                                       line + '&quot;);\n')
    else:
      OutputFile.write(templateline)
OutputFile.close()
print sys.argv[3] + &quot; written Ok.&quot;
</pre>
<p>To generate the <tt class="literal">LoadCountries.cpp</tt> file
type the following at the command line, using the appropriate file
paths:</p>
<div class="literallayout">
<p>python countriesList.py countries.txt<br>
LoadCountries_template.cpp LoadCountries.cpp</p>
</div>
<p>Then add <tt class="literal">LoadCountries.cpp</tt> and
<tt class="literal">LoadCountries.h</tt> to theWxWindows project.
Add &quot;<tt class="literal">#include &quot;LoadCountries.h&quot;</tt>&quot; and
&quot;<tt class="literal">LoadCountries(m_pCombo);</tt>&quot; to <tt class=
"literal">PythonListsDialog.h</tt> and rebuild:</p>
<pre class="programlisting">
// PythonListsDialog.h
#include &quot;PythonListsDialog.h&quot;
#include &quot;wx\icon.h&quot;
#include &quot;wx\msgdlg.h&quot;
#include &quot;LoadCountries.h&quot;
#include &lt;memory&gt;
...
void PythonListsDialog::InitDialog() {
  try {
    wxString comboContents[] = {&quot;&quot;};
    m_pCombo = new wxComboBox(this,
                    comboId, &quot;&quot;,
                    wxPoint(10,40),
                    wxDefaultSize, 0,
                    comboContents,
                    wxCB_DROPDOWN | wxCB_READONLY);
    LoadCountries(m_pCombo);
  ...
</pre>
<p>Running the executable created by rebuilding the WxWindows
project will display a small dialog box with a Combo Box of
countries. Selecting a country from the Combo Box displays its edit
box above it (see figure). The full <tt class=
"literal">CountriesList.pyscript</tt> and a Microsoft Visual C++
6.0 test application [<a href="#source">source</a>] are available
for download from my website.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e163" id="d0e163"></a>References</h2>
</div>
<div class="bibliomixed"><a name="python" id="python"></a>
<p class="bibliomixed">[python] Python: <span class=
"bibliomisc"><a href="http://www.python.org/" target=
"_top">http://www.python.org/</a></span></p>
</div>
<div class="bibliomixed"><a name="qt" id="qt"></a>
<p class="bibliomixed">[qt] Qt: <span class="bibliomisc"><a href=
"http://www.trolltech.com/products/qt/" target=
"_top">http:\\www.trolltech.com/products/qt/</a></span></p>
</div>
<div class="bibliomixed"><a name="wxwindows" id="wxwindows"></a>
<p class="bibliomixed">[wxwindows] WxWindows: <span class=
"bibliomisc"><a href="http://www.wxwindows.org" target=
"_top">http://www.wxwindows.org</a></span></p>
</div>
<div class="bibliomixed"><a name="download" id="download"></a>
<p class="bibliomixed">[download] WxWindows Download page:
<span class="bibliomisc"><a href=
"http://www.wxwindows.org/downld2.htm" target=
"_top">http://www.wxwindows.org/downld2.htm</a></span></p>
</div>
<div class="bibliomixed"><a name="wizard" id="wizard"></a>
<p class="bibliomixed">[wizard] WxWindows wizard: <span class=
"bibliomisc"><a href="http://www.wxwindows.org/dl_optn.htm" target=
"_top">http://www.wxwindows.org/dl_optn.htm</a></span></p>
</div>
<div class="bibliomixed"><a name="source" id="source"></a>
<p class="bibliomixed">[source] Full CountriesList.py script and a
Microsoft Visual C++ 6.0 test application: <span class=
"bibliomisc"><a href=
"http://www.paulgrenyer.co.uk/download/python_lists.zip" target=
"_top">http://www.paulgrenyer.co.uk/download/python_lists.zip</a></span></p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
