    <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  :: Student Code Critique Competition</title>
        <link>https://members.accu.org/index.php/articles/1248</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">Student Code Critiques from CVu journal. + CVu Journal Vol 15, #5 - Oct 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/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c183/">Code Critique</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/c106/">155</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c183+106/">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;Student Code Critique Competition</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 October 2003 13:16:00 +01:00 or Fri, 03 October 2003 13:16:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e22" id="d0e22"></a>The
problem</h2>
</div>
<p><span class="emphasis"><em>What would you do to help this
student with his programming? Note that this time the student knows
enough about C++ to write a suitable program, so the problem is in
the mind to the extent that I think he is even confused by what is
needed as output.</em></span></p>
<p>I am working on a program that will tell someone how old they
are in years, days and months. I.e. You are 27 years, 200 months,
and 1500 days old.</p>
<pre class="programlisting">
#include &lt;iostream&gt;
using namespace std;
void main() {
  int currentyear = 2003;
  int dob = 0;
  int result = 0;
  int day = 0;
  int month = 0;
  cout &lt;&lt; &quot;Enter your year of birth: &quot;;
  cin &gt;&gt; dob;
  result = dob - 2003;
  cout &lt;&lt; &quot;You are &quot; &lt;&lt; result
       &lt;&lt; &quot; years old&quot; &lt;&lt; endl;
  cout &lt;&lt; &quot;Enther you month of birth: &quot;;
  cin &gt;&gt; month;
  for(result=0; result &lt;=12; result++)
    if(result &lt;= 12) result = month+12;
  cout &lt;&lt; &quot;You are &quot; &lt;&lt; result
       &lt;&lt; &quot; months old&quot;&lt;&lt;endl;
  cout &lt;&lt; &quot;Enter you day of birth: &quot;;
  cin &gt;&gt; day;
  for(result=0; result &lt;= 365; result++)
    if(result&lt;=365) result = day+365;
  cout &lt;&lt;&quot;You are &quot; &lt;&lt; result
       &lt;&lt; &quot; days old&quot;&lt;&lt;endl;
}
</pre>
<p><span class="emphasis"><em>Of course remember to comment on the
program defects but your main focus should be how to explain the
need for clear thought when producing a solution.</em></span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e35" id="d0e35"></a>Introductory
Comments</h2>
</div>
<p>This time I had just two entries that took very different
approaches. In my opinion neither managed to display clarity of
thought in the context of code. Both provide ideas about clear
thinking before you start coding. I wonder what you think?</p>
<p>I also wonder why you did not enter. Yes I do mean you, the
person reading this now. Perhaps you thought about it but never
actually got round to doing it. Perhaps you did it but thought it
not worth sending in the result. Well that certainly makes my life
easier and it also makes it easier for James to choose a winner.
However that would be to miss the point: the real benefit from this
column is not in reading it but in participating.</p>
<p>If you cannot sit down and bash out a reasonable submission to
most of these code critique exercises in a couple of hours then you
have a great deal still to learn. What is that I hear you say? OK
so you are an expert, but how do you intend to give constructive
help to the struggling newcomer to your team?</p>
<p>Please think about it and aim to try at least one critique every
year. If you are competent you should not fear the criticism of
your peers, and if you do fear such criticism you already doubt
your own skills and should welcome the chance to learn a little
more.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e46" id="d0e46"></a>From Colin
Greenock</h2>
</div>
<p>Francis asked for a critique of a short programme derived from
the following requirement, &quot;I am working on a programme that will
tell someone how old they are in years, days and months. I.e You
are 27 years, 200 months, and 1500 days old.&quot;</p>
<p>There are two problems to be solved for this critique. The first
is to try and explain the need for clear thought when trying to
produce a solution. The second to identify defects in the code as
supplied with an unwritten requirement for a sample of code that
works,</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e53" id="d0e53"></a>Clear
Thinking</h3>
</div>
<p>So how on earth do we explain or demonstrate how to think
clearly? Perhaps it is worth taking a step further back from the
impossible and showing how a clear problem definition can make it
easier to think clearly about the problem in hand. It doesn't
remove the need for clear thought, but it provides a sieve that you
can use to filter out the rubbish that might be cluttering your
thoughts. The better the problem definition the finer the sieve
and, one hopes, the clearer the resulting thoughts.</p>
<p>Let me try and demonstrate the process.</p>
<p>Taking the original summary of the programme's purpose it looks
like the programme should report the user's age in three different
formats rather than as a single, &quot;You are 27 years, 6 months and 21
days old&quot; result. Why? Well, normally you would not report month
values greater than 11 or days greater than 364. If that is the
case then the sample data doesn't make this clear as the figures
yield 3 different ages, 27, not quite 17 and a little over 4 years.
However looking at the code, well I'm really not sure what it's
trying to do, but I think it may in fact be trying to report the
age as a single, &quot;You are x years, y months and z days old.&quot;
statement.</p>
<p>So how are we to solve this problem? Which problem? Good point,
let's step back a bit and see if we can identify what problems we
have. In no particular order:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>How are we to calculate the user's age?</p>
</li>
<li>
<p>What calculations are we to perform? What are the &quot;business&quot;
rules?</p>
</li>
<li>
<p>How is the result to be presented to the user?</p>
</li>
<li>
<p>Who is going to be using the proposed programme?</p>
</li>
<li>
<p>Why is a programme required? Do we really need a computer to
achieve a result?</p>
</li>
</ul>
</div>
<p>Well the first problem on the list is probably the least
important of them all, it will come down to (ha ha) a SMOP (simple
matter of programming) and providing the rules used to calculate
ages are followed correctly any one solution is as likely to be as
good as any other.</p>
<p>The last question is always worth asking. Is this a one off task
where the result can be obtained using a pencil and paper with,
perhaps, the backing of an electronic calculator?</p>
<p>Correct answers to the remaining questions are vital to the
successful outcome of our project. So how are we going to answer
these questions? Simple. We're going to have to ask someone and
more to the point someone who knows about the problem area.</p>
<p>The <span class="emphasis"><em>really</em></span> difficult part
of our trade is that there's only one way of finding answers to the
questions above. That is talking to other people and extracting
information and decisions from them. This is a skill every bit as
important as being able to think clearly or knowing how to write
the leanest, meanest most efficient code ever in the most
fashionable language of the moment.</p>
<p>So how might this go in the commercial world? Well let's
imagine....</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>&quot;Good morning Sir. I'm from the I.T. dept. Have you a few
minutes, perhaps half an hour to talk about your request for a
programme to report someone's age?</p>
<p>What!? Can't you read? I sent a memorandum to your head chap
detailing my requirements last week!</p>
<p>Ah, yes Sir. I have a copy here. I have read it, but there are
still a few grey areas that we need to clear up with you and...</p>
<p>Oh, very well then. If you must, you must, but I'm a busy man so
it had better not take too long.</p>
<p>Well, shall we start with how the programme is to find out how
old the user is...</p>
<p>Isn't it obvious? He or she will enter their date of birth!</p>
<p>Ah, yes. We did rather expect that, but how will they enter
their date of birth?</p>
<p>Do you want them to be able to enter a date as they would on a
paper form or is the user to enter each part separately?</p>
<p>Don't play silly beggars with me young woman, as you would on a
form of course!</p>
<p>Ha hm. Just so. Ah, is this programme to be used in our overseas
offices?</p>
<p>Now just what the blazes has that got to do with anything?</p>
<p>Well if we're going to ship it to all our overseas branches then
the staff in each branch will probably want to use the calendar
that they're used to..</p>
<p>What are you blethering on about?</p>
<p>Well the Islamic, Hebrew and Chinese calendars are in common use
in some of our offices and I'm not certain but I think that one or
two our branches in the Balkans are still using the Julian
calendar...&quot;</p>
</blockquote>
</div>
<p>... and so it went on. Our heroine ploughed through a list of
questions that she had, adding others that arose out of the
discussion. Then, after a good deal of explanation that a programme
written to a limited specification would be quicker to produce and
above all would be far, far, far cheaper to produce than one that
dealt gracefully with locale issues, she presented the following to
<span class="strikethrough">Colonel Blimp</span> her
customer...</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>&quot;A programme shall be written that will report the user's age as
the number of complete years since the user's birth, the number of
complete months since the user's birth and the number of complete
days since the user's birth.</p>
<p>When the programme is run the user shall be prompted to enter
first the year, then the month and finally the day of their
birth.</p>
<p>The programme shall not attempt to calculate the age of the user
until all of the date information is entered.</p>
<div class="variablelist">
<dl>
<dt><span class="term">For example:</span></dt>
<dd>
<pre class="screen">
Please enter a year of birth : 1904
Please enter a month of birth : 6
Please enter a day of birth : 13
Age at end of 2003/09/02 was 99 years, 2 months, 21 days.
</pre></dd>
</dl>
</div>
<p>The programme shall apply the following validation rules to the
entered data.</p>
<div class="variablelist">
<dl>
<dt><span class="term">Years</span></dt>
<dd>
<p>From (current date - 130) to current date. Inclusive. For
example in 2003 the range would be 1873 to 2003 inclusive.</p>
</dd>
<dt><span class="term">Months</span></dt>
<dd>
<p>1 to 12. Inclusive</p>
</dd>
<dt><span class="term">Days</span></dt>
<dd>
<p>1 to maximum number of days in month. Inclusive.</p>
</dd>
</dl>
</div>
<p>If a user enters a value outside a valid range he or she will be
asked to enter a value that lies within the valid range.</p>
<div class="variablelist">
<dl>
<dt><span class="term">For example:</span></dt>
<dd>
<pre class="screen">
Please enter your year of birth : 1837
  Please enter a value between 1873 and 2003.
