1 OPTION TYPE=EXPLICIT ! BASIC_CREATE_STATS.BAS ! ! Program to process the input drawing data file ! and generate 2 statistics files. ! ! Flow: ! Read every record from the drawing file. ! For each record update both statistics arrays. ! Upon completion of input file, close it. ! Calculate over-all stats values updating arrays. ! Write new statistics index files. ! %INCLUDE "MEGA_INC:MEGA_RECS.INC" %INCLUDE "LIB$ROUTINES" %FROM %LIBRARY !;;;;;;;;;; ! Constants !;;;;;;;;;; DECLARE BYTE CONSTANT draw_chan% = 6% DECLARE BYTE CONSTANT dstat_chan% = 7% DECLARE BYTE CONSTANT mstat_chan% = 8% DECLARE BYTE CONSTANT elm_count% = 52% DECLARE STRING CONSTANT drawing_data$ = "MY_MEGA_FILE", & drawing_stats$ = "DRAWING_STATS", & mega_stats$ = "MEGA_STATS" !;;;;;;;;;; ! Maps !;;;;;;;;;; MAP (LOCAL_MAP) STRING TRANSLATED_NAME$ = 255%, & FILE_NAME$ = 255% MAP (DRAW_MAP) DRAWING_RECORD DRAW_REC MAP (D_STAT_MAP) ZILLIONARE_STATS_RECORD D_STAT MAP (M_STAT_MAP) ZILLIONARE_STATS_RECORD M_STAT !;;;;;;;;;; ! Local Variables !;;;;;;;;;; DIM ZILLIONARE_STATS_RECORD D_STATS( elm_count%) DIM ZILLIONARE_STATS_RECORD M_STATS( elm_count%) DECLARE BYTE B_EOF% DECLARE WORD W_X% DECLARE LONG L_X%, L_ERR%, L_DRAW_NO%, L_MISSED%, L_SUB% DECLARE STRING WORK_STR$, LOG_TXT$ !;;;;;;;;;; ! Main Logic !;;;;;;;;;; 100 GOSUB A900_FILL_IN_LOGICALS L_ERR% = 0% GOSUB A910_OPEN_FILES IF L_ERR% = 0% THEN GOSUB A930_READ_TO_EOF GOSUB A940_GENERATE_STATS GOSUB A950_WRITE_STATS END IF GOTO PROGRAM_EXIT 900 !;;;;;;;;;; ! Subroutine to fill in logical values ! Ordinarily developers simply "assume" that either ! logicals have been defined or do so in a job stream ! but this will allow the demonstration of service calls. !;;;;;;;;;; A900_FILL_IN_LOGICALS: WORK_STR$ = drawing_data$ TRANSLATED_NAME$ = " " ! destination has to be pre-allocated W_X% = 0% L_X% = LIB$GET_LOGICAL( WORK_STR$, TRANSLATED_NAME$, W_X%,,,,) IF LEN( TRM$( TRANSLATED_NAME$)) < 1 THEN LOG_TXT$ = drawing_data$ + ".IDX" L_X% = LIB$SET_LOGICAL( WORK_STR$, LOG_TXT$,,,) END IF WORK_STR$ = drawing_stats$ TRANSLATED_NAME$ = " " ! destination has to be pre-allocated W_X% = 0% L_X% = LIB$GET_LOGICAL( WORK_STR$, TRANSLATED_NAME$,,,,) IF LEN( TRM$( TRANSLATED_NAME$)) < 1 THEN LOG_TXT$ = drawing_stats$ + ".IDX" L_X% = LIB$SET_LOGICAL( WORK_STR$, LOG_TXT$,,,) END IF WORK_STR$ = mega_stats$ TRANSLATED_NAME$ = " " ! destination has to be pre-allocated W_X% = 0% L_X% = LIB$GET_LOGICAL( WORK_STR$, TRANSLATED_NAME$,,,,) IF LEN( TRM$( TRANSLATED_NAME$)) < 1 THEN LOG_TXT$ = mega_stats$ + ".IDX" L_X% = LIB$SET_LOGICAL( WORK_STR$, LOG_TXT$,,,) END IF RETURN 910 !;;;;;;;;;; ! Subroutine to open indexed files !;;;;;;;;;; A910_OPEN_FILES: WHEN ERROR IN L_ERR% = 0% OPEN drawing_data$ FOR INPUT AS FILE #draw_chan%, & ORGANIZATION INDEXED FIXED, & ALLOW NONE, & RECORDTYPE FORTRAN, & RECORDSIZE drawing_record_size, & MAP DRAW_MAP USE L_ERR% = ERR PRINT "Unable to open input file"; drawing_data$ PRINT "Error: ";L_ERR%;" ";ERT$( L_ERR%) END WHEN RETURN IF L_ERR% <> 0% WHEN ERROR IN L_ERR% = 0% OPEN drawing_stats$ FOR OUTPUT AS FILE #dstat_chan%, & ORGANIZATION INDEXED FIXED, & ALLOW NONE, & RECORDTYPE FORTRAN, & RECORDSIZE zillionare_stats_record_size, & PRIMARY KEY D_STAT::ELM_NO, & MAP D_STAT_MAP USE L_ERR% = ERR PRINT "Unable to open drawing stat output file"; drawing_stats$ PRINT "Error: ";L_ERR%;" ";ERT$( L_ERR%) END WHEN WHEN ERROR IN L_ERR% = 0% OPEN mega_stats$ FOR OUTPUT AS FILE #mstat_chan%, & ORGANIZATION INDEXED FIXED, & ALLOW NONE, & RECORDTYPE FORTRAN, & RECORDSIZE zillionare_stats_record_size, & PRIMARY KEY M_STAT::ELM_NO, & MAP M_STAT_MAP USE L_ERR% = ERR PRINT "Unable to open mega stat output file"; mega_stats$ PRINT "Error: ";L_ERR%;" ";ERT$( L_ERR%) END WHEN RETURN 930 !;;;;;;;;;; ! Subroutine to load up the basic stats of hit counts !;;;;;;;;;; A930_READ_TO_EOF: L_DRAW_NO% = 0% B_EOF% = 0% !;;;;; ! Get first record via index to establish a key of refference !;;;;; WHEN ERROR IN GET #draw_chan%, KEY # 0% GE " " USE L_ERR% = ERR B_EOF% = 1% PRINT "Error getting first record from file" PRINT "Error: ";L_ERR%;" ";ERT$( L_ERR%) END WHEN !;;;;; ! Sequentially loop until end of file !;;;;; WHILE B_EOF% = 0% L_DRAW_NO% = L_DRAW_NO% + 1% IF MOD(L_DRAW_NO%,100%) = 0% THEN PRINT "Processed ";L_DRAW_NO%;" records" END IF GOSUB B1000_UPDATE_DRAW_STATS GOSUB B1100_UPDATE_MEGA_STATS WHEN ERROR IN GET #draw_chan% ! sequential get this time USE L_ERR% = ERR B_EOF% = 1% IF L_ERR% <> 11% ! not end of file THEN PRINT "Error getting first record from file" PRINT "Error: ";L_ERR%;" ";ERT$( L_ERR%) END IF END WHEN NEXT ! end while b_eof loop RETURN 940 !;;;;;;;;;; ! Subroutine to generate over all stats on both arrays !;;;;;;;;;; A940_GENERATE_STATS: FOR L_X%=1% TO elm_count% ! ! Drawing stats ! D_STATS( L_X%)::PCT_HITS = REAL( D_STATS( L_X%)::HIT_COUNT) & / REAL( L_DRAW_NO%) L_MISSED% = L_DRAW_NO% - D_STATS( L_X%)::HIT_COUNT D_STATS( L_X%)::AVE_BTWN = REAL( L_MISSED%) & / REAL( D_STATS( L_X%)::HIT_COUNT) D_STATS( L_X%)::SINCE_LAST = L_DRAW_NO% - D_STATS( L_X%)::LAST_DRAW_NO ! ! Mega Stats ! M_STATS( L_X%)::PCT_HITS = REAL( M_STATS( L_X%)::HIT_COUNT) & / REAL( L_DRAW_NO%) L_MISSED% = L_DRAW_NO% - M_STATS( L_X%)::HIT_COUNT M_STATS( L_X%)::AVE_BTWN = REAL( L_MISSED%) & / REAL( M_STATS( L_X%)::HIT_COUNT) M_STATS( L_X%)::SINCE_LAST = L_DRAW_NO% - M_STATS( L_X%)::LAST_DRAW_NO NEXT L_X% RETURN 950 !;;;;;;;;;; ! Subroutine to write out stats records to files !;;;;;;;;;; A950_WRITE_STATS: FOR L_X%=1% TO elm_count% WHEN ERROR IN L_ERR% = 0% D_STATS( L_X%)::ELM_NO = L_X% D_STAT = D_STATS( L_X%) PUT #dstat_chan% USE L_ERR% = ERR PRINT "Error writing dstat record" PRINT "Error: ";L_ERR%;" ";ERT$( L_ERR%) END WHEN WHEN ERROR IN L_ERR% = 0% M_STATS( L_X%)::ELM_NO = L_X% M_STAT = M_STATS( L_X%) PUT #mstat_chan% USE L_ERR% = ERR PRINT "Error writing mstat record" PRINT "Error: ";L_ERR%;" ";ERT$( L_ERR%) END WHEN NEXT L_X% RETURN 1000 !;;;;;;;;;; ! Subroutine to update the drawing stats records !;;;;;;;;;; B1000_UPDATE_DRAW_STATS: L_SUB% = DRAW_REC::NO_1 GOSUB C2000_DSTAT_UPDATE L_SUB% = DRAW_REC::NO_2 GOSUB C2000_DSTAT_UPDATE L_SUB% = DRAW_REC::NO_3 GOSUB C2000_DSTAT_UPDATE L_SUB% = DRAW_REC::NO_4 GOSUB C2000_DSTAT_UPDATE L_SUB% = DRAW_REC::NO_5 GOSUB C2000_DSTAT_UPDATE RETURN 1100 !;;;;;;;;;; ! Subroutine to update Mega Number stats ! ! Only one Mega Number per drawing so no need for a subroutine !;;;;;;;;;; B1100_UPDATE_MEGA_STATS: L_SUB% = DRAW_REC::MEGA_NO L_X% = L_DRAW_NO% = M_STATS( L_SUB%)::LAST_DRAW_NO !;;;;; ! Are we in a sequence of hits or just a random hit? !;;;;; IF L_X% = 0% THEN M_STATS( L_SUB%)::CURR_SEQ = M_STATS( L_SUB%)::CURR_SEQ + 1% IF M_STATS( L_SUB%)::CURR_SEQ > M_STATS( L_SUB%)::LONGEST_SEQ THEN M_STATS( L_SUB%)::LONGEST_SEQ = M_STATS( L_SUB%)::CURR_SEQ END IF ELSE IF L_X% > M_STATS( L_SUB%)::MAX_BTWN THEN M_STATS( L_SUB%)::MAX_BTWN = L_X% END IF END IF M_STATS( L_SUB%)::HIT_COUNT = M_STATS( L_SUB%)::HIT_COUNT + 1% M_STATS( L_SUB%)::LAST_DRAW_NO = L_DRAW_NO% M_STATS( L_SUB%)::SINCE_LAST = L_X% RETURN 2000 !;;;;;;;;;; ! Subroutine to update d_stats array from single value !;;;;;;;;;; C2000_DSTAT_UPDATE: L_X% = L_DRAW_NO% = D_STATS( L_SUB%)::LAST_DRAW_NO !;;;;; ! Are we in a sequence of hits or just a random hit? !;;;;; IF L_X% = 0% THEN D_STATS( L_SUB%)::CURR_SEQ = D_STATS( L_SUB%)::CURR_SEQ + 1% IF D_STATS( L_SUB%)::CURR_SEQ > D_STATS( L_SUB%)::LONGEST_SEQ THEN D_STATS( L_SUB%)::LONGEST_SEQ = D_STATS( L_SUB%)::CURR_SEQ END IF ELSE IF L_X% > D_STATS( L_SUB%)::MAX_BTWN THEN D_STATS( L_SUB%)::MAX_BTWN = L_X% END IF END IF D_STATS( L_SUB%)::HIT_COUNT = D_STATS( L_SUB%)::HIT_COUNT + 1% D_STATS( L_SUB%)::LAST_DRAW_NO = L_DRAW_NO% D_STATS( L_SUB%)::SINCE_LAST = L_X% RETURN 32767 ! End of module PROGRAM_EXIT: WHEN ERROR IN CLOSE #mstat_chan% USE ! ignore error on close END WHEN WHEN ERROR IN CLOSE #draw_chan% USE ! ignore error on close END WHEN WHEN ERROR IN CLOSE #dstat_chan% USE ! ignore error on close END WHEN END