radon
radon copied to clipboard
Incorrect number of distinct operators in Halstead metric
While trying to fix #160, I noticed that the Halstead visitor counts operands incorrectly. Essentially, it states that every expression that an operator is applied to is a distinct operator. For example, in the current master,
def f(x):
x + x + x
has two distinct operands. These are x
and x + x
.
The problem is that the operator visitors claim to know what operands they are being applied to. In x + (x + x)
, the first +
claims to apply to x
and (x + x)
, and treats (x + x)
as an actual operand. I believe that Halstead only ever meant variables as operands, not arbitrary expressions containing them.
I believe that this can be fixed by forcing every visitor method to ignore operands entirely and implementing a visit_Name
method. I tried this in a quick experiment, and it fixes the above example. It also gives more reasonable results when combined with the visit_Assignment
method requested in #160.
Hi @rwbogl, I'm very sorry for the long delay. Do you happen to still have the code for this? I have been fixing a lot of issues and I'd like to close these two as well. You are welcome to open a PR!
https://www.geeksforgeeks.org/software-engineering-halsteads-software-metrics/
from Software Engineering | Halstead’s Software Metrics .... Counting rules for C language – ...
- Comments are not considered.
- The identifier and function declarations are not considered
- All the variables and constants are considered operands.
- Global variables used in different modules of the same program are counted as multiple occurrences of the same variable.
- Local variables with the same name in different functions are counted as unique operands.
- Functions calls are considered as operators.
- All looping statements e.g., do {…} while ( ), while ( ) {…}, for ( ) {…}, all control statements e.g., if ( ) {…}, if ( ) {…} else {…}, etc. are considered as operators.
- In control construct switch ( ) {case:…}, switch as well as all the case statements are considered as operators.
- The reserve words like return, default, continue, break, sizeof, etc., are considered as operators.
- All the brackets, commas, and terminators are considered as operators.
- GOTO is counted as an operator and the label is counted as an operand.
- The unary and binary occurrence of “+” and “-” are dealt separately. Similarly “*” (multiplication operator) are dealt separately.
- In the array variables such as “array-name [index]” “array-name” and “index” are considered as operands and [ ] is considered as operator.
- In the structure variables such as “struct-name, member-name” or “struct-name -> member-name”, struct-name, member-name are taken as operands and ‘.’, ‘->’ are taken as operators. Some names of member elements in different structure variables are counted as unique operands.
- All the hash directive are ignored.
int sort (int x[ ], int n)
{ int i, j, save, im1; /This function sorts array x in ascending order / If (n< 2) return 1; for (i=2; i< =n; i++) { im1=i-1; for (j=1; j< =im1; j++) if (x[i] < x[j]) { Save = x[i]; x[i] = x[j]; x[j] = save; } } return 0; } Therefore, N = 91 n = 24 V = 417.23 bits N^ = 86.51 n2 = 3 (x:array holding integer to be sorted. This is used both as input and output) V = 11.6 L = 0.027 D = 37.03 L^ = 0.038 T = 610 seconds
def sort(X,n):
if n<2: return 1
for i in range(0,n):
im=i
for j in range(im,n):
print(i,j)
if X[i]>X[j]:
print('troca',X)
X[i],X[j]=X[j],X[i]
return 0
V=[3,7,1,3,5,7,2];sort(V,len(V));print(V);exit(1)
(True, {'loc': 12, 'lloc': 15, 'sloc': 11, 'h1': 2, 'h2': 4, 'N1': 2, 'N2': 4, 'vocab': 6, 'len': 6, 'calc_len': 10.0, 'vol': 15.51, 'diffic': 1.0, 'effort': 15.51, 'time': 0.86})
Comparing the halstead´s numbers of C and Python codes for the same function the differences are very discrepant, they deserve a review. grateful for the attention.
@eloifavero The code above is quite difficult to read. Also, I am not sure those two implementations can be compared because they are quite a lot different. If you post them with proper indentation and syntax highlighting I'll be happy to take a look.
I'm curious about that, so I'm going to take the code from the source and try touching it up myself.
int sort (int x[ ], int n)
{
int i, j, save, im1;
/*This function sorts array x in ascending order */
If (n< 2) return 1;
for (i=2; i< =n; i++)
{
im1=i-1;
for (j=1; j< =im1; j++)
if (x[i] < x[j])
{
Save = x[i];
x[i] = x[j];
x[j] = save;
}
}
return 0;
}
def sort_translated(x, n):
if n < 2:
return 1
for i in range(2, n + 1):
im1 = i - 1
for j in range(1, im1 + 1):
if x[i] < x[j]:
save = x[i]
x[i] = x[j]
x[j] = save
return 0
def sort_more_idiomatic(x, n):
if n < 2:
return 1
for i in range(2, n + 1):
for j in range(1, i):
if x[i] < x[j]:
x[i], x[j] = x[j], x[i]
return 0