Finding Highest , Lowest and the Average in Cobol - average

I am creating a program that is reading in a file which consists of companies and their information. It is to reject companies with a rating lower that 3.5 and then display the highest quote and the lowest quote and then the average among the companies. I am new to Cobol so I am not sure how to find the highest, lowest and the average. I have coded what I though would work in Module 2012 to find the highest but when I run my program it does not display the information. Any help with this would be greatly appreciated. Thank you
IDENTIFICATION DIVISION.
PROGRAM-ID. MOVING-QUOTES.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT MOVING-QUOTES-FILE ASSIGN TO 'Moving-Quotes.txt'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT MOVING-QUOTES-RESULTS-FILE ASSIGN TO "MOVING.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD MOVING-QUOTES-FILE.
01 FS-MOVING-QUOTES-RECORD PIC X(45).
FD MOVING-QUOTES-RESULTS-FILE.
01 MOVING-QUOTES-RESULTS-RECORD PIC X(80).
WORKING-STORAGE SECTION.
01 WS-MOVING-QUOTES-RECORD.
05 FILLER PIC X(2).
05 MQR-COMPANY-NAME PIC X(15).
05 FILLER PIC X(1).
05 MQR-COMPANY-PHONE PIC X(13).
05 FILLER PIC X(1).
05 MQR-MOVING-QUOTE PIC 999V99.
05 FILLER PIC X(1).
05 MQR-NUMBER-ITEMS PIC 999.
05 FILLER PIC X(1).
05 MQR-RATING PIC 9V9.
01 PRT-MOVING-QUOTES-FILE.
05 FILLER PIC X(2).
05 PRT-MQR-COMPANY-NAME PIC X(15).
05 FILLER PIC X(1) VALUE SPACES.
05 PRT-MQR-COMPANY-PHONE PIC X(13).
05 FILLER PIC X(5).
05 PRT-MQR-MOVING-QUOTE PIC $zz99.99.
05 FILLER PIC X(7).
05 PRT-MQR-NUMBER-ITEMS PIC 9(3).
05 FILLER PIC X(15).
05 PRT-MQR-RATING PIC 9.9.
01 PAGE-TITLE.
05 PIC X(22) VALUE SPACES.
05 PIC X(40) VALUE 'MOVING COMPANY QUOTES'.
05 PIC X(18) VALUE SPACES.
05 PRT-PAGE-NUM PIC Z9.
01 QUOTE-HEADING-1.
05 PIC X(7) VALUE SPACES.
05 PIC X(7) VALUE 'COMPANY'.
05 PIC X(9) VALUE SPACES.
05 PIC X(5) VALUE 'PHONE'.
05 PIC X(21) VALUE SPACES.
05 PIC X(9) VALUE 'NUMBER OF'.
05 PIC X(11) VALUE SPACES.
05 PIC X(4) VALUE 'YELP'.
05 PIC X(7).
01 QUOTE-HEADING-2.
05 PIC X(8).
05 PIC X(4) VALUE 'NAME'.
05 PIC X(11) VALUE SPACES.
05 PIC X(6) VALUE 'NUMBER'.
05 PIC X(9) VALUE SPACES.
05 PIC X(5) VALUE 'QUOTE'.
05 PIC X(7) VALUE SPACES.
05 PIC X(5) VALUE 'ITEMS'.
05 PIC X(13) VALUE SPACES.
05 PIC X(6) VALUE 'RATING'.
05 PIC X(2) VALUE SPACES.
01 QUOTE-HEADING-3.
05 PIC X(6) VALUE SPACES.
05 PIC X(9) VALUE ALL '-'.
05 PIC X(7) VALUE SPACES.
05 PIC X(8) VALUE ALL '-'.
05 PIC X(7) VALUE SPACES.
05 PIC X(7) VALUE ALL '-'.
05 PIC X(5) VALUE SPACES.
05 PIC X(11) VALUE ALL '-'.
05 PIC X(7) VALUE SPACES.
05 PIC X(8) VALUE ALL '-'.
01 WS-SWITCHES-AND-COUNTERS.
05 WS-EOF PIC X VALUE 'F'.
05 NUMBER-OF-PAGES PIC S9(4) COMP VALUE 0.
05 NUMBER-OF-LINES-USED PIC S9(4) COMP VALUE 0.
05 WS-HI-BID PIC 999V99 VALUE 0.
05 WS-LO-BID PIC 999V99 VALUE 999.99.
05 WS-TOTAL-BID-SUM PIC 999V99 VALUE 0.
05 WS-NUMBER-OF-RECORDS PIC 9(4) VALUE 4.
05 WS-AVERAGE PIC 999V99.
01 HI-COMPANY-INFO.
05 FILLER PIC X(6) VALUE SPACES.
05 SAV-HI-MQR-COMPANY-NAME PIC X(15).
05 FILLER PIC X(2) VALUE SPACES.
05 SAV-HI-MQR-COMPANY-PHONE PIC X(13).
05 FILLER PIC X(2) VALUE SPACES.
05 SAV-HI-MQR-QUOTE PIC $ZZ99.99.
01 LO-COMPANY-INFO.
05 FILLER PIC X(5) VALUE SPACES.
05 SAV-LO-MQR-COMPANY-NAME PIC X(15).
05 FILLER PIC X(2) VALUE SPACES.
05 SAV-LO-MQR-COMPANY-PHONE PIC X(13).
05 FILLER PIC X(2) VALUE SPACES.
05 SAV-LO-MQR-QUOTE PIC $ZZ99.99.
01 AVG-INFO.
05 PIC X(6) VALUE SPACES.
05 SAV-AVG PIC $ZZ99.99.
01 HI-INFO-HD1.
05 PIC X(8).
05 PIC X(7) VALUE 'HIGH'.
05 PIC X(8).
05 PIC X(5) VALUE 'PHONE'.
05 PIC X(52).
01 HI-INFO-HD2.
05 PIC X(6).
05 PIC X(7) VALUE 'COMPANY'.
05 PIC X(10).
05 PIC X(6) VALUE 'NUMBER'.
05 PIC X(9).
05 PIC X(5) VALUE 'QUOTE'.
05 PIC X(37).
01 HI-INFO-HD3.
05 PIC X(5).
05 PIC X(9) VALUE ALL '-'.
05 PIC X(8).
05 PIC X(8) VALUE ALL '-'.
05 PIC X(7).
05 PIC X(7) VALUE ALL '-'.
05 PIC X(36).
01 LO-INFO-HD1.
05 PIC X(7).
05 PIC X(3) VALUE 'LOW'.
05 PIC X(13).
05 PIC X(5) VALUE 'PHONE'.
05 PIC X(52).
01 LO-INFO-HD2.
05 PIC X(6).
05 PIC X(7) VALUE 'COMPANY'.
05 PIC X(10).
05 PIC X(6) VALUE 'NUMBER'.
05 PIC X(9).
05 PIC X(5) VALUE 'QUOTE'.
05 PIC X(37).
01 LO-INFO-HD3.
05 PIC X(5).
05 PIC X(9) VALUE ALL '-'.
05 PIC X(8).
05 PIC X(8) VALUE ALL '-'.
05 PIC X(7).
05 PIC X(7) VALUE ALL '-'.
05 PIC X(36).
01 AVG-INFO-HD1.
05 PIC X(7).
05 PIC X(7) VALUE 'AVERAGE'.
01 AVG-INFO-HD2.
05 PIC X(6).
05 PIC X(9) VALUE ALL '-'.
05 PIC X(65).
PROCEDURE DIVISION.
0000-MAINLINE.
PERFORM 1000-START-MOVING-QUOTES
PERFORM 2000-READ-N-PRINT-MQ
UNTIL WS-EOF = 'T'
PERFORM 3000-FINISH-UP
STOP RUN
.
*END OF MAIN BLOCK
1000-START-MOVING-QUOTES.
OPEN INPUT MOVING-QUOTES-FILE
OUTPUT MOVING-QUOTES-RESULTS-FILE
PERFORM 8000-READ-MOVING-QUOTES-FILE
IF WS-EOF NOT = 'T'
PERFORM 8020-PRINT-TITLE-AND-HEADINGS.
.
8000-READ-MOVING-QUOTES-FILE.
READ MOVING-QUOTES-FILE
AT END MOVE 'T' TO WS-EOF
end-READ
MOVE FS-MOVING-QUOTES-RECORD TO
WS-MOVING-QUOTES-RECORD
.
8010-CHECK-LINES.
ADD 2 TO NUMBER-OF-LINES-USED
IF NUMBER-OF-LINES-USED > 90
PERFORM 8020-PRINT-TITLE-AND-HEADINGS
.
8020-PRINT-TITLE-AND-HEADINGS.
ADD 1 TO NUMBER-OF-PAGES
MOVE NUMBER-OF-PAGES TO PRT-PAGE-NUM
MOVE SPACES TO MOVING-QUOTES-RESULTS-RECORD
MOVE PAGE-TITLE TO MOVING-QUOTES-RESULTS-RECORD
WRITE MOVING-QUOTES-RESULTS-RECORD AFTER ADVANCING 3 LINES
WRITE MOVING-QUOTES-RESULTS-RECORD FROM NUMBER-OF-PAGES
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM QUOTE-HEADING-1
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM QUOTE-HEADING-2
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM QUOTE-HEADING-3
AFTER ADVANCING 1 LINE
.
8025-PRINT-HI-HD.
MOVE SPACES TO MOVING-QUOTES-RESULTS-RECORD
WRITE MOVING-QUOTES-RESULTS-RECORD FROM HI-INFO-HD1
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM HI-INFO-HD2
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM HI-INFO-HD3
AFTER ADVANCING 1 LINE
.
8026-PRINT-LO-HD.
WRITE MOVING-QUOTES-RESULTS-RECORD FROM LO-INFO-HD1
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM LO-INFO-HD2
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM LO-INFO-HD3
AFTER ADVANCING 1 LINE
.
8027-PRINT-AVG-HD.
WRITE MOVING-QUOTES-RESULTS-RECORD FROM AVG-INFO-HD1
AFTER ADVANCING 1 LINE
WRITE MOVING-QUOTES-RESULTS-RECORD FROM AVG-INFO-HD2
AFTER ADVANCING 1 LINE
.
2000-READ-N-PRINT-MQ.
* PERFORM 8010-CHECK-LINES
PERFORM 8000-READ-MOVING-QUOTES-FILE
IF (MQR-RATING >= 3.5)
MOVE WS-MOVING-QUOTES-RECORD TO
PRT-MOVING-QUOTES-FILE
PERFORM 2001-PRINT-COMP
PERFORM 2010-FIND-HI-LO-AVG
END-IF
.
2001-PRINT-COMP.
MOVE MQR-COMPANY-NAME TO PRT-MQR-COMPANY-NAME
MOVE MQR-COMPANY-PHONE TO PRT-MQR-COMPANY-PHONE
MOVE MQR-MOVING-QUOTE TO PRT-MQR-MOVING-QUOTE
MOVE MQR-NUMBER-ITEMS TO PRT-MQR-NUMBER-ITEMS
MOVE MQR-RATING TO PRT-MQR-RATING
MOVE PRT-MOVING-QUOTES-FILE TO MOVING-QUOTES-RESULTS-RECORD
WRITE MOVING-QUOTES-RESULTS-RECORD
AFTER ADVANCING 2 LINES
ADD 1 TO WS-NUMBER-OF-RECORDS
.
2010-FIND-HI-LO-AVG.
PERFORM 2012-FIND-HI
PERFORM 2013-STORING-VAL-LO
PERFORM 2014-FIND-LO
PERFORM 2015-GET-SUM
PERFORM 2016-GET-AVERAGE
* PERFORM 8000-READ-MOVING-QUOTES-FILE
.
2011-STORING-VAL-HI.
MOVE MQR-MOVING-QUOTE TO WS-HI-BID
.
2012-FIND-HI.
PERFORM 2011-STORING-VAL-HI
IF (MQR-MOVING-QUOTE > WS-HI-BID)
MOVE MQR-MOVING-QUOTE TO WS-HI-BID
MOVE MQR-COMPANY-NAME TO SAV-HI-MQR-COMPANY-NAME
MOVE MQR-COMPANY-PHONE TO SAV-HI-MQR-COMPANY-PHONE
MOVE WS-HI-BID TO SAV-HI-MQR-QUOTE
MOVE HI-COMPANY-INFO TO MOVING-QUOTES-RESULTS-RECORD
WRITE MOVING-QUOTES-RESULTS-RECORD
AFTER ADVANCING 2 LINES
END-IF
.
2013-STORING-VAL-LO.
MOVE MQR-MOVING-QUOTE TO WS-LO-BID
.
2014-FIND-LO.
IF (MQR-MOVING-QUOTE < WS-LO-BID)
MOVE MQR-MOVING-QUOTE TO WS-LO-BID
MOVE MQR-COMPANY-NAME TO SAV-LO-MQR-COMPANY-NAME
MOVE MQR-COMPANY-PHONE TO SAV-LO-MQR-COMPANY-PHONE
MOVE MQR-MOVING-QUOTE TO SAV-LO-MQR-QUOTE
.
2015-GET-SUM.
ADD MQR-MOVING-QUOTE GIVING WS-TOTAL-BID-SUM
.
2016-GET-AVERAGE.
DIVIDE WS-TOTAL-BID-SUM BY WS-NUMBER-OF-RECORDS GIVING
WS-AVERAGE
MOVE WS-AVERAGE TO SAV-AVG
.
3000-FINISH-UP.
PERFORM 8025-PRINT-HI-HD
PERFORM 2012-FIND-HI
PERFORM 3010-PRT-HI
PERFORM 8026-PRINT-LO-HD
PERFORM 2014-FIND-LO
PERFORM 3020-PRT-LO
PERFORM 8027-PRINT-AVG-HD
PERFORM 2016-GET-AVERAGE
PERFORM 3030-PRT-AVG
CLOSE MOVING-QUOTES-FILE
MOVING-QUOTES-RESULTS-FILE
.
3010-PRT-HI.
MOVE HI-COMPANY-INFO TO MOVING-QUOTES-RESULTS-RECORD
.
3020-PRT-LO.
MOVE LO-COMPANY-INFO TO MOVING-QUOTES-RESULTS-RECORD
.
3030-PRT-AVG.
MOVE SAV-AVG TO MOVING-QUOTES-RESULTS-RECORD
.

