LazStats: Inherit GuttmanUnit from BasicStatsReportFormUnit

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7899 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-11-23 00:09:14 +00:00
parent 128c037e14
commit b98f47bf19
6 changed files with 530 additions and 549 deletions

View File

@ -653,7 +653,7 @@
<Unit68>
<Filename Value="forms\analysis\measurement_programs\guttmanunit.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="GuttmanFrm"/>
<ComponentName Value="GuttmanForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="GuttmanUnit"/>

View File

@ -14,7 +14,7 @@ object CompRelFrm: TCompRelFrm
OnResize = FormResize
OnShow = FormShow
Position = poMainFormCenter
LCLVersion = '2.1.0.0'
LCLVersion = '2.0.10.0'
object Label3: TLabel
AnchorSideLeft.Control = RelList
AnchorSideTop.Control = Owner
@ -75,7 +75,7 @@ object CompRelFrm: TCompRelFrm
end
object GroupBox1: TGroupBox
AnchorSideLeft.Control = Owner
AnchorSideBottom.Control = Bevel1
AnchorSideBottom.Control = ButtonBevel
Left = 8
Height = 51
Top = 261
@ -183,7 +183,7 @@ object CompRelFrm: TCompRelFrm
OnClick = HelpBtnClick
TabOrder = 8
end
object Bevel1: TBevel
object ButtonBevel: TBevel
AnchorSideLeft.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
@ -210,7 +210,7 @@ object CompRelFrm: TCompRelFrm
object Label2: TLabel
AnchorSideLeft.Control = ItemList
AnchorSideTop.Control = Owner
Left = 185
Left = 180
Height = 15
Top = 8
Width = 76
@ -227,11 +227,11 @@ object CompRelFrm: TCompRelFrm
Left = 8
Height = 228
Top = 25
Width = 115
Width = 120
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8
BorderSpacing.Top = 2
BorderSpacing.Right = 8
BorderSpacing.Right = 6
BorderSpacing.Bottom = 8
Constraints.MinHeight = 200
ItemHeight = 0
@ -243,10 +243,10 @@ object CompRelFrm: TCompRelFrm
AnchorSideLeft.Control = Bevel2
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = VarList
Left = 140
Height = 28
Left = 141
Height = 26
Top = 25
Width = 28
Width = 26
Images = MainDataModule.ImageList
ImageIndex = 1
OnClick = InBtnClick
@ -258,10 +258,10 @@ object CompRelFrm: TCompRelFrm
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = InBtn
AnchorSideTop.Side = asrBottom
Left = 140
Height = 28
Top = 57
Width = 28
Left = 141
Height = 26
Top = 55
Width = 26
BorderSpacing.Top = 4
Images = MainDataModule.ImageList
ImageIndex = 0
@ -274,12 +274,12 @@ object CompRelFrm: TCompRelFrm
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = VarList
AnchorSideTop.Side = asrCenter
Left = 131
Left = 134
Height = 25
Top = 127
Width = 46
Width = 40
AutoSize = True
Caption = 'ALL'
Caption = 'All'
OnClick = AllBtnClick
TabOrder = 3
end
@ -290,12 +290,12 @@ object CompRelFrm: TCompRelFrm
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = GroupBox1
Left = 185
Left = 180
Height = 228
Top = 25
Width = 115
Width = 120
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8
BorderSpacing.Left = 6
BorderSpacing.Top = 2
BorderSpacing.Bottom = 8
ItemHeight = 0

View File

@ -17,7 +17,7 @@ type
{ TCompRelFrm }
TCompRelFrm = class(TForm)
Bevel1: TBevel;
ButtonBevel: TBevel;
Bevel2: TBevel;
HelpBtn: TButton;
InBtn: TBitBtn;

View File

