
(Ebook - Pdf) Kick Ass Delphi Programming
.pdf
Well, now that we’ve built this wonderful component, let’s put it to work. In this section, we’ll create a program that allows the user to select any field in any table, and get a complete statistical report displayed neatly in a Memo component. Figure 16.1 shows the StatsProject at design time.
FIGURE 9.1 StatsProject at design time.
You’ll notice that everything on the form is pretty standard—there are a few ordinary visual controls, a
TTable, a TDataSource, a TOpenDialog, and, of course, a TDBStatistics. When the user starts the
StatsProject, he/she must first select a table. This is done through BtnTableSelect, the TButton control marked “1. Select a table & field.” In the BtnTableSelect’s OnClick event, a table name is retrieved via the TOpenDialog component, OpenDialog1.
First, the Execute method is called. If a valid file name was selected, then we proceed:
with OpenDialog1 do begin
Execute;
if FileName = '' then exit;
We now set the properties of the TTable component based on the user’s file selection. In addition, we display the relevant information via two TLabel controls:
Table1.DatabaseName := ExtractFilePath(FileName);
LblDatabase.Caption := ExtractFilePath(FileName);
Table1.TableName := ExtractFileName(FileName);
LblTable.Caption := ExtractFileName(FileName);
Because TDBStatistics only operates on one field at a time, we must provide a way for the user to select a field. This is done by retrieving the field names of the TTable and placing them into a ComboBox component:
CBFields.Items.Clear; {reset TComboBox} CBFields.Text := '';
Table1.Open;
for I := 0 to Table1.FieldDefs.Count-1 do begin
Application.ProcessMessages;
CBFields.Items.Add(Table1.Fields[I].FieldName);
end;
Table1.Close;
And that’s all there is to selecting a table and field name.
Once the user has selected a field to be analyzed, he/she can generate a statistical report in the Memo control by clicking the BtnReports button. (It’s the one marked “2. Generate a report.”) In the BtnReports.OnClick event, then, we first set the appropriate properties for the DBStatistics component,
DBStatistics1:
DBStatistics1.LowerBound := 1;

