home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / manage / manpower.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  19.0 KB  |  580 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --changep.ada
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. separate (MANPOWER)
  5. procedure CHANGE_PARAMETERS (NAME  : in string;
  6.             COEFF_MM   : in out ACCURATE_FLOAT;
  7.             EXP_MM     : in out ACCURATE_FLOAT;
  8.             COEFF_TDEV : in out ACCURATE_FLOAT;
  9.             EXP_TDEV   : in out ACCURATE_FLOAT) is 
  10. ----------------------------------------------------------------------
  11. --| NAME : CHANGE_PARAMETERS
  12. --|
  13. --| OVERVIEW:
  14. --|   This procedure allows the user to modify the parameters in the
  15. --|   COCOMO equations.
  16. --|
  17. --| HISTORY:
  18. --|   written by Bonnie Burkhardt     March 1985
  19. --|
  20. --| EXCEPTIONS HANDLED: 
  21. --|    others   an error message is printed an processing continues
  22. ----------------------------------------------------------------------
  23.  
  24.   CHOICE     : integer range 1..3;
  25.   YES_OR_NO  : character := 'N';
  26.   PARAMETER  : long_float digits 15 := 0.0;
  27.  
  28. begin
  29.   -- output the current equation
  30.   new_line; put(NAME); set_col(17); put("MM = "); put(COEFF_MM,2,3,0); 
  31.   put(" * KSLOC ** "); put(EXP_MM,2,3,0); new_line;
  32.   set_col(17); put("TDEV = "); put(COEFF_TDEV,2,3,0); 
  33.   put(" * MM ** "); put(EXP_TDEV,2,3,0); new_line(2);
  34.  
  35.   -- input the ManMonth coefficient
  36.   put_line(" Enter coefficient of the ManMonth equation");
  37.   put(" (default = "); put(COEFF_MM,2,3,0); put(") : ");
  38.   begin 
  39.     if END_OF_LINE then
  40.       SKIP_LINE;
  41.     else
  42.       get (PARAMETER); SKIP_LINE;
  43.       COEFF_MM := PARAMETER;
  44.     end if;
  45.   exception
  46.     when others => skip_line;
  47.   end;
  48.   new_line(2);
  49.  
  50.   -- input the ManMonth exponent
  51.   put_line(" Enter exponent of the ManMonth equation");
  52.   put(" (default = "); put(EXP_MM,2,3,0); put(") : ");
  53.   begin 
  54.     if END_OF_LINE then
  55.       SKIP_LINE;
  56.     else
  57.       get (PARAMETER); SKIP_LINE;
  58.       EXP_MM := PARAMETER;
  59.     end if;
  60.   exception
  61.     when others => skip_line;
  62.   end;
  63.   new_line(2);
  64.  
  65.   -- input the Development Schedule coefficient
  66.   put_line(" Enter coefficient of the Development Schedule equation");
  67.   put(" (default = "); put(COEFF_TDEV,2,3,0); put(") : ");
  68.   begin 
  69.     if END_OF_LINE then
  70.       SKIP_LINE;
  71.     else
  72.       get (PARAMETER); SKIP_LINE;
  73.       COEFF_TDEV := PARAMETER;
  74.     end if;
  75.   exception
  76.     when others => skip_line;
  77.   end;
  78.   new_line(2);
  79.  
  80.   -- input the Development Schedule coefficient
  81.   put_line(" Enter coefficient of the Development Schedule equation ");
  82.   put(" (default = "); put(EXP_TDEV,2,3,0); put(") : ");
  83.   begin 
  84.     if END_OF_LINE then
  85.       SKIP_LINE;
  86.     else
  87.       get (PARAMETER); SKIP_LINE;
  88.       EXP_TDEV := PARAMETER;
  89.     end if;
  90.   exception
  91.     when others => skip_line;
  92.   end;
  93.   new_line(2);
  94.  
  95. exception
  96.   when others => put_line ("exception raised in CHANGE_PARAMETER");
  97. end CHANGE_PARAMETERS;
  98. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  99. --banner.ada
  100. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  101. separate (MANPOWER)
  102. procedure PRINT_BANNER_PAGE is
  103. ----------------------------------------------------------------------
  104. --| NAME : PRINT_BANNER_PAGE 
  105. --|
  106. --| OVERVIEW:
  107. --|   This procedure prints the banner page to the report file.  This 
  108. --|   includes the global data input to the program and references
  109. --|   to Barry Boehm's and Tom DeMarco's book (where these equations 
  110. --|   originated.
  111. --|
  112. --| HISTORY:
  113. --|   written by   Bonnie Burkhardt     March 1985
  114. --|
  115. --| EXCEPTIONS HANDLED:
  116. --|   others   An error message is printed and processing continues
  117. --| 
  118. ----------------------------------------------------------------------
  119.  
  120. package ENUMERATION_IO is new TEXT_IO.ENUMERATION_IO (MODE_TYPE);
  121. use ENUMERATION_IO;
  122.  
  123. begin
  124.   -- print out the banner page
  125.   new_page (report); new_line(report, 12); set_col(report, 40); 
  126.   put(report,"Boehm / DeMarco / Estimated Staffing Profiles");
  127.  
  128.   new_line(report, 7); set_col(report, 10);
  129.   put(report," lines of source code in thousands (KSLOC) = ");
  130.   put(report, KSLOC,5,4,0);
  131.  
  132.   new_line(report, 2); set_col(report, 10);
  133.   put(report, "Man-months of effort (equation from ");
  134.   put(report, "Barry W. Boehm, pg.75, table 6-1) = "); new_line;
  135.   put(report, MAN_MONTHS,5,4,0);
  136.  
  137.   new_line(report, 2); set_col(report, 10);
  138.   put(report, "Most likely delivery time (equation from Barry W. Boehm, ");
  139.     put(report, "pg.75, table 601) = ");
  140.   put(report, TD_NOMINAL,5,4,0);
  141.  
  142.   new_line(report, 2); set_col(report, 10);
  143.   put(report, "The impossible region (equation from Tom DeMarco, pg.181) = ");
  144.   put(report, IMP_REGION,3,3,0);
  145.   put(report, " months or less");
  146.  
  147.   new_line(report, 2); set_col(report, 10);
  148.   put(report, "Equation mode type used: ");
  149.   put(report, MODE);
  150.  
  151. exception
  152.   when others => put_line ("exception raised in BANNER");
  153. end PRINT_BANNER_PAGE;
  154. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  155. --graphit.ada
  156. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  157. separate (MANPOWER)
  158. procedure GRAPH_IT (TITLE : in string) is
  159. ----------------------------------------------------------------------
  160. --| NAME : GRAPH_IT
  161. --|
  162. --| OVERVIEW:
  163. --|   This procedure plots the monthly work distribution on a page of 
  164. --|   output.  The graph is scaled vertically with no limitation placed
  165. --|   on staffing requirement values, and horizontally, with the maximum 
  166. --|   amount of time being 100 months.
  167. --|
  168. --| HISTORY:
  169. --|   written by   Bonnie Burkhardt   March 1985
  170. --|
  171. --| EXCEPTIONS:
  172. --|   others   An error message is printed and processing continues
  173. --| 
  174. ----------------------------------------------------------------------
  175.  
  176.   DASHES      : constant string (MONTH_TYPE) := (others => '-');
  177.   MAX_LINES   : constant integer := 30;
  178.   STARS       : constant string (1..20) := (others => '*');
  179.  
  180.   A_MONTH     : MONTH_TYPE := MONTH_TYPE'first;
  181.   BIG_AT      : MONTH_TYPE := MONTH_TYPE'first;
  182.   BIGGEST     : long_float digits 15 := 0.0;
  183.   GRAPH_LINE  : string (MONTH_TYPE);
  184.   HORIZ_SCALE : integer := 3;
  185.   MONTH_WIDTH : integer := 3;
  186.   MONTH_COUNT : integer := 1;
  187.   NUM_LINES   : integer := MAX_LINES;
  188.   STAFF       : array (MONTH_TYPE) of integer range 0..MAX_LINES;
  189.   VERT_SCALE  : long_float digits 15 := 1.0;
  190.   VERT_INDEX  : integer := 1;
  191.  
  192. begin
  193.   -- print header for page
  194.   new_page(report);
  195.   set_col(report, 56); put_line(report, TITLE);
  196.   set_col(report, 56); put_line(report, DASHES(1..20));
  197.  
  198.   new_line(report, 2); put(report,' ');
  199.   put(report, STARS(1..10)); 
  200.   put(report, "     Acceleration rate = ");
  201.   put(report, ACCEL_RATE, 3, 3, 0);
  202.   set_col(report, 60); put(report, STARS(1..5));
  203.   set_col(report, 70); put(report, "Peak staffing occurs around month ");
  204.   put(report, TDEV, 3, 1, 0);
  205.   put(report, "     "); put_line(report, STARS(1..10));
  206.   
  207.   -- print header for graph
  208.   new_line(report, 2);
  209.   put(report, " Staffing Estimate:");
  210.   set_col(report, 110); put_line(report, "Month      Est. Staff");
  211.   set_col(report, 110); put(report, DASHES(1..5));
  212.   set_col(report, 121); put_line(report, DASHES(1..10));
  213.  
  214.   -- find the largest staffing requirement
  215.   for I in STAFFING'first..MONTH loop
  216.     if BIGGEST < STAFFING(I) then
  217.       BIG_AT := I;
  218.       BIGGEST := STAFFING(I);
  219.     end if;
  220.   end loop;
  221.  
  222.   -- compute vertical height of '*' on the graph for each horizontal point
  223.   if BIGGEST > long_float(MAX_LINES) then
  224.     VERT_SCALE := long_float(MAX_LINES) / BIGGEST;
  225.   else
  226.     NUM_LINES := integer(BIGGEST);
  227.   end if;
  228.  
  229.   for I in 1..MONTH loop
  230.     STAFF(I) := integer (STAFFING(I) * VERT_SCALE);
  231.   end loop;
  232.  
  233.   -- compute horizontal scaling and MONTH-COUNT field width
  234.   if MONTH > 50 then
  235.     HORIZ_SCALE := 1;
  236.   elsif MONTH > 33 then
  237.     HORIZ_SCALE := 2;
  238.     MONTH_WIDTH := 4;
  239.   end if;
  240.  
  241.   -- print out graph
  242.   for I in reverse 1..NUM_LINES loop
  243.  
  244.     -- create graph line
  245.     GRAPH_LINE := (others => ' ');
  246.     for J in 1..MONTH loop
  247.       if STAFF(J) = I then
  248.         GRAPH_LINE(J*HORIZ_SCALE) := '*';
  249.       end if;
  250.     end loop;
  251.  
  252.     -- print graph lines
  253.     VERT_INDEX := integer(long_float(I) / VERT_SCALE);
  254.     set_col(report, 3); put(report, VERT_INDEX,5);
  255.     put(report, " |"); put(report, GRAPH_LINE);
  256.     if MONTH_COUNT <= MONTH then
  257.       set_col(report, 111); put(report, MONTH_COUNT,3);
  258.       set_col(report, 121); put(report, STAFFING(MONTH_COUNT),3,5,0);
  259.       MONTH_COUNT := MONTH_COUNT + 1;
  260.     end if;
  261.     new_line(report);
  262.   end loop;
  263.  
  264.   -- print bottom lines of graph
  265.   set_col(report, 9); put(report, "+"); 
  266.   GRAPH_LINE(1..MONTH*HORIZ_SCALE) := DASHES(1..MONTH*HORIZ_SCALE);
  267.   for J in 1..MONTH loop 
  268.     if STAFF(J) = 0 then
  269.       GRAPH_LINE(J*HORIZ_SCALE) := '*';
  270.     end if;
  271.   end loop;
  272.   put(report, GRAPH_LINE);
  273.  
  274.   if MONTH_COUNT <= MONTH then
  275.     set_col(report, 111); put(report, MONTH_COUNT,3);
  276.     set_col(report, 121); put(report, STAFFING(MONTH_COUNT),3,5,0);
  277.     MONTH_COUNT := MONTH_COUNT + 1;
  278.   end if;
  279.   new_line(report);
  280.  
  281.   -- print out month numbers
  282.   set_col(report, 9); put(report, '0');
  283.   A_MONTH := 4-HORIZ_SCALE;
  284.   while A_MONTH <= MONTH loop
  285.     put(report, A_MONTH, MONTH_WIDTH);
  286.     A_MONTH := A_MONTH + (4-HORIZ_SCALE);
  287.   end loop;
  288.   if MONTH_COUNT <= MONTH then
  289.     set_col(report, 111); put(report, MONTH_COUNT,3);
  290.     set_col(report, 121); put(report, STAFFING(MONTH_COUNT),3,5,0);
  291.     MONTH_COUNT := MONTH_COUNT + 1;
  292.   end if;
  293.   new_line(report);
  294.  
  295.   -- print out month label
  296.   set_col(report, 40); put(report, "Duration (months)");
  297.   if MONTH_COUNT <= MONTH then
  298.     set_col(report, 111); put(report, MONTH_COUNT,3);
  299.     set_col(report, 121); put(report, STAFFING(MONTH_COUNT),3,5,0);
  300.     MONTH_COUNT := MONTH_COUNT + 1;
  301.   end if;
  302.   new_line(report);
  303.  
  304.   -- print out remainder of month/staffing requirement table
  305.   for I in MONTH_COUNT .. MONTH loop
  306.     set_col(report, 111); put(report, I,3);
  307.     set_col(report, 121); put(report, STAFFING(I),3,5,0);
  308.     new_line(report);
  309.   end loop;
  310. exception
  311.   when others => put_line ("exception raised in GRAPH_IT");
  312. end GRAPH_IT;
  313. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  314. --getprof.ada
  315. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  316. separate (MANPOWER)
  317. procedure GET_STAFF_PROFILE (PROFILE    : in profile_type;
  318.             ACCEL_INCREMENT : in ACCURATE_FLOAT) is
  319. ----------------------------------------------------------------------
  320. --| NAME : GET_STAFF_PROFILE 
  321. --|
  322. --| OVERVIEW:
  323. --|   This procedure calculates the manpower staffing estimates by month
  324. --|   of various acceleration rates.  The acceleration rates tested start
  325. --|   at ACCEL_INCREMENT and are incremented by ACCEL_INCREMENT for each
  326. --|   successive test.  GRAPH_IT is called to plot a graph of the
  327. --|   distribution for each acceleration rate tested.
  328. --|
  329. --| HISTORY:
  330. --|   written by Bonnie Burkhardt     March 1985
  331. --|
  332. --| EXCEPTIONS HANDLED:
  333. --|   others   An error message is printed and processng continues.
  334. --| 
  335. ----------------------------------------------------------------------
  336.  
  337. DOWN_HILL : boolean := false;
  338.  
  339. begin
  340.   ACCEL_RATE := 0.0;
  341.   OUTER_LOOP:
  342.   loop 
  343.     ACCEL_RATE := ACCEL_RATE +     ACCEL_INCREMENT;
  344.     MONTH := MONTH_TYPE'first;
  345.     TDEV := SQRT(1.0 / (2.0 * ACCEL_RATE));
  346.     STAFFING := (others => 0.0);  -- reset array
  347.  
  348.     -- the inner loop will calculate the manpower (staffing) estimates at
  349.     -- each time period (1 month increments) with a constant acceleration 
  350.     -- rate 'ACCEL_RATE'
  351.     INNER_LOOP:
  352.     loop
  353.       PARAM := -ACCEL_RATE * (long_float(MONTH)**2);
  354.       STAFFING(MONTH) := 2.0 * MAN_MONTHS * ACCEL_RATE * long_float(MONTH) 
  355.             * exp(PARAM);
  356.       DOWN_HILL := STAFFING(MONTH) < STAFFING(MONTH-1);
  357.       if DOWN_HILL and STAFFING(MONTH) < 2.0 then
  358.         exit INNER_LOOP;
  359.       end if;
  360.       MONTH := MONTH + 1;
  361.     end loop INNER_LOOP;
  362.  
  363.     -- graph the appropriate profile
  364.     if PROFILE = NOMINAL then
  365.       if (long_float(MONTH) <= TD_NOMINAL + 0.5) then
  366.         GRAPH_IT ("Nominal     Schedule");   -- nominal schedule has been found
  367.         exit OUTER_LOOP;
  368.       end if;
  369.     else
  370.       if long_float(MONTH) <= TD_NOMINAL then
  371.         GRAPH_IT("COMPRESSED  SCHEDULE");
  372.       else
  373.         GRAPH_IT("EXTENDED    SCHEDULE");
  374.       end if;
  375.       exit when STAFFING(integer(IMP_REGION)) < 2.0;
  376.     end if;
  377.   end loop OUTER_LOOP;
  378.  
  379. exception
  380.   when others => put_line ("exception raised in GET_STAFF_PROFILE");
  381. end GET_STAFF_PROFILE;
  382. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  383. --manpower.ada
  384. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  385. With TEXT_IO;
  386. package INTEGER_IO is new TEXT_IO.INTEGER_IO(integer);
  387. with TEXT_IO;
  388. package LONG_FLOAT_IO is new TEXT_IO.FLOAT_IO(long_float);
  389.  
  390. with TEXT_IO; use TEXT_IO;
  391. with LONG_FLOAT_IO; use LONG_FLOAT_IO;
  392. with INTEGER_IO; use INTEGER_IO;
  393. with IO_EXCEPTIONS; use IO_EXCEPTIONS;
  394. with FLOAT_MATH_LIB; use FLOAT_MATH_LIB;
  395. with LONG_FLOAT_MATH_LIB; use LONG_FLOAT_MATH_LIB;
  396.  
  397. procedure MANPOWER is
  398. ----------------------------------------------------------------------
  399. --| NAME : MANPOWER
  400. --|
  401. --| OVERVIEW:
  402. --|   This program uses Barry Boehm's COCOMO equations and Tom DeMarco's 
  403. --|   PNR cost model to estimate the staffing requirements for a typical 
  404. --|   software project.  Some of the basic man-month estimate equations 
  405. --|   can be modified to reflect the project more accurately.
  406. --|
  407. --| HISTORY:
  408. --|  written by Bonnie Burkhardt     March 1985
  409. --|
  410. --| EXCEPTIONS HANDLED: 
  411. --|   others   an error message is printed and execution terminates
  412. --|
  413. --| NOTES:
  414. --|   The abbreviations MM and TDEV are used in the variable names so 
  415. --|   the equations will more closely correspond to the ones used by Barry 
  416. --|   Boehm.  
  417. ----------------------------------------------------------------------
  418.  
  419.   type PROFILE_TYPE is (NOMINAL, COMPRESSED);
  420.   type MODE_TYPE is (ORGANIC, SEMIDETACHED, EMBEDDED);
  421.   subtype ACCURATE_FLOAT is long_float digits 15;
  422.   subtype MONTH_TYPE is integer range 1..100;
  423.  
  424.   TDEV       : ACCURATE_FLOAT;
  425.   ACCEL_RATE : ACCURATE_FLOAT;
  426.   STAFFING   : array (MONTH_TYPE'first-1..MONTH_TYPE'last) 
  427.                of ACCURATE_FLOAT;
  428.   MONTH      : MONTH_TYPE;
  429.   TD_NOMINAL : ACCURATE_FLOAT;
  430.   IMP_REGION : ACCURATE_FLOAT;
  431.   MAN_MONTHS : ACCURATE_FLOAT;
  432.   REPORT     : file_type;
  433.   FILE_NAME  : constant string := "MANPOWER.RPT";
  434.  
  435.   FINISHED   : boolean := false;
  436.   KSLOC      : ACCURATE_FLOAT;
  437.   MODE       : mode_type;
  438.   PARAM      : ACCURATE_FLOAT;
  439.   CHOICE     : integer range 1..3;
  440.   VALID_ENTRY: boolean := false;
  441.   YES_OR_NO  : character := 'N';
  442.  
  443.   -- parameters of the equations that may be varied
  444.   COEFF_MM_ORG     : ACCURATE_FLOAT := 2.4;
  445.   COEFF_MM_SEMI    : ACCURATE_FLOAT := 3.0;
  446.   COEFF_MM_EMBED   : ACCURATE_FLOAT := 3.6;
  447.   EXP_MM_ORG       : ACCURATE_FLOAT := 1.05;
  448.   EXP_MM_SEMI      : ACCURATE_FLOAT := 1.12;
  449.   EXP_MM_EMBED     : ACCURATE_FLOAT := 1.20;
  450.   COEFF_TDEV_ORG   : ACCURATE_FLOAT := 2.5;
  451.   COEFF_TDEV_SEMI  : ACCURATE_FLOAT := 2.5;
  452.   COEFF_TDEV_EMBED : ACCURATE_FLOAT := 2.5;
  453.   EXP_TDEV_ORG     : ACCURATE_FLOAT := 0.38;
  454.   EXP_TDEV_SEMI    : ACCURATE_FLOAT := 0.35;
  455.   EXP_TDEV_EMBED   : ACCURATE_FLOAT := 0.32;
  456.  
  457.   procedure CHANGE_PARAMETERS (NAME : in string;
  458.             COEFF_MM    : in out ACCURATE_FLOAT; 
  459.             EXP_MM      : in out ACCURATE_FLOAT;
  460.             COEFF_TDEV  : in out ACCURATE_FLOAT;
  461.             EXP_TDEV    : in out ACCURATE_FLOAT) is separate;
  462.   procedure PRINT_BANNER_PAGE is separate;
  463.   procedure GRAPH_IT (TITLE : in string) is separate;
  464.   procedure GET_STAFF_PROFILE (PROFILE  : in PROFILE_TYPE;
  465.             ACCEL_INCREMENT : in ACCURATE_FLOAT) is separate;
  466.  
  467. begin
  468.   -- open report file
  469.   create (REPORT, NAME => FILE_NAME);
  470.  
  471.   -- change the parameters of the equations, if desired
  472.   new_line(6);
  473.   put("Would you like to change any of the parameters in the COCOMO equations?");
  474.   new_line; put(" (Y or N -- def=N) : "); 
  475.   begin
  476.     if not END_OF_LINE then
  477.       get(YES_OR_NO); skip_line; new_line(3);
  478.       if YES_OR_NO = 'Y' or YES_OR_NO = 'y' then
  479.     put_line ("Enter the value of the parameter (X.X)");
  480.     put_line ("(Press <ret> to assume the default value)");
  481.  
  482.     CHANGE_PARAMETERS ("Organic", COEFF_MM_ORG, EXP_MM_ORG, 
  483.             COEFF_TDEV_ORG, EXP_TDEV_ORG);
  484.     CHANGE_PARAMETERS ("Semidetached", COEFF_MM_SEMI, EXP_MM_SEMI,
  485.             COEFF_TDEV_SEMI, EXP_TDEV_SEMI);
  486.     CHANGE_PARAMETERS ("Embedded", COEFF_MM_EMBED, EXP_MM_EMBED,
  487.             COEFF_TDEV_EMBED, EXP_TDEV_EMBED);
  488.       end if;
  489.     end if;
  490.   exception
  491.     when others => skip_line;
  492.   end;
  493.  
  494.   -- repeat until user specifies to quit
  495.   while not finished loop
  496.     -- get lines of code estimate
  497.     VALID_ENTRY := false;
  498.     new_line(6);
  499.     put(" Enter # of lines of source code in thousands (XX.X) : ");
  500.     loop
  501.       begin 
  502.         get (KSLOC);
  503.         exit;
  504.       exception
  505.         when others => 
  506.           skip_line; new_Line;
  507.           put("Invalid input, try again (e.g., 0.2 or 2.0) : ");
  508.       end;
  509.     end loop;
  510.  
  511.     -- get the MODE type
  512.     new_line(4);
  513.     put_line(" Basic Cocomo Effort and Schedule Equations:");
  514.     set_col(10); put_line("1. Organic");
  515.     set_col(10); put_line("2. Semidetached");
  516.     set_col(10); put_line("3. Embedded"); new_line(3);
  517.     put(" Enter number corresponding to MODE type desired: ");
  518.  
  519.     loop
  520.       begin 
  521.         get (CHOICE); skip_line;
  522.         exit;
  523.       exception
  524.         when others => 
  525.           skip_line; new_line;
  526.           put("Invalid input, try again :");
  527.       end;
  528.     end loop;
  529.  
  530.     -- Calculate the MAN_MONTHS of effort and the month estimate for project
  531.     -- final delivery using the user specified effort equation.  These
  532.     -- equations are Boehm's equations and can be slightly modified to reflect
  533.     -- closer estimations, if desired.
  534.     case CHOICE is
  535.       when 1 => MODE := ORGANIC;
  536.     MAN_MONTHS := COEFF_MM_ORG * exp(EXP_MM_ORG * log(KSLOC));
  537.     TD_NOMINAL := COEFF_TDEV_ORG * exp(EXP_TDEV_ORG * log(MAN_MONTHS));
  538.       when 2 => MODE := SEMIDETACHED;
  539.     MAN_MONTHS := COEFF_MM_SEMI * exp(EXP_MM_SEMI * log(KSLOC));
  540.     TD_NOMINAL := COEFF_TDEV_SEMI * exp(EXP_TDEV_SEMI * log(MAN_MONTHS));
  541.       when 3 => MODE := EMBEDDED;
  542.     MAN_MONTHS := COEFF_MM_EMBED * exp(EXP_MM_EMBED * log(KSLOC));
  543.     TD_NOMINAL := COEFF_TDEV_EMBED * exp(EXP_TDEV_EMBED * log(MAN_MONTHS));
  544.     end case;
  545.  
  546.     -- calculate the impossible region.
  547.     IMP_REGION := 1.9 * exp(0.3333333333333 * log(MAN_MONTHS));
  548.  
  549.     PRINT_BANNER_PAGE;
  550.  
  551.     -- find the nominal staffing profile
  552.     GET_STAFF_PROFILE(NOMINAL,0.001);
  553.  
  554.     -- find the compressed and expanded staffing profiles
  555.     GET_STAFF_PROFILE(COMPRESSED,0.01);
  556.  
  557.     -- determine if user wishes to continue
  558.     new_line(2);
  559.     put(" Do you want to write another report (Y or N -- def=N): ");
  560.     begin 
  561.       if END_OF_LINE then
  562.     FINISHED := true;
  563.       else
  564.     get (YES_OR_NO);
  565.     if YES_OR_NO /= 'Y' and YES_OR_NO /= 'y' then
  566.       FINISHED := true;
  567.     end if;
  568.       end if;
  569.     exception  -- default is 'N'
  570.       when others => skip_line;
  571.     end;
  572.   end loop;
  573.  
  574.   close (report);
  575.  
  576. exception
  577.   when others => put_line ("exception raised in MANPOWER");
  578. end MANPOWER;
  579.  
  580.