Please enter your year of birth :
</pre></dd>
<dt><span class="term">In addition:</span></dt>
<dd>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The Gregorian calendar shall be used.</p>
</li>
<li>
<p>Users shall not be allowed to enter dates in advance of the
current date.&quot;</p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
</blockquote>
</div>
<p>All that work, for such a <span class=
"emphasis"><em>simple</em></span> programme and we haven't even
begun to suggest any solutions never mind cutting any code.</p>
<p>By the way there's a bear trap in the foregoing. The customer
may not be, is rarely, the user and may just have led you right up
the garden path. So in the ideal case we'd go and talk to some
typical users as well before we went any further. That's the ideal
though...</p>
<p>Well what we've got is not complete, first attempts almost never
are, but it is a clearer statement of the problem that we can
discuss with colleagues and it can be used as a basis for sensible
design decisions and, just as important, we have the beginnings of
something that we can test against.</p>
<p>So why would we want to discuss our problem definition further?
Well, let's start with date entry. We want to prevent the entry of
dates in advance of the current date. This might be simpler if the
user entered the complete date at once, but then we have the
complicating factor of format validation. Then there's the matter
of valid year ranges. We've said &quot;130 years before current date&quot;
and given an example. But do we really mean 'current date' or
should we have said 'current year'? And what about that 130 limit
itself? What happens if we want to know the age of an elderly
Galapagos tortoise? Oh, and how do we define a 'complete' month and
what about someone whose birthday falls on the 29th of Feb?</p>
<p>So, where are we in our attempt to show at least one way of
reducing vulnerability to muddled thought?</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Define the problem. Unbounded problems will run away with you.
How do you define the problem? Well...</p>
</li>
<li>
<p>...find out as much as you can about the problem area from those
who know the problem area well.</p>
</li>
<li>
<p>Try to consider the problem from the point of view of the person
who posed it in the first place. Go through the problem definition
slowly and ask yourself, &quot;What if this circumstance were to
change?&quot; and &quot;Why on earth was that value chosen?&quot;</p>
</li>
<li>
<p>Write your problem restatement/expansion down in simple, short
words that anyone can understand. Get someone else - a colleague
and especially the customer - to read it. If you can explain the
problem simply to someone else and they understand what you tell
them then there's a very good chance that you understand the
problem well enough to actually solve it.</p>
</li>
<li>
<p>One more time, <span class="emphasis"><em>simple,
short</em></span> words. Avoid jargon if you can.</p>
</li>
<li>
<p>Never regard your first attempt at problem (re)definition as the
last word in all but the most trivial cases. Of course you then
have a supplementary difficulty, how trivial is trivial?</p>
</li>
</ul>
</div>
<p>At this point you can then sit back under your (metaphorical)
tree and try and feed candidate solutions through your sieve.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e221" id="d0e221"></a>Sitting under
the Tree</h3>
</div>
<p>I haven't got much to say about this as, as I said earlier, how
on earth do you teach clear thinking? So perhaps a list of points
that work for me will at least give you something to start
with&hellip;</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Don't try to solve the whole problem at once. If at all possible
break the problem down into manageable pieces.</p>
</li>
<li>
<p>Pick a section of the problem and work on it. Write things down.
Nothing is likely to reduce clarity of thought faster than trying
to maintain more information in your head than your mind can
comfortably handle. Levels vary from person to person.</p>
</li>
<li>
<p>When you are working on other sections of the problem be
prepared to revise earlier work in the light of new discoveries.
Revision might mean scrapping and starting again.</p>
</li>
<li>
<p>Take breaks from the problem, clear your mind. Make a coffee or
go for a short walk, do the washing up and if you are really
stumped go and talk to your spouse/partner/cat. Anything just so
long as it is completely unrelated to the work at hand.</p>
</li>
<li>
<p>Allow yourself enough time to deal with the problem. Panic and
its firstborn muddled thinking are very often the products of a
ridiculous deadline. If you do a good deal of commercial coding you
will, more's the pity, find this out.</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e242" id="d0e242"></a>The Original
Code</h3>
</div>
<p>So what about the original code? Well as the original statement
of requirements is a little vague there's not a lot that I can say
and I have as many questions as criticisms.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Surely it should be '2003 - dob'? If that's the case then it
won't work for any year but 2003.</p>
</li>
<li>
<p>Was 'currentyear' meant to be retrieved from current date and
the literal 2003 substituted for the sake of testing?</p>
</li>
<li>
<p>There's no validation of input data.</p>
</li>
<li>
<p>There is no explanation of the intention behind the arithmetic
used to calculate month and day values and I cannot deduce the
intent by reading the code.</p>
</li>
<li>
<p>Why the choice of 'dob' for year of birth? Was the original
intention to allow the user to enter a customary date such as
11/09/37?</p>
</li>
<li>
<p>Was there an undocumented requirement to avoid using the
standard library date and time functions?</p>
</li>
</ul>
</div>
<p>Well having written all that the very least I can do is offer a
possible solution to what might have been the original problem. It
is flawed, but then you, dear reader, are the first reviewer of the
work, the work was done without collaboration and (through no other
fault but my own) I left it until too close to the deadline to
start so poor design choices have been left as they were. Now,
remind me, what was I saying earlier? :)</p>
<pre class="programlisting">
// Warning! Only (lightly) tested with g++ on
// FreeBSD 4.6.2 For student code critique 23.

