Skip to content

Commit a6d67b3

Browse files
committed
Merge branch 'feature/30-add-arithmetic-mean-funcs' into develop
Fixes #30
2 parents 18a672e + 3af9217 commit a6d67b3

File tree

9 files changed

+1204
-447
lines changed

9 files changed

+1204
-447
lines changed

Diff for: collection/650.dat

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function ArithMean(const A: array of Double): Double; overload;
2+
var
3+
X: Double;
4+
begin
5+
if Length(A) = 0 then
6+
raise SysUtils.EArgumentException.Create(
7+
'ArithMean: array is empty'
8+
);
9+
Result := 0.0;
10+
for X in A do
11+
Result := Result + X / Length(A);
12+
end;

Diff for: collection/651.dat

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function ArithMean(const A: array of Integer): Double; overload;
2+
var
3+
X: Integer;
4+
begin
5+
if Length(A) = 0 then
6+
raise SysUtils.EArgumentException.Create(
7+
'ArithMean: array is empty'
8+
);
9+
Result := 0.0;
10+
for X in A do
11+
Result := Result + X / Length(A);
12+
end;

Diff for: collection/652.dat

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function ArithMean(const A: array of Cardinal): Double; overload;
2+
var
3+
X: Cardinal;
4+
begin
5+
if Length(A) = 0 then
6+
raise SysUtils.EArgumentException.Create(
7+
'ArithMean: array is empty'
8+
);
9+
Result := 0.0;
10+
for X in A do
11+
Result := Result + X / Length(A);
12+
end;

Diff for: collection/653.dat

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function WeightedArithMean(const Values: array of Double;
2+
const Weights: array of Double): Double; overload;
3+
var
4+
WeightSum: Double;
5+
Weight: Double;
6+
Idx: Integer;
7+
begin
8+
if Length(Values) = 0 then
9+
raise SysUtils.EArgumentException.Create('Array of values is empty');
10+
if Length(Values) <> Length(Weights) then
11+
raise SysUtils.EArgumentException.Create(
12+
'Number of values and number of weights must be the same'
13+
);
14+
WeightSum := 0.0;
15+
for Weight in Weights do
16+
begin
17+
if Math.Sign(Weight) = Math.NegativeValue then
18+
raise SysUtils.EArgumentException.Create('Weights must all be >= 0');
19+
WeightSum := WeightSum + Weight;
20+
end;
21+
if Math.IsZero(WeightSum) then
22+
raise SysUtils.EArgumentException.Create('All weights are 0');
23+
Result := 0.0;
24+
for Idx := Low(Values) to High(Values) do
25+
Result := Result + Weights[Idx] * Values[Idx] / WeightSum;
26+
end;

Diff for: collection/654.dat

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function WeightedArithMean(const Values: array of Integer;
2+
const Weights: array of Double): Double; overload;
3+
var
4+
Idx: Integer;
5+
DblVals: array of Double;
6+
begin
7+
SetLength(DblVals, Length(Values));
8+
for Idx := Low(Values) to High(Values) do
9+
DblVals[Idx] := Values[Idx];
10+
Result := WeightedArithMean(DblVals, Weights);
11+
end;

Diff for: collection/655.dat

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function WeightedArithMean(const Values: array of Cardinal;
2+
const Weights: array of Double): Double; overload;
3+
var
4+
Idx: Integer;
5+
DblVals: array of Double;
6+
begin
7+
SetLength(DblVals, Length(Values));
8+
for Idx := Low(Values) to High(Values) do
9+
DblVals[Idx] := Values[Idx];
10+
Result := WeightedArithMean(DblVals, Weights);
11+
end;

Diff for: collection/maths.ini

