TweetFollow Us on Twitter

FaceIt Fortran
Volume Number:5
Issue Number:9
Column Tag:Fortran's World

FaceIt Saves Fortran

By Mark McBride, Oxford, CA

Porting Number Crunching Routines

When the first Fortran articles appeared in MacTutor the goal was to discuss porting Fortran applications to the Mac. The articles I have written evolved into a discussion of programming the Mac interface using MacFortran. Porting Fortran programs really meant running the program in its sequential, non-Mac, form unless you were willing to invest substantial time re-writing the user front-end to your code. The advent of MPW based Fortran’s (Language Systems is shipping and Absoft is reportedly working on a MPW Fortran compiler) means we may eventually get MacApp support. But even MacApp support would mean writing your own event loop and window environment.

Enter FaceIt. FaceIt has been discussed previously in MacTutor. Chuck Bouldin reviews the basics of FaceIt (formerly known as MacFace) in the July 1987 issue. FaceIt’s author, Dan Kampmeier wrote a letter to the editor in which he presents where FaceIt can be beneficial. While earlier versions of FaceIt made adding a Mac interface easier for text windows and plotting graphs, most of my work as an economist involves heavy number crunching routines. The basic structure of the Fortran program sets up the data and parameters to be used, passes the array to a subroutine to calculate, and then writes out the results.

Version 3.3 of FaceIt adds a feature, sheets, which dramatically increases its value in porting number crunching Fortran programs. A sheet in FaceIt is a spreadsheet tagged to any numeric array you choose. The user can enter and edit the numeric values in the array with spreadsheet ease. The program can have as many as four sheets open at once. Sheets will be explained below.

Figure 1. A Sheet

At the same time that FaceIt was adding sheets, Absoft technical support released a subroutine which allows dynamic array allocation (phone 904 423-7587 to get a copy). Provision of a method of dynamically allocating arrays means that the toolbox memory manager can be used to allocate a block of memory for the array, with the size of the array depending on available memory. When the program needs a new array of different dimensions, the old array can be de-allocated, thus recapturing its space for use with the new array.

Given that using FaceIt is resource intensive, I have tried to structure the article into the main issues confronted with porting an existing number crunching program to a Mac interface. The example program (Listing One) is a general data editor program with a subroutine for calculating the means of the selected observations (rows) of the selected variables (columns). The user is given the opportunity to analyze (via a dialog) a set of variables and observations other than the current selection in the sheet window. The source code given can be used with very little modification to move your number crunching subroutine into a Mac interface. The structure for creating, opening, and saving real*8 arrays is provided. Just define the appropriate arrays and add your favorite cruncher.

Data Editor

Dynamic Arrays

Absoft has released an assembly language routine which allows a programmer to allocate memory using the toolbox and then assign an array to the newly allocated memory block. The process is straightforward.

• code a new main program to allocate an array (of any size) and call your original main program as a subroutine. For example:

 PROGRAM shell
 real*8 thearray(1)
 call main(thearray)
 end

• rewrite your main program as a subroutine which accepts an array as an argument. Continuing the example:

 SUBROUTINE main(thearray)
 real*8 thearray(*)
 integer i,toolbx,blkptr
 include memory.inc
 blkptr=toolbx(NEWPTR,1024)
 call dynam(blkptr)
 do (i=1,100)
   myarray(i)=i
 repeat
 call Cruncher(thearray)
 call toolbx(DISPOSEPTR,blkptr)
 return
 end
 SUBROUTINE Cruncher(thearray)
 real*8 thearray(*)
 {do something with the array}
 return
 end

• by allocating a new block of memory with the toolbox routine NEWPTR or NEWHANDLE, as much memory as can be reasonably retrieved can be used. If you use NEWHANDLE, be sure to lock the block in place before calling the dynam subroutine and using the memory space.

• When using dynam, the last argument passed in the subroutine call will be redirected to the allocated memory block. The ‘C’ compile option for detecting array boundary overruns will not be functional and cannot be used when compiling the program.

• To allocate a new array of a different size dispose of the old memory allocation, allocate a new pointer or handle and then just recall dynam. For example:

 Subroutine Main (thearray)
 ....
 blkptr=toolbx(NEWPTR,1024)
 call dynam(blkptr)
 {... use the array ...}
 call toolbx(DISPOSPTR,blkptr)
 blkptr=toolbx(NEWPTR,2048)
 call dynam(blkptr)
 {... use the new array space ...}
 ...

The only other task is to do error checking. Examination of the Data Editor program (Listing One) demonstrates simple error checking.

Event Handling

A Mac interface is programmed essentially as a continuously repeated event loop. When the user indicates an action, then an appropriate response is made. FaceIt simplifies adding the event driven loop by handling all the usual events in a Mac interface: standard menus; text window events; dialogs; text cut, copy, or paste; and sheet window events. The programmer concentrates on handling the program specific menu selections. A simple FaceIt program has the following event loop structure:

 do
   call FaceIt(0,0,0,0,0,0) !give control to user
   select case (MAC) !MAC tells us which menu chosen
     case(‘About’)
     .....{do about action}
     case(‘Means’)
     .....{do means action}
   end select
 repeat

