Writing rexx output logically to a dataset using EXECIO? - mainframe

I have this Rexx program which I want to write the output to a particular dataset. However I can't get to print the exact output produced on the terminal to the dataset.
/* REXX */
"FREE FI(outdd)"
"ALLOC FI(outdd) DA('Z01510.OUTPUT(SAMPLCBL)') SHR REUSE"
row = 0
hline = ' *-----------------------'
mline.0 = ' IDENTIFICATION DIVISION.'
mline.1 = ' *'
mline.2 = ' PROGRAM-ID. '
mline.3 = ' *'
mline.4 = ' *'
mline.5 = ' * Description :'
mline.6 = ' *'
mline.7 = ' * Created on : 'date()
mline.8 = ' * Created by : '
mline.9 = ' * : Userid('')'
mline.10 = ' * : Using' '()'
mline.11 = ' *'
mline.12 = ' * Called by :'
mline.13 = ' *'
mline.14 = ' * Calls :'
mline.15 = ' * Change Activity :'
mline.16 = ' * ©Copyright of -----.'
mline.17 = ' ENVIRONMENT DIVISION.'
mline.18 = ' INPUT-OUTPUT SECTION.'
mline.19 = ' DATA DIVISION.'
mline.20 = ' WORKING-STORAGE SECTION.'
mline.21 = ' LINKAGE SECTION.'
mline.22 = ' PROCEDURE DIVISION.'
mline.23 = ' A-MAIN SECTION.'
mline.24 = ' STOP RUN.'
mline.25 = ' * End of '
say hline
say mline.0
say hline
say mline.2
say hline
do i = 4 to 16
say mline.i
end
say hline
do i=17 to 24
say mline.i
say hline
end
say mline.25
"EXECIO * DISKW outdd (STEM mline."
"EXECIO 0 DISKW outdd (FINIS"
"FREE FI(outdd)"
exit
I run the Rexx script on the z/OS terminal and I get the following sample output which I want copied to the dataset in the exact same way.
*-----------------------
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID.
*-----------------------
*
* Description :
*
* Created on : 14 Oct 2020
* Created by :
* : Userid(')
* : Using ()
*
* Called by :
*
* Calls :
* Change Activity :
* ©Copyright of -----.
*-----------------------
ENVIRONMENT DIVISION.
*-----------------------
INPUT-OUTPUT SECTION.
*-----------------------
DATA DIVISION.
*-----------------------
WORKING-STORAGE SECTION.
*-----------------------
LINKAGE SECTION.
*-----------------------
PROCEDURE DIVISION.
*-----------------------
A-MAIN SECTION.
*-----------------------
STOP RUN.
*-----------------------
* End of

You should not store data in mline.0 but the count of stem tails (mline.1 mline,2 etc) and pass this to EXECIO as the number of records to write. Using mline.0 is not wrong but 'normal' practice is to use it as a count - same as EXECIO does when it reads into a stem.
If you want your hline to be written then you need to add it to the mline stem first at the appropriate places.

There's a few ways to achieve what you're looking for, but the easiest way would likely be to:
Replace each say with QUEUE to place the lines on the stack
Change EXECIO to accommodate writing out the stack
Clear the stack with DELSTACK
So, your script would look like this:
/* REXX */
"FREE FI(outdd)"
"ALLOC FI(outdd) DA('Z01510.OUTPUT(SAMPLCBL)') SHR REUSE"
row = 0
hline = ' *-----------------------'
mline.0 = ' IDENTIFICATION DIVISION.'
mline.1 = ' *'
mline.2 = ' PROGRAM-ID. '
mline.3 = ' *'
mline.4 = ' *'
mline.5 = ' * Description :'
mline.6 = ' *'
mline.7 = ' * Created on : 'date()
mline.8 = ' * Created by : '
mline.9 = ' * : Userid('')'
mline.10 = ' * : Using' '()'
mline.11 = ' *'
mline.12 = ' * Called by :'
mline.13 = ' *'
mline.14 = ' * Calls :'
mline.15 = ' * Change Activity :'
mline.16 = ' * Copyright of -----.'
mline.17 = ' ENVIRONMENT DIVISION.'
mline.18 = ' INPUT-OUTPUT SECTION.'
mline.19 = ' DATA DIVISION.'
mline.20 = ' WORKING-STORAGE SECTION.'
mline.21 = ' LINKAGE SECTION.'
mline.22 = ' PROCEDURE DIVISION.'
mline.23 = ' A-MAIN SECTION.'
mline.24 = ' STOP RUN.'
mline.25 = ' * End of '
QUEUE hline
QUEUE mline.0
QUEUE hline
QUEUE mline.2
QUEUE hline
do i = 4 to 16
QUEUE mline.i
end
QUEUE hline
do i=17 to 24
QUEUE mline.i
QUEUE hline
end
QUEUE mline.25
"Execio "Queued()" DISKW outdd (FINIS"
"FREE FI(outdd)"
"DELSTACK"
exit

At least, you should not use mline.0. EXECIO DISKW will start writing from mline.1, index 0 is ignored.
Except this problem, I do not see any output error except if you want hline variable in the output file. In this case, just insert mline indices at the right place with the content of hline.
If this is not your problem, please, describe more precisely what do you mean by "I can't get to print the exact output"

I edited my previous answer so it does what you want. Here is the adjusted answer:
/* REXX */
queue ' *-----------------------'
queue ' IDENTIFICATION DIVISION.'
queue ' *-----------------------'
queue ' PROGRAM-ID. '
queue ' *-----------------------'
queue ' *'
queue ' *'
queue ' * Description :'
queue ' *'
queue ' * Created on : 'date()
queue ' * Created by : '
queue ' * : Userid('')'
queue ' * : Using' '()'
queue ' *'
queue ' * Called by :'
queue ' *'
queue ' * Calls :'
queue ' * Change Activity :'
queue ' * ©Copyright of -----.'
queue ' *-----------------------'
queue ' ENVIRONMENT DIVISION.'
queue ' *-----------------------'
queue ' INPUT-OUTPUT SECTION.'
queue ' *-----------------------'
queue ' DATA DIVISION.'
queue ' *-----------------------'
queue ' WORKING-STORAGE SECTION.'
queue ' *-----------------------'
queue ' LINKAGE SECTION.'
queue ' *-----------------------'
queue ' PROCEDURE DIVISION.'
queue ' *-----------------------'
queue ' A-MAIN SECTION.'
queue ' *-----------------------'
queue ' STOP RUN.'
queue ' *-----------------------'
queue ' * End of '
queue ' *-----------------------'
do i = 1 to queued()
parse pull line
say line
mline.i = line
end
rc = BPXWDYN( 'alloc fi(outdd) da(''Z01510.OUTPUT(SAMPLCBL)'') shr reuse' )
address 'MVS' 'EXECIO * DISKW' outdd '(finis stem mline.'
rc = BPXWDYN( 'free fi(outdd)' )
exit rc

Related

Nodejs indexOf with array of arrays

I'd be grateful if someone can explain what I'm doing wrong here. I compare two arrays of geographic coordinates, successfully find the common elements and then try to get the indexes for the first hit. Only arrB works as expected. Although the key is quite clearly at arrA[1], no match is found. I've included loads of logging because I don't quite believe what I'm seeing.
function arrayIntersect(a, b) {
/* credit https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */
var aa = {};
a.forEach(function(v) { aa[v]=1; });
return b.filter(function(v) { return v in aa; });
}
const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]]
const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]]
console.log(arrA.length + ' ' + Array.isArray(arrA))
console.log(arrB.length + ' ' + Array.isArray(arrB))
console.log(arrA[0].length + ' ' + Array.isArray(arrA[0])) // sample entries
console.log(arrB[0].length + ' ' + Array.isArray(arrB[0]))
res = arrayIntersect(arrA, arrB) ; console.log('res ' + res + ' ' + Array.isArray(res))
let key = res[0] ; console.log('key ' + key + ' ' + Array.isArray(key))
let idxA = arrA.indexOf(key) ; console.log('idxA ' + idxA)
let idxB = arrB.indexOf(key) ; console.log('idxB ' + idxB)
Results
Server started at http://localhost:8080
28 true
53 true
2 true
2 true
res 53.7,-2.45,53.93,-2.77,53.66,-2.75,53.62,-2.96 true
key 53.7,-2.45 true
idxA -1
idxB 13
When you use arrays with objects in it the indexOf function compares then the object reference and not the object itself to get the index value. And remember, in your case you have arrays in arrays but in javascript also arrays are objects so this aplies as well in your case.
Then your arrayIntersect function filters arrB, therefor the originale objects from arrB are stored then in the res array which then only can be used to get back the index in the arrB.
One approach could be to just use find for arrA to get the index and just stringify the objects while comparing:
function arrayIntersect(a, b) {
/* credit https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */
var aa = {};
a.forEach(function(v) { aa[v]=1; });
return b.filter(function(v) { return v in aa; });
}
const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]]
const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]]
console.log(arrA.length + ' ' + Array.isArray(arrA))
console.log(arrB.length + ' ' + Array.isArray(arrB))
console.log(arrA[0].length + ' ' + Array.isArray(arrA[0])) // sample entries
console.log(arrB[0].length + ' ' + Array.isArray(arrB[0]))
res = arrayIntersect(arrA, arrB) ; console.log('res ' + res + ' ' + Array.isArray(res))
let key = res[0] ; console.log('key ' + key + ' ' + Array.isArray(key))
let idxA = arrA.indexOf(arrA.find(el=>JSON.stringify(el)===JSON.stringify(key))) ; console.log('idxA ' + idxA)
let idxB = arrB.indexOf(key) ; console.log('idxB ' + idxB)

