Skip to content

Commit 712173a

Browse files
committed
feat(maths): add harmonic mean algorithm
1 parent 8106aea commit 712173a

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

maths/harmonic_mean.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""
2+
The Harmonic Mean of n numbers is defined as n divided by the sum of the
3+
reciprocals of those numbers. It is used to calculate average rates and ratios.
4+
https://en.wikipedia.org/wiki/Harmonic_mean
5+
"""
6+
7+
from typing import Union
8+
9+
10+
def compute_harmonic_mean(*args: Union[int, float]) -> float:
11+
"""
12+
Return the harmonic mean of the argument numbers.
13+
14+
The harmonic mean is particularly useful for rates (e.g., speed, density).
15+
16+
>>> compute_harmonic_mean(1, 2, 4)
17+
1.7142857142857142
18+
>>> compute_harmonic_mean(2, 4)
19+
2.6666666666666665
20+
>>> compute_harmonic_mean('a', 4)
21+
Traceback (most recent call last):
22+
...
23+
TypeError: Not a Number
24+
>>> compute_harmonic_mean(1, 0)
25+
Traceback (most recent call last):
26+
...
27+
ValueError: Cannot compute harmonic mean with zero values
28+
>>> compute_harmonic_mean(1, -1)
29+
Traceback (most recent call last):
30+
...
31+
ValueError: Cannot compute harmonic mean with non-positive values
32+
>>> compute_harmonic_mean()
33+
Traceback (most recent call last):
34+
...
35+
ValueError: At least one number is required
36+
>>> compute_harmonic_mean(4, 4, 4)
37+
4.0
38+
>>> compute_harmonic_mean(1, 2)
39+
1.3333333333333333
40+
"""
41+
if len(args) == 0:
42+
raise ValueError("At least one number is required")
43+
44+
reciprocal_sum = 0
45+
for number in args:
46+
if not isinstance(number, (int, float)):
47+
raise TypeError("Not a Number")
48+
if number == 0:
49+
raise ValueError("Cannot compute harmonic mean with zero values")
50+
if number < 0:
51+
raise ValueError("Cannot compute harmonic mean with non-positive values")
52+
reciprocal_sum += 1 / number
53+
54+
return len(args) / reciprocal_sum
55+
56+
57+
if __name__ == "__main__":
58+
from doctest import testmod
59+
60+
testmod(name="compute_harmonic_mean")
61+
print(compute_harmonic_mean(1, 2, 4))

0 commit comments

Comments
 (0)