Wednesday, March 24, 2021

Printing the pattern of letters from A to Z using the respective letter itself

Hiya! Hope 🀞 this blog post will be fun πŸ˜€ as I really enjoyed writing this particular 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 got now on the logon screen of IBM's Master the Mainframe 2020 system.

Click on the image for a larger version.

Each letter's shape in the string 'z/OS' is printed using the same letter, that too in Italics. 

Intro

I was longing to write a COBOL program which 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 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 a 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 little bit tricky. I chose 7 x 7 cell to spread out the shape of each letter. An excel sheet, in which I drew all the 26 letter's shapes, came in handy as I referred the sheet before going to code the logic for each letter. 

An excel sheet with each alphabet's pattern 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 one-dimensional table that occurs 7 times. Assume each element of WS-LINE as a row.
 
WS-LETTER is an element of a two-dimensional table that occurs 70 times in each occurence of WS-LINE. Assume each element of WS-LETTER as a column. 

For readability, I've limited the maximum length of the string, input by the user, to 10 bytes. Hence, each line is 70 bytes 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 be clear enough to read. 

That isn't easy to read. BAD πŸ™ˆ


Hence, I came up with yet another multi-dimensional table solely for printing purpose. 


This table gets data from the former 2D table (which we've already seen before) only at the point of displaying the entire stuff. 

In the PROCEDURE DIVISION, there are references to 3 para's,
  1. which would ask for the input string from the user; validate it. Upon successful validation of user input (read the next item),
  2. go through each letter of the string one by one with help of Reference Modification in COBOL; call the para corresponding to each letter - to print its shape - with the help of EVALUATE verb.
  3. display output and STOP RUN.
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 para.


This πŸ‘† part of code prints the shape of letter T. There are 2 PERFORM VARYING loops ➿. 
Let's look at the first loop ➰. 
  • The first loop iterates for 7 times with WS-J data item's value ranging from 0 to 6 and forms the horizontal line of 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 with 7 to put the letter's shape in the right set of rows and columns. 
  • COMPUTE statement is coded before the MOVE 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 to WS-LETTER which is an element of two-dimensional table. 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 as 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
WS-J = 2
WS-TEMP = 5
Letter T is moved to WS-LETTER(1, 5)

4th iteration:
WS-I = 1
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
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 to all the rows in 4th column of 7x7 cell. At the end of second loop, the shape of letter will be formed. 



Executing the code..

The full code is available πŸ‘‰ here in JDOODLE, an online compiler and editor for many programming langauges including COBOL. 

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 give a string, max. of 10 characters, in Stdin Inputs and click Execute button in the blue box. After the execution, the result will be displayed in the Result area (black colored rectangle box). 

Output after running the code in JDOODLE.

Please note the following before providing input in Stdin Inputs tab:
  • Numbers and symbols like hyphen (-), dollar ($) etc., aren't supposed to be entered. The program code is hardwired with logics to form shapes only for the 26 alphabets (in upper-case). 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. String with length beyond 10 will be truncated.
  • If there are spaces in between the string, user will be prompted to re-enter another string without spaces in between. 
Stdin Inputs has got 3 lines of input string; first 2 lines has got 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.
  • Length of the string, input by the user can be extended. 
  • The height and width of the cell is 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 got 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 got only one branch named main. Having the code in 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 commiting them to main. When a new branch is created, a new copy or snapshot of main 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 got the COBOL program. 

All you need is an account on GitHub to create new branch for yourself in order to suggest edits/improvements for 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 are good to go πŸ‘ .


That's it for now! πŸ”š

Hope you liked this post. Should you have any questions/suggestions, please post it in the comments section below.

ThxπŸ‘!



3 comments:

  1. Great info, its very useful. But can you provide code for printing numbers too in its shape.

    ReplyDelete
  2. I second that; would love an update for printing numbers too.

    ReplyDelete
    Replies
    1. I will share another post on my blog with code to print numbers, by end of this week.

      Delete