Taken from the update in Finding Highest , Lowest and the Average in a Cobol program
Some more issues in 2000- the perform 8000- should be at the end of the procedure
Currently:
2000-READ-N-PRINT-MQ.
* PERFORM 8010-CHECK-LINES
PERFORM 8000-READ-MOVING-QUOTES-FILE
IF (MQR-RATING >= 3.5)
MOVE WS-MOVING-QUOTES-RECORD TO
PRT-MOVING-QUOTES-FILE
PERFORM 2001-PRINT-COMP
PERFORM 2010-FIND-HI-LO-AVG
END-IF
Should be:
2000-READ-N-PRINT-MQ.
* PERFORM 8010-CHECK-LINES
IF (MQR-RATING >= 3.5)
MOVE WS-MOVING-QUOTES-RECORD TO
PRT-MOVING-QUOTES-FILE
PERFORM 2001-PRINT-COMP
PERFORM 2010-FIND-HI-LO-AVG
END-IF
PERFORM 8000-READ-MOVING-QUOTES-FILE
also in 2012- why are you doing a write, surely this should be done at the end (section 3000-).
the 2012-, 2013- do not make any sense
in 2000, 2011, 2012 you need to do
if value-from-input-file > current-high
move input-file-details to current-High-details
end-if
if value-from-input-file < current-low
move input-file-details to current-Low-details
end-if
You would then write out the hi/lo results in 3000-
It is also very important to initialize the hi/low values appropriately ???
Try either
putting in Display's at the start of procedure's (+ relavent details)
Using a debugger
either will tell you what the program flow is

