27 May 2008

Exam prep: 4

So I've finished my read-through of the Microsoft training material, and I have my exam scheduled for Friday, so that I can take advantage of the Second Shot program. A 4-hour exam, and material I've been trying to absorb for several months: I'm pretty sure that I will need to exercise my free retest option.

06 May 2008

Fun with 88's: Part 3

Continuing my series of posts on tips and tricks with COBOL named conditions (part 1, part 2), let's look at the REDEFINES keyword, which works like a struct, and the OCCURS keyword, which defines an array.

Let's say that requirements for our toy name and address processing application have changed again, and that Canadian addresses and post codes must be supported. We'll put a record type indicator in the unused space at the end of the card, and lay out the city-state-zip storage differently depending on the record type. Remember how we left some space in the level numbers for maintenance? Here's a case where the practice comes in handy:



01 CARD-IMAGE.
03 CARD-NAME-AND-ADDRESS.
05 CARD-NAME.
07 CARD-FIRST-NAME PIC X(10).
07 CARD-LAST-NAME PIC X(10).
05 FILLER PIC X(3).
05 CARD-ADDRESS.
07 CARD-ADDRESS-LINE-1 PIC X(15).
07 CARD-ADDRESS-LINE-2 PIC X(15).
06 CARD-USA-AREA.
07 CARD-CITY PIC X(10).
07 CARD-STATE PIC X(2).
88 CARD-IS-DISTRICT VALUE "DC".
88 CARD-IS-COMMONWEALTH VALUE "PA", "KY", "VA", "MA".
07 FILLER PIC X(8).
07 CARD-ZIP-CODE PIC 9(5).
06 CARD-CANADA-AREA.
REDEFINES CARD-USA-AREA.
07 FILLER PIC X(10).
07 CARD-PROVINCE PIC X(2).
07 FILLER PIC X(6).
07 CARD-POST-CODE PIC X(7).
03 CARD-RECORD-TYPE PIC X(2).
88 CARD-IS-USA VALUE "US".
88 CARD-IS-CANADA VALUE "CA".



Granted, there is opportunity for the record type indicator to disagree with the way the storage is used: object-oriented languages do have something to offer here.

We don't have to provide a separate name for the city part of CARD-CANADA-AREA: we can use CARD-CITY to refer to characters 54 through 63, irrespective of record type.

Now, let's say that we want to print the city and state part of the card image, separated by a comma, with the trailing whitespace squeezed out, for example, "New York, NY". (The STRING statement can also be used to do this, but that's a post for another day.) We can use OCCURS to treat the characters of CARD-CITY as an array (1-based) of 10 characters, and similarly for CARD-STATE.



* * *
07 CARD-CITY.
09 CARD-CITY-CHAR PIC X(1)
OCCURS 10 TIMES.
88 CARD-CITY-CHAR-IS-SPACE
VALUE " ".
07 CARD-STATE.
88 CARD-IS-DISTRICT VALUE "DC".
88 CARD-IS-COMMONWEALTH VALUE "PA", "KY", "VA", "MA".
09 CARD-STATE-CHAR PIC X(1)
OCCURS 2 TIMES.




TIMES is another noise word that usually isn't coded. We'll need an output area and a couple of indexes:



01 OUTPUT-STRING.
03 OUTPUT-CHAR PIC X(1)
OCCURS 13.
01 IEND PIC S9(4) USAGE COMP.
01 IFROM PIC S9(4) USAGE COMP.
01 ITO PIC S9(4) USAGE COMP.



Now we're ready to write some procedural logic. PERFORM... VARYING makes a counted for loop. MOVE is the workhorse assignment statement: notice that the "left hand side" is actually coded on the right.



PROCEDURE DIVISION.
* * *
* Initialize result and its indexer
MOVE SPACES TO OUTPUT-STRING
MOVE ZERO TO ITO
* Scan from the end of the city area until
* a nonspace character is found
PERFORM VARYING IEND FROM 10 BY -1
UNTIL IEND < 1
OR NOT CARD-CITY-CHAR-IS-SPACE(IEND)

CONTINUE
END-PERFORM

* [Some exception-handling logic for the case
* in which the city portion is completely blank
* could be written here.]

* Copy the city, one character at a time, to the output
PERFORM VARYING IFROM FROM 1 BY 1
UNTIL IFROM > IEND

ADD 1 TO ITO
MOVE CARD-CITY-CHAR(IFROM) TO OUTPUT-CHAR(ITO)
END-PERFORM
* Copy the comma
ADD 1 TO ITO
MOVE "," TO OUTPUT-CHAR(ITO)
* Copy the state
PERFORM VARYING IFROM BY 1 BY 1
UNTIL IFROM > 2

ADD 1 TO ITO
MOVE CARD-STATE-CHAR(IFROM) TO OUTPUT-CHAR(ITO)
END-PERFORM



There's all sorts of things we could do to improve and simplify this logic. One change would be to add code to the WORKING-STORAGE SECTION to define the entire card image as an array of 80 characters. It's common that more experienced COBOL programmers write proportionally more code in the DATA DIVISION than they do in the PROCEDURE DIVISION.

A warning, once again: all of the above code is from memory, and hasn't been subjected to compilation or testing. In particular, I don't remember for certain whether 88's can be applied to group-level items as I did above with CARD-STATE.

05 May 2008

Community Builder

Version 3.1 of EFM Community has been released. Along with a heapin' helpin' of bug fixes, this version incorporates a Community Builder module, which
...will allow organizations to quickly and cost effectively create and manage online community panels and provide a voice to customers, employees and other constituents.

01 May 2008

Happy birthday, BASIC

John Kemeny and Thomas Kurtz did the first load and go of a BASIC compiler on this day in 1964 (DTSS timesharing and an interpreter were to come shortly thereafter), as Randy Alfred reports,

Exam prep: 3

I've completed my read-thru of the training material for MCTS 70-528. I still have all the security and crypto material from MCTS 70-536 to read. I'm planning to schedule the exam for the end of this month. Pass or fail, I'm doing a 5-minute presentation at an upcoming monthly group meeting on the Microsoft certification process.