Converting Byte to String in Visual Basic

I am new to VB and I am trying to get a program to output text instead of hex. I found the code online, a program called maxiCOM. Here is the link http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm. The source code can be downloaded at the bottom of the page.
Unfortunately, the level of coding in the program is far above my level of understanding, and I don't really get how to change the output from hex to text. I would greatly appreciate it if someone could explain to me how to do this. The snippet of the code is
Public Class MaxiTester
Dim SpaceCount As Byte = 0
Dim LookUpTable As String = "0123456789ABCDEF"
Dim RXArray(2047) As Char ' Text buffer. Must be global to be accessible from more threads.
Dim RXCnt As Integer ' Length of text buffer. Must be global too.
' Make a new System.IO.Ports.SerialPort instance, which is able to fire events.
Dim WithEvents COMPort As New SerialPort
Private Sub Receiver(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles COMPort.DataReceived
Dim RXByte As Byte
Do
'----- Start of communication protocol handling -----------------------------------------------------------
' The code between the two lines does the communication protocol. In this case, it simply emties the
' receive buffer and converts it to text, but for all practical applications, you must replace this part
' with a code, which can collect one entire telegram by searching for the telegram
' delimiter/termination. In case of a simple ASCII protocol, you may just use ReadLine and receive
' in a global string instead of a byte array.
' Because this routine runs on a thread pool thread, it does not block the UI, so if you have any data
' convertion, encryption, expansion, error detection, error correction etc. to do, do it here.
RXCnt = 0
Do
RXByte = COMPort.ReadByte
RXArray(RXCnt) = LookUpTable(RXByte >> 4) ' Convert each byte to two hexadecimal characters
RXCnt = RXCnt + 1
RXArray(RXCnt) = LookUpTable(RXByte And 15)
RXCnt = RXCnt + 1
RXArray(RXCnt) = " "
RXCnt = RXCnt + 1
SpaceCount = (SpaceCount + 1) And 31 ' Insert spaces and CRLF for better readability
If SpaceCount = 0 Then ' Insert CRLF after 32 numbers
RXArray(RXCnt) = Chr(13) ' CR
RXCnt = RXCnt + 1
RXArray(RXCnt) = Chr(10) ' LF
RXCnt = RXCnt + 1
Else
If (SpaceCount And 3) = 0 Then ' Insert two extra spaces for each 4 numbers
RXArray(RXCnt) = " "
RXCnt = RXCnt + 1
RXArray(RXCnt) = " "
RXCnt = RXCnt + 1
End If
End If
Loop Until (COMPort.BytesToRead = 0)
'----- End of communication protocol handling -------------------------------------------------------------
Me.Invoke(New MethodInvoker(AddressOf Display)) ' Start "Display" on the UI thread
Loop Until (COMPort.BytesToRead = 0) ' Don't return if more bytes have become available in the meantime
End Sub
' Text display routine, which appends the received string to any text in the Received TextBox.
Private Sub Display()
Received.AppendText(New String(RXArray, 0, RXCnt))
End Sub
System.Text.Encoding.Unicode.GetString(bytes) 'bytes is your byte array'
Notice the first line after Do in your inner loop:
RXByte = COMPort.ReadByte
This is the only point in your code where you have the actual byte value read from the COM port. After this point the code converts the byte into two hex values using bit-shifting. You should create a global variable of string type and append the read byte value to this string before it is lost.
Add the following line immediately after the above line:
YourString &= Convert.ToChar(RXByte).ToString()
where YourString is your global string variable.
Note that you can attain some efficiency by using StringBuilder instead of string, but I'm leaving that for you as exercise.

Python I am making a calculator for the formula/answer of 3 different things, but 2/3 of the things display with extra characters

PYTHON
I am making a calculator that displays formulas and answers of a few different things after you enter time, distance, mass, etc. Velocity works fine, but Speed and Acceleration are display apostrophes, commas, and parentheses. Some of them aren't even in the editor.
Output:
('Speed = Distance / Time = 1m / 1s', ' = 1m/s')
('Acceleration = Force / Mass = 1N', ' / 1kg = 1.0m/s/s')
Velocity = Speed + Direction = 1m/s + Direction = 1m/s North
The variables in the program:
SpeedFormula = 'Speed = Distance / Time = ' + distanceDisplay + ' / ' + timeDisplay, ' = ' + speedDisplay
AccelerationFormula = 'Acceleration = Force / Mass = ' + forceDisplay, ' / ' + massDisplay + ' = ' + AccelerationDisplay
VelocityFormula = 'Velocity = Speed + Direction = ' + speedDisplay + " + " + 'Direction' + ' = ' + VelocityDisplay
Anyone know why they display differently and how I can fix it?
Replace
timeDisplay, ' = ' + speedDisplay
with
timeDisplay + ' = ' + speedDisplay
When you use comma SpeedFormula becomes a tuple, not a string.
P.S. You should probably use formatting like this:
distanceDisplay = 20
timeDisplay = 2
speedDisplay = 10
SpeedFormula = 'Speed = Distance / Time = %d / %d = %d' % (distanceDisplay,timeDisplay,speedDisplay)

Excel (2007) function does not calculate when I open the file (Automatic calculation)

I have created a function via vba and I have used this function to make an iterative table. I have set the workbook calculation to automatic and it all works fine but when I open the excel file, the cells that contain the mentioned function, give me #name error and everytime I need to recalculate. Is there a way to fix this?
Public Function FrictionFactor(relativeroughness, reynoldsnumber)
'Dim relativeroughness, reynoldsnumber As Double
fNext = 0.005 ' initial value for f
fIncrement = 0.005 ' initial step size
Convergence = 0.000001 ' sets the decimal place accuracy of the result
Do
fStart = fNext
LHSColebrookStart = 1 / (fStart ^ 0.5)
RHSColebrookStart = -2 * (Log((relativeroughness / 3.7) + (2.51 / (reynoldsnumber * (fStart ^ 0.5)))) / Log(10))
DifferenceStart = LHSColebrookStart - RHSColebrookStart
fNext = fStart + fIncrement
LHSColebrookNext = 1 / (fNext ^ 0.5)
RHSColebrookNext = -2 * (Log((relativeroughness / 3.7) + (2.51 / (reynoldsnumber * (fNext ^ 0.5)))) / Log(10))
DifferenceNext = LHSColebrookNext - RHSColebrookNext
If DifferenceStart * DifferenceNext < 0 Then ' march f in opposite direction and more slowly
fIncrement = fIncrement / -10
ElseIf DifferenceStart * DifferenceNext = 0 Then ' done
fIncrement = 0
End If ' keep marching f in same direction and at same rate
Loop While Abs(fStart - fNext) > Convergence
FrictionFactor = fStart
End Function
The usual reason this happens is that macros are not enabled when the workbook is opened. Check your Security settings.

My VBA code is aborting unexpectedly upon exiting a 'While' loop. Why?

I am new to VBA coding. I have done some coding in Javascript and C++, so I do understand the concepts. I'm not too familiar with the specifics of VBA, though. This particular code is for Excel 2007. The sort function was copied from elsewhere as pseudocode (documentation is not mine). I've rewritten it as VBA (unsuccessfully).
This code is not working properly. The code is abruptly aborting entirely (not just jumping out of a loop or function, but quitting completely after going through the While loop twice.
To replicate the problem, save this code as a Macro for an Excel sheet, type the number 9853 in B5, and in B6 type "=Kaprekar(B5)". Essentially, run Kaprekar(9853).
Could someone please help me figure out what I'm doing wrong here? Thanks.
By the way, I'm using While-Wend now. I also tried Do While-Loop with the same result.
Here's the code:
Function Sort(A)
limit = UBound(A)
For i = 1 To limit
' A[ i ] is added in the sorted sequence A[0, .. i-1]
' save A[i] to make a hole at index iHole
Item = A(i)
iHole = i
' keep moving the hole to next smaller index until A[iHole - 1] is <= item
While ((iHole > 0) And (A(iHole - 1) > Item))
' move hole to next smaller index
A(iHole) = A(iHole - 1)
iHole = iHole - 1
Wend
' put item in the hole
A(iHole) = Item
Next i
Sort = A
End Function
Function Kaprekar%(Original%)
Dim Ord(0 To 3) As Integer
Ord(0) = Original \ 1000
Ord(1) = (Original - (Ord(0) * 1000)) \ 100
Ord(2) = (Original - (Ord(1) * 100) - (Ord(0) * 1000)) \ 10
Ord(3) = (Original - (Ord(2) * 10) - (Ord(1) * 100) - (Ord(0) * 1000))
If (Ord(0) = Ord(1)) * (Ord(1) = Ord(2)) * (Ord(2) = Ord(3)) * (Ord(3) = Ord(0)) = 1 Then
Kaprekar = -1
Exit Function
End If
Arr = Sort(Ord)
Kaprekar = Ord(3)
End Function
excel evaluates both items in the while statement, so
While ((ihole > 0) And (A(ihole - 1) > item))
when ihole=0, returns false for the first test, and out of bounds for the second test, bombing out of the function with a #Value error.
A quick bubblesort would be something like this:
Option Explicit
Function Sort(A)
Dim iLoop As Long
Dim jLoop As Long
Dim Last As Long
Dim Temp
Last = UBound(A)
For iLoop = 0 To Last - 1
For jLoop = iLoop + 1 To Last
If A(iLoop) > A(jLoop) Then
Temp = A(jLoop)
A(jLoop) = A(iLoop)
A(iLoop) = Temp
End If
Next jLoop
Next iLoop
Sort = A
End Function

Resources