@ -1,186 +1,156 @@
object GuttmanFrm: TGuttmanFrm
inherited GuttmanForm: TGuttmanForm
Left = 608
Height = 307
Top = 322
Width = 382
Width = 719
HelpType = htKeyword
HelpKeyword = 'html/GuttmanScalogramAnalysis.htm'
AutoSize = True
Caption = 'Guttman Sclaogram Analysis'
ClientHeight = 307
ClientWidth = 382
OnActivate = FormActivate
OnCreate = FormCreate
OnShow = FormShow
Position = poMainFormCenter
LCLVersion = '2.1.0.0'
object Label1: TLabel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
Left = 8
Height = 15
Top = 8
Width = 97
BorderSpacing.Left = 8
BorderSpacing.Top = 8
Caption = 'Variables Available'
ParentColor = False
ClientWidth = 719
inherited ParamsPanel: TPanel
Height = 291
ClientHeight = 291
inherited CloseBtn: TButton
Top = 266
TabOrder = 8
end
inherited ComputeBtn: TButton
Top = 266
TabOrder = 7
end
inherited ResetBtn: TButton
Top = 266
TabOrder = 6
end
inherited HelpBtn: TButton
Top = 266
TabOrder = 5
end
inherited ButtonBevel: TBevel
Top = 250
end
object Label1: TLabel[5]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = ParamsPanel
Left = 0
Height = 15
Top = 0
Width = 97
Caption = 'Variables Available'
ParentColor = False
end
object Label2: TLabel[6]
AnchorSideLeft.Control = ItemList
AnchorSideTop.Control = ParamsPanel
Left = 171
Height = 15
Top = 0
Width = 76
Caption = 'Selected Items'
ParentColor = False
end
object VarList: TListBox[7]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = Label1
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AllBtn
AnchorSideBottom.Control = ButtonBevel
Left = 0
Height = 233
Top = 17
Width = 119
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 2
BorderSpacing.Right = 6
Constraints.MinHeight = 200
ItemHeight = 0
MultiSelect = True
OnDblClick = VarListDblClick
OnSelectionChange = VarListSelectionChange
TabOrder = 0
end
object InBtn: TBitBtn[8]
AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter
Left = 132
Height = 26
Top = 25
Width = 26
Images = MainDataModule.ImageList
ImageIndex = 1
OnClick = InBtnClick
Spacing = 0
TabOrder = 1
end
object OutBtn: TBitBtn[9]
AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter
Left = 132
Height = 26
Top = 56
Width = 26
Images = MainDataModule.ImageList
ImageIndex = 0
OnClick = OutBtnClick
Spacing = 0
TabOrder = 2
end
object AllBtn: TBitBtn[10]
AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter
Left = 125
Height = 25
Top = 104
Width = 40
AutoSize = True
Caption = 'All'
OnClick = AllBtnClick
Spacing = 0
TabOrder = 3
end
object ItemList: TListBox[11]
AnchorSideLeft.Control = AllBtn
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Label2
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = ButtonBevel
Left = 171
Height = 233
Top = 17
Width = 120
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 6
BorderSpacing.Top = 2
ItemHeight = 0
OnDblClick = ItemListDblClick
OnSelectionChange = VarListSelectionChange
TabOrder = 4
end
end
object Label2: TLabel
AnchorSideLeft.Control = ItemList
AnchorSideTop.Control = Owner
Left = 222
Height = 15
Top = 8
Width = 76
BorderSpacing.Top = 8
Caption = 'Selected Items'
ParentColor = False
inherited ParamsSplitter: TSplitter
Height = 307
end
object VarList: TListBox
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Label1
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AllBtn
AnchorSideBottom.Control = Bevel1
Left = 8
Height = 233
Top = 25
Width = 152
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8
BorderSpacing.Top = 2
object PageControl: TPageControl[2]
Left = 312
Height = 291
Top = 8
Width = 399
ActivePage = GoodenoughPage
Align = alClient
BorderSpacing.Left = 4
BorderSpacing.Top = 8
BorderSpacing.Right = 8
Constraints.MinHeight = 200
ItemHeight = 0
MultiSelect = True
OnSelectionChange = VarListSelectionChange
TabOrder = 0
end
object InBtn: TBitBtn
AnchorSideLeft.Control = Owner
AnchorSideLeft.Side = asrCenter
Left = 177
Height = 28
Top = 25
Width = 28
Images = MainDataModule.ImageList
ImageIndex = 1
OnClick = InBtnClick
Spacing = 0
TabOrder = 1
end
object OutBtn: TBitBtn
AnchorSideLeft.Control = Owner
AnchorSideLeft.Side = asrCenter
Left = 177
Height = 28
Top = 56
Width = 28
Images = MainDataModule.ImageList
ImageIndex = 0
OnClick = OutBtnClick
Spacing = 0
BorderSpacing.Bottom = 8
TabIndex = 1
TabOrder = 2
end
object AllBtn: TBitBtn
AnchorSideLeft.Control = Owner
AnchorSideLeft.Side = asrCenter
Left = 168
Height = 25
Top = 104
Width = 46
AutoSize = True
Caption = 'ALL'
OnClick = AllBtnClick
Spacing = 0
TabOrder = 3
end
object ItemList: TListBox
AnchorSideLeft.Control = AllBtn
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Label2
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Bevel1
Left = 222
Height = 233
Top = 25
Width = 152
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8
BorderSpacing.Top = 2
BorderSpacing.Right = 8
ItemHeight = 0
OnSelectionChange = VarListSelectionChange
TabOrder = 4
end
object ResetBtn: TButton
AnchorSideRight.Control = ComputeBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 169
Height = 25
Top = 274
Width = 54
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 12
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Reset'
OnClick = ResetBtnClick
TabOrder = 5
end
object ComputeBtn: TButton
AnchorSideRight.Control = CloseBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 231
Height = 25
Top = 274
Width = 76
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Compute'
OnClick = ComputeBtnClick
TabOrder = 6
end
object CloseBtn: TButton
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 315
Height = 25
Top = 274
Width = 55
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 12
BorderSpacing.Bottom = 8
Caption = 'Close'
ModalResult = 11
TabOrder = 7
end
object Bevel1: TBevel
AnchorSideLeft.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = CloseBtn
Left = 0
Height = 8
Top = 258
Width = 382
Anchors = [akLeft, akRight, akBottom]
Shape = bsBottomLine
object CornellPage: TTabSheet
Caption = 'Cornell method'
end
object GoodenoughPage: TTabSheet
Caption = 'Goodenough method'
end
end
end

View File