#include &lt;iostream&gt;
#include &lt;ctime&gt; // in g++ this is an alias

// for time.h - it may not always be so.
using namespace std;
// Assumptions -
// Gregorian calendar is going to be used.
// We don't expect to find anyone older than
// about 125.
// All sorts of assumptions about current
// date, time and we had
// to have a look at time.h to check what we'd get back.
const int MAX_LIFETIME_YEARS = 130;
const int SYS_BASE_YEAR = 1900;
const int MONTHS_IN_YEAR = 12;
enum eMonth {
  Unknown,
  January = 1, February, March, April, May,
  June, July, August, September, October,
  November, December
};

bool IsLeapYear(int Year) {
// Leap years in the Gregorian calendar occur
// in years that are exactly divisible by 400.
// Non-centenary years that are exactly
// divisible by 4.
  if(Year % 100 == 0 &amp;&amp; Year % 400 == 0)
    return true;
  if(Year % 100 != 0 &amp;&amp; Year % 4 == 0)
    return true;
  return false;
}
int DaysInMonth(int Year, eMonth Month) {
/* Thirty days hath September, April, June &amp;
   November, All the rest have thirty-one.
   Excepting February which hath 28 except...
*/
  int days = 31;
  switch (Month) {
    case February:
      if(IsLeapYear(Year))
        days = 29;
      else
        days = 28;
      break;
    case September:
    case June:
    case April:
    case November:
      days = 30;
      break;
  }
  return days;
}