The call FaceIt(0,0,0,0,0,0) turns control over to the FaceIt event loop, which handles events until a user specifies a program specific menu action. Thus the programmer need not be worried about dragging and re-sizing windows, tracking menu actions, handling DA’s, handling text entry in a text edit window, opening or saving text edit windows to disk, or number entry and editing in a spreadsheet window. When the user specifies a program specific menu action, FaceIt returns control to the programmer, passing the menu selection in the global variable MAC. Thus the programmer focuses on handling the program specific actions, not the basic Mac interface actions.

In the Data Editor program, one sheet window and one text edit window has been specified by retaining only wind resources #1001 and #1006 in the program specific copy of the FaceIt resources (more below on FaceIt resources). The FaceIt ‘File’ menu resource has been modified to include a ‘New Sheet’ choice:

The open, save as, and append to actions are provided by FaceIt for the text edit window. However, for the sheet window, we must provide our own open and save routines. The print routine will print the currently active window (either the text window or the sheet window). The only other menu added is the options menu (ID#105) which contains one item:

When selected, the current array assigned to the sheet window is passed to the routine which calculates the means of the selected observations. The results of the calculations are passed back to the text editor window for viewing, printing, and saving. Thus our program must contain code for creating a new array and tagging it to a sheet, opening and saving the sheet (array) to binary disk files, the means routine which operates on an array passed to it, and quitting (to insure the option of saving changes in the current sheet to the disk file).

New Sheet

Allocation of a new sheet in FaceIt using dynamic arrays involves a few simple steps. These steps are followed for creation of a brand new sheet or for opening into a sheet from a saved data file (see Listing One).

• If an existing sheet exists, then call a save routine to save the existing data.

• Call a setup dialog to get the number of rows and columns for the new array. Upon entry to the dialog, use COMPACTMEM to determine available space. Next retrieve the number of rows and columns from the user via a dialog. Finally, check to see if the requested number of data cells can fit in available memory (leaving a buffer for other program use). If the array can be allocated return to the new sheet allocation.

• If the number of cells requested can be allocated, dispose of the existing array in the heap, then call FaceIt’s NEWBLK routine. FaceIt’s routine will provide additional memory error handling protection over and above the toolbox routines (NEWPTR, NEWHANDLE). NEWBLK allocates a new handle in the heap and locks it in place.

• If the new memory is successfully allocated on the heap, call dynam to redirect the array to new memory space.

• Finally, relate the array to the sheet and clean up the sheet display with calls to the FaceIt routines SetSh and FixSh.

Following these steps the program can continually reuse heap space to allocate the array to the size needed whenever the user requests a new sheet or opens into a the sheet from a disk file. Notice allocating the array in heap space means that the program can be used under MultiFinder and will only use space allocated to the program.

Saving

Saving the current array to a binary disk file is a straight forward process. The format of the binary save is nmax, kmax (the number of rows and columns), the kmax titles, and finally the data. The steps are:

• If the user selected ‘save as’ set the current name to null. If the data has not been previously saved (name is null), call FaceIt’s StdSav routine to use the standard save dialog to select the disk file name. FaceIt returns the name the user selected in the variable ‘name’.

• If the user did not click cancel, then open the disk file as unformatted and write the data.

• Reset the sheet title to reflect the current name.

• Set the disk file type flag to ‘DPTE’ which indicates a binary data file created by the Data Editor program.

Opening

Opening an existing binary data file into the the array is much the same process as creating a new sheet. The binary data file must have been created with a save command from the Data Editor program and have a file type of ‘DPTE’. The steps to open are:

• If the user clicks cancel during any of the following steps, drop through the routine, leaving the current array/sheet intact.

• If an existing sheet exists, then call a save routine to save the existing data.

• Call the FaceIt routine StdOpn with a file type of ‘DPTE’ passed via the variable MAC. This will present the user with the standard file package open routine displaying only binary data files created by Data Editor.

• Dispose the existing array in the heap, read in the number of cells in the data file (nmax, kmax), then call FaceIt’s NEWBLK routine.

• If the new memory is successfully allocated on the heap, call dynam to redirect the array to new memory space, then read in the titles and data values.

• Finally, relate the array to the sheet and clean up the sheet display with calls to the FaceIt routines SetSh and FixSh.

Means

The means routine expects an array, the number of rows, and the number of columns. A dialog is called to have the user select the observations and variables on which to perform the analysis. The selection dialog could have been handled prior to the call to the means routine and the selection passed as an argument to the means subroutine. The dialog defaults to the current selection in the sheet window. The means are calculated and then output to the text edit window starting at the current selection point. Given the simple output nature of the means subroutine, I put the FaceIt calls necessary to write to the text edit window in the routine. However, on many occasions, there a substantial number of write statements. In those cases, the write statements can be sent to a temporary disk file and then the disk file opened into the text edit window (all with a few simple FaceIt calls).

Quitting

FaceIt normally handles the quit routine, but the programmer can have FaceIt return control during the quit sequence. The Data Editor program has a small quit routine which asks the user if the current sheet should be saved before quitting (or transferring) and then returns control to FaceIt to complete the quit (or transfer) process.

Resource Basis

Using FaceIt to attach a Mac interface is a resource intensive process. Whenever you start a new program, you copy the FaceIt resource file (called Resources) giving the copy a new name. The initial call to FaceIt expects the name of the resource file to be in the ‘name’ variable. Rezedit can be used to modify and add to the FaceIt resources. The resource file contains window resources for 4 text editors, 4 sheet windows, and 2 graph windows. By removing all the unwanted window resources, FaceIt knows how many windows (and their types) to use when starting. The standard FaceIt menus can be added to (but not removed) for your program specific actions. As shown earlier, Data Editor adds one item to the FaceIt File menu and adds one new menu (options).

One major aspect of using FaceIt is the handling of dialogs. By carefully constructing the dialog in Rezedit, the programmer can let FaceIt handle most of the dialog actions. The programmer only needs to worry about getting info into and out of the dialog. The FaceIt routine to handle dialogs is called Opndlg. The basic steps in using a dialog are:

• Create the dialog in Rezedit, assigning it a proc id of 0 and a resource ID greater than 1005 (Kampmeier may add modeless dialogs in a future release of FaceIt with ID’s 1001-1004).

• In the program code, set the default status of items via the shared array ‘dialog’.

• Set the default values for edit text items via the ‘name’ variable.

• Call the FaceIt routine OpnDlg.

• Read the changes made by the user to text items via the ‘name’ variable.

• Read the status of the items via the array ‘dialog’.

The Data Editor program uses two dialogs: one to get the new array size when the New Sheet menu item is selected, and one to get the observations and variables to number crunch.

New Sheet

The New Sheet dialog contains seven items. The DITL from Rezedit is shown below. The circles indicate the item number and the item type is listed next to the circle. The number in parenthesis indicates the value passed to the FaceIt’s array ‘Dialog’.

Figure 2. Dialog Parameters

Writing the default values for nmax and kmax to the new sheet dialog is easy from Fortran. A write(name,’2i8') nmax,kmax statement will stuff the values of nmax and kmax in the ‘name’ variable with the format I8. Notice that the values specified in the DITL for the editable text items gave the width each item was to take in the ‘name’ variable (in the case at hand, 8 spaces each).

When an enable dialog item has been activated by the user, FaceIt’s OpnDlg routine returns control to the program with the item number activated in array element ‘Dialog(1)’. For the new sheet dialog, I check for a click in the ok or cancel buttons. Actions in the edit text items are handled by FaceIt and the Data Editor program need not taken any additional action. If the ok button is clicked, then a read(name,’2i8')nmax,kmax statement will return the values of nmax and kmax specified by the user. When in operation the dialog appears as follows to the user:

Select Observations

The other custom dialog in the Data Editor program requests from the user which observations (rows) and variables (columns) of the spreadsheet to perform the calculations upon. The select observations dialog contains eight items. The DITL from Rezedit is given below. Again, the circles indicate the item number and the item type is listed next to the circle. The number in parenthesis indicates the value passed to the FaceIt’s array ‘Dialog’.

Notice that this dialog is very similar to the new sheet dialog and operates almost exactly the same manner. The starting and ending observations default values are passed by writing FaceIt’s variable selrect to the ‘name’ variable. The major difference is the inclusion of the user item (#8).

The user item provides space for a selection list. The names of the columns (which are maintained in a STR# resource) are passed by assigning the STR# resource ID to the FaceIt variable listID(1). Each variable (column) which was currently selected by the user has an asterisk append at the beginning to indicate to FaceIt that these variables are currently selected. The selection list will appear with those variables selected. Note that FaceIt does support multiple or single selections in a list, but the multiple selections must be contiguous (non-contiguous selections in a list are not support by the List Manager). After the user has clicked the ok button, the program can determine which items in the list were selected by searching for an asterisk at the start of each column name.

The dialog appears as follows to the user:

A final note about the selection dialog. If the user indicates an ending observation greater than the number of rows than all available observations are used.

Alerts

FaceIt also provides for the handling of alerts. Although alerts can be called easily from most any language, the advantages of using FaceIt are updating of windows behind the alert prior to giving control to the user and delaying the alert when the application is in the background under MultiFinder until the application is switched to the foreground. Examination of the Data Editor source indicates how easily alerts are integrated into a FaceIt program. The alerts used in Data Editor and their DITL lists are:

• About alert (ID # 1009)

• Memory Error Alert (ID # 1005)

• Save or Discard Alert (ID # 1030)

Cleaning Up

The program given in Listing One and the resources picture previously will allow you to get Data Editor up and running. Of course, FaceIt has to be on the disk, in the system file, or attached to the program. The remaining tasks to turn Data Editor into a true Mac application was to provide online help and assign custom icons. FaceIt gives you the ability to do both.

Customizing Help

FaceIt provides a limited ability to customize its help for your application. Given that FaceIt expects the Apple, File, Edit, and Window menus to be as designed, adding help under the Apple menu is not straight forward. In addition, FaceIt’s help under the Apple menu must remain, even though many aspects of it may not be apply to your application (why have graph help when your are not doing graphs). Version 3.3 supports some customization of the FaceIt help. You can re-assign some of the help buttons to your own custom help alerts and you can hide the others from view. I liked the heap space indicator and clipboard display of the FaceIt help alert, but didn’t need the graphing help buttons. Thus, I customized the help alert as shown:

To perform these customizations, the FaceIt alerts must be copied from the FaceIt file to your resource file. FaceIt will check for these resources in the applications resource file before using its own. In the customization, button item # 21 is connect to alert ID # 1102. My custom help alert ID # 1102 appears as:

Attaching Icons

The FaceIt manual provides simple step by step instructions for attaching icons using the BNDL resource. The creator was set to ‘MMDE’ with icons and Frefs set. The custom icons (with the ID #’s) for the Data Editor program are:

The ‘MMDE’ resource was created with the text that displays under the Get Info Finder menu option.

Conclusion

The major element necessary to customize this program for your favorite number crunching routine is the appropriate declaration of arrays and other variables, appropriate menu choices for actions to be undertaken with the arrays, and calls to the number crunching routines. The addition of sheets to FaceIt makes it relatively painless to port you Fortran programs to a Mac user interface and the Data Editor program provides the shell you need to start.

Listing One

***************************************************************
*  Data Editor                                                   
*  © 1988 by Mark E. McBride                                     
*            1205 Dana Drive                                     
*            Oxford, OH  45056                                       
                                                            
*  Developed using Absoft MacFortran/020 and FaceIt.             
*  Program provides a Mac user interface to which number         
*  crunching routines can easily be added.  Takes advantage      
*  of FaceIt’s general event loop, standard Mac environment,     
*  sheet windows.                                                    
                                                            
**************************************************************
      PROGRAM DataEdit
 real*8 pt(1)
 call main(pt)
 end
 
 Subroutine main(pt)
 implicit none
*  Absoft toolbox parameter equates, change path to reflect
*  your disk setup.
 include HD40:Fortran:Include Files:memory.inc
 INTEGER PTR
 PARAMETER (PTR=Z’C0000000')
*  Local variables
 real*8 pt(*)
      integer*4 toolbx,i,j,npt,PtPtr,PtHdl
 integer*4 action,nmax,kmax
 character*256 Head,saveMAC
 logical*1 check
 
*  Include FaceIt declarations
 include HD40:Fortran:FaceIt:StorMF.inc

*load JumpMF !!!REMOVE line if JumpMF is linked to program!!!
*load toolbx  !!!REMOVE line if toolbx is linked to program!!

      name = ‘DEdit.Rsrc’           !temporary resource file
      call FaceIt(1,1,-1,50,1,2)    !initialize FaceIt

*  setup default array information
 data nmax/100/
 data kmax/2/
 
*  set initial sheet to 1x1 array so that open command
*  is available, do not hide sheet
*  sheet window must be active window to get open routine
*  called for the sheet.
 PtPtr=0!pointer to pt array
 PtHdl=0!handle to pt array

* The use of “1” for the first argument of the SetSh1 command
* indicates that we will support “Open”, “Save As”, and “Save”
* for this sheet.
 pt(0)=0
 name=’empty’
 arrayptr(1) = toolbx(PTR,pt)
 call FaceIt(1,SetSh1,1,1,0,-6)
 call FaceIt(0,ShoSh1,RetCtl,0,0,0)
*  Set Means... menu off until an array has been tagged to
*  the sheet.
   call UpdateMenu(menuhdl(5),PtPtr)
   
*  Main loop
      do
        call FaceIt(0,0,0,0,0,0)        !give control to user
   select case (MAC)
     case(‘About’)
       call FaceIt(0,OpnAlt,1009,0,0,0)  !open “About” alert
* points can be loaded from a DEdit data file.  Data format
* consists of nmax, kmax, kmax string titles, the data.
     case(‘Open’)
       Head=’opening sheet’
 action=0
 if (PtPtr<>0) then
   call FaceIt(1,FixSh1,RetCtl,0,0,0)
   call SaveIt(Head,action)
 end if
 if (action=1)
     +      call SaveDa(pt,nmax*kmax,nmax,kmax)
 MAC = ‘DPTE’
 if (action<3) call FaceIt(0,StdOpn,0,0,0,0)
 if ((name<>’Cancel’).and.(action<3)) then
   if (PtPtr<>0)
     +  call toolbx(DISPOSHANDLE,PtHdl)
   open(3,file = name,status = ‘old’,
     +                      form=’unformatted’)
   read(3)nmax,kmax
   I4=nmax*kmax*8
   call FaceIt(0,NewBlk,0,0,0,0)
   if (I4<>0) then
     PtHdl=I4
     PtPtr=long(I4)
     call dynam(PtPtr)
   else
     MAC=’Failed to allocate memory.’
     call FaceIt(0,OpnAlt,1005,0,0,0)
     stop
   end if
   do (i=1,nmax*kmax)
     pt(i)=0
   repeat
   do (i=1,kmax)
     read(3)Head
     MAC=trim(Head)
     call FaceIt(0,SetStr,1001,i,0,0)
   repeat
   read(3)(pt(i),i=1,nmax*kmax)
   close(3)
   arrayptr(1) = toolbx(PTR,pt)
   call FaceIt(1,SetSh1,nmax,kmax,0,-6)
   fixrect(1)=1;fixrect(2)=1;
   fixrect(3)=nmax;fixrect(4)=kmax;
   call FaceIt(1,FixSh1,0,0,0,0)
 end if
* We also support the saving of points back to disk...
     case(‘Save As’,’Save’)
       if (MAC=’Save As’) name=’’
 call SaveDa(pt,nmax*kmax,nmax,kmax)
* Create a new array and tag it to the sheet window
     case(‘New Sheet’)
       Head=’setting new sheet’
 action=0
 if (PtPtr<>0) then
   call FaceIt(1,FixSh1,RetCtl,0,0,0)
   call SaveIt(Head,action)
 end if
 if (action=1)
     +      call SaveDa(pt,nmax*kmax,nmax,kmax)
 check=.false.
 if (action<3) call NewDlg(nmax,kmax,check)
 if ((check).and.(action<3)) then 
         if (PtPtr<>0)
     +            call toolbx(DISPOSHANDLE,PtHdl)
   I4=nmax*kmax*8
   call FaceIt(0,NewBlk,0,0,0,0)
   if (I4<>0) then
     PtHdl=I4
     PtPtr=long(I4)
     call dynam(PtPtr)
   else
     MAC=’Failed to allocate memory.’
     call FaceIt(0,OpnAlt,1005,0,0,0)
     stop
   end if
   do (i=1,nmax*kmax)
     pt(i)=0
   repeat
   name=’’
   do (i=1,kmax)
     I4=i
     call FaceIt(0,I4ToS,0,0,0,0)
     MAC=’X’//trim(MAC)
     call FaceIt(0,SetStr,1001,i,0,0)
   repeat
   arrayptr(1) = toolbx(PTR,pt)
   call FaceIt(1,SetSh1,nmax,kmax,0,-6)
   fixrect(1)=1;fixrect(2)=1;
   fixrect(3)=nmax;fixrect(4)=kmax;
   call FaceIt(1,FixSh1,0,0,0,0)
 end if
     case(‘Quit’,’Transfer’)
       saveMAC=MAC
 if (MAC=’Quit’)Head=’Quitting’
 if (MAC=’Transfer’)Head=’Transferring’
 action=0
 if (PtPtr<>0) then
   call FaceIt(1,FixSh1,RetCtl,0,0,0)
   call SaveIt(Head,action)
 end if
 if (action=1)
     +      call SaveDa(pt,nmax*kmax,nmax,kmax)
 if (action<3) then
   if (saveMAC=’Quit’) then
     call FaceIt(0,DoQuit,0,0,0,0)      !complete Quit
   else if (saveMAC=’Transfer’) then
     call FaceIt(0,DoTran,0,0,0,0)      !complete Transfer
   end if
 end if
     case(‘Means...’)
   call Means(pt,nmax,kmax)
     case default
   end select
   call UpdateMenu(menuhdl(5),PtPtr)
 repeat
      end

* The following menu-updating routine keeps a single menu item
* updated.
 SUBROUTINE UpdateMenu(amenuhdl,aPtr)
 implicit none
      INTEGER ENABLEITEM
      PARAMETER (ENABLEITEM=Z’93911000')
 INTEGER DISABLEITEM
 PARAMETER (DISABLEITEM=Z’93A11000')
 integer*4 amenuhdl,aPtr
 if (aPtr<>0) then !data in array
   call toolbx(ENABLEITEM,amenuhdl,1)
 else
   call toolbx(DISABLEITEM,amenuhdl,1)
 end if
 end

*  Write data to output file
 Subroutine SaveDa(pt,npts,nmax,kmax)
 implicit none
     real*8 pt(npts)
 integer*4 i,npts,nmax,kmax
 character*256 Head
 
      include HD40:Fortran:FaceIt:StorMF.inc
 
 if (trim(name)=’’) then
   MAC = ‘Save data points as’
   call FaceIt(0,StdSav,0,0,0,0)
 end if
 if (name <> ‘Cancel’) then
   open(3,file = name,status = ‘new’,form=’unformatted’)
   write(3)nmax,kmax
   do (i=1,kmax)
     call FaceIt(0,GetStr,1001,i,0,0)
     Head=trim(MAC)
     write(3)Head
   repeat
   write(3)(pt(i),i=1,npts)
   close(3)
   call FaceIt(1,MovSh1,0,0,0,0)  !reset title
   MAC = ‘DPTE’
   call FaceIt(0,SetTyp,RetCtl,0,0,0)
      end if
 end

*  means sub calculates the means of the selected variables
*  Over the selected observations
 Subroutine Means(pt,nmax,kmax)
 implicit none
 integer*4 nmax,kmax
 real*8 pt(nmax,kmax),sum,xbar
      integer*4 toolbx,i,j
 integer*4 nbeg,nend,kbeg,kend
 character*80 head(10),temp
 logical*1 check

      include HD40:Fortran:FaceIt:StorMF.inc

*  call dialog to get observations and variables
 call SelObs(nbeg,nend,nmax,kmax,check)
 if (check) then
*  Write out headers, first select output window
*  then write out information
   head(1)=’Calculated Means’
   head(2)=’’
   write(temp,’(i5)’) nbeg
   head(3)=’Observations:  # ‘//trim(temp)
   write(temp,’(i5)’) nend
   head(3)=trim(head(3))//’ to # ‘//trim(temp)
   head(4)=’’
   do (i=1,4)
     MAC=head(i)
     call FaceIt(-1,RetCtl,0,0,0,0)
   repeat
  
*  Calculate Means and print out results
   kbeg=0
   kend=0
   do (j=1,kmax)
     call FaceIt(0,GetStr,1001,j,0,0)
     if (MAC(1:1)=’*’) then
       if (kbeg=0) kbeg=j
 if ((kend=0).or.(kbeg>0)) kend=j
       sum=0
 do (i=nbeg,nend)
   sum=sum+pt(i,j)
 repeat
 xbar=sum/(nend-nbeg+1)
 write(temp,’(f12.6)’) xbar
 call FaceIt(0,GetStr,1001,j,0,0)
 MAC=’Mean of ‘//trim(MAC(2:22))//’= ‘//trim(temp)
 call FaceIt(-1,RetCtl,0,0,0,0)
     end if
   repeat
   selrect1(1)=nbeg
   selrect1(3)=nend
   selrect1(2)=kbeg
   selrect1(4)=kend
   fixrect(1)=1;fixrect(2)=1;
   fixrect(3)=nmax;fixrect(4)=kmax;
   call FaceIt(0,FixSh1,0,0,0,0)
 end if
 do (j=1,kmax)
   call FaceIt(0,GetStr,1001,j,0,0)
   if (MAC(1:1)=’*’) then
     MAC=MAC(2:len(trim(MAC)))
     call FaceIt(0,SetStr,1001,j,0,0)
   end if
 repeat 
 MAC=’ ‘
 call FaceIt(-1,RetCtl,0,0,0,0)
 MAC=’ ‘
 call FaceIt(-1,RetCtl,0,0,0,0)
 end

*  Set bounds for a new sheet
 subroutine NewDlg(nmax,kmax,check)
 implicit none
  integer*4 toolbx,i,nmax,kmax,avail
 integer*2 mydialog(7)
 logical*1 check
 character*256 oldname
*  Absoft toolbox param equates, change path for your setup
 include HD40:Fortran:Include Files:memory.inc
      include HD40:Fortran:FaceIt:StorMF.inc

 save mydialog
 data mydialog/0,0,-2,0,-2,0,-2/
 oldname=name
 write(name,10) nmax,kmax
10 format(2i8)
 do (i = 1,7)
   dialog(i) = mydialog(i)
 repeat
 check=.false.
 avail=toolbx(COMPACTMEM,8000000)
 while (check<>.true.)
   call FaceIt(0,OpnDlg,1010,0,0,0)      !open dialog #1010
   if (dialog(1) = 1) then
     read(name,12) nmax,kmax
12        format(2i8)
     if (nmax*kmax*8>avail-20000) then
       write(MAC,*)’Not enough memory. ‘,
     +      (avail-20000)/8,’ cells available.  ‘,
     +      ‘Click to continue.’
 call FaceIt(0,OpnAlt,1005,0,0,0)
     else
       check=.true.
 do (i = 1,7)                       !update all values
   mydialog(i) = dialog(i)
 repeat
     end if
   else if (dialog(2)=1) then
     check=.false.
     call FaceIt(0,RetCtl,0,0,0,0) !close dialog window
     name=oldname
     return
   end if
 repeat
 call FaceIt(0,RetCtl,0,0,0,0)!close dialog window
 end

*  Set observations to perform means on
 subroutine SelObs(nbeg,nend,nmax,kmax,check)
 implicit none
  integer*4 nbeg,nend,nmax,kmax
 integer*4 toolbx,i,j
 integer*2 mydialog(8)
 logical*1 check
 character*256 oldname
 
      include HD40:Fortran:FaceIt:StorMF.inc

 data mydialog/0,0,-2,0,-2,0,-2,0/
 oldname=name
 write(name,10) selrect1(1),selrect1(3)
10 format(2i8)
 do (j=selrect1(2),selrect1(4))
   call FaceIt(0,GetStr,1001,j,0,0)
   MAC=’*’//trim(MAC)
   call FaceIt(0,SetStr,1001,j,0,0)
 repeat
 do (i = 1,8)
   dialog(i) = mydialog(i)
 repeat
 listID(1)=-1001
 check=.false.
 while (check<>.true.)
   call FaceIt(0,OpnDlg,1020,0,0,0)        !open dialog #1020
   if (dialog(1) = 1) then
     read(name,12) nbeg,nend
12        format(2i8)
   if (nend>nmax) nend=nmax
     do (i = 1,8)                          !update all values
 mydialog(i) = dialog(i)
     repeat
     check=.true.
   else if (dialog(2)=1) then
     call FaceIt(0,RetCtl,0,0,0,0) !close dialog window
     check=.false.
     name=oldname
     return
   end if
 repeat
 name=oldname
 call FaceIt(0,RetCtl,0,0,0,0)      !close dialog window
 end

*  check whether to save Data before opening
 subroutine SaveIt(what,action)
 implicit none
 integer*4 action
 character*256 what
      include HD40:Fortran:FaceIt:StorMF.inc
 write(MAC,’(2a64)’)trim(name),trim(what)
 call FaceIt(0,OpnAlt,1030,0,0,0)
 action=dialog(1)
 end
*  Include FaceIt declarations
      include HD40:Fortran:FaceIt:FaceMF.inc

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Yasu 4.0.0 β - System maintenance app; p...
Yasu was created with System Administrators who service large groups of workstations in mind, Yasu (Yet Another System Utility) was made to do a specific group of maintenance tasks quickly within a... Read more
Skype 7.37.0.178 - Voice-over-internet p...
Skype allows you to talk to friends, family and co-workers across the Internet without the inconvenience of long distance telephone charges. Using peer-to-peer data transmission technology, Skype... Read more
EtreCheck 3.0.5 - For troubleshooting yo...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
Amadeus Pro 2.3.1 - Multitrack sound rec...
Amadeus Pro lets you use your Mac computer for any audio-related task, such as live audio recording, digitizing tapes and records, converting between a variety of sound formats, etc. Thanks to its... Read more
NeoFinder 6.9.3 - Catalog your external...
NeoFinder (formerly CDFinder) rapidly organizes your data, either on external or internal disks, or any other volumes. It catalogs all your data, so you stay in control of your data archive or disk... Read more
WhatsApp 0.2.1880 - Desktop client for W...
WhatsApp is the desktop client for WhatsApp Messenger, a cross-platform mobile messaging app which allows you to exchange messages without having to pay for SMS. WhatsApp Messenger is available for... Read more
Hazel 4.0.6 - Create rules for organizin...
Hazel is your personal housekeeper, organizing and cleaning folders based on rules you define. Hazel can also manage your trash and uninstall your applications. Organize your files using a familiar... Read more
Apple iBooks Author 2.5 - Create and pub...
Apple iBooks Author helps you create and publish amazing Multi-Touch books for iPad. Now anyone can create stunning iBooks textbooks, cookbooks, history books, picture books, and more for iPad. All... Read more
MYStuff Pro 2.0.26 - $39.99
MYStuff Pro is the most flexible way to create detail-rich inventories for your home or small business. Add items to MYStuff by dragging and dropping existing information, uploading new images, or... Read more
MarsEdit 3.7.8 - Quick and convenient bl...
MarsEdit is a blog editor for OS X that makes editing your blog like writing email, with spell-checking, drafts, multiple windows, and even AppleScript support. It works with with most blog services... Read more

How to get past Vulture Island's tr...
Vulture Island is a colorful and quirky mish-mash of platforming and puzzles. It’s creative and fresh, but sometimes the game can throw a curveball at you, leaving you stuck as to how you should progress. These tips will help you explore smoothly... | Read more »
The new Clash of Kings is just for Weste...
If you’ve played the original Clash of Kings, you’ll probably recognise the city building, alliance forging and strategic battles in Clash of Kings: The West. What sets this version apart is that it’s tailor made for a Western audience and the... | Read more »
Frost - Survival card game (Games)
Frost - Survival card game 1.12.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.12.1 (iTunes) Description: *Warning: the game will work on iPhone 5C and above and iPad Pro / 4. Other devices are not supported* | Read more »
How to build and care for your team in D...
Before you hit the trail and become a dog sledding legend, there’s actually a fair bit of prep work to be done. In Dog Sled Saga, you’re not only racing, you’re also building and caring for a team of furry friends. There’s a lot to consider—... | Read more »
How to win every race in Dog Sled Saga
If I had to guess, I’d say Dog Sled Saga is the most adorable racing game on the App Store right now. It’s a dog sled racing sim full of adorable, loyal puppies. Just look at those fluffy little tails wagging. Behind that cute, pixelated facade is... | Read more »
Let the war games commence in Gunship Ba...
Buzz Lightyear famously said, “This isn’t flying, this is falling – with style!” In the case of Gunship Battle: Second War, though, this really is flying - with style! The flight simulator app from Joycity puts you in control of 20 faithfully... | Read more »
How to get a high score in Fired Up
Fired Up is Noodlecake Games’ high score chasing, firefighting adventure. You take control of a wayward firefighter who propels himself up the side of a highrise with blasts of water. Sound silly? It is. It’s also pretty difficult. You can’t... | Read more »
NBA 2K17 (Games)
NBA 2K17 1.0 Device: iOS iPhone Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: Following the record-breaking launch of NBA 2K16, the NBA 2K franchise continues to stake its claim as the most authentic sports video... | Read more »
Dog Sled Saga (Games)
Dog Sled Saga 1.0.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.1 (iTunes) Description: A game by Dan + Lisa As a rookie musher, foster a dogsledding team whose skills will grow if they're treated right. Week by... | Read more »
60 Seconds! Atomic Adventure (Games)
60 Seconds! Atomic Adventure 1.2 Device: iOS Universal Category: Games Price: $2.99, Version: 1.2 (iTunes) Description: 60 Seconds! is a dark comedy atomic adventure of scavenge and survival. Collect supplies and rescue your family... | Read more »

Price Scanner via MacPrices.net

21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $120 off MSRP including free shipping plus NY sales tax only: - 21″ 3.1GHz iMac 4K: $1379 $120 off MSRP - 21″ 2.8GHz iMac: $1199.99 $100 off MSRP - 21″ 1... Read more
13-inch 2.7GHz/256GB Retina MacBook Pro on sa...
Amazon.com has the 13″ 2.7GHz/256GB Retina Apple MacBook Pro on sale for $151 off MSRP including free shipping: - 13″ 2.7GHz/256GB Retina MacBook Pro (sku MF840LL/A): $1348 $151 off MSRP Read more
Apple TVs on sale for up to $50 off MSRP
Best Buy has 32GB and 64GB Apple TVs on sale for $40-$50 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Sale prices for online orders only, in-store... Read more
Apple refurbished 13-inch Retina MacBook Pros...
Apple has Certified Refurbished 13″ Retina MacBook Pros available for up to $270 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 13″ 2.7GHz... Read more
Duplicate Sweeper Free On Mac App Store For O...
To celebrate the launch of Apple’s latest macOS Sierra, Stafford, United Kingdom based Wide Angle Software has announced that its duplicate file finder software, Duplicate Sweeper, is now available... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has 13″ Retina Apple MacBook Pros on sale for up to $150 off MSRP. Shipping is free, and B&H charges NY tax only: - 13″ 2.7GHz/128GB Retina MacBook Pro: $1174.99 $125 off MSRP - 13... Read more
Evidence Surfaces Pointing To New A10X Chip F...
Citing a job description for a Project Lead position at Apple’s Austin, Texas engineering labs, Motley Fool’s Ashraf Eassa deduces that development is progressing well on Apple’s next-generation in-... Read more
Check Print’R for macOS Allows Anyone to Easi...
Delaware-based Match Software has announced the release and immediate availability of Check Print’R 3.21, an important update to their easy-to-use check printing application for macOS. Check Print’R... Read more
Apple refurbished 11-inch MacBook Airs availa...
Apple has Certified Refurbished 11″ MacBook Airs (the latest models), available for up to $170 off the cost of new models. An Apple one-year warranty is included with each MacBook, and shipping is... Read more
Apple refurbished 15-inch Retina MacBook Pros...
Apple has Certified Refurbished 2015 15″ Retina MacBook Pros available for up to $380 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 15″ 2... Read more

Jobs Board

Sr. *Apple* Mac Engineer - Net2Source Inc....
…staffing, training and technology. We have following position open with our client. Sr. Apple Mac Engineer6+ Months CTH Start date : 19th Sept Travelling Job If Read more
*Apple* Retail - Multiple Positions-Norfolk,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Restaurant Manager (Neighborhood Captain) - A...
…in every aspect of daily operation. WHY YOU'LL LIKE IT: You'll be the Big Apple . You'll solve problems. You'll get to show your ability to handle the stress and Read more
Lead *Apple* Solutions Consultant - Apple (...
# Lead Apple Solutions Consultant Job Number: 51829230 Detroit, Michigan, United States Posted: Sep. 19, 2016 Weekly Hours: 40.00 **Job Summary** The Lead ASC is an Read more
US- *Apple* Store Leader Program - Apple (Un...
…Summary Learn and grow as you explore the art of leadership at the Apple Store. You'll master our retail business inside and out through training, hands-on Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.