@ -5,98 +5,88 @@ unit GuttmanUnit;
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls,
MainUnit, OutputUnit, Globals, DataProcs;
Classes, SysUtils, Forms, Controls, Graphics, StdCtrls, Buttons, ExtCtrls,
ComCtrls, MainUnit, Globals, ReportFrameUnit, BasicStatsReportFormUnit;
type
{ TGuttmanFrm }
{ TGuttmanForm }
TGuttmanFrm = class(TForm)
Bevel1: TBevel;
TGuttmanForm = class(TBasicStatsReportForm)
InBtn: TBitBtn;
OutBtn: TBitBtn;
AllBtn: TBitBtn;
ResetBtn: TButton;
ComputeBtn: TButton;
CloseBtn: TButton;
Label1: TLabel;
Label2: TLabel;
ItemList: TListBox;
PageControl: TPageControl;
CornellPage: TTabSheet;
GoodenoughPage: TTabSheet;
VarList: TListBox;
procedure AllBtnClick(Sender: TObject);
procedure ComputeBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure InBtnClick(Sender: TObject);
procedure ItemListDblClick(Sender: TObject);
procedure OutBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
private
{ private declarations }
FAutoSized: Boolean;
procedure UpdateBtnStates;
FCornellReportFrame: TReportFrame;
FGoodenoughReportFrame: TReportFrame;
protected
procedure AdjustConstraints; override;
procedure Compute; override;
procedure UpdateBtnStates; override;
function Validate(out AMsg: String; out AControl: TWinControl): boolean; override;
public
{ public declarations }
constructor Create(AOwner: TComponent); override;
procedure Reset; override;
end;
var
GuttmanFrm: TGuttmanFrm;
GuttmanForm: TGuttmanForm;
implementation
{$R *.lfm}
uses
Math, Utils;
Utils, MatrixUnit, GridProcs;
{ TGuttmanFrm }
procedure TGuttmanFrm.ResetBtnClick(Sender: TObject);
var
i: integer;
{ TGuttmanForm }
constructor TGuttmanForm.Create(AOwner: TComponent);
begin
VarList.Clear;
ItemList.Clear;
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
UpdateBtnStates;
inherited;
FCornellReportFrame := FReportFrame;
InitToolbar(FReportFrame.ReportToolbar, tpTop);
FReportFrame.ClearBorderSpacings;
FReportFrame.Parent := CornellPage;
FGoodenoughReportFrame := TReportFrame.Create(self);
FGoodenoughReportFrame.Parent := GoodenoughPage;
FGoodenoughReportFrame.Align := alClient;
PageControl.ActivePageIndex := 0;
end;
procedure TGuttmanFrm.VarListSelectionChange(Sender: TObject; User: boolean);
procedure TGuttmanForm.AdjustConstraints;
begin
UpdateBtnStates;
inherited;
ParamsPanel.Constraints.MinWidth := 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left;
ParamsPanel.Constraints.MinHeight := AllBtn.Top + AllBtn.Height +
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
end;
procedure TGuttmanFrm.FormActivate(Sender: TObject);
var
w: Integer;
begin
if FAutoSized then
exit;
w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
ResetBtn.Constraints.MinWidth := w;
ComputeBtn.Constraints.MinWidth := w;
CloseBtn.Constraints.MinWidth := w;
Constraints.MinWidth := Width + w; // make form a bit wider...
Constraints.MinHeight := Height;
FAutoSized := true;
end;
procedure TGuttmanFrm.FormCreate(Sender: TObject);
begin
Assert(OS3MainFrm <> nil);
end;
procedure TGuttmanFrm.FormShow(Sender: TObject);
begin
ResetBtnClick(self);
end;
procedure TGuttmanFrm.AllBtnClick(Sender: TObject);
procedure TGuttmanForm.AllBtnClick(Sender: TObject);
var
i: integer;
begin
@ -106,9 +96,10 @@ begin
UpdateBtnStates;
end;
procedure TGuttmanFrm.ComputeBtnClick(Sender: TObject);
procedure TGuttmanForm.Compute;
var
i, j, k, col, X, e0, e1, e2, e3, first, last, errors : integer;
i, j, k, X, e0, e1, e2, e3, first, last, errors : integer;
totalerrors, rowno : integer;
FreqMat0 : IntDyneMat = nil; // Pointer to array of 0 responses for each item by score group
FreqMat1 : IntDyneMat = nil; // Pointer to array of 1 responses for each item by score group
@ -132,140 +123,95 @@ var
Min_Coeff : double;
lReport: TStrings;
begin
if ItemList.Count = 0 then
begin
MessageDlg('No variable(s) selected.', mtError, [mbOK], 0);
exit;
end;
// Allocate heap space for arrays
SetLength(FreqMat0,NoCases,NoVariables);
SetLength(FreqMat1,NoCases,NoVariables);
SetLength(RowTots,NoCases);
SetLength(ColTots,NoVariables,2);
SetLength(ColProps,NoVariables);
SetLength(CaseVector,NoCases);
SetLength(CutScore,NoCases);
SetLength(ErrorMat,NoVariables,2);
SetLength(sequence,NoVariables);
SetLength(CaseNo,NoCases);
SetLength(ModalArray, NoVariables+1, NoVariables+1);
// allocate heap space for arrays
SetLength(ColNoSelected,NoVariables);
SetLength(FreqMat0,NoCases,NoVariables);
SetLength(FreqMat1,NoCases,NoVariables);
SetLength(RowTots,NoCases);
SetLength(ColTots,NoVariables,2);
SetLength(ColProps,NoVariables);
SetLength(CaseVector,NoCases);
SetLength(CutScore,NoCases);
SetLength(ErrorMat,NoVariables,2);
SetLength(sequence,NoVariables);
SetLength(CaseNo,NoCases);
SetLength(ModalArray,NoVariables+1,NoVariables+1);
SetLength(VarLabels,NoVariables);
// get variables used for the analysis
// Get variables used for the analysis
NoSelected := ItemList.Items.Count;
for i := 1 to NoVariables do
SetLength(VarLabels, NoSelected);
SetLength(ColNoSelected, NoSelected);
for j := 0 to NoSelected-1 do
begin
for j := 1 to NoSelected do
begin
if OS3MainFrm.DataGrid.Cells[i,0] = ItemList.Items.Strings[j-1] then
begin
ColNoSelected[j-1] := i;
VarLabels[j-1] := OS3MainFrm.DataGrid.Cells[i,0];
end;
end;
VarLabels[j] := ItemList.Items[j];
ColNoSelected[j] := GetVariableIndex(OS3MainFrm.DataGrid, VarLabels[j]);
end;
// Initialize sequence
for i := 1 to NoSelected do sequence[i-1] := i;
for i := 0 to NoSelected-1 do sequence[i] := i+1;
// Initialize arrays
for i := 0 to NoSelected-1 do
begin
ColTots[i,0] := 0;
ColTots[i,1] := 0;
ColProps[i] := 0.0;
ErrorMat[i,0] := 0;
ErrorMat[i,1] := 0;
end;
for i := 0 to NoCases-1 do
begin
RowTots[i] := 0;
CutScore[i] := 0;
CaseNo[i] := i+1;
for j := 0 to NoSelected-1 do
begin
FreqMat0[i,j] := 0;
FreqMat1[i,j] := 0;
end;
end;
if (NoCases > NoSelected) then
begin
for i := 1 to NoCases do CaseVector[i-1] := 0;
end
else begin
for i := 1 to NoSelected do CaseVector[i-1] := 0;
end;
CaseNo[i] := i+1;
// Get data into the frequency matrices of 0 and 1 responses
for i := 1 to NoCases do
begin
if (not GoodRecord(i,NoSelected,ColNoSelected)) then continue;
TotalScore := 0;
for j := 1 to NoSelected do
begin
col := ColNoSelected[j-1];
X := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col,i])));
CaseVector[j-1] := X;
TotalScore := TotalScore + X;
end;
for j := 1 to NoSelected do
begin
if (CaseVector[j-1] = 0) then FreqMat0[i-1,j-1] := 1
else FreqMat1[i-1,j-1] := 1;
end;
if (not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected)) then continue;
TotalScore := 0;
for j := 0 to NoSelected-1 do
begin
X := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNoSelected[j], i])));
CaseVector[j] := X;
TotalScore := TotalScore + X;
end;
for j := 0 to NoSelected-1 do
if (CaseVector[j] = 0) then
FreqMat0[i-1, j] := 1
else
FreqMat1[i-1, j] := 1;
end;
// Get Row Totals for each score group (rows of FreqMat1)
for i := 1 to NoCases do
begin
if (not GoodRecord(i,NoSelected,ColNoSelected)) then continue;
for j := 1 to NoSelected do
begin
RowTots[i-1] := RowTots[i-1] + FreqMat1[i-1,j-1];
end;
if (not GoodRecord(oS3MainFrm.DataGrid, i, ColNoSelected)) then continue;
for j := 0 to NoSelected-1 do
RowTots[i-1] := RowTots[i-1] + FreqMat1[i-1, j];
end;
// Get Column Totals for item scores of 1 and 0
for i := 1 to NoSelected do //columns
for i := 0 to NoSelected-1 do //columns
begin
for j := 1 to NoCases do // rows
begin
if (not GoodRecord(j,NoSelected,ColNoSelected)) then continue;
ColTots[i-1,0] := ColTots[i-1,0] + FreqMat0[j-1,i-1];
ColTots[i-1,1] := ColTots[i-1,1] + FreqMat1[j-1,i-1];
end;
for j := 0 to NoCases-1 do // rows
begin
if (not GoodRecord(OS3MainFrm.DataGrid, j+1, ColNoSelected)) then continue;
ColTots[i, 0] := ColTots[i, 0] + FreqMat0[j, i];
ColTots[i, 1] := ColTots[i, 1] + FreqMat1[j, i];
end;
end;
//Sort frequency matrices into descending order
for i := 1 to NoCases - 1 do
begin
if (not GoodRecord(i,NoSelected,ColNoSelected)) then continue;
for j := i + 1 to NoCases do
if (not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected)) then continue;
for j := i + 1 to NoCases do
begin
if (not GoodRecord(OS3MainFrm.DataGrid, j, ColNoSelected)) then continue;
if (RowTots[i-1] < RowTots[j-1]) then //swap
begin
if (not GoodRecord(j,NoSelected,ColNoSelected)) then continue;
if (RowTots[i-1] < RowTots[j-1]) then //swap
begin
for k := 1 to NoSelected do
begin // carry all columns in the swap
temp := FreqMat0[i-1,k-1];
FreqMat0[i-1,k-1] := FreqMat0[j-1,k-1];
FreqMat0[j-1,k-1] := temp;
temp := FreqMat1[i-1,k-1];
FreqMat1[i-1,k-1] := FreqMat1[j-1,k-1];
FreqMat1[j-1,k-1] := temp;
end;
// Also swap row totals
temp := RowTots[i-1];
RowTots[i-1] := RowTots[j-1];
RowTots[j-1] := temp;
// And case number
temp := CaseNo[i-1];
CaseNo[i-1] := CaseNo[j-1];
CaseNo[j-1] := temp;
end; // end if
end; // Next j
for k := 1 to NoSelected do
begin // carry all columns in the swap
Exchange(FreqMat0[i-1, k-1], FreqMat0[j-1, k-1]);
Exchange(FreqMat1[i-1, k-1], FreqMat1[j-1, k-1]);
end;
// Also swap row totals
Exchange(RowTots[i-1], RowTots[j-1]);
// And case number
Exchange(CaseNo[i-1], CaseNo[j-1]);
end; // end if
end; // Next j
end; // next i
// Now sort the columns into ascending order of number right
@ -277,7 +223,7 @@ begin
begin
for k := 1 to NoCases do
begin
if (not GoodRecord(k,NoSelected,ColNoSelected)) then continue;
if (not GoodRecord(OS3MainFrm.DataGrid, k, ColNoSelected)) then continue;
temp := FreqMat0[k-1,i-1];
FreqMat0[k-1,i-1] := FreqMat0[k-1,j-1];
FreqMat0[k-1,j-1] := temp;
@ -306,19 +252,19 @@ begin
CutScore[i-1] := 0;
for j := 1 to NoCases do // j is the trial cut point
begin
if (not GoodRecord(j,NoSelected,ColNoSelected)) then continue;
if (not GoodRecord(OS3MainFrm.DataGrid, j, ColNoSelected)) then continue;
e0 := 0;
e1 := 0;
//Get errors prior to the cut point
for k := 1 to j do
begin
if (not GoodRecord(k,NoSelected,ColNoSelected)) then continue;
if (not GoodRecord(OS3MainFrm.DataGrid, k, ColNoSelected)) then continue;
if (FreqMat0[k-1,i-1] = 1) then e0 := e0 + 1;
end;
//Get errors following the cut point
for k := j + 1 to NoCases do
begin
if (not GoodRecord(k,NoSelected,ColNoSelected)) then continue;
if (not GoodRecord(OS3MainFrm.DataGrid, k, ColNoSelected)) then continue;
if (FreqMat1[k-1,i-1] = 1) then e1 := e1 + 1;
end;
//Save errors for each cut
@ -329,7 +275,7 @@ begin
e3 := 0;
for j := 1 to NoCases do
begin
if (not GoodRecord(j,NoSelected,ColNoSelected)) then continue;
if (not GoodRecord(OS3MainFrm.DataGrid, j, ColNoSelected)) then continue;
if (CaseVector[j-1] < e2) then
begin
e2 := CaseVector[j-1];
@ -344,13 +290,13 @@ begin
begin
for j := 1 to CutScore[i-1] do
begin
if (not GoodRecord(j,NoSelected,ColNoSelected)) then continue;
if (not GoodRecord(OS3MainFrm.DataGrid, j, ColNoSelected)) then continue;
if ((FreqMat0[j-1,i-1] > 0) or (FreqMat1[j-1,i-1] > 0)) then
ErrorMat[i-1,0] := ErrorMat[i-1,0] + FreqMat0[j-1,i-1];
end;
for j := CutScore[i-1] + 1 to NoCases do
begin
if (not GoodRecord(j,NoSelected,ColNoSelected)) then continue;
if (not GoodRecord(OS3MainFrm.DataGrid, j, ColNoSelected)) then continue;
if ((FreqMat0[j-1,i-1] > 0) or (FreqMat1[j-1,i-1] > 0)) then
ErrorMat[i-1,1] := ErrorMat[i-1,1] + FreqMat1[j-1,i-1];
end;
@ -359,11 +305,11 @@ begin
// Print results
lReport := TStringList.Create;
try
lReport.Add(' GUTTMAN SCALOGRAM ANALYSIS');
lReport.Add(' Cornell Method');
lReport.Add('GUTTMAN SCALOGRAM ANALYSIS');
lReport.Add('Cornell Method');
lReport.Add('');
lReport.Add('No. of Cases: %5d', [NoCases]);
lReport.Add('No. of items: %5d', [NoSelected]);
lReport.Add('Number of cases: %5d', [NoCases]);
lReport.Add('Number of items: %5d', [NoSelected]);
lReport.Add('');
lReport.Add('RESPONSE MATRIX');
lReport.Add('');
@ -372,54 +318,57 @@ begin
if (last > NoSelected) then last := NoSelected;
done := false;
while (not done) do //loop through all of the score groups
// Loop through all of the score groups
while (not done) do
begin
lReport.Add('Subject Row Item Number');
outline := 'Label Sum';
lReport.Add('Subject Row Item Number');
outline := ' Label Sum ';
for i := first to last do
outline := outline + Format('%10s', [VarLabels[sequence[i-1]-1]]);
outline := outline + ' ' + CenterString(VarLabels[sequence[i-1]-1], 10);
lReport.Add(outline);
outline := ' ';
outline := ' ';
for i := first to last do
outline := outline + ' 0 1 ';
outline := outline + ' ' + ' 0 1 ';
lReport.Add(outline);
lReport.Add('');
for i := 1 to NoCases do // rows
begin
if (not GoodRecord(i,NoSelected,ColNoSelected)) then continue;
outline := Format(' %3d %3d ', [CaseNo[i-1], RowTots[i-1]]);
if (not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected)) then continue;
outline := Format(' %3d %3d ', [CaseNo[i-1], RowTots[i-1]]);
for j := first to last do
outline := outline + Format(' %3d %3d ', [FreqMat0[i-1,j-1], FreqMat1[i-1,j-1]]);
outline := outline + Format(' %3d %3d ', [FreqMat0[i-1,j-1], FreqMat1[i-1,j-1]]);
lReport.Add(outline);
// check for optimal cut point for this score
outline := ' ';
outline :=' ';
for j := first to last do
if (CutScore[j-1] = i) then
outline := outline + ' -cut- '
outline := outline + ' -cut- '
else
outline := outline + ' ';
outline := outline + ' ';
lReport.Add(outline);
end; // Next row (score group)
lReport.Add('');
outline := 'TOTALS ';
outline := 'TOTALS ';
for j := first to last do
outline := outline + Format(' %3d %3d ', [ColTots[j-1,0], ColTots[j-1,1]]);
outline := outline + Format(' %3d %3d ', [ColTots[j-1,0], ColTots[j-1,1]]);
lReport.Add(outline);
outline := 'ERRORS ';
outline := 'ERRORS ';
for j := first to last do
outline := outline + Format(' %3d %3d ', [ErrorMat[j-1,0], ErrorMat[j-1,1]]);
outline := outline + Format(' %3d %3d ', [ErrorMat[j-1,0], ErrorMat[j-1,1]]);
lReport.Add(outline);
if (last < NoSelected) then
begin
first := last + 1;
last := first + 5; // column (item) index
if (last > NoSelected) then last := NoSelected;
first := last + 1;
last := first + 5; // column (item) index
if (last > NoSelected) then last := NoSelected;
end
else done := true;
else
done := true;
lReport.Add('');
end;
@ -429,14 +378,15 @@ begin
CoefRepro := CoefRepro + ErrorMat[j-1,0] + ErrorMat[j-1,1];
CoefRepro := 1.0 - (CoefRepro / (NoCases * NoSelected));
lReport.Add('Coefficient of Reproducibility := %6.3f',[CoefRepro]);
lReport.Add('');
FCornellReportFrame.DisplayReport(lReport);
lReport.Clear;
//-----------------------------GOODENOUGH----------------------------------
// Complete Goodenough method and print results
lReport.Add('');
lReport.Add(' GUTTMAN SCALOGRAM ANALYSIS');
lReport.Add(' Goodenough Modification Using Modal Responses');
lReport.Add('GUTTMAN SCALOGRAM ANALYSIS');
lReport.Add('Goodenough Modification Using Modal Responses');
lReport.Add('');
totalerrors := 0;
Min_Coeff := 0.0;
@ -456,7 +406,7 @@ begin
// Build modal response array for the total scores by items
lReport.Add('');
lReport.Add(' MODAL ITEM RESPONSES');
lReport.Add('MODAL ITEM RESPONSES');
lReport.Add('');
lReport.Add('TOTAL ITEMS');
outline := ' ';
@ -477,15 +427,16 @@ begin
outline := astring;
for j := 1 to NoSelected do
begin
astring := format(' %3d ',[ModalArray[i,j-1]]);
outline := outline + astring;
astring := format(' %3d ',[ModalArray[i,j-1]]);
outline := outline + astring;
end;
lReport.Add(outline);
end;
lReport.Add('');
lReport.Add('No. of Cases: %3d', [NoCases]);
lReport.Add('No. of items: %3d', [NoSelected]);
lReport.Add('Number of cases: %3d', [NoCases]);
lReport.Add('Number of items: %3d', [NoSelected]);
lReport.Add('');
lReport.Add('');
lReport.Add('RESPONSE MATRIX');
lReport.Add('');
@ -493,48 +444,49 @@ begin
last := first + 5; // column (item) index
if (last > NoSelected) then last := NoSelected;
// Loop through all of the score groups
done := false;
while (not done) do //loop through all of the score groups
while (not done) do
begin
lReport.Add('Subject Row Error Item Number');
outline := 'Label Sum Count';
lReport.Add('Subject Row Error Item Number');
outline := ' Label Sum Count';
for i := first to last do
outline := outline + Format('%10s', [VarLabels[sequence[i-1]-1]]);
outline := outline + ' ' + CenterString(Varlabels[sequence[i-1]-1], 10);
lReport.Add(outline);
outline := ' ';
outline := ' ';
for i := first to last do
outline := outline + ' 0 1 ';
outline := outline + ' ' + ' 0 1 ';
lReport.Add(outline);
lReport.Add('');
for i := 1 to NoCases do // rows
begin
if (not GoodRecord(i,NoSelected,ColNoSelected)) then continue;
errors := 0;
for j := first to last do
begin
rowno := NoSelected - RowTots[i-1] + 1;
if (FreqMat1[i-1,j-1] <> ModalArray[rowno-1,j-1]) then errors := errors + 1;
end;
if (not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected)) then continue;
errors := 0;
for j := first to last do
begin
rowno := NoSelected - RowTots[i-1] + 1;
if (FreqMat1[i-1,j-1] <> ModalArray[rowno-1,j-1]) then errors := errors + 1;
end;
outline := format(' %3d %3d %3d ',[CaseNo[i-1],RowTots[i-1],errors]);
for j := first to last do
begin
astring := format(' %3d %3d ',[FreqMat0[i-1,j-1],FreqMat1[i-1,j-1]]);
outline := outline + astring;
end;
lReport.Add(outline);
totalerrors := totalerrors + errors;
outline := Format(' %3d %3d %3d ',[CaseNo[i-1],RowTots[i-1],errors]);
for j := first to last do
begin
astring := Format(' %3d %3d ',[FreqMat0[i-1,j-1],FreqMat1[i-1,j-1]]);
outline := outline + astring;
end;
lReport.Add(outline);
totalerrors := totalerrors + errors;
end; // Next row (score group)
lReport.Add('');
outline :='TOTALS ';
outline := 'TOTALS ';
for j := first to last do
outline := outline + Format(' %3d %3d ',[ColTots[j-1,0], ColTots[j-1,1]]);
outline := outline + Format(' %3d %3d ',[ColTots[j-1,0], ColTots[j-1,1]]);
lReport.Add(outline);
outline := 'PROPORTIONS ';
outline := 'PROPORTIONS ';
for j := first to last do
outline := outline + Format('%4.2f %4.2f ',[(1.0-ColProps[j-1]), ColProps[j-1]]);
outline := outline + Format('%5.2f%5.2f ',[(1.0-ColProps[j-1]), ColProps[j-1]]);
lReport.Add(outline);
if (last < NoSelected) then
@ -560,28 +512,14 @@ begin
lReport.Add('Minimal Marginal Reproducibility: %6.3f', [Min_Coeff]);
DisplayReport(lReport);
FGoodenoughReportFrame.DisplayReport(lReport);
finally
lReport.Free;
// Clean up the heap
VarLabels := nil;
ModalArray := nil;
CaseNo := nil;
sequence := nil;
ErrorMat := nil;
CutScore := nil;
CaseVector := nil;
ColProps := nil;
ColTots := nil;
RowTots := nil;
FreqMat1 := nil;
FreqMat0 := nil;
ColNoSelected := nil;
end;
end;
procedure TGuttmanFrm.InBtnClick(Sender: TObject);
procedure TGuttmanForm.InBtnClick(Sender: TObject);
var
i: integer;
begin
@ -600,7 +538,22 @@ begin
UpdateBtnStates;
end;
procedure TGuttmanFrm.OutBtnClick(Sender: TObject);
procedure TGuttmanForm.ItemListDblClick(Sender: TObject);
var
index: Integer;
begin
index := ItemList.ItemIndex;
if index > -1 then
begin
VarList.Items.Add(ItemList.Items[index]);
ItemList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TGuttmanForm.OutBtnClick(Sender: TObject);
var
i: integer;
begin
@ -619,15 +572,67 @@ begin
UpdateBtnStates;
end;
procedure TGuttmanFrm.UpdateBtnStates;
procedure TGuttmanForm.Reset;
begin
inherited;
if FGoodenoughReportFrame <> nil then
FGoodenoughReportFrame.Clear;
CollectVariableNames(OS3MainFrm.DataGrid, VarList.Items);
ItemList.Clear;
UpdateBtnStates;
end;
procedure TGuttmanForm.UpdateBtnStates;
begin
inherited;
if FGoodenoughReportFrame <> nil then
FGoodenoughReportFrame.UpdateBtnStates;
InBtn.Enabled := AnySelected(Varlist);
OutBtn.Enabled := AnySelected(Itemlist);
AllBtn.Enabled := VarList.Items.Count > 0;
end;
initialization
{$I guttmanunit.lrs}
function TGuttmanForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
begin
Result := false;
if ItemList.Count = 0 then
begin
AMsg := 'No variable(s) selected.';
AControl := VarList;
exit;
end;
Result := true;
end;
procedure TGuttmanForm.VarListDblClick(Sender: TObject);
var
index: Integer;
begin
index := VarList.ItemIndex;
if index > -1 then
begin
ItemList.Items.Add(VarList.Items[index]);
VarList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TGuttmanForm.VarListSelectionChange(Sender: TObject; User: boolean);
begin
UpdateBtnStates;
end;
end.