+74
Original file line numberDiff line numberDiff line change
@@ -1681,3 +1681,77 @@ DelphiXE3=Y
16811681
DelphiXE4=Y
16821682
Delphi10S=Y
16831683
FPC=Y
1684+
1685+
[ArithMean_Double]
1686+
DisplayName="ArithMean (Double overload)"
1687+
DescEx="<p>Returns the arithmetic mean of an array of <var>Double</var> values.</p><p><var>EArgumentException</var> is raised if the array is empty.</p>"
1688+
Units=SysUtils
1689+
SeeAlso=ArithMean_Integer,ArithMean_Cardinal
1690+
TestInfo=advanced
1691+
AdvancedTest.Level=unit-tests
1692+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
1693+
Snip=650.dat
1694+
DelphiXE=Y
1695+
Delphi12A=Y
1696+
1697+
[ArithMean_Integer]
1698+
DisplayName="ArithMean (Integer overload)"
1699+
DescEx="<p>Returns the arithmetic mean of an array of <var>Integer</var> values.</p><p><var>EArgumentException</var> is raised if the array is empty.</p>"
1700+
Units=SysUtils
1701+
SeeAlso=ArithMean_Double,ArithMean_Cardinal
1702+
TestInfo=advanced
1703+
AdvancedTest.Level=unit-tests
1704+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
1705+
Snip=651.dat
1706+
DelphiXE=Y
1707+
Delphi12A=Y
1708+
1709+
[ArithMean_Cardinal]
1710+
DisplayName="ArithMean (Cardinal overload)"
1711+
DescEx="<p>Returns the arithmetic mean of an array of <var>Cardinal</var> values.</p><p><var>EArgumentException</var> is raised if the array is empty.</p>"
1712+
Units=SysUtils
1713+
SeeAlso=ArithMean_Double,ArithMean_Integer
1714+
TestInfo=advanced
1715+
AdvancedTest.Level=unit-tests
1716+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
1717+
Snip=652.dat
1718+
DelphiXE=Y
1719+
Delphi12A=Y
1720+
1721+
[WeightedArithMean_Double]
1722+
DisplayName="WeightedArithMean (Double overload)"
1723+
DescEx="<p>Calculates and returns the weighted average of the <var>Double</var> elements of array <var>Values</var> where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
1724+
Units=SysUtils,Math
1725+
SeeAlso=ArithMean_Double,WeightedArithMean_Integer,WeightedArithMean_Cardinal
1726+
TestInfo=advanced
1727+
AdvancedTest.Level=unit-tests
1728+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
1729+
Snip=653.dat
1730+
DelphiXE=Y
1731+
Delphi12A=Y
1732+
1733+
[WeightedArithMean_Integer]
1734+
DisplayName="WeightedArithMean (Integer overload)"
1735+
DescEx="<p>Calculates and returns the weighted average of the <var>Integer</var> elements of array <var>Values</var> where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
1736+
Units=
1737+
Depends=WeightedArithMean_Double
1738+
SeeAlso=ArithMean_Integer,WeightedArithMean_Double,WeightedArithMean_Cardinal
1739+
TestInfo=advanced
1740+
AdvancedTest.Level=unit-tests
1741+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
1742+
Snip=654.dat
1743+
DelphiXE=Y
1744+
Delphi12A=Y
1745+
1746+
[WeightedArithMean_Cardinal]
1747+
DisplayName="WeightedArithMean (Cardinal overload)"
1748+
DescEx="<p>Calculates and returns the weighted average of the <var>Cardinal</var> elements of array <var>Values</var> where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
1749+
Units=
1750+
Depends=WeightedArithMean_Double
1751+
SeeAlso=ArithMean_Cardinal,WeightedArithMean_Double,WeightedArithMean_Integer
1752+
TestInfo=advanced
1753+
AdvancedTest.Level=unit-tests
1754+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
1755+
Snip=655.dat
1756+
DelphiXE=Y
1757+
Delphi12A=Y

Diff for: tests/Cat-Maths/TestUMathsCatSnippets.pas

+168
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ TestMathsCatSnippets = class(TTestCase)
1111
procedure StretchRect_A_Except1;
1212
procedure StretchRect_A_Except2;
1313
procedure StretchRect_B_Except;
14+
procedure TestArithMean_Integer_Except;
15+
procedure TestArithMean_Cardinal_Except;
16+
procedure TestArithMean_Double_Except;
17+
procedure TestWeightedArithMean_Double_Except1;
18+
procedure TestWeightedArithMean_Double_Except2;
19+
procedure TestWeightedArithMean_Double_Except3;
20+
procedure TestWeightedArithMean_Double_Except4;
21+
1422
published
1523
procedure TestDigitCount;
1624
procedure TestDigitCount2;
@@ -57,6 +65,13 @@ TestMathsCatSnippets = class(TTestCase)
5765
procedure TestSumOfLogs_Cardinal;
5866
procedure TestSumOfLogs_Int64;
5967
procedure TestSumOfLogs_UInt64;
68+
procedure TestArithMean_Integer;
69+
procedure TestArithMean_Cardinal;
70+
procedure TestArithMean_Double;
71+
72+
procedure TestWeightedArithMean_Integer;
73+
procedure TestWeightedArithMean_Cardinal;
74+
procedure TestWeightedArithMean_Double;
6075
end;
6176

