GNU Info

Info Node: (emacs-lisp-intro.info)Another Bug

(emacs-lisp-intro.info)Another Bug


Next: Final printed graph Prev: mapcar Up: Print Whole Graph
Enter node , (file) or (file)node

Another Bug ... Most Insidious
------------------------------

   I said `almost ready to print'!  Of course, there is a bug in the
`print-graph' function ...  It has a `vertical-step' option, but not a
`horizontal-step' option.  The `top-of-range' scale goes from 10 to 300
by tens.  But the `print-graph' function will print only by ones.

   This is a classic example of what some consider the most insidious
type of bug, the bug of omission.  This is not the kind of bug you can
find by studying the code, for it is not in the code; it is an omitted
feature.  Your best actions are to try your program early and often;
and try to arrange, as much as you can, to write code that is easy to
understand and easy to change.  Try to be aware, whenever you can, that
whatever you have written, _will_ be rewritten, if not soon,
eventually.  A hard maxim to follow.

   It is the `print-X-axis-numbered-line' function that needs the work;
and then the `print-X-axis' and the `print-graph' functions need to be
adapted.  Not much needs to be done; there is one nicety: the numbers
ought to line up under the tic marks.  This takes a little thought.

   Here is the corrected `print-X-axis-numbered-line':

     (defun print-X-axis-numbered-line
       (number-of-X-tics X-axis-leading-spaces
        &optional horizontal-step)
       "Print line of X-axis numbers"
       (let ((number X-axis-label-spacing)
             (horizontal-step (or horizontal-step 1)))
         (insert X-axis-leading-spaces)
         ;; Delete extra leading spaces.
         (delete-char
          (- (1-
              (length (number-to-string horizontal-step)))))
         (insert (concat
                  (make-string
                   ;; Insert white space.
                   (-  (* symbol-width
                          X-axis-label-spacing)
                       (1-
                        (length
                         (number-to-string horizontal-step)))
                       2)
                   ? )
                  (number-to-string
                   (* number horizontal-step))))
         ;; Insert remaining numbers.
         (setq number (+ number X-axis-label-spacing))
         (while (> number-of-X-tics 1)
           (insert (X-axis-element
                    (* number horizontal-step)))
           (setq number (+ number X-axis-label-spacing))
           (setq number-of-X-tics (1- number-of-X-tics)))))

   If you are reading this in Info, you can see the new versions of
`print-X-axis' `print-graph' and evaluate them.  If you are reading
this in a printed book, you can see the changed lines here (the full
text is too much to print).

     (defun print-X-axis (numbers-list horizontal-step)
       "Print X axis labels to length of NUMBERS-LIST.
     Optionally, HORIZONTAL-STEP, a positive integer,
     specifies how much an X  axis label increments for
     each column."
     ;; Value of symbol-width and full-Y-label-width
     ;; are passed by `print-graph'.
       (let* ((leading-spaces
               (make-string full-Y-label-width ? ))
            ;; symbol-width is provided by graph-body-print
            (tic-width (* symbol-width X-axis-label-spacing))
            (X-length (length numbers-list))
            (X-tic
             (concat
              (make-string
               ;; Make a string of blanks.
               (-  (* symbol-width X-axis-label-spacing)
                   (length X-axis-tic-symbol))
               ? )
              ;; Concatenate blanks with tic symbol.
              X-axis-tic-symbol))
            (tic-number
             (if (zerop (% X-length tic-width))
                 (/ X-length tic-width)
               (1+ (/ X-length tic-width)))))
     
         (print-X-axis-tic-line
          tic-number leading-spaces X-tic)
         (insert "\n")
         (print-X-axis-numbered-line
          tic-number leading-spaces horizontal-step)))

     (defun print-graph
       (numbers-list &optional vertical-step horizontal-step)
       "Print labelled bar graph of the NUMBERS-LIST.
     The numbers-list consists of the Y-axis values.
     
     Optionally, VERTICAL-STEP, a positive integer,
     specifies how much a Y axis label increments for
     each line.  For example, a step of 5 means that
     each row is five units.
     
     Optionally, HORIZONTAL-STEP, a positive integer,
     specifies how much an X  axis label increments for
     each column."
       (let* ((symbol-width (length graph-blank))
              ;; `height' is both the largest number
              ;; and the number with the most digits.
              (height (apply 'max numbers-list))
              (height-of-top-line
               (if (zerop (% height Y-axis-label-spacing))
                   height
                 ;; else
                 (* (1+ (/ height Y-axis-label-spacing))
                    Y-axis-label-spacing)))
              (vertical-step (or vertical-step 1))
              (full-Y-label-width
               (length
                (concat
                 (number-to-string
                  (* height-of-top-line vertical-step))
                 Y-axis-tic))))
         (print-Y-axis
          height-of-top-line full-Y-label-width vertical-step)
         (graph-body-print
             numbers-list height-of-top-line symbol-width)
         (print-X-axis numbers-list horizontal-step)))


automatically generated by info2www version 1.2.2.9