Prosta hierarchia klas: obliczenia statystyczne¶
W poniższym przykładzie powstanie kilka klas, umożliwiających obliczenia statystyczne na kolumnie liczb.
Każda z klas ma jasno sprecyzowany cel, a funkcjonalność, którą dostarcza, zaimplementowana jest w operatorze wywołania
(call operator). Dodatkowo każda z tych klas umie się przedstawić (metoda name())
Klasy dziedziczą po abstrakcyjnej klasie bazowej AbstractStatistCalculator, która definiuje metody,
zaimplementowane w klasach potomnych. Najciekawszym przypadkiem jest klasa SumVariance, która zarówno zawiera
obiekty klasy AbstractStatistCalculator jak i sama po niej dziedziczy. Również sama nie wykonuje żadnych obliczeń.
Wymaganą funkcjonalność zapewnia, wywołując odpowiednie metody ze składowych obiektów (delegacje).
1class AbstractStatistCalculator:
2
3 def __call__(self, *args):
4 raise NotImplemented("to be implemented in by a derived class")
5
6 def name(self, *args):
7 raise NotImplemented("to be implemented in by a derived class")
8
9
10class Sum(AbstractStatistCalculator):
11
12 def __call__(self, *args):
13 if len(args) == 1: args = args[0]
14 s = 0
15 for v in args: s+=v
16 return s
17
18 def name(self, *args):
19 return " sum"
20
21class Average(AbstractStatistCalculator):
22
23 def __call__(self, *args):
24 if len(args) == 1: args = args[0]
25 s = 0
26 for v in args: s+=v
27 return s/len(args)
28
29 def name(self, *args):
30 return " average"
31
32
33class Variance(AbstractStatistCalculator):
34
35 def __call__(self, *args):
36 if len(args) == 1: args = args[0]
37 s, s2 = 0, 0
38 for v in args:
39 s += v
40 s2 += v * v
41 s = s/len(args)
42 return s2/len(args) - s*s
43
44 def name(self, *args):
45 return " variance"
46
47
48class SumVariance(AbstractStatistCalculator):
49
50 def __init__(self):
51 self.__avg = Sum()
52 self.__var = Variance()
53
54 def __call__(self, *args):
55 return self.__avg(*args), self.__var(*args)
56
57 def name(self, *args):
58 return "sum and variance"
59
60
61if __name__ == "__main__":
62
63 from random import random
64
65 sum = Sum()
66 avg = Average()
67 var = Variance()
68
69 stats = [sum, avg, var, SumVariance()]
70 input_data = [random() for i in range(100)]
71
72 for calc in stats:
73 print(calc.name()+" :",calc(input_data))