6277
implementation
@@ -194,6 +209,81 @@ procedure TestMathsCatSnippets.StretchRect_B_Except;
194209
R1 := StretchRect(R0, 1234567890.0);
195210
end;
196211

212+
procedure TestMathsCatSnippets.TestArithMean_Cardinal;
213+
const
214+
A0: array[0..1] of Cardinal = (0, 0);
215+
A1: array[0..0] of Cardinal = (56);
216+
A4: array[0..3] of Cardinal = (12, 78, 0, 3);
217+
E0 = 0.0;
218+
E1 = 56.0;
219+
E4 = (12.+78.+0.0+3.0)/4.0;
220+
begin
221+
CheckTrue(Math.SameValue(E0, ArithMean(A0)), 'A0');
222+
CheckTrue(Math.SameValue(E1, ArithMean(A1)), 'A1');
223+
CheckTrue(Math.SameValue(E4, ArithMean(A4)), 'A4');
224+
CheckException(
225+
TestArithMean_Cardinal_Except, EArgumentException, 'Exception'
226+
);
227+
end;
228+
229+
procedure TestMathsCatSnippets.TestArithMean_Cardinal_Except;
230+
var
231+
A: array of Cardinal;
232+
begin
233+
SetLength(A, 0);
234+
ArithMean(A);
235+
end;
236+
237+
procedure TestMathsCatSnippets.TestArithMean_Double;
238+
const
239+
A0: array[0..1] of Double = (0.0, 0.0);
240+
A1: array[0..0] of Double = (-PI);
241+
A4: array[0..3] of Double = (12.42, -56.47, 0.0, 3.0);
242+
E0 = 0.0;
243+
E1 = -PI;
244+
E4 = (12.42-56.47+3.0)/4.0;
245+
begin
246+
CheckTrue(Math.SameValue(E0, ArithMean(A0)), 'A0');
247+
CheckTrue(Math.SameValue(E1, ArithMean(A1)), 'A1');
248+
CheckTrue(Math.SameValue(E4, ArithMean(A4)), 'A4');
249+
CheckException(
250+
TestArithMean_Double_Except, EArgumentException, 'Exception'
251+
);
252+
end;
253+
254+
procedure TestMathsCatSnippets.TestArithMean_Double_Except;
255+
var
256+
A: array of Double;
257+
begin
258+
SetLength(A, 0);
259+
ArithMean(A);
260+
end;
261+
262+
procedure TestMathsCatSnippets.TestArithMean_Integer;
263+
const
264+
A0: array[0..1] of Integer = (0, 0);
265+
A1: array[0..0] of Integer = (-56);
266+
A4: array[0..3] of Integer = (12, -42, 0, 3);
267+
E0 = 0.0;
268+
E1 = -56.0;
269+
E4 = (12.0-42.0+3.0)/4.0;
270+
begin
271+
CheckTrue(Math.SameValue(E0, ArithMean(A0)), 'A0');
272+
CheckTrue(Math.SameValue(E1, ArithMean(A1)), 'A1');
273+
CheckTrue(Math.SameValue(E4, ArithMean(A4)), 'A4');
274+
CheckException(
275+
TestArithMean_Integer_Except, EArgumentException, 'Exception'
276+
);
277+
end;
278+
279+
procedure TestMathsCatSnippets.TestArithMean_Integer_Except;
280+
var
281+
A: array of Integer;
282+
begin
283+
SetLength(A, 0);
284+
ArithMean(A);
285+
end;
286+
197287
procedure TestMathsCatSnippets.TestArraySum_Cardinal;
198288
const
199289
A: array[0..3] of Cardinal = (12, 78, 0, 3);
@@ -944,6 +1034,84 @@ procedure TestMathsCatSnippets.TestSumOfLogs_UInt64;
9441034
CheckTrue(BoolRes, 'SumOfLogs_UInt64');
9451035
end;
9461036

