Printing the Alphabets A to Z's shape
Hiya! ๐ This blog post will be fun ๐ as I really enjoyed writing this particular piece of code which you will be witnessing shortly.
When I saw the black screens ๐ป for the first time when I was trained on Mainframe (that was in 2014 ๐ ), I was totally amused. The logon screen had something similar to what we have now on the logon screen of IBM's Master the Mainframe 2020 system.
Click on the image for a larger version.
In the picture above, each letter's shape, in the string 'z/OS', is printed using the respective letter, that too in italics.
Introduction
I was longing to write a COBOL program that would print the ASCII character strings (just the letters A-Z for now) in large size to the output, using the respective letter itself (sometimes people prefer the asterisk '*' or '#' to print shapes). This blog post is all about the approach I took to come up with such a program.
At the end of this post, there's a short write-up on publishing code on GitHub, as I'm used to Endevorยฎ and GitHub (a code hosting platform) is new to me.
Approach
Printing just one letter's shape in the output is simple. All you need is a PERFORM VARYING
loop in COBOL, a logic to form the letter's shape, and a DISPLAY
statement printing the lines for each iteration of the loop. An example can be found ๐ here.
However, printing each letter's shape of the string from left to right is a little bit tricky. I chose a 7 x 7 cell to spread out the shape of each letter. An Excel sheet, in which I drew all 26 letter's shapes, came in handy as I referred to the sheet before going to code the logic for each letter.
Shown in the picture above is an Excel sheet with each alphabet's shape spread out in a 7 x 7 cell.
I leveraged the two-dimensional table to store the letter's shape. The COBOL code is as follows:
WS-LINE
is an element of a one-dimensional table that occurs 7 times. You may assume each element of WS-LINE
is a row.
WS-LETTER
is an element of a two-dimensional table that occurs 70 times for each occurrence of WS-LINE
. Assume each element of WS-LETTER
is a column.
For readability, I've limited the maximum length of the string input by the user to 10 characters. Therefore, each line is 70 characters long.
When I was halfway with my code, I ran ๐ some tests only to realize that a space in between each letter's shape would have been clear enough to read.
As shown in the picture above, that isn't quite easy to read. BAD ๐
Hence, I came up with yet another multi-dimensional table solely for printing purpose.
As seen in the picture above, the only difference between the former 2D table and this one is WS-FILLER
which works like magic in terms of readability during the output display.
This table, WS-TABLE2
gets data from the former 2D table only during the course of displaying the letter's shape in the output.
In the PROCEDURE DIVISION
, there are references to 3 paragraphs:
which would ask for the input string from the user; validate it. Upon successful validation of user input,
go through each letter of the string one by one with the help of Reference Modification in COBOL; with the help of
EVALUATE
verb, call the para corresponding to each letter to print its shape.display the output and
STOP RUN
.
Code walk-through
There are 26 para's coded to print the shape of 26 alphabets in English. A lot of PERFORM VARYING
loops and COMPUTE
statements are used to build ๐งฑ the logic in each para. Let's look at the code for one of those paragraphs.
This ๐ part of code prints the shape of letter T. There are 2 PERFORM VARYING
loops โฟ.
Let's take a look at the first loop โฐ.
The first loop iterates seven times with
WS-J
data-item's value ranging from 0 to 6 and creates the horizontal line of the letter T's shape.WS-I
data-item holds the position of the letter in the string entered by the user.WS-I
data-item's value is multiplied by 7 to put the letter's shape in the right set of rows and columns.COMPUTE
statement is coded before theMOVE
statement because arithmetic expressions aren't supported (on IBM Enterprise COBOL for z/OS 6.3.0 compiler) in the subscripting.The
MOVE
statement moves the letter T toWS-LETTER
, which is an element of the two-dimensional table,WS-TABLE1
. In a two-dimensional table, the two subscripts correspond to the row and column numbers.
Given the following 7x7 cell:
The following happens in each iteration of the first loop if WS-I's value is assumed to be 1:
1st iteration:
WS-I
= 1
WS-J
= 0
WS-TEMP
= 7
Letter T is moved to WS-LETTER(1, 7)
2nd iteration:
WS-I
= 1
WS-J
= 1
WS-TEMP
= 6
Letter T is moved to WS-LETTER(1, 6)
3rd iteration:
WS-I
= 1 and WS-J
= 2
WS-TEMP
= 5
Letter T is moved to WS-LETTER(1, 5)
4th iteration:
WS-I
= 1 and WS-J
= 3
WS-TEMP
= 4
Letter T is moved to WS-LETTER(1, 4)
5th iteration:
WS-I
= 1
WS-J
= 4
WS-TEMP
= 3
Letter T is moved to WS-LETTER(1, 3)
6th iteration:
WS-I
= 1 and WS-J
= 5
WS-TEMP
= 2
Letter T is moved to WS-LETTER(1, 2)
7th iteration:
WS-I
= 1; WS-J
= 6;
WS-TEMP
= 1
Letter T is moved to WS-LETTER(1, 1)
At the end of first loop, the cell will look like below:
The second loop does something similar to the first loop and it moves the letter T to all the rows in 4th column of 7x7 cell. At the end of second loop, the shape of letter T will be formed.
Executing the code
Here ๐ is the full code.
ID DIVISION.
PROGRAM-ID. PATTERN.
AUTHOR. SRINIVASAN.
DATE-WRITTEN. 24-MAR-2021.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATA-ITEMS.
05 WS-INPUT PIC X(10).
05 WS-INPUT-UPPER PIC X(10).
05 WS-PART1 PIC X(10).
05 WS-PART2 PIC X(10).
05 WS-COUNT PIC 9(2) COMP.
05 WS-I PIC 9(2).
05 WS-J PIC 9(2).
05 WS-K PIC 9(2).
05 WS-L PIC 9(2).
05 WS-TEMP PIC 9(2).
01 WS-TABLE1.
05 WS-LINE OCCURS 7 TIMES.
10 WS-LETTER OCCURS 70 TIMES PIC X(1).
01 WS-TABLE2.
05 WS-DISPLAY-LINE OCCURS 7 TIMES.
10 WS-DISPLAY OCCURS 10 TIMES.
15 WS-DATA PIC X(7).
15 WS-FILLER PIC X.
PROCEDURE DIVISION.
INITIALIZE WS-TABLE1
WS-TABLE2
WS-DATA-ITEMS.
PERFORM ASK-USER THRU ASK-EXIT
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-COUNT
EVALUATE WS-INPUT-UPPER(WS-I:1)
WHEN 'A'
PERFORM A-PARA THRU A-EXIT
WHEN 'B'
PERFORM B-PARA THRU B-EXIT
WHEN 'C'
PERFORM C-PARA THRU C-EXIT
WHEN 'D'
PERFORM D-PARA THRU D-EXIT
WHEN 'E'
PERFORM E-PARA THRU E-EXIT
WHEN 'F'
PERFORM F-PARA THRU F-EXIT
WHEN 'G'
PERFORM G-PARA THRU G-EXIT
WHEN 'H'
PERFORM H-PARA THRU H-EXIT
WHEN 'I'
PERFORM I-PARA THRU I-EXIT
WHEN 'J'
PERFORM J-PARA THRU J-EXIT
WHEN 'K'
PERFORM K-PARA THRU K-EXIT
WHEN 'L'
PERFORM L-PARA THRU L-EXIT
WHEN 'M'
PERFORM M-PARA THRU M-EXIT
WHEN 'N'
PERFORM N-PARA THRU N-EXIT
WHEN 'O'
PERFORM O-PARA THRU O-EXIT
WHEN 'P'
PERFORM P-PARA THRU P-EXIT
WHEN 'Q'
PERFORM Q-PARA THRU Q-EXIT
WHEN 'R'
PERFORM R-PARA THRU R-EXIT
WHEN 'S'
PERFORM S-PARA THRU S-EXIT
WHEN 'T'
PERFORM T-PARA THRU T-EXIT
WHEN 'U'
PERFORM U-PARA THRU U-EXIT
WHEN 'V'
PERFORM V-PARA THRU V-EXIT
WHEN 'W'
PERFORM W-PARA THRU W-EXIT
WHEN 'X'
PERFORM X-PARA THRU X-EXIT
WHEN 'Y'
PERFORM Y-PARA THRU Y-EXIT
WHEN 'Z'
PERFORM Z-PARA THRU Z-EXIT
END-EVALUATE
END-PERFORM
PERFORM DISPLAY-PARA THRU DISPLAY-EXIT.
STOP RUN.
A-PARA.
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'A' TO WS-LETTER( 1, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 4
MOVE 'A' TO WS-LETTER( 2, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 2
MOVE 'A' TO WS-LETTER( 2, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 5
MOVE 'A' TO WS-LETTER( 3, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 1
MOVE 'A' TO WS-LETTER( 3, WS-TEMP )
PERFORM VARYING WS-J FROM 4 BY 1 UNTIL WS-J > 7
COMPUTE WS-TEMP = WS-I * 7
MOVE 'A' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'A' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J > 5
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'A' TO WS-LETTER( 5, WS-TEMP )
END-PERFORM.
A-EXIT. EXIT.
B-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'B' TO WS-LETTER( 1, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'B' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7
MOVE 'B' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'B' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J > 5
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'B' TO WS-LETTER( 4, WS-TEMP )
END-PERFORM.
B-EXIT. EXIT.
C-PARA.
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'C' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'C' TO WS-LETTER( 1, WS-TEMP )
MOVE 'C' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM.
C-EXIT. EXIT.
D-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'D' TO WS-LETTER( 1, WS-TEMP )
MOVE 'D' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7
MOVE 'D' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'D' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM.
D-EXIT. EXIT.
E-PARA.
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'E' TO WS-LETTER( 1, WS-TEMP )
MOVE 'E' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'E' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'E' TO WS-LETTER( 4, WS-TEMP )
END-PERFORM.
E-EXIT. EXIT.
F-PARA.
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'F' TO WS-LETTER( 1, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'F' TO WS-LETTER( WS-J, WS-TEMP)
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'F' TO WS-LETTER( 4, WS-TEMP )
END-PERFORM.
F-EXIT. EXIT.
G-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'G' TO WS-LETTER( 1, WS-TEMP )
MOVE 'G' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'G' TO WS-LETTER( WS-J, WS-TEMP )
IF WS-J NOT EQUAL 3 THEN
COMPUTE WS-TEMP = WS-I * 7
MOVE 'G' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 4 THEN
COMPUTE WS-TEMP = WS-I * 7 - 1
MOVE 'G' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 2
MOVE 'G' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'G' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 5 THEN
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'G' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
END-PERFORM.
G-EXIT. EXIT.
H-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7
MOVE 'H' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'H' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'H' TO WS-LETTER( 4, WS-TEMP )
END-PERFORM.
H-EXIT. EXIT.
I-PARA.
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'I' TO WS-LETTER( 1, WS-TEMP )
MOVE 'I' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'I' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM.
I-EXIT. EXIT.
J-PARA.
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J > 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'J' TO WS-LETTER( 1, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 8
IF WS-J EQUAL 5 OR WS-J EQUAL 6 THEN
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'J' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'J' TO WS-LETTER( WS-J, WS-TEMP )
IF WS-J EQUAL 7 THEN
COMPUTE WS-TEMP = WS-I * 7 - 5
MOVE 'J' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 4
MOVE 'J' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
END-PERFORM.
J-EXIT. EXIT.
K-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 8
IF WS-J EQUAL 1 OR WS-J EQUAL 7 THEN
COMPUTE WS-TEMP = WS-I * 7
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 2 OR WS-J EQUAL 6 THEN
COMPUTE WS-TEMP = WS-I * 7 - 2
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 1
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 3 OR WS-J EQUAL 5 THEN
COMPUTE WS-TEMP = WS-I * 7 - 4
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 4 THEN
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 5
MOVE 'K' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
END-PERFORM.
K-EXIT. EXIT.
L-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'L' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'L' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM.
L-EXIT. EXIT.
M-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'M' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'M' TO WS-LETTER( WS-J, WS-TEMP )
IF WS-J EQUAL 2 THEN
COMPUTE WS-TEMP = WS-I * 7 - 5
MOVE 'M' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 1
MOVE 'M' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 3 THEN
COMPUTE WS-TEMP = WS-I * 7 - 4
MOVE 'M' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 2
MOVE 'M' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 4 THEN
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'M' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
END-PERFORM.
M-EXIT. EXIT.
N-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'N' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'N' TO WS-LETTER( WS-J, WS-TEMP )
IF WS-J EQUAL 2 THEN
COMPUTE WS-TEMP = WS-I * 7 - 5
MOVE 'N' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 3 THEN
COMPUTE WS-TEMP = WS-I * 7 - 4
MOVE 'N' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 4 THEN
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'N' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 5 THEN
COMPUTE WS-TEMP = WS-I * 7 - 2
MOVE 'N' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 6 THEN
COMPUTE WS-TEMP = WS-I * 7 - 1
MOVE 'N' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
END-PERFORM.
N-EXIT. EXIT.
O-PARA.
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'O' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'O' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'O' TO WS-LETTER( 1, WS-TEMP )
MOVE 'O' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM.
O-EXIT. EXIT.
P-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'P' TO WS-LETTER( 1, WS-TEMP )
MOVE 'P' TO WS-LETTER( 4, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 4
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'P' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'P' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 5 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'P' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM.
P-EXIT. EXIT.
Q-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'Q' TO WS-LETTER( 1, WS-TEMP )
MOVE 'Q' TO WS-LETTER( 6, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'Q' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'Q' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
COMPUTE WS-TEMP = WS-I * 7
MOVE 'Q' TO WS-LETTER( 7, WS-TEMP).
Q-EXIT. EXIT.
R-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'R' TO WS-LETTER( 1, WS-TEMP )
MOVE 'R' TO WS-LETTER( 4, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 4
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'R' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'R' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 5 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'R' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'R' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM.
R-EXIT. EXIT.
S-PARA.
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'S' TO WS-LETTER( 1, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'S' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'S' TO WS-LETTER( 4, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 4
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'S' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 5 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7
MOVE 'S' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM.
S-EXIT. EXIT.
T-PARA.
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'T' TO WS-LETTER( 1, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 2 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'T' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM.
T-EXIT. EXIT.
U-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'U' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'U' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'U' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM.
U-EXIT. EXIT.
V-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 4
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'V' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'V' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
PERFORM VARYING WS-J FROM 4 BY 1 UNTIL WS-J = 6
COMPUTE WS-TEMP = WS-I * 7 - 5
MOVE 'V' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 1
MOVE 'V' TO WS-LETTER( WS-J, WS-TEMP )
END-PERFORM
COMPUTE WS-TEMP = WS-I * 7 - 4
MOVE 'V' TO WS-LETTER( 6, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 2
MOVE 'V' TO WS-LETTER( 6, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'V' TO WS-LETTER( 7, WS-TEMP ).
V-EXIT. EXIT.
W-PARA.
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - 6
MOVE 'W' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7
MOVE 'W' TO WS-LETTER( WS-J, WS-TEMP )
IF WS-J EQUAL 5 THEN
COMPUTE WS-TEMP = WS-I * 7 - 3
MOVE 'W' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
IF WS-J EQUAL 6 THEN
COMPUTE WS-TEMP = WS-I * 7 - 4
MOVE 'W' TO WS-LETTER( WS-J, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 2
MOVE 'W' TO WS-LETTER( WS-J, WS-TEMP )
END-IF
END-PERFORM
COMPUTE WS-TEMP = WS-I * 7 - 5
MOVE 'W' TO WS-LETTER( 7, WS-TEMP )
COMPUTE WS-TEMP = WS-I * 7 - 1
MOVE 'W' TO WS-LETTER( 7, WS-TEMP ).
W-EXIT. EXIT.
X-PARA.
MOVE 6 TO WS-L
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 8
COMPUTE WS-TEMP = WS-I * 7 - WS-L
MOVE 'X' TO WS-LETTER( WS-J, WS-TEMP )
SUBTRACT 1 FROM WS-L
END-PERFORM
MOVE 6 TO WS-L
PERFORM VARYING WS-J FROM 7 BY -1 UNTIL WS-J = 0
COMPUTE WS-TEMP = WS-I * 7 - WS-L
MOVE 'X' TO WS-LETTER( WS-J, WS-TEMP )
SUBTRACT 1 FROM WS-L
END-PERFORM.
X-EXIT. EXIT.
Y-PARA.
MOVE 6 TO WS-L
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J = 5
COMPUTE WS-TEMP = WS-I * 7 - WS-L
MOVE 'Y' TO WS-LETTER( WS-J, WS-TEMP )
SUBTRACT 1 FROM WS-L
END-PERFORM
MOVE 6 TO WS-L
PERFORM VARYING WS-J FROM 7 BY -1 UNTIL WS-J = 0
COMPUTE WS-TEMP = WS-I * 7 - WS-L
MOVE 'Y' TO WS-LETTER( WS-J, WS-TEMP )
SUBTRACT 1 FROM WS-L
END-PERFORM.
Y-EXIT. EXIT.
Z-PARA.
PERFORM VARYING WS-J FROM 0 BY 1 UNTIL WS-J = 7
COMPUTE WS-TEMP = WS-I * 7 - WS-J
MOVE 'Z' TO WS-LETTER( 1, WS-TEMP )
MOVE 'Z' TO WS-LETTER( 7, WS-TEMP )
END-PERFORM
MOVE 6 TO WS-L
PERFORM VARYING WS-J FROM 7 BY -1 UNTIL WS-J = 0
COMPUTE WS-TEMP = WS-I * 7 - WS-L
MOVE 'Z' TO WS-LETTER( WS-J, WS-TEMP )
SUBTRACT 1 FROM WS-L
END-PERFORM.
Z-EXIT. EXIT.
ASK-USER.
DISPLAY 'ENTER A STRING. PLEASE LIMIT TO'
DISPLAY 'MAX 10 CHARACTERS. THE PROGRAM '
DISPLAY 'WILL NOT KNOW THE CHARACTERS '
DISPLAY 'ENTERED BEYOND 10 ;) '
ACCEPT WS-INPUT
DISPLAY ' '
DISPLAY 'ENTERED STRING IS ' WS-INPUT
DISPLAY ' '
MOVE FUNCTION UPPER-CASE(WS-INPUT) TO WS-INPUT-UPPER
INITIALIZE WS-PART1
WS-PART2
UNSTRING WS-INPUT DELIMITED BY SPACE INTO
WS-PART1, WS-PART2
IF WS-PART2 NOT EQUAL SPACES THEN
DISPLAY 'ENTER A STRING WITHOUT SPACES IN BETWEEN.'
PERFORM ASK-USER THRU ASK-EXIT
ELSE
INSPECT WS-INPUT TALLYING WS-COUNT FOR CHARACTERS.
ASK-EXIT. EXIT.
DISPLAY-PARA.
PERFORM ANOTHER-TABLE-PARA THRU ANOTHER-EXIT
VARYING WS-K FROM 1 BY 1 UNTIL WS-K = 8
PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J > 7
DISPLAY WS-DISPLAY-LINE(WS-J)
END-PERFORM
DISPLAY ' '
DISPLAY ' '.
DISPLAY-EXIT. EXIT.
ANOTHER-TABLE-PARA.
MOVE 1 TO WS-L
PERFORM VARYING WS-J FROM 1 BY 7 UNTIL WS-J > 70
MOVE WS-LINE(WS-K)(WS-J:7) TO WS-DATA(WS-K, WS-L)
MOVE ' ' TO WS-FILLER(WS-K, WS-L)
ADD 1 TO WS-L
END-PERFORM.
ANOTHER-EXIT. EXIT.
You can execute the code on JDoodle, an online compiler and editor for many programming languages including COBOL, by clicking ๐ here.
The COBOL program that I've written mimics the functionality of Banner command in Linux.
After clicking on the link, just scroll to the bottom of the code and enter a string, a maximum of 10 characters, in Stdin Inputs, and click on the Execute button. After the execution, the result will be displayed in the Output window.
The image above shows the output after running the code in JDOODLE.
Please make note of the following before providing input in the Stdin Inputs tab:
Numbers and symbols like hyphens (-), dollars ($), etc. aren't supposed to be entered. The program code is hardwired with logic to form shapes only for the 26 alphabets (in uppercase). If numbers and symbols are part of the string, they will be replaced with spaces.
I've used an intrinsic function (
FUNCTION UPPER-CASE
) to convert any string entered by the user to upper-case.Please limit the input string to a maximum of 10 characters. Strings with lengths beyond 10 will be truncated.
If there are spaces in between the string, the user will be prompted to re-enter another string without spaces in between.
In the picture above, Stdin Inputs has 3 lines of input string; the first 2 lines have strings with a space in between. Note the messages in the Result area.
Scope for improvement ๐
Improvements can be made to the existing code to shorten the total number of lines.
Logics for lower-case alphabets, numbers and symbols can be added.
The length of the string, input by the user can be extended.
The height and width of the cell are fixed for now and can be made scalable by altering the code.
GitHub
GitHub hosts millions of projects written in different programming languages. Each project is placed in its own container called a repository (repo) that can store code and other files of the project. Any changes to the files within a repo will be tracked via version control.
Each repo has a name. There can be lots of repositories with same name. Hence, it's always better to use a link to locate the repo you're looking for.
Go ahead and open this ๐ repo I've created for this project.
By default, this repository, which I've created, has only one branch named main. Having the code in the main branch is similar to having the code in the production stage of CA Endevorยฎ, a source code management tool for z/OS.
If you want to do some edits on the code, you take a copy of the code residing in the production stage of CA Endevorยฎ to your personal PDS. Likewise, in GitHub, we use branches to make edits before committing them to main. When a new branch is created, a new copy or snapshot of the main branch is made.
There are 2 files in the main branch of the repository I've created for this project. A README
file, which describes the project, and a file named CBL1
, which has the COBOL program.
All you need is an account on GitHub to create a new branch for yourself in order to suggest edits/improvements to the code. commit
by saving your changes. Open a pull request to propose your changes and request someone to review by using GitHub's @mention system. pull requests
are merged to the main
branch when the new changes are reviewed and deemed good-to-go ๐.
Conclusion
That's it for now!
I hope you liked this post. Should you have any questions/suggestions, please post it in the comments section below.
Thx๐!
๐
P.S. The original version of this post was written at https://iamamainframer.blogspot.com and has been reposted here.
Subscribe to my newsletter
Read articles from Srinivasan JV directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Srinivasan JV
Srinivasan JV
I have been a mainframe developer for the past 10 years. As part of work obligations, I am currently in pursuit of learning Java. You'll find me writing more about the mainframe.