Table1.Open;
DBStatistics1.UpperBound := Table1.RecordCount; Table1.Close;
DataSource1.DataSet := Table1; DBStatistics1.DataSource := DataSource1;
DBStatistics1.DataField := CBFields.Text;{user-selected field}
Then, we call DBStatistics1.GetAllStats and print the results to the Memo component:
DBStatistics1.GetAllStats;
Memo1.Text := '';
Memo1.Lines.Add('Mean: ' + #09 + #09 + FloatToStr(DBStatistics1.Mean));
{etc......}
Memo1.Lines.Add('Kurtosis: ' + #09 + #09 +
FloatToStr(DBStatistics1.Kurtosis));
And that’s about all there is to it. We now have a complete statistical report generator.
Bugs in the Math Unit
Yes, believe it or not, there is a bug in the Math unit. But it’s probably better you hear it now than find out the hard way, right?
So here goes: MinValue and MaxValue are reversed. MinValue actually returns the largest value in the array, while MaxValue returns the smallest value in the array. While this bug isn’t a showstopper, it does deserve mentioning. (Of course, the DBStatistics component fixes this problem with regards to its own
MaxValue and MinValue properties.)
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

To access the contents, click the chapter and section titles.
Kick Ass Delphi Programming
Go!
Keyword
(Publisher: The Coriolis Group)
Author(s): Don Taylor, Jim Mischel, John Penman, Terence Goggin
ISBN: 1576100448
Publication Date: 09/01/96
Search this book:
Go!
-----------
Poly: The Function That Got Away
While I was preparing the complete list of the Math unit’s functions presented at the end of this chapter, there was one function that was intentionally omitted. Why? Because Borland didn’t document it either! So it isn’t clear whether it’s “really” supposed to be in the Math unit at all. (In fact, the only way anyone would ever find it is if they were studying the source for the Math unit while preparing a chapter for KickAss Delphi....)
What’s this mysterious function all about? Here it is:
function Poly(X: Extended; const Coefficients: array of Double): Extended;
Basically, Poly solves polynomial equations for you. The only limitation is that they must be polynomials in one variable. You pass Poly two pieces of information: a value, X, at which you want the polynomial evaluated, and the coefficients of the polynomial’s terms. The coefficients should be ordered in increasing powers of X.
What this means is that if you have a polynomial such as
4x4 [+ 0x3] - x2 + 3x + 34
the values in your coefficients array should be ordered like this:
34, 3, -1, 0, 4.
If you were to put an interface on the Poly function, you’d probably end up with something like Figure 16.2, which shows PolyProject running.
FIGURE 9.2 Graphing a function with Poly.
PolyProject (on the CD-ROM for this chapter) is just such an application. It allows the user to enter a polynomial, and then actually graphs it. You’ll notice that the PolyProject’s main window has a few Edit controls, along with some Labels, set up so that the user can enter coefficients for a generic polynomial. However, all of the significant work of the PolyProject is done in the OnClick event of the “Solve!” Button:
procedure TForm1.SolveButtonClick(Sender: TObject); var
i : Integer;
XCoes : array[0..4] of double; X,Y, OffsetX, OffsetY : Integer; NewRect: TRect;
Our first job is to fill the XCoes array with the coefficient values the user has entered:
begin
XCoes[0] := StrToFloat(TxtX0.Text); XCoes[1] := StrToFloat(TxtX1.Text); XCoes[2] := StrToFloat(TxtX2.Text); XCoes[3] := StrToFloat(TxtX3.Text); XCoes[4] := StrToFloat(TxtX4.Text);
...
That done, we now have to set the center for our graphing area. I prefer to use the center of the TImage control, but you could just as easily use any point you like:
OffsetX := Image1.Width div 2;
OffsetY := Image1.Height div 2;
Next, we initialize our X-coordinate value and clear the graph by essentially filling Image1 with a solid white rectangle. Then, we reset Image1.Canvas.Brush.Color so that our graph will be drawn in black:
X := 0; {Initialize X just to be safe}
NewRect := Rect(0, 0, Image1.Width, Image1.Height); Image1.Canvas.Brush.Color := clWhite; Image1.Canvas.FillRect(NewRect); Image1.Canvas.Brush.Color := clBlack;
Here’s where the calculations are done. We first generate a starting point for the line. Note that we don’t actually draw anything until we’re inside the for loop. This is because we need a point at which to position the “pen” before we do any serious drawing. So we call the Poly function, passing the value contained in the lower bound range edit box (TxtRangeStart) and the XCoes array:
with Image1.Canvas do begin
Y := Trunc(Poly(StrToInt(TxtRangeStart.Text), XCoes));
...
You may be surprised to see that I’ve truncated the result of the Poly function. This is for graphing purposes only; although the Poly function returns a floating point (Extended type) value, the Windows API only understands integer coordinates.

Next, we convert the result we just got to an (X, Y) pair that corresponds to our center, and we move the “pen” to that point:
X := StrToInt(TxtRangeStart.Text) + OffsetX;
Y := OffsetY - Y;
MoveTo(X,Y);
We then use a for loop to iterate through the X-range values, one at a time, starting with the lower bound plus 1 (we just did the lower bound value a moment ago), and continuing through to the value contained in the upper bound edit box (TxtRangeEnd):
for i := StrToInt(TxtRangeStart.Text) + 1 to StrToInt(TxtRangeEnd.Text) do
begin
Y := Trunc(Poly(I, XCoes)); X := I + OffsetX;
Y := OffsetY - Y; LineTo(X,Y); MoveTo(X,Y);
end;
While Poly appears to be the only publicly available, undocumented function in the Math unit, there are a few routines declared in the implementation section that look interesting. (One actually determines if value A is “small” relative to value B!) While they can’t be discussed here due to space constraints, I’d recommend reading them over if you’ve got the source code—and the patience, of course!
Filling the Pascal Power Gap
The Math unit introduces something Pascal has never had: an official power (exponent) function. In fact, the Math unit contains two power functions.
The first power function, Power, takes two Extended type values; one is the base, the other is the exponent. The second power function, IntPower, takes one Extended type parameter and one integer parameter; the Extended value is the base, the integer is the exponent.
The difference between the two routines is that IntPower, like many of the Math unit’s routines, is coded entirely in Pentium FPU optimized assembler, making it quite fast.
If you’re concerned about which one your app should use, don’t be.
Although it’s not explained or documented, Power itself will decide whether the exponent is an integer. If it is, Power calls IntPower. If, on the other hand, the exponent is a true floating point value, Power uses the natural log/base e method of calculating its result.
Math Unit Function Summary
To close out this chapter, I’ll present a complete list of the functions and procedures presented in the Math unit. Most of them are reasonably self-explanatory. Those that aren’t—well, sit yourself down and do some sleuthing. Not all Delphi knowledge will be handed to you on a silver-plated Help screen!

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

To access the contents, click the chapter and section titles.
Kick Ass Delphi Programming
Go!
Keyword
(Publisher: The Coriolis Group)
Author(s): Don Taylor, Jim Mischel, John Penman, Terence Goggin
ISBN: 1576100448
Publication Date: 09/01/96
Search this book:
Go!
-----------
Trigonometric Functions and Procedures
ArcCos
Inverse Cosine.
ArcCosh
Inverse Hyperbolic Cosine.
ArcSin
Inverse Sine.
ArcSinh
Inverse Hyperbolic Sine.
ArcTanh
Inverse Hyperbolic Tangent.
ArcTan2
Inverse Tangent with corrections for the proper quadrant. (The function can be found in the System unit.)
Cosh
Hyperbolic Cosine.
Cotan
Cotangent.
CycleToRad
Converts Cycles to Radians.
DegToRad
Converts a measure in degrees to radians..
GradToRad
Converts Grads to Radians.
Hypot
Calculates the length of the hypotenuse of a triangle given the length of the two sides.
RadToDeg
Converts a measure in radians to degrees.
RadToCycle
Converts Radians to Cycles.
RadToGrad
Converts Radians to Grads.
SinCos
Calculates both the Sine and Cosine for a given angle. Just as with SumAndSquares and MeanAndStdDev, it is faster to generate both values at once.
Sinh
Hyperbolic Sine.
Tan
Tangent.
Tanh
Hyperbolic Tangent.
Arithmetic Functions and Procedures
Ceil
Rounds up.
Floor
Rounds down.
Frexp
Calculates the Mantissa and exponent of a given value.
IntPower
Raises a number to an integral power. If you’re not going to use Float-based exponents, this function is to be highly recommended because of its speed.
Ldexp
Calculates X times 2 to a given power.
LnXP1
Calculates the natural log of X + 1. This is intended for estimating Xs close to zero.
Log10
Calculates the natural log of X.
Log2
Calculates the log in base two of X.
LogN
Given a base and an X value, calculates the base N log of X.
Power
Raises a number to an exponent. This one isn’t as fast as IntPower, but if you need Float-type exponents, it’ll do quite well.
Financial Functions and Procedures
DoubleDecliningBalance
Calculates depreciation using the double-declining balance formula.
FutureValue
Calculates the future value of an investment.
InterestPayment
Calculates the amount of the loan payment that is interest.
InterestRate
Calculates the interest rate necessary to earn a specified amount.
InternalRateOfReturn
Calculates a rate of return based on cash flow data.
NumberOfPeriods
Calculates the number of periods for an investment to reach a specified value.
NetPresentValue
Calculates the current value of a set of cash flow values, taking the interest rate into account.
Payment
Calculates the amount of Loan payments, given the amount borrowed, the interest rate, and present and future values of the investment.
PeriodPayment
Calculates the amount of the loan payment that is principal.
PresentValue
Calculates the present value of an investment.
SLNDepreciation
Calculates the Straight Line Depreciation of an investment.
SYDDepreciation
Calculates the Sum-of-Years-Digits Depreciation.
Statistical Functions and Procedures
MaxValue
Is supposed to find the largest value in a set of data, but instead finds smallest value.
Mean
Calculates the Mean for a set of values.
MeanAndStdDev

Calculates both the Mean and standard deviation for a set of data. This is faster than calculating each value separately.
MinValue
Is supposed to find the smallest value in a set of data, but instead finds largest value.
MomentSkewKurtosis
Calculates the skew and kurtosis for a given set of data.
Norm
Calculates the norm for a given set of data. The norm is the square root of the sum of squares.
PopnStdDev
Calculates the population standard deviation, which differs from the standard deviation in that it uses the population variance (PopnVariance), defined below.
PopnVariance
Calculates the population variance for a given set of data. This routine uses the TotalVariance / n or “biased” formula.
RandG
Generates “fake” data points given a mean and a standard deviation.
StdDev
Calculates the standard deviation for a set of data.
Sum
Calculates the sum of a set of values.
SumsAndSquares
Calculates both the sum and the sum of squares for a given set of data. As with several of the Math unit’s routines, it is faster to generate these two results at once, rather than first generating the Sum and then the sum of squares.
SumOfSquares
Calculates the sum of the squares of a set of values.
TotalVariance
Calculates the total variance for a given set of data. Total variance is the sum of every value’s distance from the mean squared.
Variance
Calculates the sample variance for a given set of data. This routine uses the TotalVariance / (n-1) or “unbiased” formula.