Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,5 @@ cython_debug/
*~
*.swp
*.swo

.vscode/
121 changes: 121 additions & 0 deletions probdists/Weibulldistribution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import math
import numpy as np
from matplotlib import pyplot as plt
from .Generaldistribution import Distribution


class Weibull(Distribution):
""" Weibull distribution class for calculating and
visualizing a Weibull distribution.

Attributes:

mean (float): the mean value of the distribution
stdev (float): the standard deviation of the distribution

data (list of floats): extracted from the data file

lmbda (float): scale parameter of the distribution
(missing an 'a' to prevent name clash with Python keyword)
k (float): shape parameter of the distribution

"""
def __init__(self, lmbda=1, k=1.5):
self.lmbda = lmbda
self.k = k
self.calculate_mean()
self.calculate_stdev()

def calculate_mean(self, round_to=2):
""" Method to calculate the mean

Args:
round_to (int): Round the mean value. [Default value: 2 floating point]

Returns:
float: mean of the distribution
"""
gamma_factor = math.gamma(1 + (1 / self.k))
self.mean = self.lmbda * gamma_factor
return round(self.mean, round_to)

def calculate_stdev(self, round_to=2):
""" Method to calculate the standard deviation

Args:
round_to (int): Round the mean value. [Default value: 2 floating point]

Returns:
float: standard deviation of the distribution
"""
first = math.gamma(1 + (2 / self.k))
second = math.gamma(1 + (1 / self.k)) ** 2
self.stdev = math.sqrt(self.lmbda ** 2 * (first - second))
return round(self.stdev, round_to)

def calculate_pdf(self, x, round_to=2):
""" Probability density function calculator for the Weibull distribution.

Args:
x (float): point for caluclating the probability density function
round_to (int): Round the mean value. [Default value: 2 floating point]

Returns:
float: probability density function
"""
if x < 0:
out = 0
else:
exp_factor = math.exp(-(x / self.lmbda) ** self.k)
out = (self.k / self.lmbda) * exp_factor * \
(x / self.lmbda) ** (self.k - 1)
return round(out, round_to)

def calculate_cdf(self, x, round_to=2):
"""
Cumulative density function calculator for the Weibull distribution.
Args:
x (float): point for calculating the cumulative density function
round_to (int): Round the mean value. [Default value: 2 floating point]

Returns:
float: cumulative density function output
"""
if x < 0:
out = 0
else:
out = 1 - math.exp(-(x / self.lmbda) ** self.k)
return round(out, round_to)

def plot_pdf(self, samples=250):
""" Method to plot the pdf of the Weibull distribution.

Args:
samples (int): number of discrete data points

Returns:
list: y values for the pdf plot

"""
x = np.linspace(0, 2.5, num=samples)
y = np.zeros_like(x)

for index, value in enumerate(x):
y[index] = self.calculate_pdf(value)

plt.plot(x, y, label=f"lambda={self.lmbda}; k={self.k}")
plt.legend()
plt.title(f"Probability Distribution Function for Weibull \
Distribution lambda={self.lmbda} k={self.k}")
plt.show()
return y

def __repr__(self):
""" Method to output the characteristics of the Weibull instace.
Args:
None
Returns:
string: characteristics of the Weibull
"""
return f"lambda: {self.lmbda}, k: {self.k}, mean: {self.mean}, \
standard deviation: {self.stdev}"
1 change: 1 addition & 0 deletions probdists/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from .Bernoullidistribution import Bernoulli
from .Uniformdistribution import Uniform
from .Triangulardistribution import Triangular, TriangularValueException
from .Weibulldistribution import Weibull
37 changes: 36 additions & 1 deletion test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from probdists import Bernoulli
from probdists import Uniform
from probdists import Triangular, TriangularValueException
from probdists import Weibull


class TestGeneraldistribution(unittest.TestCase):
Expand Down Expand Up @@ -238,7 +239,6 @@ def test_cdf(self):
self.assertEqual(self.uniform.calculate_cdf(4), 0.75, 'calculate_cdf function does not give expected result')



class TestGammaClass(unittest.TestCase):
def setUp(self):
self.gamma = Gamma()
Expand Down Expand Up @@ -407,5 +407,40 @@ def test_cdf(self):
self.assertEqual(self.triangle.calculate_cdf(12), 1)


class TestWeibullClass(unittest.TestCase):
def setUp(self):
self.weibull = Weibull()

def test_initialization(self):
self.assertEqual(self.weibull.k, 1.5, 'incorrect k')
self.assertEqual(self.weibull.lmbda, 1, 'incorrect lambda')

def test_meancalculation(self):
self.weibull.calculate_mean()
self.assertEqual(round(self.weibull.mean, 5), 0.90275,
'calculated mean not as expected')

def test_stdevcalculation(self):
self.weibull.calculate_stdev()
self.assertEqual(round(self.weibull.stdev, 5), 0.61294,
'calculated stdev not as expected')

def test_pdf(self):
self.assertEqual(self.weibull.calculate_pdf(0.5, 5), 0.74478,
'unexpected pdf value')
self.weibull.calculate_mean()
self.weibull.calculate_stdev()
self.assertEqual(self.weibull.calculate_pdf(1, 5), 0.55182,
'unexpected pdf value')
self.assertEqual(self.weibull.calculate_pdf(2.0, 5), 0.12538,
'unexpected pdf')

def test_cdf(self):
self.assertEqual(self.weibull.calculate_cdf(0.5, 5), 0.29781,
'unexpected cdf value')
self.assertEqual(self.weibull.calculate_cdf(1.0, 5), 0.63212,
'unexpected cdf value')


if __name__ == '__main__':
unittest.main()