Related

How to get the maximum value of HID report according to mouse sensor parameters?

I'm making a mouse to joystick converter.The solution is map the maximum and minimum value that the mouse can report to the joystick.How can I get the theoretically maximum or minimum value(not logically,regardless of error) of the mouse HID report according to the parameters of the mouse sensor?
My mouse is logitech G403
I dump the HID descriptor:
Usage Page (Generic Desktop) 05 01
Usage (Mouse) 09 02
Collection (Application) A1 01
Usage (Pointer) 09 01
Collection (Physical) A1 00
Usage Page (Button) 05 09
Usage Minimum (Button 1) 19 01
Usage Maximum (Button 16) 29 10
Logical Minimum (0) 15 00
Logical Maximum (1) 25 01
Report Count (16) 95 10
Report Size (1) 75 01
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Usage Page (Generic Desktop) 05 01
Logical Minimum (-32767) 16 01 80
Logical Maximum (32767) 26 FF 7F
Report Size (16) 75 10
Report Count (2) 95 02
Usage (X) 09 30
Usage (Y) 09 31
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
Logical Minimum (-127) 15 81
Logical Maximum (127) 25 7F
Report Size (8) 75 08
Report Count (1) 95 01
Usage (Wheel) 09 38
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
Usage Page (Consumer Devices) 05 0C
Usage (AC Pan) 0A 38 02
Report Count (1) 95 01
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
End Collection C0
End Collection
I can only know the logical maximum and minimum of X and Y from this descriptor,No physical values or units are given here.
Through some rough tests I got the following data:
12000dpi,1000 report rate: the maximum value I measured was about 900
6000dpi,1000 report rate: the maximum value I measured was about 450
12000dpi,125 report rate: the maximum value I measured was about 8000
Although you can see here that the report values and DPI/report rate vary linearly but I still don't know what the report value really means.
This mouse fps(sampling rate?) is 12000,That's up to 12000 counts per second?
But obviously the report value is not number of counts.

