home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 138 / pascal / stats.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-05-13  |  45.5 KB  |  1,961 lines

  1. program STATS;
  2.  
  3.  
  4. {
  5.  
  6.    AUTHOR : Gary Curtis Newport
  7.             27808 Manon Ave # 18
  8.             Hayward, CA 94544
  9.  
  10.   COMPUTER: Atari 1040 ST
  11.  
  12.   LANGUAGE: Personal Pascal
  13.             Optimised Systems Software
  14.             1221 B Kentwood Ave
  15.             San Jose, CA 95129
  16.  
  17.  
  18.    This program does one statistical task--it calculates the mean and
  19.    standard deviation of a set of numbers--but allows great flexibility
  20.    to the user while accomplishing that task.  Numbers may be entered
  21.    from the keyboard or read from a disk file.  Once entered, the
  22.    numbers can be edited, saved to disk or printed in their original
  23.    order or in sorted order.  The calculated results can be displayed
  24.    on the screen and then printed out.  A bar chart of the frequency
  25.    distribution can be displayed or printed.  Several help screens are
  26.    available from the menu to explain these options.  Numbers entered
  27.    from the keyboard are validated upon entry, and a non-numeric entry
  28.    brings up an alert box which offers the option to stop data entry
  29.    and go on to some other function, or to edit the numbers already
  30.    entered.  The program is designed to run in medium resolution, but
  31.    will probably work fine in high resolution IF the call to load the
  32.    medium resolution Degas title is omitted.
  33.  
  34.    For Pascal programmers, the source code offers a number of potentially
  35.    useful examples.  Besides menus, alert boxes and dialog boxes, there
  36.    are: use of a DEGAS picture as a title page, cursor control, saving
  37.    screens (to avoid redrawing), checking monitor resolution, checking
  38.    whether the printer is online, help screens, use of library routines,
  39.    and one or two other things.
  40.  
  41.    Note that the DEGAS picture file, TITLE.PI2, must be available
  42.    to the program when run, and that a folder, INCLIB, must
  43.    be available, and must contain the appropriate routines, when
  44.    compiling the program.
  45.  
  46.    I must apologise for the condition of the source code: it is poorly
  47.    commented and there are stylistic inconsistencies.  The slovenly
  48.    state of the source is primarily due to the fact that I wrote the
  49.    program as an exercise in learning GEM manipulation from Personal
  50.    Pascal and not as an exercise in software engineering.
  51.  
  52.    The first rule of programming is: "steal from the best," so I want
  53.    to acknowledge the folks at Optimised Systems Software, and
  54.    especially the OSS bulletin board, as well as Jinfu Chen and
  55.    several anonymous Pascalites on CompuServe and elsewhere, for
  56.    offering something worth stealing.  The Public Domain belongs to
  57.    all of us: do your part to keep it healthy!
  58.  
  59. }
  60.  
  61.  
  62.    CONST
  63.  
  64.       {$I gemconst }
  65.  
  66.       Max_array_size   = 1000;
  67.       space            = ' ';
  68.       Desk_title       = 3;
  69.       bell             = 7;
  70.  
  71.       Max_lines        = 18;  {                  }
  72.       MaxPlusOne       = 19;  {  Page control    }
  73.       Max_chars        = 80;  {                  }
  74.       Offset           = 4;   {                  }
  75.  
  76.       ShowWhite        = 0 ;  {                  }
  77.       ShowRed          = 1 ;  {  Display colors  }
  78.       ShowGreen        = 2 ;  {                  }
  79.       ShowBlack        = 3 ;  {                  }
  80.  
  81.    TYPE
  82.  
  83.       {$I gemtype }
  84.  
  85.       Xarraytype        = array [1..Max_array_size] of real;
  86.       NumStrType        = array [1..80] of char;
  87.  
  88.    VAR
  89.  
  90.                    {    PROGRAM VARIABLES   }
  91.  
  92.       Data,
  93.       Sorted_data      : Xarraytype;
  94.  
  95.       Mean,
  96.       Std_dev,
  97.       Sample_Std_Dev,
  98.       Median           : real;
  99.       index,
  100.       WrapIndex,
  101.       N                : integer;      { counts input values }
  102.       Numeric_chrs     : set of char;
  103.       Done             : boolean;
  104.       DataSetName      : Str255;
  105.  
  106.  
  107.                    {    GEM VARIABLES   }
  108.  
  109.  
  110.       Msg              : Message_Buffer;
  111.       The_menu         : Menu_Ptr;
  112.  
  113.       Help,                 { menu title }
  114.       Option,               { menu title }
  115.       Instructions,         { menu item  }
  116.       HelpEnter,            { menu item  }
  117.       HelpRead,             { menu item  }
  118.       HelpEdit,             { menu item  }
  119.       HelpGraph,            { menu item  }
  120.       Enter_data,           { menu item  }
  121.       Read_data,            { menu item  }
  122.       Edit_data,            { menu item  }
  123.       View_sorted,          { menu item  }
  124.       Calc_results,         { menu item  }
  125.       Show_graph,           { menu item  }
  126.       Print_results,        { menu item  }
  127.       Print_graph,          { menu item  }
  128.       Print_sorted_data,    { menu item  }
  129.       Print_raw_data,       { menu item  }
  130.       Save_sorted_data,     { menu item  }
  131.       Save_raw_data,        { menu item  }
  132.       Exit_stats,           { menu item  }
  133.  
  134.       what_key,
  135.       resolution,
  136.       dummy,
  137.       event,
  138.       event_mask         : integer;
  139.  
  140.  
  141.  
  142.               {    PROCEDURES AND FUNCTIONS    }
  143.  
  144.  
  145. {$I gemsubs         }
  146. {$I INCLIB\MIN      }
  147. {$I INCLIB\MEANSTD  }
  148. {$I INCLIB\STR_REAL }
  149. {$I INCLIB\COUNTDIG }
  150. {$I INCLIB\CURSOR   }
  151. {$I INCLIB\GOTOXY   }
  152.  
  153.  
  154. function
  155. GetRez    : integer;
  156.  
  157.    XBIOS( 4 );
  158.  
  159.  
  160.  
  161.  
  162. procedure
  163. Initialize;
  164.  
  165.    VAR
  166.  
  167.       i     : integer;
  168.  
  169.  
  170. BEGIN {INITIALIZE}
  171.  
  172. Numeric_chrs := [ '-', '.'] + [ '0'..'9' ];
  173. Done := false;
  174. index := 0;
  175. N := 0;
  176. WrapIndex := 0;
  177.  
  178.  
  179. Event_mask := E_Message |  E_Keyboard;
  180. Menu_disable( The_menu, Edit_data);
  181. Menu_disable( The_menu, View_sorted);
  182. Menu_disable( The_menu, Calc_results);
  183. Menu_disable( The_menu, Show_graph);
  184. Menu_disable( The_menu, Print_results);
  185. Menu_disable( The_menu, Print_graph);
  186. Menu_disable( The_menu, Save_sorted_data);
  187. Menu_disable( The_menu, Save_raw_data );
  188. Menu_disable( The_menu, Print_sorted_data);
  189. Menu_disable( The_menu, Print_raw_data);
  190.  
  191. END;  {INITIALIZE}
  192.  
  193.  
  194. function
  195. GetPrinterStatus : long_integer;
  196.  
  197. GEMDOS($11);
  198.  
  199.  
  200.  
  201.  
  202.  
  203. procedure
  204. Show_ProgName;
  205.  
  206. BEGIN {SHOW_PROGNAME}
  207.  
  208.    dummy := Do_alert(
  209.  
  210. '[0][STATS|Version 1.4|By Gary C. Newport|Written in OSS PERSONAL PASCAL][OK]'
  211.                    ,1)
  212.  
  213. END; {SHOW_PROGNAME}
  214.  
  215.  
  216. procedure
  217. Ask_DS_Name;
  218.  
  219.    CONST
  220.  
  221.       sf          = System_Font;
  222.  
  223.    VAR
  224.  
  225.       DialogBox   : Dialog_ptr;
  226.       pushed,
  227.       ok_button,
  228.       DItem       : integer;
  229.  
  230. BEGIN {ASK_DS_NAME}
  231.  
  232. DialogBox := New_Dialog( 8, 0, 0, 40, 10 );
  233. DItem := Add_DItem(DialogBox, G_Text, none, 2, 1,36, 1, 0, $1180);
  234. Set_DText( DialogBox, DItem,
  235.            'Enter the name of your data set :', sf, TE_Left);
  236. DItem := Add_DItem(DialogBox, G_FBoxText, Editable, 2, 3, 36, 2, 0, $1180);
  237. Set_DEdit( DialogBox, DItem,
  238.           '______________________________',
  239.           'nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn',
  240.           '',
  241.           sf, TE_Center
  242.          );
  243. ok_button := Add_DItem(DialogBox, G_Button, Exit_Btn | Selectable,
  244.                        18, 7, 4, 2, 0, $1180
  245.                       );
  246. Set_DText( DialogBox, ok_button, 'OK', sf, TE_Center );
  247. Center_Dialog( DialogBox );
  248. pushed := Do_Dialog( DialogBox, DItem );
  249. Get_DEdit( DialogBox, DItem, DataSetName );
  250. End_Dialog( DialogBox );
  251.  
  252. END; {ASK_DS_NAME}
  253.  
  254.  
  255.  
  256. procedure
  257. Erase_Page;
  258.  
  259.    VAR
  260.        i    : integer;
  261.  
  262. BEGIN {ERASE_PAGE}
  263.  
  264. Hide_mouse;
  265. Gotoxy( 1, Offset - 1 );
  266. ClrEos;
  267. Show_mouse;
  268.  
  269. END; {ERASE_PAGE}
  270.  
  271.  
  272.  
  273. procedure
  274. Erase_Commands;
  275.  
  276.    CONST
  277.  
  278.       CommandLine = 23;
  279.  
  280.  
  281. BEGIN {ERASE_COMMANDS}
  282.  
  283. Hide_mouse;
  284. Gotoxy( 1, CommandLine );
  285. ClrEos;
  286. Show_mouse
  287.  
  288. END; {ERASE_COMMANDS}
  289.  
  290.  
  291. procedure
  292. SelectSort ( VAR Data, Sorted_Data : XarrayType );
  293.  
  294.    VAR
  295.  
  296.       i, j, k   : integer;
  297.       small       : real;
  298.  
  299. BEGIN {SELECTSORT}
  300.  
  301. Sorted_data := Data;
  302.  
  303. For i := 1 to N - 1 do begin
  304.    k := i;
  305.    small := Sorted_Data [ i ];
  306.  
  307.    For j := i + 1 to N do
  308.       If Sorted_Data [ j ] < small then
  309.          begin
  310.             k := j;
  311.             small := Sorted_Data [ j ]
  312.          end; {If}
  313.  
  314.       Sorted_Data [ k ] := Sorted_data [ i ];
  315.       Sorted_Data [ i ] := small;
  316. end {For i }
  317.  
  318. END; {SELECTSORT}
  319.  
  320.  
  321.  
  322. procedure
  323. Is_There_More ( VAR More : boolean;
  324.                 VAR Edit : boolean
  325.               );
  326.  
  327.  
  328.    VAR
  329.  
  330.       Response          : integer;
  331.  
  332.  
  333. BEGIN {IS_THERE_MORE}
  334.  
  335. Response := Do_Alert(
  336.  
  337. '[2][MORE data|DONE entering|EDIT this page    ][ MORE | DONE | EDIT ]'
  338.                    ,0);
  339.  
  340. More := ( Response = 1 );
  341. Edit := ( Response = 3 )
  342.  
  343. END; {IS_THERE_MORE}
  344.  
  345.  
  346. procedure
  347. Get_Index   ( VAR index     : integer;
  348.                   LowValue  : integer;
  349.                   Highvalue : integer;
  350.               VAR GoodIndex : boolean
  351.            );
  352.  
  353.    VAR
  354.  
  355.       Temp      : integer;
  356.       RealTemp  : real;
  357.  
  358.  
  359. BEGIN {GET_INDEX}
  360.  
  361. Get_Num(RealTemp, GoodIndex);
  362. Temp := trunc(RealTemp);
  363. If (GoodIndex
  364. And (Temp >= LowValue)
  365. And (Temp <= HighValue)) then
  366.    index := Temp
  367. Else
  368.    GoodIndex := false
  369.  
  370. END; {GET_INDEX}
  371.  
  372.  
  373.  
  374.  
  375. procedure
  376. Edit_Item(
  377.           VAR item       : integer;
  378.           VAR Data       : Xarraytype;
  379.               PageNum    : integer;
  380.           VAR N          : integer;
  381.           VAR Change     : boolean;
  382.           VAR Delete     : boolean;
  383.           VAR Cancel     : boolean
  384.           );
  385.  
  386.    CONST
  387.  
  388.       A_Change     = 1;
  389.       A_Delete     = 1;
  390.       A_Cancel     = 2;
  391.       NullChoice   = 0;
  392.  
  393.    VAR
  394.  
  395.       i,
  396.       Choice,
  397.       Topline,
  398.       Bottomline   : integer;
  399.       Temp         : real;
  400.       GoodIndex,
  401.       GoodValue    : boolean;
  402.  
  403. BEGIN {EDIT_ITEM}
  404.  
  405. If PageNum = 1 then
  406.    Topline := 1
  407. Else
  408.    Topline := (PageNum - 1) * Max_lines;
  409. Bottomline := Min_Int( (PageNum * Max_lines), (N + 1) );
  410. Gotoxy(40,23);
  411. write('topline = ',topline, ' p ',PageNum);
  412. gotoxy(40,24);
  413. write('bottom line = ',bottomline);
  414.  
  415. Choice := Do_Alert(
  416.  
  417. '[2][ Change item| Delete item][ CHANGE | DELETE ]'
  418.                , 0 );
  419. If (Choice = A_Change) then
  420.    begin
  421.       change := true;
  422.       delete := false;
  423.       cancel := false;
  424.       Gotoxy( 1, 23 );
  425.       TextColor(ShowRed);
  426.       write('Change which datum? ');
  427.  
  428.       Repeat
  429.          Gotoxy(22, 23 );
  430.          ClrEol;
  431.          CursOn;
  432.          Get_Index( item, Topline, Bottomline, GoodIndex );
  433.          If not GoodIndex then
  434.             begin
  435.                write( Chr(bell) );
  436.                Choice := Do_Alert(
  437.  
  438.    '[3][You can only change |data on this page][ CHANGE | CANCEL ]',
  439.                          2)
  440.  
  441.              end; {If}
  442.          Cancel := ( Choice = A_Cancel );
  443.          Change := ( Not Cancel )
  444.       Until (GoodIndex
  445.       Or     Cancel    );
  446.  
  447.       CursOff;
  448.       TextColor(ShowBlack);
  449.       If (GoodIndex
  450.       And Change    ) then
  451.          begin
  452.  
  453.             Repeat
  454.                Gotoxy(1, 24);
  455.                TextColor(ShowRed);
  456.                write('New value? ');
  457.                CursOn;
  458.                Get_Num(Temp, GoodValue);
  459.                If ( not GoodValue ) then
  460.                   write( chr(bell) );
  461.                CursOff;
  462.                TextColor(ShowBlack)
  463.             Until GoodValue;
  464.  
  465.             Data[item] := Temp;
  466.             If item = (N + 1) then
  467.                N := N + 1;
  468.          end {If}
  469.    end {If}
  470. Else
  471.    begin
  472.       Choice := NullChoice;
  473.       delete := true;
  474.       cancel := false;
  475.       change := false;
  476.       TextColor(ShowRed);
  477.       Gotoxy(1, 23);
  478.       Bottomline := Min_Int( (PageNum * Max_lines), N );
  479.       write('Delete which datum? ');
  480.  
  481.       Repeat
  482.          CursOn;
  483.          Gotoxy(22, 23);
  484.          Get_Index(item, Topline, Bottomline, GoodIndex);
  485.          If not GoodIndex then
  486.             begin
  487.                write( chr(bell) );
  488.                Choice := Do_Alert(
  489.  
  490.    '[3][You can only delete |data on this page][ DELETE | CANCEL ]',
  491.                          2);
  492.                Gotoxy(22, 23 );
  493.                ClrEol;
  494.                Delete := ( Choice = A_Delete );
  495.                Cancel := ( Not Delete )
  496.              end; {If}
  497.           CursOff;
  498.           TextColor(ShowBlack)
  499.        Until (GoodIndex
  500.        Or     Cancel    );
  501.  
  502.       If (GoodIndex
  503.       And Delete   ) then
  504.          begin
  505.             N := N - 1;
  506.  
  507.             For i := item to N do
  508.                Data[i] := Data[i + 1];
  509.  
  510.          end {If}
  511.    end; {Else}
  512.  
  513. Erase_Commands
  514.  
  515. END; {EDIT_ITEM}
  516.  
  517.  
  518.  
  519. procedure
  520. Allow_Options;
  521.  
  522. BEGIN {ALLOW_OPTIONS}
  523.  
  524. Menu_enable( The_menu, Calc_results);
  525. Menu_enable( The_menu, Edit_data);
  526. Menu_enable( The_menu, View_sorted );
  527. Menu_enable( The_menu, Print_sorted_data );
  528. Menu_enable( The_menu, Print_Raw_Data );
  529. Menu_enable( The_menu, Save_sorted_data );
  530. Menu_enable( The_menu, Save_raw_data );
  531.  
  532. END; {ALLOW_OPTIONS}
  533.  
  534.  
  535.  
  536. procedure
  537. Input_Data(
  538.            VAR index     : integer;
  539.            VAR Data      : XarrayType;
  540.            VAR WrapIndex : integer;
  541.            VAR N         : integer
  542.            );
  543.  
  544.    VAR
  545.  
  546.       More_data,
  547.       Edit,
  548.       change,
  549.       delete,
  550.       cancel,
  551.       Good_value         : boolean;
  552.       Temp               : real;
  553.       Alert,
  554.       Skip,
  555.       item,
  556.       PageNum,
  557.       LineCount,
  558.       NewLine,
  559.       i, j, k            : integer;
  560.  
  561.  
  562. BEGIN {INPUT_DATA}
  563.  
  564. More_data := true;
  565. index := N;
  566. If ( N > 0 ) then
  567.    PageNum := N div Max_lines
  568. Else
  569.    PageNum := 0;
  570. PageNum := PageNum + 1;
  571. LineCount := 1 + (index - WrapIndex);
  572. {If LineCount = 1 then
  573.    Erase_Page;}
  574.  
  575. While More_data and ( index <= Max_Array_Size ) do begin
  576.    index := index + 1;
  577.    If index = Max_Array_Size then
  578.       begin
  579.          write( chr( bell ) );
  580.          Alert := Do_Alert(
  581.  
  582. '[3][WARNING! |You can enter only|one more value][OK]', 1
  583.  
  584.                        );
  585.       end; {If}
  586.  
  587.    Hide_mouse;
  588.    NewLine := LineCount;
  589.    Gotoxy( 1, ((NewLine  mod MaxPlusOne) + offset) );
  590.    write(space:80);
  591.    Gotoxy( 1, ((NewLine  mod MaxPlusOne) + offset) );
  592.    write ('datum[', index, '] ');
  593.    Get_Num( temp, Good_value );
  594.  
  595.    If Good_value then
  596.       begin
  597.          N := N + 1;
  598.          Data[N] := Temp;
  599.          LineCount := LineCount + 1
  600.       end {If }
  601.    Else
  602.       begin
  603.          index := index - 1;
  604.          write( Chr( bell ) );
  605.          Is_There_More ( More_data, Edit);
  606.  
  607.          If Edit then
  608.             begin
  609.                More_data := true;
  610.                item := index;
  611.                Edit_Item( item, Data, PageNum, N, change,
  612.                           delete, cancel );
  613.                If change then
  614.                   begin
  615.                      If item = index + 1  then
  616.                         begin
  617.                            index := item;   { Datum added to end of array. }
  618.                            LineCount := LineCount + 1
  619.                         end; {If}
  620.                      If item = WrapIndex then
  621.                         Gotoxy( 1, Offset - 1)
  622.                      Else
  623.                         begin
  624.                            j := item - WrapIndex;
  625.                            Gotoxy( 1, ( (j mod MaxPlusOne) + Offset) )
  626.                         end; {Else}
  627.                      write('datum[', item, '] ');
  628.                      skip := 7 - CountDigits(item);
  629.                      TextColor(ShowRed);
  630.                      write( space:skip, Data[item]:14:6 );
  631.                      TextColor(ShowBlack)
  632.                   end {change}
  633.                Else If delete then
  634.                   begin
  635.                      Erase_Page;
  636.                      If ( (item = WrapIndex)
  637.                      And  (LineCount = 1) ) then
  638.                         begin
  639.                            PageNum := PageNum - 1;
  640.                            LineCount := MaxPlusOne;
  641.                            WrapIndex := ((PageNum - 1) * Max_lines) ;
  642.                         end; {If}
  643.                      index := index - 1;
  644.                      LineCount := LineCount - 1;
  645.                      If (WrapIndex <> 0) then
  646.                         begin
  647.                            Gotoxy(1, Offset - 1);
  648.                            skip := 7 - CountDigits(WrapIndex);
  649.                            write('datum[', WrapIndex, '] ',
  650.                                  space:skip, Data[WrapIndex]:14:6)
  651.                          end; {If}
  652.  
  653.                       For j := 1 to LineCount do begin
  654.                          k := j + WrapIndex;
  655.                          skip := 7 - CountDigits(k);
  656.                          Gotoxy(1, ((j mod MaxPlusOne) + Offset ) );
  657.                          write('datum[', k, '] ', space:skip,
  658.                                 Data[k]:14:6 )
  659.                       end; {For}
  660.  
  661.                   end; {Else}
  662.                Edit := false
  663.             end {If}
  664.       end; {Else}
  665.    If (( (LineCount mod MaxPlusOne) = 0)
  666.    And   (N >= Max_lines) ) then
  667.       begin
  668.          Erase_Page;
  669.          PageNum := PageNum + 1;
  670.          WrapIndex := Max_lines + WrapIndex;
  671.          LineCount := 1;
  672.          Gotoxy( 1, Offset - 1 );
  673.          Skip := 7 - CountDigits( index - 1 );
  674.          write( 'datum[', WrapIndex, '] ', Space:Skip,
  675.                  Data[ WrapIndex ]:14:6 )
  676.       end; {If}
  677.    Show_mouse;
  678. end; {while }
  679.  
  680. Menu_disable( The_menu, Enter_data);
  681. Menu_disable( The_menu, Read_data );
  682. Allow_options;
  683. Menu_Normal( The_menu, Option)
  684.  
  685. END; {INPUT_DATA}
  686.  
  687.  
  688.  
  689. procedure
  690. ReadFromDisk ( Var N : integer );
  691.  
  692.    VAR
  693.  
  694.       Default_path,
  695.       Chosen_path    : Path_name;
  696.       i              : integer;
  697.       temp           : real;
  698.  
  699. BEGIN {READFROMDISK}
  700.  
  701. Default_path := 'D:\PASCAL\*.DAT';
  702. i := 0;
  703. If Get_In_File( Default_path, Chosen_path ) then
  704.    begin
  705.       Set_mouse( M_bee );
  706.       Reset( Input, Chosen_path );
  707.  
  708.       While not eof do begin
  709.          Readln( temp );
  710.          i := i + 1;
  711.          Data[i] := temp
  712.       end; {While}
  713.  
  714.       N := i;
  715.       Reset( Input, 'CON:' );
  716.       Set_mouse( M_arrow );
  717.       Menu_normal( The_menu,Option );
  718.       Menu_disable( The_menu, Enter_data );
  719.       Allow_options;
  720.    end; {If}
  721. Erase_page;
  722. Erase_commands;
  723.  
  724. END; {READFROMDISK}
  725.  
  726.  
  727.  
  728. procedure
  729. Offer_Edit(
  730.             VAR Editing     : boolean
  731.           );
  732.  
  733.  
  734.    VAR
  735.  
  736.       choice  : integer;
  737.  
  738. BEGIN {OFFER_EDIT}
  739.  
  740.    choice := Do_Alert(
  741.  
  742. '[0][EDIT this page|GO TO next page][ EDIT | GO TO ]', 2 );
  743.  
  744.    Editing := ( choice = 1 );
  745.  
  746. END; {OFFER_EDIT}
  747.  
  748.  
  749. procedure
  750. Edit_All ( VAR Data : Xarraytype );
  751.  
  752.    VAR
  753.  
  754.       i,
  755.       choice,
  756.       item,
  757.       PageNum,
  758.       Skip,
  759.       LineCount,
  760.       data_left,
  761.       index            : integer;
  762.       Editing,
  763.       Change,
  764.       Delete,
  765.       Cancel,
  766.       More_data        : boolean;
  767.  
  768. BEGIN {EDIT_ALL}
  769.  
  770.  
  771. Menu_disable( The_menu, Print_results);
  772. Menu_disable(The_menu, Show_graph);
  773. Menu_disable(The_menu, Print_graph);
  774. index := 0;
  775. More_data := true;
  776. PageNum := 1;
  777. LineCount := 0;
  778. More_data := ( N >= 1 );
  779. Hide_mouse;
  780.  
  781. while More_data do begin
  782.    Erase_Page;
  783.    data_left := N - index;
  784.    WrapIndex := index;
  785.    LineCount := Min_Int( Max_lines, data_left );
  786.    If WrapIndex <> 0 then
  787.       begin
  788.          Gotoxy(1, Offset - 1);
  789.          skip := 7 - CountDigits(WrapIndex);
  790.          write('datum[', WrapIndex, '] ', space:skip,
  791.                 Data[WrapIndex]:14:6)
  792.       end; {If}
  793.  
  794.    For i := 1 to LineCount do begin
  795.       index := Index + 1;
  796.       skip := 7 - CountDigits(index);
  797.       Gotoxy(1, ((i mod MaxPlusOne) + Offset) );
  798.       write('datum[',index, '] ', space:skip,
  799.              Data[index]:14:6 )
  800.    end; {For}
  801.  
  802.    editing := true;
  803.  
  804.    While editing do begin
  805.       Offer_Edit( editing );
  806.       If editing then
  807.          begin
  808.             Edit_Item(item, Data, PageNum, N, Change,
  809.                       Delete, Cancel );
  810.             If Change then
  811.                begin
  812.                   If item = WrapIndex then
  813.                      Gotoxy(1, Offset - 1)
  814.                   Else
  815.                      begin
  816.                         i := item - wrapIndex;
  817.                         Gotoxy(1, ((i mod MaxPlusOne) + Offset) )
  818.                      end; {Else}
  819.                   skip := 7 - Countdigits(item);
  820.                   write('datum[', item, '] ', space:skip);
  821.                   TextColor(ShowRed);
  822.                   write(Data[item]:14:6);
  823.                   TextColor(ShowBlack)
  824.                end {If}
  825.             Else If Delete then
  826.                begin
  827.                   editing := false;
  828.                   i := item - WrapIndex;
  829.                   Gotoxy(1, ((i mod MaxPlusOne) + Offset) );
  830.                   write(space:80);
  831.                   PageNum := PageNum - 1;
  832.                   index := WrapIndex
  833.                end {Else If}
  834.          end {If}
  835.  
  836.    end; {While}
  837.  
  838. More_data := ( ( N - Index ) >= 1 );
  839. If More_data then
  840.    PageNum := PageNum + 1;
  841.  
  842. end; {While}
  843.  
  844. write( chr(bell) );
  845. choice := Do_Alert(
  846.  
  847. '[2][DONE editing|ADD to data][ DONE | ADD ]', 1 );
  848.  
  849. If choice = 2 then
  850.    begin
  851.       Menu_enable(The_menu, Enter_data);
  852.       If ( LineCount = Max_lines ) then
  853.          begin
  854.             PageNum := PageNum + 1;
  855.             Erase_Page;
  856.             WrapIndex := N;
  857.             Gotoxy(1, Offset - 1);
  858.             skip := 7 - CountDigits(WrapIndex);
  859.             write('datum[',wrapIndex,'] ', space:skip,
  860.                    Data[WrapIndex]:14:6)
  861.          end;
  862.     end; {If}
  863. Show_mouse;
  864. Menu_normal( The_menu, Option );
  865.  
  866. END; {EDIT_ALL}
  867.  
  868.  
  869.  
  870. procedure
  871. Build_Menu;
  872.  
  873. BEGIN {BUILD_MENU}
  874.  
  875. The_menu := NEW_MENU(32, 'STATS PROGRAM');
  876. Help := Add_MTitle(The_menu, ' Help ');
  877. Option := Add_MTitle(The_menu, ' Option ');
  878.  
  879. Instructions := Add_MItem(The_menu, Help,      '  Instructions      ');
  880. HelpEnter := Add_MItem(The_menu, Help,         '  Enter data        ');
  881. HelpRead := Add_MItem(The_menu, Help,          '  Read data         ');
  882. HelpEdit := Add_MItem(The_menu, Help,          '  Edit data         ');
  883. HelpGraph := Add_MItem(The_menu, Help,         '  The graph         ');
  884. Enter_data := Add_MItem(The_menu,Option,       '  Enter data        ');
  885. Read_Data  := Add_MItem(The_menu,Option,       '  Read data file    ');
  886. Edit_data := Add_MItem(The_menu,Option,        '  Edit data         ');
  887. View_sorted := Add_MItem(The_menu,Option,      '  View sorted data  ');
  888. Calc_results := Add_MItem(The_menu,Option,     '  Calculate results ');
  889. Show_graph := Add_MItem( The_menu, Option,     '  Show graph        ');
  890. Print_results := Add_MItem(The_menu,Option,    '  Print results     ');
  891. Print_graph := Add_MItem(The_menu, Option,     '  Print graph       ');
  892. Print_sorted_data := Add_MItem(The_menu,Option,'  Print sorted data ');
  893. Print_raw_data := Add_MItem(The_menu,Option,   '  Print raw data    ');
  894. Save_sorted_data := Add_MItem(The_menu,Option, '  Save sorted data  ');
  895. Save_raw_data := Add_MItem(The_menu,Option,    '  Save raw data     ');
  896. Exit_stats     := Add_MItem(The_menu,Option,   '  Exit program      ');
  897. Draw_Menu (The_menu);
  898.  
  899. END; {BUILD_MENU}
  900.  
  901.  
  902.  
  903. procedure
  904. View      ( VAR Data : Xarraytype );
  905.  
  906.    VAR
  907.  
  908.       i,
  909.       Skip,
  910.       data_left,
  911.       index,
  912.       lines      : integer;
  913.       More_data  : boolean;
  914.  
  915. BEGIN { VIEW }
  916.  
  917. index := 0;
  918. ERASE_PAGE;
  919. Hide_Mouse;
  920. More_data := (N >= 1);
  921.  
  922.  
  923. While More_data do begin
  924.  
  925.    Erase_Page;
  926.    data_left := N - index;
  927.    lines := Min_Int(Max_lines, data_left);
  928.  
  929.    For i := 1 to lines do begin
  930.       index := index + 1;
  931.       GOTOXY( 1, ( i  mod MaxPlusOne ) + Offset );
  932.       Skip := 7 - ( CountDigits( index ) );
  933.       write ('datum[', index, '] ', Space:Skip, Data[index]:14:6 )
  934.    end; {For}
  935.  
  936.    dummy := Do_Alert(
  937.  
  938.   '[2][Next page][OK]', 1);
  939.  
  940.    More_data := ((N - index) >= 1)
  941. end; {While}
  942.  
  943. write( Chr( bell ));
  944. dummy := Do_Alert(
  945.  
  946. '[1][Last page][OK]',1);
  947.  
  948. Erase_Page;
  949. Show_mouse;
  950. Menu_normal( The_menu, Option )
  951.  
  952. END; {VIEW}
  953.  
  954.  
  955.  
  956. procedure
  957. Results_Proc;
  958.  
  959.    VAR
  960.  
  961.       Dummychar   : char;
  962.  
  963. BEGIN {RESULTS_PROC}
  964.  
  965. HIDE_MOUSE;
  966. ERASE_PAGE;
  967. GOTOXY( 1, Offset - 1 );
  968. writeln( space:20, 'DATA SET: ',DataSetName );
  969. writeln;
  970. writeln('Number of values entered  :  ', N);
  971. writeln;
  972. SELECTSORT( Data, Sorted_data );
  973. MEANSTD (Sorted_data, N, Mean, Std_dev, Sample_Std_Dev);
  974.  
  975. If Odd( N ) then
  976.    Median := Sorted_data [ Trunc( N/2) + 1 ]
  977. Else
  978.    Median := ( Sorted_data [ N div 2 ] + Sorted_data [ (N div 2) + 1 ] )/2 ;
  979. write('low : ',Sorted_Data[1]:14:6);
  980. writeln(space:15,'high : ',Sorted_data[N]:14:6);
  981. writeln;
  982. writeln('median               : ', median:14:6);
  983. writeln;
  984. writeln('mean                 : ',mean:14:6);
  985. writeln;
  986. writeln('std dev (population) : ',Std_dev:14:6);
  987. write(  'std dev (sample)     : ',Sample_Std_Dev:14:6);
  988. Gotoxy(1, 23);
  989. TextColor( ShowRed );
  990. write('Press ');
  991. InverseVideo;
  992. write(' Return ');
  993. NormVideo;
  994. write(' to continue...');
  995. show_mouse;
  996. readln( dummychar );
  997. TextColor( ShowBlack );
  998. Hide_mouse;
  999. ERASE_PAGE;
  1000. ERASE_COMMANDS;
  1001. SHOW_MOUSE;
  1002. Menu_enable( The_menu, Show_graph );
  1003. Menu_enable( The_menu, Print_results );
  1004. Menu_enable( The_menu, Print_graph );
  1005. Menu_normal(The_menu, Option )
  1006.  
  1007. END; {RESULTS_PROC}
  1008.  
  1009.  
  1010. procedure
  1011. ShowGraph;
  1012.  
  1013.    VAR
  1014.  
  1015.       FreqCount     : array [1..10] of integer;
  1016.       LowValue,
  1017.       HighValue,
  1018.       UpperBound,
  1019.       Range,
  1020.       NextBound     : real;
  1021.       row,
  1022.       i, j          : integer;
  1023.       DummyChar      : char;
  1024.  
  1025.  
  1026. BEGIN {SHOWGRAPH}
  1027.  
  1028. Hide_mouse;
  1029. Erase_Page;
  1030. GoToxy( 1, Offset - 1 );
  1031. write( 'DATA SET : ', DataSetName );
  1032. LowValue := Sorted_Data[1];
  1033. HighValue := Sorted_Data[N];
  1034. Range := HighValue - LowValue;
  1035. NextBound := (Range / 10 );
  1036.  
  1037. For i := 1 to 10 do
  1038.    FreqCount[i] := 0;
  1039.  
  1040. UpperBound := LowValue;
  1041. j := 1;
  1042.  
  1043. For i := 1 to 10 do begin
  1044.    UpperBound := UpperBound + NextBound;
  1045.  
  1046.    While (( Sorted_Data[j] <=  UpperBound )
  1047.    And    ( j <= N )) do begin
  1048.       FreqCount[i] := FreqCount[i] + 1;
  1049.       j := j + 1
  1050.    end; {while}
  1051.  
  1052. end; {For}
  1053.  
  1054.  
  1055. row := Offset + 1;
  1056. GoToxy( 16, row );
  1057. write('Value');
  1058. row := row + 1;
  1059. UpperBound := HighValue;
  1060.  
  1061. For i := 10 downto 1 do begin
  1062.    Gotoxy(1, row );
  1063.    write( UpperBound:14:6);
  1064.    write( space:3, '|' );
  1065.    If FreqCount[i] <> 0 then
  1066.       begin
  1067.          TextColor( ShowGreen );
  1068.          If FreqCount[i] <= 50 then
  1069.             For j := 1 to FreqCount[i] do
  1070.                write('X')
  1071.          Else
  1072.             begin
  1073.                For j := 1 to 50 do
  1074.                    write('X');
  1075.                    TextColor(ShowRed);
  1076.                write(space, FreqCount[i])
  1077.             end; {Else}
  1078.          TextColor( ShowBlack )
  1079.       end; {If}
  1080.    row := row + 1;
  1081.    UpperBound := UpperBound - NextBound
  1082. end; {For}
  1083.  
  1084. GoToxy(1, row);
  1085. write( LowValue:14:6);
  1086. GoToxy( 18, row );
  1087. write( '+' );
  1088.  
  1089. For i := 1 to 53 do
  1090.    If ( i mod 5 ) = 0 then
  1091.       write('+')
  1092.    Else
  1093.       write('-');
  1094.  
  1095. write('Frequency');
  1096. row := row + 2;
  1097. GoToxy( 1, row );
  1098. write(space:5, 'Frequency increment : ', 1 );
  1099. write(space:5, 'Value increment : ', NextBound:14:6 );
  1100. Gotoxy(1, 23);
  1101. TextColor( ShowRed );
  1102. write('Press ');
  1103. InverseVideo;
  1104. write(' Return ');
  1105. NormVideo;
  1106. write(' to continue...');
  1107. Show_mouse;
  1108. readln( dummychar );
  1109. TextColor( ShowBlack );
  1110. Hide_mouse;
  1111. Erase_Page;
  1112. Erase_Commands;
  1113. Show_mouse;
  1114. Menu_Normal( The_Menu, Option )
  1115.  
  1116. END; {SHOWGRAPH}
  1117.  
  1118.  
  1119. procedure
  1120. PrintGraph;
  1121.  
  1122.    VAR
  1123.  
  1124.       Alert         : integer;
  1125.       FreqCount     : array [1..10] of integer;
  1126.       LowValue,
  1127.       HighValue,
  1128.       UpperBound,
  1129.       Range,
  1130.       NextBound     : real;
  1131.       i, j          : integer;
  1132.       PrinterStatus : long_integer;
  1133.  
  1134.  
  1135. BEGIN {PRINTGRAPH}
  1136.  
  1137. Repeat
  1138.    PrinterStatus := GetPrinterStatus;
  1139.    If PrinterStatus = 0 then
  1140.       Alert := Do_Alert(
  1141.  
  1142.    '[3][Printer is not online][ OK ]', 1);
  1143.  
  1144. Until ( PrinterStatus <> 0 );
  1145.  
  1146. set_mouse(M_bee);
  1147. rewrite(output, 'PRN:');
  1148. writeln(space:25, 'STATS : ',DataSetName);
  1149. writeln;
  1150. writeln(space:18, 'FREQUENCY DISTRIBUTION');
  1151. writeln;
  1152. writeln;
  1153.  
  1154. LowValue := Sorted_Data[1];
  1155. HighValue := Sorted_Data[N];
  1156. Range := HighValue - LowValue;
  1157. NextBound := (Range / 10 );
  1158.  
  1159. For i := 1 to 10 do
  1160.    FreqCount[i] := 0;
  1161.  
  1162. UpperBound := LowValue;
  1163. j := 1;
  1164.  
  1165. For i := 1 to 10 do begin
  1166.    UpperBound := UpperBound + NextBound;
  1167.  
  1168.    While (( Sorted_Data[j] <=  UpperBound )
  1169.    And    ( j <= N )) do begin
  1170.       FreqCount[i] := FreqCount[i] + 1;
  1171.       j := j + 1
  1172.    end; {while}
  1173.  
  1174. end; {For}
  1175.  
  1176. writeln('Value':20);
  1177. UpperBound := HighValue;
  1178.  
  1179. For i := 10 downto 1 do begin
  1180.    write( UpperBound:14:6);
  1181.    write( space:3, '|' );
  1182.    If FreqCount[i] <> 0 then
  1183.       begin
  1184.          If FreqCount[i] <= 50 then
  1185.             For j := 1 to FreqCount[i] do
  1186.                write('X')
  1187.          Else
  1188.             begin
  1189.                For j := 1 to 50 do
  1190.                    write('X');
  1191.                write(space, FreqCount[i])
  1192.             end {Else}
  1193.       end; {If}
  1194.    writeln;
  1195.    UpperBound := UpperBound - NextBound;
  1196. end; {For}
  1197.  
  1198. write( LowValue:14:6);
  1199. write(space:3);
  1200. write( '+' );
  1201. For i := 1 to 53 do
  1202.    If ( i mod 5 ) = 0 then
  1203.       write('+')
  1204.    Else
  1205.       write('-');
  1206.  
  1207. writeln('Frequency');
  1208. writeln;
  1209. writeln;
  1210. write(space:5, 'Frequency increment : ', 1 );
  1211. write(space:5, 'Value increment : ', NextBound:14:6 );
  1212. page;
  1213. rewrite(output, 'CON:');
  1214. set_mouse(M_arrow);
  1215. Menu_Normal( The_Menu, Option )
  1216.  
  1217. END; {PRINTGRAPH}
  1218.  
  1219. procedure
  1220. Do_Print_Results;
  1221.  
  1222.    VAR
  1223.  
  1224.       PrinterStatus : long_integer;
  1225.       Alert         : integer;
  1226.  
  1227.  
  1228. BEGIN {DO_PRINT_RESULTS}
  1229.  
  1230.  
  1231. Set_mouse( M_bee );
  1232. Rewrite( Output, 'PRN:' );
  1233.  
  1234. Repeat
  1235.    PrinterStatus := GetPrinterStatus;
  1236.    If PrinterStatus = 0 then
  1237.       Alert := Do_Alert(
  1238.  
  1239.    '[3][Printer is not online][ OK ]', 1);
  1240.  
  1241. Until ( PrinterStatus <> 0 );
  1242.  
  1243. writeln(space:25, 'STATS : ', DataSetName );
  1244. writeln;
  1245. writeln( Space:30, 'RESULTS' );
  1246. writeln;
  1247. writeln;
  1248. writeln( Space:6, 'Number of values entered : ', N );
  1249. writeln( Space:6,
  1250.         'Low value : ',Sorted_data[1]:14:6, '       High value : ',
  1251.          Sorted_data[N]:14:6);
  1252. writeln;
  1253. writeln( Space:6,' Median : ', median:14:6 );
  1254. writeln;
  1255. writeln( Space:6,' Mean   : ', Mean:14:6 );
  1256. writeln;
  1257. writeln( Space:6,'Standard deviation for population : ', Std_dev:14:6 );
  1258. writeln;
  1259. writeln(Space:6, 'Standard deviation for sample     : ', Sample_Std_Dev:14:6);
  1260. page;
  1261. Rewrite( Output, 'CON:' );
  1262. Set_mouse( M_arrow );
  1263. Menu_normal( The_menu, Option );
  1264.  
  1265. END; {DO_PRINT_RESULTS}
  1266.  
  1267.  
  1268.  
  1269. procedure
  1270. Do_Title;
  1271.  
  1272. BEGIN {DO-TITLE}
  1273.  
  1274. write( Space:25, 'STATS : ',DataSetName );
  1275. writeln;
  1276. writeln;
  1277. writeln
  1278.  
  1279. END; {DO_TITLE}
  1280.  
  1281.  
  1282.  
  1283. procedure
  1284. Print_Array ( VAR Data : XarrayType; N : integer );
  1285.  
  1286.    CONST
  1287.  
  1288.       MaxLines         = 50;  { Max lines per page }
  1289.  
  1290.    VAR
  1291.  
  1292.       PrinterStatus : long_integer;
  1293.       Alert         : integer;
  1294.       Skip,
  1295.       i, j          : integer;
  1296.       EndOfData     : boolean;
  1297.  
  1298.  
  1299. BEGIN {PRINT_ARRAY}
  1300.  
  1301. Repeat
  1302.    PrinterStatus := GetPrinterStatus;
  1303.    If PrinterStatus = 0 then
  1304.       Alert := Do_Alert(
  1305.  
  1306.    '[3][Printer is not online][ OK ]', 1);
  1307.  
  1308. Until ( PrinterStatus <> 0 );
  1309.  
  1310. Set_mouse( M_bee );
  1311. rewrite( Output, 'PRN:' );
  1312. i := 0;
  1313. j := 0;
  1314. DO_TITLE;
  1315. EndOfData := ( N <= 0 );
  1316.  
  1317. While (not EndOfData) do begin
  1318.    i := i + 1;
  1319.    Skip := 7 - ( CountDigits( i ) );
  1320.    write( Space:6);
  1321.    write('[', i, '] ', Space:Skip, Data[i]:15:6 );
  1322.    If ( i + MaxLines ) <= N then
  1323.       begin
  1324.          write( Space:18 );
  1325.          Skip := 7 - ( CountDigits( i + MaxLines ) );
  1326.          write( '[', ( i + MaxLines ), '] ', Space:Skip,
  1327.                  Data[ i + MaxLines ]:15:6 );
  1328.          j := j + 1;
  1329.          If (j mod MaxLines ) = 0 then
  1330.             begin
  1331.                page;
  1332.                DO_TITLE;
  1333.                i := i + MaxLines;
  1334.                j := 0
  1335.             end; {If}
  1336.       end; {If}
  1337.    writeln;
  1338.    EndOfData := ( i + j ) >= N
  1339. end; {While}
  1340.  
  1341. page;
  1342. Set_mouse( M_arrow );
  1343. rewrite( Output,'CON:' );
  1344. Menu_normal( The_menu, Option)
  1345.  
  1346. END; {PRINT_ARRAY}
  1347.  
  1348.  
  1349.  
  1350. procedure
  1351. Save      ( VAR Data: Xarraytype );
  1352.  
  1353.    VAR
  1354.  
  1355.      i          : integer;
  1356.      Disk_file  : Path_name;
  1357.  
  1358. BEGIN {SAVE}
  1359.  
  1360. If Get_Out_File( 'Save as: filename.DAT', Disk_file ) then
  1361.    begin
  1362.       Set_mouse( M_bee );
  1363.       Rewrite( Output, Disk_file );
  1364.       i := 1;
  1365.  
  1366.       While ( i <= N ) do begin
  1367.          writeln( Data[i] );
  1368.          i := i + 1
  1369.       end; {While}
  1370.  
  1371.       Rewrite( Output, 'CON:' );
  1372.       Set_mouse( M_arrow )
  1373.     end; {If}
  1374. Menu_normal( The_menu, Option );
  1375. Erase_page;
  1376. Erase_commands;
  1377.  
  1378. END; {SAVE}
  1379.  
  1380.  
  1381.  
  1382.  
  1383. procedure
  1384. EXIT_PROC;
  1385.  
  1386. BEGIN {EXIT_PROC}
  1387.  
  1388. ERASE_MENU (The_menu);
  1389. Init_Mouse;
  1390.  
  1391. END; {EXIT_PROC}
  1392.  
  1393.  
  1394.  
  1395. procedure
  1396. Option_Proc;
  1397.  
  1398. BEGIN {OPTION_PROC}
  1399.  
  1400. if msg[4] = Enter_data then
  1401.    Input_Data (index, Data, WrapIndex, N )
  1402. else if msg[4] = Read_data then
  1403.    ReadFromDisk( N )
  1404. else if msg[4] = Calc_results then
  1405.    Results_Proc
  1406. else if msg[4] = Edit_data then
  1407.    Edit_All ( Data )
  1408. else if msg[4] = View_sorted then
  1409.    begin
  1410.       SelectSort( Data, Sorted_data );
  1411.       View ( Sorted_data )
  1412.    end { else }
  1413. else if msg[4] = Print_results then
  1414.    Do_Print_Results
  1415. else if msg[4] = Show_graph then
  1416.    ShowGraph
  1417. else if msg[4] = Print_graph then
  1418.    PrintGraph
  1419. else if msg[4] = Print_Sorted_Data then
  1420.    begin
  1421.       SelectSort( Data, Sorted_data );
  1422.       Print_Array( Sorted_Data, N )
  1423.    end {else}
  1424. else if msg[4] = Print_Raw_Data then
  1425.    Print_Array( Data, N )
  1426. else if msg[4] = Save_sorted_data then
  1427.    begin
  1428.       Selectsort( Data, Sorted_data );
  1429.       Save( Sorted_data )
  1430.    end {else}
  1431. else if msg[4] = Save_raw_data then
  1432.    Save( Data )
  1433. else if msg[4] = Exit_stats then
  1434.    Done := true;
  1435. Menu_normal( The_menu, Option )
  1436.  
  1437. END; {OPTION_PROC}
  1438.  
  1439.  
  1440.  
  1441. procedure
  1442. GIVEINSTRUCTIONS;
  1443.  
  1444.    VAR
  1445.  
  1446.       dummychar   : char;
  1447.  
  1448. BEGIN { GiveInstructions }
  1449.  
  1450. ClrScr;
  1451. Gotoxy( 1, Offset );
  1452. writeln('STATS calculates the mean, median and standard deviation for a');
  1453. writeln('set of numbers.  Numbers may be ENTERed from the keyboard, or READ');
  1454. writeln('from a disk file.  Once entered, the data may be EDITed, VIEWed');
  1455. writeln('in sorted order, SAVEd to disk or PRINTed in raw or sorted order');
  1456. writeln;
  1457. writeln('After a data set has been entered, you may CALCULATE the RESULTS;');
  1458. writeln('(mean and standard deviation).  The results will be displayed on');
  1459. writeln('the screen and several OPTIONs will become enabled; for example,');
  1460. writeln('You may then SHOW the GRAPH, which is a frequency distribution');
  1461. writeln('of the data set.  You may also PRINT the RESULTS and the GRAPH');
  1462. writeln;
  1463. Gotoxy(1,23);
  1464. TextColor( ShowRed );
  1465. write('Press ');
  1466. InverseVideo;
  1467. write(' Return ');
  1468. NormVideo;
  1469. write(' to continue...');
  1470. readln(dummychar);
  1471. TextColor( ShowBlack )
  1472.  
  1473. END;  { GiveInstructions }
  1474.  
  1475.  
  1476.  
  1477.  
  1478. procedure
  1479. GiveEnterHelp;
  1480.  
  1481.    VAR
  1482.  
  1483.       dummychar  : char;
  1484.  
  1485. BEGIN { GiveEnterHelp }
  1486.  
  1487. ClrScr;
  1488. Gotoxy( 1, Offset );
  1489. writeln('Data may be entered from the keyboard as integers or real');
  1490. writeln('numbers, or as a mixture of the two.  A maximum of eighteen');
  1491. writeln('values can be entered on a screen; the last value will "wrap');
  1492. writeln('around" to the top of the next screen.');
  1493. writeln;
  1494. writeln('If you enter an invalid number, an alert box will appear to ask');
  1495. writeln('if you are DONE entering data, if there is MORE data, or if');
  1496. writeln('you want to EDIT the data on that page.');
  1497. writeln;
  1498. writeln('If you enter an incorrect number, just press return at the');
  1499. writeln('next prompt and select EDIT in the first alert box.  You will');
  1500. writeln('be prompted for the index of the offending value and asked');
  1501. writeln('whether you wish to CHANGE the value or DELETE it.  You may');
  1502. writeln('change or delete any datum visible on the page, including the');
  1503. writeln('"wrapped" value from the previous page.');
  1504. writeln;
  1505. writeln('When you have finished entering your data, press return at the next');
  1506. writeln('prompt, click on DONE, and select an action from the OPTION menu.');
  1507. Gotoxy(1, 23);
  1508. TextColor( ShowRed );
  1509. write('Press ');
  1510. InverseVideo;
  1511. write(' Return ');
  1512. NormVideo;
  1513. write(' to continue...');
  1514. readln( dummychar );
  1515. TextColor( ShowBlack )
  1516.  
  1517. END; { GiveEnterHelp }
  1518.  
  1519.  
  1520.  
  1521.  
  1522. procedure
  1523. GiveReadHelp;
  1524.  
  1525.  
  1526.    VAR
  1527.  
  1528.       DummyChar  : char;
  1529.  
  1530.  
  1531. BEGIN {GiveReadHelp}
  1532.  
  1533. ClrScr;
  1534. Gotoxy(1, Offset);
  1535. writeln('If your data are in a disk file, clicking on READ DATA');
  1536. writeln('will bring up a file selector dialog box.  By default,');
  1537. writeln('the program looks in the current subdirectory for files');
  1538. writeln('with the extender .DAT, but you may edit the file and');
  1539. writeln('path name as usual.');
  1540. writeln;
  1541. writeln('Data files must be ASCII text files with one (real or integer)');
  1542. writeln('number per line, terminated by a carriage return.');
  1543. writeln;
  1544. writeln('Reading a file disables ENTER DATA, but you may modify the');
  1545. writeln('data set by selecting EDIT DATA.');
  1546. Gotoxy(1, 23);
  1547. TextColor( ShowRed );
  1548. write('Press ');
  1549. InverseVideo;
  1550. write(' Return ');
  1551. NormVideo;
  1552. write(' to continue...');
  1553. readln( dummychar );
  1554. TextColor( ShowBlack )
  1555.  
  1556. END; {GiveReadHelp}
  1557.  
  1558.  
  1559.  
  1560. procedure
  1561. GiveEditHelp;
  1562.  
  1563.    VAR
  1564.  
  1565.       DummyChar : Char;
  1566.  
  1567. BEGIN {GiveEditHelp}
  1568.  
  1569. ClrScr;
  1570. Gotoxy(1, Offset);
  1571. writeln('When you select EDIT DATA, your data will be displayed one');
  1572. writeln('page at a time.  After each page has been displayed, an alert');
  1573. writeln('box will appear, giving you the choice to EDIT that page or');
  1574. writeln('GO ON to the next page.  If you select EDIT, you will have');
  1575. writeln('the opportunity to CHANGE or DELETE any datum on that page,');
  1576. writeln('including the "wrapped" datum from the last page.');
  1577. writeln;
  1578. writeln('When the last page has been displayed, you will be asked');
  1579. writeln('whether you are DONE editing, or whether you wish to ADD more');
  1580. writeln('data. If you select ADD, you can then return to ENTER DATA');
  1581. writeln('mode, starting at the end of the data you have previously');
  1582. writeln('entered or read from a disk file.');
  1583. Gotoxy(1, 23);
  1584. TextColor( ShowRed );
  1585. write('Press ');
  1586. InverseVideo;
  1587. write(' Return ');
  1588. NormVideo;
  1589. write(' to continue...');
  1590. readln( dummychar );
  1591. TextColor( ShowBlack )
  1592.  
  1593. END; {GiveEditHelp}
  1594.  
  1595.  
  1596.  
  1597. procedure
  1598. GiveGraphHelp;
  1599.  
  1600.    VAR
  1601.  
  1602.       DummyChar  : char;
  1603.  
  1604.  
  1605. BEGIN {GiveGraphHelp}
  1606.  
  1607. ClrScr;
  1608. Gotoxy(1, Offset);
  1609. writeln('The GRAPH, which you may SHOW and then PRINT, is a frequency');
  1610. writeln('distribution, showing the number of data points in each of');
  1611. writeln('ten evenly spaced intervals.  This option is enabled after');
  1612. writeln('you have clicked on CALCULATE.');
  1613. writeln;
  1614. writeln('The value just level with the "Frequency" axis is the lowest');
  1615. writeln('value in your data set.  The value at the top of the "Value"');
  1616. writeln('axis is the highest value in the set.  The numbers in between');
  1617. writeln('(including the high value) are upper bounds of the intervals.');
  1618. writeln('Each green "X" along the frequency axis to the right of a value');
  1619. writeln('represents one datum which is less than or equal to that value, and');
  1620. writeln('greater than the next lower value on the "Value" axis.');
  1621. writeln;
  1622. writeln('A maximum of 50 data points in any interval will be represented');
  1623. writeln('by green X''s; if the frequency exceeds 50, the actual number');
  1624. writeln('of data points will appear in red to the right of the X''s.');
  1625. Gotoxy(1, 23);
  1626. TextColor( ShowRed );
  1627. write('Press ');
  1628. InverseVideo;
  1629. write(' Return ');
  1630. NormVideo;
  1631. write(' to continue...');
  1632. readln( dummychar );
  1633. TextColor( ShowBlack )
  1634.  
  1635. END; {GiveGraphHelp}
  1636.  
  1637.  
  1638.  
  1639. procedure
  1640. Help_Proc;
  1641.  
  1642.  
  1643. TYPE
  1644.  
  1645.    Screen = PACKED ARRAY [ 1..32000 ] of BYTE;
  1646.    S_Ptr = ^Screen;     { pointer to screen data }
  1647.  
  1648.  
  1649. VAR
  1650.  
  1651.    Scn_buf : Screen;    { a place to stash the screen }
  1652.    Scn_ptr : S_Ptr;     { a pointer to screen }
  1653.  
  1654.  
  1655. FUNCTION Physbase : S_Ptr;    { xbios routine returns address of screen }
  1656.   Xbios( 2 );
  1657.  
  1658.  
  1659. PROCEDURE Sav_scn;              { proc saves screen to buf }
  1660. {$P-}           { turn pointer checking off }
  1661.  
  1662.    begin
  1663.       Scn_ptr := Physbase;      { get addr of screen in memory }
  1664.       Scn_buf := Scn_Ptr^;      { do assignment, copy entire array }
  1665.    end;
  1666.  
  1667. {$P=}           { restore pointer checking to old state }
  1668.  
  1669.  
  1670. PROCEDURE Rest_scn;             { restore screen from buf }
  1671. {$P-}           { turn pointer checking off }
  1672.  
  1673.    begin
  1674.       Scn_ptr := Physbase;      { get addr of screen in memory }
  1675.       Scn_ptr^ := Scn_buf;      { assign, copy array }
  1676.    end;
  1677.  
  1678. {$P=}           { set pointer checking to old state }
  1679.  
  1680.  
  1681.  
  1682. BEGIN {HELP_PROC}
  1683.  
  1684. Hide_mouse;
  1685. Sav_scn;
  1686. If msg[4] = Instructions then
  1687.    GiveInstructions
  1688. Else If msg[4] = HelpEnter then
  1689.    GiveEnterHelp
  1690. Else If msg[4] = HelpRead then
  1691.    GiveReadHelp
  1692. Else If msg[4] = HelpEdit then
  1693.    GiveEditHelp
  1694. Else If msg[4] = HelpGraph then
  1695.    GiveGraphHelp;
  1696. Rest_scn;
  1697. Menu_normal( The_menu, Help);
  1698. Show_mouse
  1699.  
  1700. END; {HELP_PROC}
  1701.  
  1702.  
  1703.  
  1704. procedure
  1705. Menu_Proc;
  1706.  
  1707. BEGIN {MENU_PROC}
  1708.  
  1709. if msg[3] = Help then
  1710.    HELP_PROC
  1711. else if msg[3] = Option then
  1712.    OPTION_PROC
  1713. else if msg[3] = Desk_title then
  1714.    begin
  1715.       SHOW_PROGNAME;
  1716.       Menu_normal( The_menu, Desk_title)
  1717.    end; {else}
  1718.  
  1719. END; {MENU_PROC}
  1720.  
  1721.  
  1722.  
  1723. procedure
  1724. Msg_Proc;
  1725.  
  1726. BEGIN {MSG_PROC}
  1727.  
  1728. if ( msg[0] = MN_Selected ) then
  1729.    MENU_PROC
  1730.  
  1731. END; {MSG_PROC}
  1732.  
  1733.  
  1734.  
  1735. procedure
  1736. Event_Proc;
  1737.  
  1738. BEGIN {EVENT_PROC}
  1739.  
  1740. event := GET_EVENT( event_mask,
  1741.                        0,0,0,
  1742.                        0,
  1743.                        false,0,0,0,0,
  1744.                        false,0,0,0,0,
  1745.                        msg,
  1746.                        what_key,
  1747.                        dummy,dummy,
  1748.                        dummy,dummy,
  1749.                        dummy
  1750.                        );
  1751.  
  1752. if ( event & E_Message ) <> 0 then
  1753.    MSG_PROC;
  1754.  
  1755. END; {EVENT_PROC}
  1756.  
  1757.  
  1758.  
  1759. procedure
  1760. TitlePage;
  1761.  
  1762. {$P-} { turn pointer checking off.. }
  1763.  
  1764. {
  1765.  
  1766.         Procedure to save and restore the ST display to/from degas files.
  1767.  
  1768.         12/9/86 MJC
  1769.  
  1770.         Copyright 1986 By OSS, Inc.  All Rights Reserved.
  1771.  
  1772. }
  1773.  
  1774. CONST
  1775.         Mono = 2;               { monochrome screen resolution }
  1776.  
  1777. TYPE
  1778.  
  1779.         { The ST screen is 32000 bytes of data, soooo.... }
  1780.         Screen = packed array [ 0..31999 ] of BYTE;
  1781.  
  1782.         Ptr_screen = ^Screen;   { pointer to the screen array }
  1783.  
  1784.         Palette = Packed Array [ 0..15 ] of Integer;
  1785.  
  1786.         Resolution = Integer;
  1787.  
  1788.         Degas_scrn = PACKED RECORD
  1789.               Res : Resolution;
  1790.               Pal : Palette;
  1791.               Pic : Screen;
  1792.            End;
  1793.  
  1794. VAR
  1795.  
  1796.         S_ptr : Ptr_screen;     { a pointer to a packed array of bytes... }
  1797.         SavScrn : Screen;       { a place to save the current screen }
  1798.         File_nam : String;      { Temp file name..                      }
  1799.  
  1800. { **********************************************************************
  1801.  
  1802.         declare routine to get address of screen
  1803.  
  1804.   *********************************************************************** }
  1805.  
  1806. { physbase returns a pointer to the start of the ST's screen.  }
  1807.  
  1808. FUNCTION Physbase : Ptr_screen;
  1809.    XBIOS( 2 );
  1810.  
  1811. FUNCTION Getrez : Resolution;
  1812.    XBIOS( 4 );
  1813.  
  1814. PROCEDURE Setscreen( Logadr, Physadr : Long_Integer; Res : Resolution );
  1815.    XBIOS( 5 );
  1816.  
  1817. PROCEDURE Setpalette( VAR Pal : Palette );
  1818.    XBIOS( 6 );
  1819.  
  1820. FUNCTION Setcolor( N , Color : Integer ) : Integer;
  1821.    XBIOS( 7 );
  1822.  
  1823.  
  1824.  
  1825.  
  1826. { ***************************************************************************
  1827.  
  1828.         Restore screen data from degas file.
  1829.  
  1830.   *************************************************************************  }
  1831.  
  1832. PROCEDURE SRestore( name : STRING );
  1833.  
  1834. VAR
  1835.    i : Integer;
  1836.    f : file of Degas_scrn;     { a file containing a screenful of bytes.. }
  1837.    Rez : Resolution;
  1838.    Oldpal : Palette;
  1839.  
  1840.    BEGIN
  1841.  
  1842.         Rez := Getrez;
  1843.         S_ptr := Physbase;              { grab location of screen... }
  1844.  
  1845.         reset( f, name );               { bind f to file name }
  1846.  
  1847.         { reset automatically fills file buffer with data from first record }
  1848.  
  1849.         { decide if resolution can be changed...                }
  1850.         IF ( ( f^.Res < Mono ) AND ( Rez < Mono ) ) THEN
  1851.               Setscreen( -1, -1, f^.Res );
  1852.  
  1853.         { now check for picture compatability...                }
  1854.  
  1855.         IF ( ( f^.Res = Mono ) AND ( Rez = Mono )
  1856.           OR
  1857.            ( Rez < Mono ) AND ( f^.Res < Mono ) ) THEN
  1858.            Begin
  1859.               For i:= 0 TO 15 DO              { save palette          }
  1860.                  Oldpal[ i ] := Setcolor( i, -1 );
  1861.  
  1862.               Setpalette( f^.Pal );           { use degas palette     }
  1863.  
  1864.               SavScrn := S_ptr^;              { save current screen       }
  1865.               S_ptr^ := f^.Pic;               { stuff picture into screen }
  1866. (*
  1867.               S_Ptr^ := SavScrn;              { restore old screen            }
  1868.               Setpalette( Oldpal );           { restore old palette           }
  1869.               Setscreen( -1, -1, Rez )        { restore old resolution        }
  1870.  
  1871. *)
  1872.            End;
  1873.         { file is automatically closed when we leave this procedure. }
  1874.    END;
  1875.  
  1876.  
  1877. { *********************************************************************
  1878.  
  1879.         miscellaneous subroutines...
  1880.  
  1881. *********************************************************************** }
  1882.  
  1883.  
  1884.  
  1885.  
  1886. { clear screen procedure }
  1887.  
  1888. PROCEDURE cls;
  1889.  
  1890.    BEGIN
  1891.  
  1892.         write( chr( 27 ) );
  1893.         write( 'E' );
  1894.  
  1895.    END;
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901. { ************************************************************************
  1902.  
  1903.         Main routine starts here.  Just execute routines in sequence...
  1904.  
  1905.   ************************************************************************ }
  1906.  
  1907.  
  1908. BEGIN
  1909.  
  1910.  
  1911.  
  1912.         File_nam := 'Title.pi2';
  1913.         cls;                    { clear screen... }
  1914.         SRestore( File_nam ); { read screen data from file... }
  1915.  
  1916.  
  1917. END; {TITLEPAGE}
  1918.  
  1919.  
  1920.  
  1921.  
  1922.  
  1923.  
  1924. BEGIN {STATS}
  1925.  
  1926. If (Init_Gem  >= 0) then
  1927.    begin
  1928.       resolution := GetRez;
  1929.       If resolution = 0 then
  1930.          begin
  1931.             write( chr(bell) );
  1932.             dummy := Do_Alert(
  1933.  
  1934. '[3][STATS does not|run in low resolution][ OK ]',1)
  1935.  
  1936.           end {If}
  1937.       Else
  1938.          begin
  1939.             N := 0;
  1940.             Init_Mouse;
  1941.             Hide_Mouse;
  1942.             TitlePage;
  1943.             Show_Mouse;
  1944.             Show_ProgName;
  1945.             Ask_DS_Name;
  1946.             Clear_Screen;
  1947.             Build_Menu;
  1948.             Initialize;
  1949.             Erase_Page;
  1950.  
  1951.             repeat
  1952.                Event_Proc
  1953.             until Done
  1954.  
  1955.          end; {Else}
  1956.       Exit_Proc
  1957.    end; {if}
  1958. Init_mouse
  1959.  
  1960. END. {STATS}
  1961.