int main() {
  int Day = 0;
  int Month = 0;
  int Year = 0;
 
  // We mustn't allow anyone to enter a date
  // later than the current date.
  time_t NowInSeconds = 0 ;
  tm* pCurrentDate;
  int CurrentYear = 0;
  int CurrentMonth = 0;
  int CurrentDay = 0;

  // Find out what the current date is.
  time(&amp;NowInSeconds);
  pCurrentDate = localtime(
    const_cast&lt;time_t* &gt; (&amp;NowInSeconds));
  CurrentYear = SYS_BASE_YEAR +
                pCurrentDate-&gt;tm_year;
  int ApplicationBaseYear =
                CurrentYear - MAX_LIFETIME_YEARS;
  CurrentMonth = 1 + pCurrentDate-&gt;tm_mon;
                CurrentDay = pCurrentDate-&gt;tm_mday;

  // Let's keep a track of where we are.
  cout &lt;&lt; &quot;Currently : &quot; &lt;&lt; CurrentYear &lt;&lt; &quot;/&quot;
       &lt;&lt; ((CurrentMonth &lt; 10) ? &quot;0&quot; : &quot;&quot;)
       &lt;&lt; CurrentMonth &lt;&lt; &quot;/&quot;
       &lt;&lt; ((CurrentDay &lt; 10) ? &quot;0&quot; : &quot;&quot;)
       &lt;&lt; CurrentDay &lt;&lt; '\n';

  while(Year &lt; ApplicationBaseYear
        || Year &gt; CurrentYear) {
    cout &lt;&lt; &quot;Please enter a year of birth: &quot;;
    cin &gt;&gt; Year;
    if(Year &lt; ApplicationBaseYear
       || Year &gt; CurrentYear)
      cout &lt;&lt; &quot;\tPlease enter a year from &quot;
           &lt;&lt; ApplicationBaseYear
           &lt;&lt; &quot; to &quot; &lt;&lt; CurrentYear &lt;&lt; '\n';
  }

  int MaxMonth = MONTHS_IN_YEAR;
  if(Year == CurrentYear)
    MaxMonth = CurrentMonth;
  while(Month &lt; 1 || Month &gt; MaxMonth) {
    cout &lt;&lt; &quot;Please enter the month of birth: &quot;;
    cin &gt;&gt; Month;
    if(Month &lt; 1 || Month &gt; MaxMonth) {
      cout &lt;&lt; &quot;\tA month from 1 to &quot;
           &lt;&lt; MaxMonth &lt;&lt; &quot; please.\n&quot;;
      Month = 0;
    }
  }

  int MaxDay = DaysInMonth(Year,
                 static_cast&lt;eMonth&gt;(Month));
  if(Year == CurrentYear
     &amp;&amp; Month == CurrentMonth)
    MaxDay = CurrentDay;
  while(Day &lt; 1 || Day &gt; MaxDay) {
    cout &lt;&lt; &quot;Please enter a day of birth: &quot;;
    cin &gt;&gt; Day;
    if(Day &lt; 1 || Day &gt; MaxDay) {
      cout &lt;&lt; &quot;\tA day between 1 and &quot;
           &lt;&lt; MaxDay &lt;&lt; &quot; please.\n&quot;;
      Day = 0;
    }
  }

  int WholeYears = CurrentYear
                   - Year - (CurrentYear&gt;Year? 1 : 0);
  int WholeMonths = 0;
  int WholeDays = 0;

  if(CurrentMonth == Month) {
    if(CurrentDay &gt;= Day) ++WholeYears;
    else WholeMonths = MONTHS_IN_YEAR-1;
  }
  else if(CurrentMonth &gt; Month) {
    if(CurrentYear &gt; Year) ++WholeYears;
    WholeMonths = CurrentMonth - Month- 1;
  }
  else {
    WholeMonths =
      MONTHS_IN_YEAR - Month + CurrentMonth;
    if(CurrentDay &lt; Day) -WholeMonths;
  }
  if(CurrentDay &gt;=Day) {
    WholeDays = CurrentDay -Day;
  }
  else {
    int PreviousMonth = (CurrentMonth + 
          MONTHS_IN_YEAR -1) % MONTHS_IN_YEAR;
    WholeDays = DaysInMonth(CurrentYear,
    static_cast&lt;eMonth&gt;(PreviousMonth)) - Day;
    if(WholeDays &lt; 1) WholeDays = 0;
      WholeDays = WholeDays + CurrentDay -1;
  }

  cout &lt;&lt; &quot;Age at end of &quot;
       &lt;&lt; CurrentYear &lt;&lt; &quot;/&quot;
       &lt;&lt; ((CurrentMonth &lt; 10) ? &quot;0&quot; : &quot;&quot;)
       &lt;&lt; CurrentMonth &lt;&lt; &quot;/&quot;
       &lt;&lt; ((CurrentDay &lt; 10) ? &quot;0&quot; : &quot;&quot;)
       &lt;&lt; CurrentDay &lt;&lt; &quot; was &quot;
       &lt;&lt; WholeYears &lt;&lt; &quot; year&quot;
       &lt;&lt; ((WholeYears != 1) ? &quot;s &quot; :&quot; &quot;)
       &lt;&lt; WholeMonths &lt;&lt; &quot; month&quot;
       &lt;&lt; ((WholeMonths != 1) ? &quot;s&quot; :&quot;&quot;)
       &lt;&lt; &quot; and &quot;
       &lt;&lt; WholeDays &lt;&lt; &quot; day&quot;
       &lt;&lt; ((WholeDays != 1) ? &quot;s.&quot; :&quot;.\n&quot;);
  return 0;
}
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e270" id="d0e270"></a>Francis'
Comments</h3>
</div>
<p><span class="emphasis"><em>Colin's code caused me some problems
because there is a relatively large amount of it and in the
original he had added a considerable amount of comment. Space is
always at a premium in C Vu so I removed most of the comments. The
result may be less readable but it is almost a page shorter, which,
in this context, matters.</em></span></p>
<p><span class="emphasis"><em>There are several points that I want
to comment on before moving on to the next entry.</em></span></p>
<p><span class="emphasis"><em>To my mind <tt class=
"literal">main</tt> is clearly far too large and includes far too
many nested structures. While Colin has carefully validated the
input in regards to the numerical values he has not checked for
successful input. In real life, in my experience, the latter
problem is far more common.</em></span></p>
<p><span class="emphasis"><em>A large proportion of his code (and
most of the nested conditionals) is the result of the way he has
approached the problem. How could he have done it differently?
Consider:</em></span></p>
<pre class="programlisting">
int years = current_year birth_year;
int months = current_month - birth_month;
int days = current_day - birth_day;
if(days &lt; 0) {
  --months;
  days += days_in[leap][current_month-1]
}
if(months &lt; 0) {
  --years;
  months += months_in_year;
}
if(years &lt; 0) {
  cout &lt;&lt; &quot;You haven't been born yet.\n&quot;;
else
  cout &lt;&lt; &quot;Your age is:&quot;
// etc
</pre>
<p><span class="emphasis"><em>Oh, that days is in because I would
always use a look up table for this kind of irregular data. In this
case I would store the number of days in December as both the first
and the last entry. Check that out, it ensures that January works
correctly even when the current date is earlier than a January
birthday. The other advantage of a look-up table is that it makes
the validation code for <tt class="literal">birth_day</tt> much
simpler. <tt class="literal">leap</tt> will have been evaluated
earlier.</em></span></p>
<p><span class="emphasis"><em>One thing always worth considering is
distinguishing between unlikely data and impossible data. The claim
to have been born in 1503 is (extremely) unlikely but the claim to
have been born in the 15th month or the 33rd day of the seventh
month is impossible (for a Gregorian Calendar). I tend to favour
accepting unlikely data but perhaps verifying it.</em></span></p>
<p><span class="emphasis"><em>(Editorial note: I would not use a
lookup table here as - to my mind - it adds complexity rather than
clarity. But that just shows that simplicity and elegance is hard
to pin down, and even experienced programmers can reasonably
disagree sometimes. James)</em></span></p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e305" id="d0e305"></a>from Walter
Milner <tt class="email">&lt;<a href=
"mailto:%3Cw.w.milner@bham.ac.uk%3E">&lt;w.w.milner@bham.ac.uk&gt;</a>&gt;</tt></h2>
</div>
<p>We will firstly check through the program as you have written
it, then take a broader look.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e312" id="d0e312"></a>The program as
written</h3>
</div>
<p>Firstly</p>
<pre class="programlisting">
void main()
</pre>
<p>might often be written as</p>
<pre class="programlisting">
int main(void)
</pre>
<p>together with a</p>
<pre class="programlisting">
return 0;
</pre>
<p>at the end of function main.</p>
<p>[<span class="emphasis"><em>Not strong enough. It should be
written with an int return type unless you are happy to write
non-portable code relying on a vendor extension.
Francis]</em></span></p>
<p>Then you declare</p>
<pre class="programlisting">
int currentyear = 2003;
</pre>
<p>This works this year, but you would have to rewrite the program
next year. Ideally one would get the program to use the system to
tell you the current date. However you seem to have forgotten what
you've done when you write</p>
<pre class="programlisting">
result = dob - 2003;
</pre>
<p>using the 'magic number' 2003 rather than</p>
<pre class="programlisting">
result = dob - currentyear;
</pre>
<p>However suppose dob is 1983, then <tt class=
"varname">result</tt> = 1983 - 2003 = -20. You should have said</p>
<pre class="programlisting">
result = currentyear - dob;
</pre>
<p>This raises the question of naming variables. I suppose dob is
'date of birth', but it is used in the program in the sense of
'year of birth'. Does the difference matter? Yes. There are a
variety of naming conventions, but it is generally accepted that
variable names should reflect as closely as possible the 'meaning'
of the variable, and this often prompts you to ask yourself 'what
exactly is this variable about?' which is often a very useful
question. You can probably now see the problem with the name
'result'.</p>
<p>We then have</p>
<pre class="programlisting">
for(result=0; result &lt;=12; result++)
if(result &lt;=12) result = month + 12;
  cout &lt;&lt; &quot;You are &quot; &lt;&lt; result
       &lt;&lt; &quot;months old&quot; &lt;&lt; endl;
</pre>
<p>Let's see what this will do. The value of month will be between
1 and 12 (if the user entered a valid value). The first time into
the loop, result will be 0, so</p>
<pre class="programlisting">
result = month + 12;
</pre>
<p>will give <tt class="varname">result</tt> a value between 13 and
24. Then <tt class="literal">result++</tt> will add 1 to this, and
since result will be 14 or more, the loop will terminate. If I was
born in January it will tell me I'm 14 months old.</p>
<p>So what did you think it would do? You have a ' + 12' inside a
loop - so are you adding 12 for each year of the person's life? If
so you would have needed to say</p>
<pre class="programlisting">
result += 12;
</pre>
<p>then added <tt class="varname">month</tt> in once after the loop
for the incomplete year. But</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>you loop through this 13 times, not for each year of life,
and</p>
</li>
<li>
<p>you use <tt class="varname">result</tt> both as the loop counter
and to hold the required answer.</p>
</li>
</ul>
</div>
<p>Using more precise variable names, such as <tt class=
"varname">yearOfLife</tt> or <tt class="varname">monthOfLife</tt>,
might have made the problem slightly more apparent to you.</p>
<p>You repeat the same code pattern in</p>
<pre class="programlisting">
for(result=0; result&lt;=365; result++)
  if(result&lt;=365) result = day + 365;
    cout &lt;&lt; &quot;You are &quot; &lt;&lt; result &lt;&lt; &quot; days old&quot;
         &lt;&lt; endl;
</pre>
<p>Before you repeat a code pattern - make sure the original
works.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e403" id="d0e403"></a>The broader
view</h3>
</div>
<p>We start from the question -</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>'What is this program supposed to do?&quot;</p>
</blockquote>
</div>
<p>You say it should 'tell the user how old they are in years, days
and months i.e. 27 years 200 months and 1500 days old'</p>
<p>I think you mean &quot;e.g.&quot; not &quot;i.e.&quot; Now this might mean how old
in <span class="emphasis"><em>complete</em></span> years,
<span class="emphasis"><em>complete</em></span> months and days.
Alternatively it might mean how old in years (ignoring part years)
or in months (ignoring part months) or in days (ignoring... you've
got it). Your example seems to suggest the latter, but not clearly,
since someone who was exactly 27 years old would have be 324 months
old, not 200. Before writing the program, you must be clear as to
what it is supposed to do. Let's take the second interpretation
here.</p>
<p>Einstein is supposed to have said</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>Keep it simple</p>
</blockquote>
</div>
<p>which has been made into the acronymn KISS, keep it simple,
stupid. However Einstein added the more useful caution</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>But not too simple.</p>
</blockquote>
</div>
<p>In the context of calendars, dates and times, 'not too simple'
is really quite complicated. For a start, what do you mean by month
- calendar or lunar? Well calendar is a lot easier here, so we'll
do that. As another example, calculating the number of complete
years involves not just the year of birth and the current year. For
example, the current date is 21 August 2003. If my date of birth
was say 1 November 2002, my age in complete years is not 2003 -
2002 = 1. It is zero - I have not yet lived 12 months. Similar
ideas apply for months and days. In this way we have a more precise
specification for the program:</p>
<div class="variablelist">
<dl>
<dt><span class="term">input:</span></dt>
<dd>
<p>date of birth (day month and year) and current date (day month
and year)</p>
</dd>
<dt><span class="term">output:</span></dt>
<dd>
<p>age in complete years, age in complete calendar months and age
in complete days.</p>
</dd>
</dl>
</div>
<p>How do we do it? Well, you need to re-submit this assignment so
I will not do it for you, just outline two approaches. The first is
to use calendar and date library functions which will essentially
do it for you. However that is not what you are expected to do
here. The second approach is to do it yourself, as follows:</p>
<p>Firstly calculate the complete years. You would need to compare
the current month and the month of birth, and if they are equal,
the birth day compared to the current day. It might help to draw
some diagrams, or work out some examples on paper.</p>
<p>Then calculate the complete months. This is the complete years
times 12 plus the difference in the months.</p>
<p>Then the days. The simple approach is the complete years
multiplied by 365, plus the days in the months - which depends on
which months they are.</p>
<p>The correct approach takes leap years and leap centuries into
account - and this is what makes libraries so nice.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e456" id="d0e456"></a>Francis'
Comments</h3>
</div>
<p><span class="emphasis"><em>Interesting that both submissions
religiously use <tt class="literal">endl</tt>. What is wrong with
'\n' which does exactly what you want unless you really do need to
flush the output. I actually edited most of Colin's uses of
<tt class="literal">endl</tt> but left Walter's in so I could make
this comment.</em></span></p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e468" id="d0e468"></a>The Winner of
SCC 23</h2>
</div>
<p>The editor's choice is: Colin Greenock</p>
<p>Please email <tt class="email">&lt;<a href=
"mailto:francis@robinton.demon.co.uk">francis@robinton.demon.co.uk</a>&gt;</tt>
to arrange for your prize.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e478" id="d0e478"></a>Student Code
Critique 24</h2>
</div>
<p>(Submissions to <tt class="email">&lt;<a href=
"mailto:francis@robinton.demon.co.uk">francis@robinton.demon.co.uk</a>&gt;</tt>
by Nov. 14th)</p>
<p><span class="emphasis"><em>Curious what novices set out to do
but that should not stop us from trying to help them achieve their
objectives. I suspect that the writer of this is trying to grab the
console output and paste it into a file. Now we know what he should
be doing, but while helping him try to raise the code
quality.</em></span></p>
<p>I want to copy my C++ program output to an ASCII text file</p>
<p>I store my data in arrays and then use coutto output the data in
DOS... as I generate data in the order of 1000's ...I am having a
problem with physically copy pasting the data into notepad (an MS
Windows pure text editor).</p>
<p>Here is my code...please suggest what changes are necessary. My
coding is not really that efficient. Please bear with me</p>
<pre class="programlisting">
# include&lt;iostream.h&gt;
# include&lt;conio.h&gt;
# include&lt;math.h&gt;
# include&lt;iomanip.h&gt;

void main(){
  void clrscr();
  int i,r,j,m,x;
  static Sum[5000][5000];
  Sum[1][1]=25000;
  Sum[2][1]=35000;
// input the data into arrays
  for(j=2; j&lt;=11; j++)
    for(i=1; i&lt;=pow(2,j); i++) {
      if(i==1) {
        Sum[i][j] = Sum[i][j-1] + 25000;
        Sum[i+1][j] = Sum[i][j-1] + 35000;
      }
      if(i&gt;1) {
        Sum[i][j] = Sum[r][j-1] + 25000;
        r=r+1;
        Sum[i+1][j] =
          Sum[(i+1)/2][j-1] + 35000;
      }
      i=i+1;
      r=2;
    }
// output the data
  for(m=2; m&lt;=11; m++) {
    for(x=1;x &lt;= pow(2,m); x++) {
      for(i=1; i&lt;=2; i++) {
        cout &lt;&lt; x &lt;&lt; m
             &lt;&lt; setw(10) &lt;&lt; Sum[x][m] &lt;&lt; '\n';
      }
    }
    getch(); 
  }
}
</pre>
<p>My output reads:</p>
<pre class="screen">
11 25000
11 25000
12 35000
12 35000
</pre>
<p>so on..so forth</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