How to decode hex into separate bits in Perl?

A byte stored as two hex numbers contains a set of flags. I need to extract these flags, as 0's and 1's. Iterating over entries in a file with:
foreach(<>)
{
#line = split(/ /,$_);
$torR = !!((hex $line[4]) & 0x3); # bit 0 or 1
$torY = !!((hex $line[4]) & 0x4); # bit 2
$torG = !!((hex $line[4]) & 0x8); # bit 3
print "$torR,$torY,$torG\n";
}
run on data file:
796.129 [1f/01] len:7< 02 01 D5 01 8B 0A 8E
796.224 [1f/01] len:7< 02 01 D4 03 09 A9 B8
796.320 [1f/01] len:7< 00 01 D4 03 07 49 5A
796.415 [1f/01] len:7< 00 01 D4 00 11 A0 EE
796.515 [1f/01] len:7< 00 01 D4 00 00 31 4C
796.627 [1f/01] len:7< 02 01 D4 01 89 C1 FD
796.724 [1f/01] len:7< 02 01 D3 03 06 39 FD
796.820 [1f/01] len:7< 08 01 D4 03 08 40 6F
796.915 [1f/01] len:7< 08 01 D5 00 13 3D A4
797.015 [1f/01] len:7< 08 01 D4 00 00 34 04
Actual Result -
1,,
1,,
,,
,,
,,
1,,
1,,
,,1
,,1
,,1
Desired result:
1,0,0
1,0,0
0,0,0
0,0,0
0,0,0
1,0,0
1,0,0
0,0,1
0,0,1
0,0,1
Seems like 'false' gets stored as empty string instead of '0'.
Is there a neat trick to get this right at once, or do I need to convert empty strings to zeros "manually"?
If you want the true/false values to be numeric, you need to coerce them to be numeric:
$torR = 0 + !!((hex $line[4]) & 0x3); # bit 0 or 1
$torY = 0 + !!((hex $line[4]) & 0x4); # bit 2
$torG = 0 + !!((hex $line[4]) & 0x8); # bit 3
Keep in mind that the empty string '' is also a false value.
On the other hand, I might be inclined to write that as:
my (#ryg) = map 0 + !!((hex $line[4]) & $_), 0x3, 0x4, 0x5;
print join(', ', #ryg), "\n";
In addition, you would probably benefit from not using plain numbers in your program. Consider, for example, having a %FLAG structure that gives names to these constants, and a %COL structure that gives names to the columns you are interested in. Using the data you posted:
use Const::Fast;
const my %FLAG => (
torR => 0x3,
torY => 0x4,
torG => 0x5,
);
const my %COL => (
# ...
tor => 4,
);
while (my $line = <DATA>) {
my #line = split ' ', $line;
my %set_flags = map +($_ => 0 + !!((hex $line[$COL{tor}]) & $FLAG{$_})), qw(torR torY torG);
print join(', ', #set_flags{qw(torR torY torG)}), "\n";
}
__DATA__
796.129 [1f/01] len:7< 02 01 D5 01 8B 0A 8E
796.224 [1f/01] len:7< 02 01 D4 03 09 A9 B8
796.320 [1f/01] len:7< 00 01 D4 03 07 49 5A
796.415 [1f/01] len:7< 00 01 D4 00 11 A0 EE
796.515 [1f/01] len:7< 00 01 D4 00 00 31 4C
796.627 [1f/01] len:7< 02 01 D4 01 89 C1 FD
796.724 [1f/01] len:7< 02 01 D3 03 06 39 FD
796.820 [1f/01] len:7< 08 01 D4 03 08 40 6F
796.915 [1f/01] len:7< 08 01 D5 00 13 3D A4
797.015 [1f/01] len:7< 08 01 D4 00 00 34 04
I think I would use split and unpack to turn each value into an array of zeroes and ones, and then examine them individually
use strict;
use warnings 'all';
for my $val ( qw/ 02 02 00 00 00 01 01 08 08 08 / ) {
my #bits = split //, unpack 'b8', chr hex $val;
my $torR = $bits[0] || $bits[1] ? 1 : 0;
my $torY = $bits[2] ? 1 : 0;
my $torG = $bits[3] ? 1 : 0;
print "$torR,$torY,$torG\n";
}
output
1,0,0
1,0,0
0,0,0
0,0,0
0,0,0
1,0,0
1,0,0
0,0,1
0,0,1
0,0,1
Or here's a way using the Bit::Vector which produces the same result
use strict;
use warnings 'all';
use Bit::Vector;
for my $val ( qw/ 02 02 00 00 00 01 01 08 08 08 / ) {
my $vec = Bit::Vector->new_Hex(8, $val);
my $torR = $vec->Chunk_Read(2, 0) ? 1 : 0;
my $torY = $vec->Chunk_Read(1, 2) ? 1 : 0;
my $torG = $vec->Chunk_Read(1, 3) ? 1 : 0;
print "$torR,$torY,$torG\n";
}

What does illegal character in numeric field error concern for Cobol using Unix system?

How to solve the error:
Execution error : file 'prog3.int'
error code: 163, pc=177, call=1, seg=0
163 Illegal character in numeric field
IDENTIFICATION DIVISION.
PROGRAM-ID. prog3.
ENVIRONMENT DIVISION.
Input-output Section.
File-Control.
select input-file assign to
"/home1/c/a/acsi203/realestate.dat".
select output-file assign to "prog3out.dat"
organization is line sequential.
DATA DIVISION.
File Section.
FD Input-File.
01 INPUT-REC.
02 PropertyAddress pic x(27).
02 City pic a(15).
02 Zip pic 9(5).
02 State pic a(2).
02 Bedrooms pic 9.
02 Bathrooms pic 9.
02 SqFt pic 9(4).
02 PropertyType pic x(8).
02 SaleDayofWeek pic a(3).
02 Filler pic x(1).
02 SaleMonth pic a(3).
02 Filler pic x(1).
02 SaleDay pic 9(2).
02 Filler pic x(1).
02 SaleHour pic 9(2).
02 Filler pic x(1).
02 SaleMinute pic 9(2).
02 Filler pic x(1).
02 SaleSecond pic 9(2).
02 Filler pic x(1).
02 TimeZone pic a(3).
02 Filler pic x(1).
02 SaleYear pic 9(4).
02 SalePrice pic 9(6).
02 Filler pic x(18).
FD OUTPUT-FILE.
01 OUTPUT-REC pic x(114).
WORKING-STORAGE SECTION.
01 REPORT-HEADER.
02 Filler pic x(27) value spaces.
02 Filler pic x(66) value
"Sacramento Area Real Estate Transactions-MM/DD/YYYY".
02 Filler pic x(61) value spaces.
01 RECORDS-PROCESSED.
02 Filler pic x(28) value
"Number Of Records Processed:".
02 num-recs pic 9(4) value 0.
02 Filler pic x(15) value spaces.
01 AVERAGE-PROCESSED.
02 Filler pic x(9) value
"Average: ".
02 num-nonzero pic 9(4) value 0.
02 Filler pic x(45) value spaces.
02 BedroomAverage-out pic x(1).
02 Filler pic x(10) value spaces.
02 BathroomAverage-out pic x(1).
02 Filler pic x(18) value spaces.
02 SqFtAverage-out pic $ZZ,ZZ9.99.
02 Filler pic x(4) value spaces.
02 SalePriceAverage-out pic $ZZ,ZZ9.99.
01 END-OF-REPORT.
02 Filler pic x(13) value
"End Of Report".
01 COLUMN-HEADER.
02 Filler pic x(2) value spaces.
02 Filler pic x(16) value "Property Address".
02 Filler pic x(10) value spaces.
02 Filler pic x(4) value "City".
02 Filler pic x(10) value spaces.
02 Filler pic x(5) value "Zip".
02 Filler pic x(1) value spaces.
02 Filler pic x(5) value "State".
02 Filler pic x(2) value spaces.
02 Filler pic x(8) value "Bedrooms".
02 Filler pic x(3) value spaces.
02 Filler pic x(9) value "Bathrooms".
02 Filler pic x(2) value spaces.
02 Filler pic x(4) value "SqFt".
02 Filler pic x(1) value spaces.
02 Filler pic x(13) value "Property Type".
02 Filler pic x(1) value spaces.
02 Filler pic x(13) value "SaleDayOfWeek".
02 Filler pic x(1) value spaces.
02 Filler pic x(9) value "SaleMonth".
02 Filler pic x(1) value spaces.
02 Filler pic x(7) value "SaleDay".
02 Filler pic x(1) value spaces.
02 Filler pic x(8) value "SaleHour".
02 Filler pic x(1) value spaces.
02 Filler pic x(10) value "SaleMinute".
02 Filler pic x(1) value spaces.
02 Filler pic x(10) value "SaleSecond".
02 Filler pic x(1) value spaces.
02 Filler pic x(8) value "TimeZone".
02 Filler pic x(1) value spaces.
02 Filler pic x(8) value "SaleYear".
02 Filler pic x(1) value spaces.
02 Filler pic x(9) value "SalePrice".
02 Filler pic x(1) value spaces.
02 Filler pic x(12) value "PricePerSqFt".
02 Filler pic x(1) value spaces.
02 Filler pic x(5) value "Taxes".
01 INFO-LINE.
02 Filler pic x(3) value spaces.
02 PropertyAddress-out pic x(20).
02 Filler pic x(2) value spaces.
02 City-out pic a(15).
02 Filler pic x(1) value spaces.
02 Zip-out pic 9(6).
02 Filler pic x(2) value spaces.
02 State-out pic a(2).
02 Filler pic x(7) value spaces.
02 Bedrooms-out pic 9.
02 Filler pic x(10) value spaces.
02 Bathrooms-out pic 9.
02 Filler pic x(2) value spaces.
02 SqFt-out pic 9(4).
02 Filler pic x(9) value spaces.
02 PropertyType-out pic x(8).
02 Filler pic x(5) values spaces.
02 SaleDayOfWeek-out pic a(3).
02 Filler pic x(5).
02 SaleMonth-out pic a(3).
02 Filler pic x(5) value spaces.
02 SaleDay-out pic 9(2).
02 Filler pic x(1) value spaces.
02 SaleHour-out pic 9(2).
02 Filler pic x(1) value spaces.
02 SaleMinute-out pic 9(2).
02 Filler pic x(1) value spaces.
02 SaleSecond-out pic 9(2).
02 Filler pic x(2) value spaces.
02 TimeZone-out pic a(3).
02 Filler pic x(1) value spaces.
02 SaleYear-out pic 9(4).
02 Filler pic x(5) value spaces.
02 SalePrice-out pic 9(6).
02 Filler pic x(4) value spaces.
02 PriceSqFtT-out pic $ZZ,ZZ9.99.
02 Filler pic x(2) value spaces.
02 Taxes-out pic 9(5).
01 TEMP-VAR.
02 PriceSqFtT pic 9(5) value zero.
02 PriceSqFtAccum pic 9(6) value zero.
02 BedroomAverage pic 9(1) value zero.
02 BathroomAverage pic 9(1) value zero.
02 SqFtAverage pic 9(6) value zero.
02 SalePriceAverage pic 9(7) value zero.
02 Taxes pic 9(6) value zero.
01 eof-flag pic x(3) value "No".
PROCEDURE DIVISION.
0000-MAIN-LOGIC.
Perform 1000-init.
Perform 2000-main-loop until eof-flag = "yes".
Perform 3000-finish.
stop run.
1000-init.
open input input-file
output output-file.
write output-rec from Report-Header.
write output-rec from Column-Header.
Read input-file at end move "yes" to eof-flag.
2000-main-loop.
DISPLAY INPUT-REC.
move PropertyAddress to PropertyAddress-out.
move City to City-out.
move Zip to Zip-out.
move State to State-out.
move Bedrooms to Bedrooms-out.
move Bathrooms to Bathrooms-out.
move PropertyType to PropertyType-out.
move SalePrice to SalePrice-out.
move SaleDayOfWeek to SaleDayOfWeek-out.
move SaleMonth to SaleMonth-out.
move SaleDay to SaleDay-out.
move SaleHour to SaleHour-out.
move SaleMinute to SaleMinute-out.
move TimeZone to TimeZone-out.
move SaleYear to SaleYear-out.
move SalePrice to SalePrice-out.
divide SalePrice by sqFt giving PriceSqFtT.
Add PriceSqFtT to PriceSqFtAccum.
Move PriceSqFtT to PriceSqFtT-out.
add 1 to num-recs.
if sqft not = 0 and Bedrooms not = 0 and
Bathrooms not = 0 and SalePrice not = 0
add 1 to num-nonzero.
IF city EQUALS "SACRAMENTO" and Bedrooms EQUALS 2
compute Taxes = salePrice * 7.5.
IF city EQUALS "SACRAMENTO" THEN
MULTIPLY salePrice by 6 giving Taxes.
IF city NOT EQUAL "SACRAMENTO"
MULTIPLY salePrice by 6 giving Taxes.
move Taxes to Taxes-out.
divide Bedrooms by num-nonzero giving BedroomAverage.
divide Bathrooms by num-nonzero giving BathroomAverage.
divide SqFt by num-nonzero giving SqFtAverage.
divide SalePrice by num-nonzero giving SalePriceAverage.
move Bedrooms to BedroomAverage-out.
move Bathrooms to BathroomAverage-out.
move SqFt to SqFtAverage-out.
move SalePrice to SalePriceAverage-out.
write output-rec from info-line.
read input-file at end move "yes" to eof-flag.
3000-finish.
write output-rec from Records-processed
write output-rec from AVERAGE-PROCESSED
write output-rec from END-OF-REPORT
close input-file output-file.
**************THE FOLLOWING IS THE OUTPUT PRODUCED WITH THE ERROR***************
1122 WILD POPPY CT GALT 95632 CA 321406 Resident Wed May 21 02:00:00 EDT 2008 178760 38287789121294715
4520 BOMARK WAY SACRAMENTO 95842 CA 421943 Multi-Fa Wed May 21 00:00:00 EDT 2008 179580 38665724121358576
4520 BOBAY PKWAY SACRAMENTO 95842 CA k2194j Multi-Fa Wed May 21 00:00:00 EDT 2008 179580 38665724121358576
Execution error : file 'prog3.int'
error code: 163, pc=189, call=1, seg=0
163 Illegal character in numeric field
**************END OF OUTPUT WITH EXECUTION ERROR***************************
I am creating a Cobol program that computes the lines of information and averages on following input file. However, I keep getting the 'illegal character in numeric field' error and I can't understand why. I am using Unix system to compile and run this. Please help. Very new to this!
Input File: /home1/c/a/acsi203/realestate.dat
Columns Type Data
------- ---- ---------
1-27 Alphanumeric Property Address
28-42 Alphabetic City
43-47 Numeric Zip
48-49 Alphabetic State
50 Numeric Number of Bedrooms
51 Numeric Number of Bathrooms
52-55 Numeric Square Feet
56-63 Alphanumeric Property Type
64-66 Alhpabetic Sale Day of Week
68-70 Alphabetic Sale Month
72-73 Numeric Sale Day
75-76 Numeric Sale Hour
78-79 Numeric Sale Minute
81-82 Numeric Sale Second
84-86 Alphabetic Time Zone
88-91 Numeric Sale Year
92-97 Numeric Sale Price
98-105 Numeric Property Latitude (2 places to left)
106-114 Numeric Property Longitude(2 places to left)
You have a missing FILLER PIC X after the Zip. You need to go through with the actual data and make sure that all the fields line up with your definitions. Don't rely on the written definitions you included. The data is what it really is. Now that comments aren't compressing spaces, the long and lat can go back, but note that they are not numeric-edited fields as you previously described.
You are using a Micro Focus COBOL.
Here, http://supportline.microfocus.com/kbdocs/KBdo4363.HTM, is a description of your error code.
Here, is the relevant quote for your problem:
Every value you attempt to move to a numeric or numeric edited field is checked to ensure that it is numeric.
You have now edited your question to show that your Longitude and Latitude fields are numeric-edited fields. That means they are not numeric. So when you attempt:
move PropertyLatitude to PropertyLatitude-out.
You will get that message.
Of course, this presumes that your definition of that field matches the data.
Why are you moving those two fields to two two-digit numeric fields in your report?
This does not answer your question, but I thought I should bring to your attention that the rules for taxes in your code do not make sense (see below). The second if statement will always replace the results of the first if statement. If this code is really producing the outcome you want, you could get the same result by replacing all 6 lines of code with one line: MULTIPLY salePrice by 6 giving Taxes.
IF city EQUALS "SACRAMENTO" and Bedrooms EQUALS 2
compute Taxes = salePrice * 7.5.
IF city EQUALS "SACRAMENTO" THEN
MULTIPLY salePrice by 6 giving Taxes.
IF city NOT EQUAL "SACRAMENTO"
MULTIPLY salePrice by 6 giving Taxes.

APDU: "Conditions of use not satisfied" (69 85) while calculate signature

With a smart card Gemalto (IAS ECC), I would to calculate a signature by using private key stored on smart card. For this, I use APDU commands:
// Verify PIN
00 20 00 01 04 31 32 33 34
-> 90 00
// Create a context for security operation
00 22 41 B6 06 84 01 84 80 01 12
-> 90 00
// Set the hash of the document
00 2A 90 A0 14 HASH OF DOCUMENT
-> 69 85
// Calculating the signature
00 2A 9E 9A 80
-> 69 85
My problem is the following: the las two commands return the error code "69 85", meaning "Conditions of use not satisfied".
I have already tried several solutions, but I obtain always the same error. How to resolve it? What does this code can mean?
After some tests, I discovered something interesting. When I replace cla "00" by "10", smart card returns a different response:
// Create a context for security operation
00 22 41 B6 06 84 01 84 80 01 12
// Verify PIN
00 20 00 01 04 31 32 33 34
// Calculating the signature (I replace "00" by "10")
10 2A 9E 9A 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 12 13 14 15
I don't know if it's the good solution because smart card returns "90 00". But, it would return the content of my signature!
Thank you for your help!
Best regards
You are getting SW 6985 for
// Set the hash of the document
00 2A 90 A0 14 HASH OF DOCUMENT
-> 69 85
Since you have not set the correct context in current security environment.
Let me explain this below
First you performed VERIFY PIN command which was successful
// Verify PIN
00 20 00 01 04 31 32 33 34
-> 90 00
Then you performed MSE SET command,Where you set the security context.For this you have to understood how SE works(Please refer to section 3.5 fron IAS ECC v1.01).
At the time of personalisation, the Personaliser agent create SDO(Secure Data Object) inside the card.The reference to this SDO are mentioned in SE(Security Environment) in form of CRT(Control reference template).
// Create a context for security operation
00 22 41 B6 06 84 01 84 80 01 12
-> 90 00
Generally speaking, MSE SET command will always return SW 900 even if the SDO reference is wrong. Since it only return SW 6A80 when the template is wrong not when the reference is wrong.(The SDO reference is passed in tag 84)
After that you performed PSO HASH command
// Set the hash of the document
00 2A 90 A0 14 HASH OF DOCUMENT
-> 69 85
where the card return SW 6985(Condition of use not satisfied), This indicate the algorithm and SDO reference used for calculating Hash may wrong. Which is probably happening since the SDO reference which was sent during the time of MSE SET command is not available
Detecting error coming from MSE SET could be tricky since it return SW 9000.
For these type of situation you have to check the personalisation file carefully and need to match the MSE SET command with regard to SDO reference and supported ALGOs.
It may be useful to put the default context (e.g., cryptographic algorithms or
security operations) into the current SE in order to have few exchanges of MSE set commands.

sed search and replace specific column only

Im taking weather day from wunderground.com and I and then trimming down the data for use on gnuplot. Im having trouble replacing the second column only data from number to months abbreviations. Only interested in the second column.
I want to go from this;
>2013 08 02 23 37 00 73.3
>2013 08 02 23 42 00 73.4
>2013 08 02 23 45 00 73.3
>2013 08 02 23 47 00 73.1
>2013 08 02 23 52 00 73.1
>2013 08 02 23 57 00 73.1
To this:
>2013 AUG 02 23 37 00 73.3
>2013 AUG 02 23 42 00 73.4
>2013 AUG 02 23 45 00 73.3
>2013 AUG 02 23 47 00 73.1
>2013 AUG 02 23 52 00 73.1
>2013 AUG 02 23 57 00 73.1
i am trying to use sed to change the numbers into the correct month and i keep getting this. I only want the correct sed expression to execute not all of them. This is the command i am trying to use.
sed -e 's/01/JAN/' -e 's/02/FEB/' -e 's/03/MAR/' -e 's/04/APR/' -e 's/05/MAY/' -e 's/06/JUN/' -e 's/07/JUL/' -e 's/08/AUG/' -e 's/09/SEP/' -e 's/10/OCT/' -e 's/11/NOV/' -e 's/12/DEC/'
How would i go about this.
This might work for you (GNU sed):
sed -nri 'G;s/$/01JAN02FEB03MAR04APR05MAY06JUN07JUL08AUG09SEP10OCT11NOV12DEC/;s/ (..)(.*)\1(...)/ \3\2/;P' file
This adds a lookup table to the end of each line and substitutes the key for the value.
I would use awk for this:
$ awk 'BEGIN{split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",a)} {$2=a[$2+0]}1' a
>2013 Aug 02 23 37 00 73.3
>2013 Aug 02 23 42 00 73.4
>2013 Aug 02 23 45 00 73.3
>2013 Aug 02 23 47 00 73.1
>2013 Aug 02 23 52 00 73.1
>2013 Aug 02 23 57 00 73.1
To update the field with the new content, just redirect and then move:
awk .... file > temp_file && mv temp_file file
Explanation
What we do is to give awk a list of strings with the months names. Once we convert it into an array, a[1] will be Jan, a[2] Feb and so on. So then it is just a matter of replacing the 2nd field with a[2nd field].
BEGIN{split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",a)} fetches the data and inserts into the a[] array.
{$2=a[$2+0]} sets the 2nd field as a[2nd field]. The $2+0 is done to convert 08 to 8.
Finally 1 evaluates as true and makes awk perform its default action: {print $0}.
Workaround that works for this problem (since your first column is very predictable) but not the general question:
sed -E -e 's/^([0-9]{4}) 01/\1 JAN/' -e 's/^([0-9]{4}) 02/\1 FEB/' etc.
awk has a sub function that could get unwieldy for many options you have here.
Perl scripts might be the best way to go.
$ awk '{$2=substr("JanFebMarAprMayJunJulAugSepOctNovDec",(3*$2)-2,3)}1' file
>2013 Aug 02 23 37 00 73.3
>2013 Aug 02 23 42 00 73.4
>2013 Aug 02 23 45 00 73.3
>2013 Aug 02 23 47 00 73.1
>2013 Aug 02 23 52 00 73.1
>2013 Aug 02 23 57 00 73.1
Since it came up in a comment:
The idiomatic awk way to map from a month number to a name is:
number = (match("JanFebMarAprMayJunJulAugSepOctNovDec",<name>)+2)/3
and the above is just the natural inverse of that:
name = substr("JanFebMarAprMayJunJulAugSepOctNovDec",(3*<number>)-2,3)
Like with anything in awk there's various ways to get the output you want but IMHO the symmetry here makes it an attractive solution:
awk 'BEGIN{
months = "JanFebMarAprMayJunJulAugSepOctNovDec"
name = "Jul"
number = (match(months,name)+2)/3
print name " -> " number
name = substr(months,(3*number)-2,3)
print number " -> " name
}'
Jul -> 7
7 -> Jul
Notice that the script uses the same definition for months no matter which direction the conversion is being done and it's a similar math calculation in both directions.
Nothing wrong with doing it this way too of course:
awk 'BEGIN{
split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",num2name)
for (number in num2name) {
name2num[num2name[number]] = number
}
name = "Jul"
number = name2num[name]
print name " -> " number
name = num2name[number]
print number " -> " name
}'
Jul -> 7
7 -> Jul
Just a few more lines of code, nbd.
Using gnu awk's function strftime() and mktime()
awk '{$2=strftime("%b",mktime("2014 " $2 " 1 1 0 0"))}1' file
>2013 Aug 02 23 37 00 73.3
>2013 Aug 02 23 42 00 73.4
>2013 Aug 02 23 45 00 73.3
>2013 Aug 02 23 47 00 73.1
>2013 Aug 02 23 52 00 73.1
>2013 Aug 02 23 57 00 73.1
Explanation
mktime("2014 " $2 " 1 1 0 0") fake the epoch time, use the column 2 as month
strftime("%b",mktime("2014 " $2 " 1 1 0 0")) convert the epoch back to the date, with %b, export the abbreviated month name (Jan, Feb, etc)
The benefit with this awk:
It is shorter, of course. Second, you can control/adjust the format in strftime() to export any date format you like.
For example, if change to full month name %B. You needn't rewrite the code.
awk '{$2=strftime("%B",mktime("2014 " $2 " 1 1 0 0"))}1' file