7
7
import itertools as it
8
8
import logging
9
9
import warnings
10
+ from collections import defaultdict
10
11
11
12
from codebasin import util
12
13
@@ -81,6 +82,74 @@ def divergence(setmap):
81
82
return d / float (npairs )
82
83
83
84
85
+ def utilization (setmap : defaultdict [frozenset [str ], int ]) -> float :
86
+ """
87
+ Compute the average code utilization for all lines in the setmap.
88
+ i.e., (reused SLOC / total SLOC)
89
+
90
+ Parameters
91
+ ----------
92
+ setmap: defaultdict[frozenset[str], int]
93
+ The mapping from platform sets to SLOC.
94
+
95
+ Returns
96
+ -------
97
+ float
98
+ The average code utilization, in the range [0, NumPlatforms].
99
+ If the number of total SLOC is 0, returns NaN.
100
+ """
101
+ reused_sloc = 0
102
+ total_sloc = 0
103
+ for k , v in setmap .items ():
104
+ reused_sloc += len (k ) * v
105
+ total_sloc += v
106
+ if total_sloc == 0 :
107
+ return float ("nan" )
108
+
109
+ return reused_sloc / total_sloc
110
+
111
+
112
+ def normalized_utilization (
113
+ setmap : defaultdict [frozenset [str ], int ],
114
+ total_platforms : int | None = None ,
115
+ ) -> float :
116
+ """
117
+ Compute the average code utilization, normalized for a specific number of
118
+ platforms.
119
+
120
+ Parameters
121
+ ----------
122
+ setmap: defaultdict[frozenset[str,int]
123
+ The mapping from platform sets to SLOC.
124
+
125
+ total_platforms: int, optional
126
+ The total number of platforms to use as the denominator.
127
+ By default, the denominator will be derived from the setmap.
128
+
129
+ Returns
130
+ -------
131
+ float
132
+ The average code utilization, in the range [0, 1].
133
+
134
+ Raises
135
+ ------
136
+ ValueError
137
+ If `total_platforms` < the number of platforms in `setmap`.
138
+ """
139
+ original_platforms = len (extract_platforms (setmap ))
140
+ if total_platforms is None :
141
+ total_platforms = original_platforms
142
+ if total_platforms < original_platforms :
143
+ raise ValueError (
144
+ "Cannot normalize to fewer platforms than the setmap contains." ,
145
+ )
146
+
147
+ if total_platforms == 0 :
148
+ return float ("nan" )
149
+ else :
150
+ return utilization (setmap ) / total_platforms
151
+
152
+
84
153
def summary (setmap ):
85
154
"""
86
155
Produce a summary report for the platform set
@@ -99,8 +168,10 @@ def summary(setmap):
99
168
lines += [table (["Platform Set" , "LOC" , "% LOC" ], data )]
100
169
101
170
cd = divergence (setmap )
171
+ nu = normalized_utilization (setmap )
102
172
unused = (setmap [frozenset ()] / total_count ) * 100.0
103
173
lines += [f"Code Divergence: { cd :.2f} " ]
174
+ lines += [f"Code Utilization: { nu :.2f} " ]
104
175
lines += [f"Unused Code (%): { unused :.2f} " ]
105
176
lines += [f"Total SLOC: { total_count } " ]
106
177
0 commit comments