View File

@ -757,70 +757,6 @@ begin
LogLinScreenFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Generate Sample Test Data"
procedure TOS3MainFrm.mnuAnalysisMeas_SampleDataClick(Sender: TObject);
begin
if TestGenFrm = nil then
Application.CreateForm(TTestGenFrm, TestGenFrm);
TestGenFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Classical Test Analysis"
procedure TOS3MainFrm.mnuAnalysisMeas_ClassicalClick(Sender: TObject);
begin
if TestScoreForm = nil then
Application.CreateForm(TTestScoreForm, TestScoreForm);
TestScoreForm.Show;
end;
// Menu "Analysis" > "Measurement Programs" > "Rasch Test Calibration"
procedure TOS3MainFrm.mnuAnalysisMeas_RashClick(Sender: TObject);
begin
if RaschForm = nil then
Application.CreateForm(TRaschForm, RaschForm);
RaschForm.Show;
end;
// Menu "Analysis" > "Measurement Programs" > "Successive Interval Scaling"
procedure TOS3MainFrm.mnuAnalysisMeas_IntervalClick(Sender: TObject);
begin
if SuccIntFrm = nil then
Application.CreateForm(TSuccIntFrm, SuccIntFrm);
SuccIntFrm.Show;
end;
// Menu "Analysis" > "Measurement Programs" > "Guttman Scalogram Analysis
procedure TOS3MainFrm.mnuAnalysisMeas_GuttmanClick(Sender: TObject);
begin
if GuttmanFrm = nil then
Application.CreateForm(TGuttmanFrm, GuttmanFrm);
GuttmanFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Weighted Composite Reliability"
procedure TOS3MainFrm.mnuAnalysisMeas_CompositeClick(Sender: TObject);
begin
if CompRelFrm = nil then
Application.CreateForm(TCompRelFrm, CompRelFrm);
CompRelFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Kuder-Richardson #21 Reliability"
procedure TOS3MainFrm.mnuAnalysisMeas_KR21Click(Sender: TObject);
begin
if KR21Frm = nil then
Application.CreateForm(TKR21Frm, KR21Frm);
KR21Frm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Spearman-Brown Prophecy Reliability"
procedure TOS3MainFrm.mnuAnalysisMeas_SpearmanClick(Sender: TObject);
begin
if SpBrFrm = nil then
Application.CreateForm(TSpBrFrm, SpBrFrm);
SpBrFrm.ShowModal;
end;
// Menu "Analysis" > "One sample tests"
procedure TOS3MainFrm.mnuAnalysisOneSampleTestsClick(Sender: TObject);
begin
@ -1495,13 +1431,6 @@ begin
GLMFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Grade Book"
procedure TOS3MainFrm.mnuAnalysisMeas_GradeBookClick(Sender: TObject);
begin
if GradeBookFrm = nil then
Application.CreateForm(TGradeBookFrm, GradeBookFrm);
GradebookFrm.ShowModal;
end;
(* replaced by ShowTOC
// Menu "Help" > "General Help"
@ -1512,13 +1441,6 @@ begin
HelpFrm.ShowModal;
end;
*)
// Menu "Analysis" > "Measurement Programs" > "Item Banking"
procedure TOS3MainFrm.mnuAnalysisMeas_ItemBankingClick(Sender: TObject);
begin
if ItemBankFrm = nil then
Application.CreateForm(TItemBankFrm, ItembankFrm);
ItemBankFrm.ShowModal;
end;
procedure TOS3MainFrm.mnuAnalysisNonPar_KSTestClick(Sender: TObject);
begin
@ -1542,30 +1464,6 @@ begin
MedianPolishForm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Reliability Due to Test Variance Change"
procedure TOS3MainFrm.mnuAnalysisMeas_VarChangeClick(Sender: TObject);
begin
if RelChangeFrm = nil then
Application.CreateForm(TRelChangeFrm, RelChangeFrm);
RelChangeFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Differential Item Functioning"
procedure TOS3MainFrm.mnuAnalysisMeas_DifferentialClick(Sender: TObject);
begin
if DIFFrm = nil then
Application.CreateForm(TDIFFrm, DIFFrm);
DIFFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Polytomous DIF Analysis"
procedure TOS3MainFrm.mnuAnalysisMeas_PolytomousClick(Sender: TObject);
begin
if PolyDIFFrm = nil then
Application.CreateForm(TPolyDIFFrm, PolyDIFFrm);
PolyDIFFrm.ShowModal;
end;
// Menu "Analysis" > "Financial" > "Loan Amortization Schedule"
procedure TOS3MainFrm.mnuAnalysisFinancial_LoanAmortClick(Sender: TObject);
begin
@ -1610,6 +1508,114 @@ begin
end;
{ "Measurement Programs" commands }
// Menu "Analysis" > "Measurement Programs" > "Generate Sample Test Data"
procedure TOS3MainFrm.mnuAnalysisMeas_SampleDataClick(Sender: TObject);
begin
if TestGenFrm = nil then
Application.CreateForm(TTestGenFrm, TestGenFrm);
TestGenFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Classical Test Analysis"
procedure TOS3MainFrm.mnuAnalysisMeas_ClassicalClick(Sender: TObject);
begin
if TestScoreForm = nil then
Application.CreateForm(TTestScoreForm, TestScoreForm);
TestScoreForm.Show;
end;
// Menu "Analysis" > "Measurement Programs" > "Rasch Test Calibration"
procedure TOS3MainFrm.mnuAnalysisMeas_RashClick(Sender: TObject);
begin
if RaschForm = nil then
Application.CreateForm(TRaschForm, RaschForm);
RaschForm.Show;
end;
// Menu "Analysis" > "Measurement Programs" > "Successive Interval Scaling"
procedure TOS3MainFrm.mnuAnalysisMeas_IntervalClick(Sender: TObject);
begin
if SuccIntFrm = nil then
Application.CreateForm(TSuccIntFrm, SuccIntFrm);
SuccIntFrm.Show;
end;
// Menu "Analysis" > "Measurement Programs" > "Guttman Scalogram Analysis
procedure TOS3MainFrm.mnuAnalysisMeas_GuttmanClick(Sender: TObject);
begin
if GuttmanForm = nil then
Application.CreateForm(TGuttmanForm, GuttmanForm);
GuttmanForm.Show;
end;
// Menu "Analysis" > "Measurement Programs" > "Weighted Composite Reliability"
procedure TOS3MainFrm.mnuAnalysisMeas_CompositeClick(Sender: TObject);
begin
if CompRelFrm = nil then
Application.CreateForm(TCompRelFrm, CompRelFrm);
CompRelFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Kuder-Richardson #21 Reliability"
procedure TOS3MainFrm.mnuAnalysisMeas_KR21Click(Sender: TObject);
begin
if KR21Frm = nil then
Application.CreateForm(TKR21Frm, KR21Frm);
KR21Frm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Spearman-Brown Prophecy Reliability"
procedure TOS3MainFrm.mnuAnalysisMeas_SpearmanClick(Sender: TObject);
begin
if SpBrFrm = nil then
Application.CreateForm(TSpBrFrm, SpBrFrm);
SpBrFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Grade Book"
procedure TOS3MainFrm.mnuAnalysisMeas_GradeBookClick(Sender: TObject);
begin
if GradeBookFrm = nil then
Application.CreateForm(TGradeBookFrm, GradeBookFrm);
GradebookFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Item Banking"
procedure TOS3MainFrm.mnuAnalysisMeas_ItemBankingClick(Sender: TObject);
begin
if ItemBankFrm = nil then
Application.CreateForm(TItemBankFrm, ItembankFrm);
ItemBankFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Reliability Due to Test Variance Change"
procedure TOS3MainFrm.mnuAnalysisMeas_VarChangeClick(Sender: TObject);
begin
if RelChangeFrm = nil then
Application.CreateForm(TRelChangeFrm, RelChangeFrm);
RelChangeFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Differential Item Functioning"
procedure TOS3MainFrm.mnuAnalysisMeas_DifferentialClick(Sender: TObject);
begin
if DIFFrm = nil then
Application.CreateForm(TDIFFrm, DIFFrm);
DIFFrm.ShowModal;
end;
// Menu "Analysis" > "Measurement Programs" > "Polytomous DIF Analysis"
procedure TOS3MainFrm.mnuAnalysisMeas_PolytomousClick(Sender: TObject);
begin
if PolyDIFFrm = nil then
Application.CreateForm(TPolyDIFFrm, PolyDIFFrm);
PolyDIFFrm.ShowModal;
end;
{ "Nonparametric" commands }
// Menu "Analysis" > "Nonparametric" > "Contingency Chi Square"