1037+
procedure TestMathsCatSnippets.TestWeightedArithMean_Cardinal;
1038+
const
1039+
A: array[1..3] of Cardinal = (12, 6, 3);
1040+
W: array[0..2] of Double = (0.5, 0.25, 0.75);
1041+
E = 6.5;
1042+
begin
1043+
CheckTrue(Math.SameValue(E, WeightedArithMean(A, W)));
1044+
end;
1045+
1046+
procedure TestMathsCatSnippets.TestWeightedArithMean_Double;
1047+
const
1048+
A1: array[1..1] of Double = (42.456);
1049+
W1: array[3..3] of Double = (1.7);
1050+
E1 = 42.456;
1051+
A2: array[1..5] of Double = (23.5, -3.9987, 66.0, 0.0, 47.6864);
1052+
W2: array[1..5] of Double = (7.6, 0.0, 12.7, 4.5, 3.2);
1053+
E2 = 41.7642; // from online calculator: accurate to 4 decimal places
1054+
FudgeFactor2 = 10000;
1055+
A3: array[1..3] of Double = (0.0, 0.0, 0.0);
1056+
W3: array[1..3] of Double = (23.5, 99.7, 27.898);
1057+
begin
1058+
CheckTrue(Math.SameValue(E1, WeightedArithMean(A1, W1)), 'A1');
1059+
// E2 is accurate to 4DP - so round of both values multiplied by 10,000
1060+
CheckEquals(Round(E2 * FudgeFactor2), Round(WeightedArithMean(A2, W2) * FudgeFactor2), 'A2');
1061+
CheckTrue(Math.IsZero(WeightedArithMean(A3, W3)), 'A3');
1062+
1063+
CheckException(TestWeightedArithMean_Double_Except1, EArgumentException, 'Except 1');
1064+
CheckException(TestWeightedArithMean_Double_Except2, EArgumentException, 'Except 2');
1065+
CheckException(TestWeightedArithMean_Double_Except3, EArgumentException, 'Except 3');
1066+
CheckException(TestWeightedArithMean_Double_Except4, EArgumentException, 'Except 4');
1067+
end;
1068+
1069+
procedure TestMathsCatSnippets.TestWeightedArithMean_Double_Except1;
1070+
var
1071+
A, W: array of Double;
1072+
begin
1073+
// Empty array error
1074+
SetLength(A, 0);
1075+
SetLength(W, 0);
1076+
WeightedArithMean(A, W);
1077+
end;
1078+
1079+
procedure TestMathsCatSnippets.TestWeightedArithMean_Double_Except2;
1080+
const
1081+
A: array[1..3] of Double = (1.0, 2.0, PI);
1082+
W: array[1..2] of Double = (0.5, 0.7);
1083+
begin
1084+
// Different size A & W arrays
1085+
WeightedArithMean(A, W);
1086+
end;
1087+
1088+
procedure TestMathsCatSnippets.TestWeightedArithMean_Double_Except3;
1089+
const
1090+
A: array[1..4] of Double = (1.0, 2.0, PI, -67.948);
1091+
W: array[1..4] of Double = (0.5, 0, -42.0, 0.7);
1092+
begin
1093+
// W array contains -ve value
1094+
WeightedArithMean(A, W);
1095+
end;
1096+
1097+
procedure TestMathsCatSnippets.TestWeightedArithMean_Double_Except4;
1098+
const
1099+
A: array[1..3] of Double = (1.0, 2.0, PI);
1100+
W: array[1..3] of Double = (0.0, 0.0, 0.0);
1101+
begin
1102+
// W array sums to 0
1103+
WeightedArithMean(A, W);
1104+
end;
1105+
1106+
procedure TestMathsCatSnippets.TestWeightedArithMean_Integer;
1107+
const
1108+
A: array[1..3] of Integer = (12, -6, 3);
1109+
W: array[0..2] of Double = (0.5, 0.25, 0.75);
1110+
E = 4.5;
1111+
begin
1112+
CheckTrue(Math.SameValue(E, WeightedArithMean(A, W)));
1113+
end;
1114+
9471115
initialization
9481116
// Register any test cases with the test runner
9491117
RegisterTest(TestMathsCatSnippets.Suite);

0 commit comments

Comments
 (0)