nerder-index
v0.2.8
Published
Calculate a difficulty for a given functions.
Downloads
6
Maintainers
Readme
Nerder Index (N)
Contents
Dependencies
- Node >= 6.0.0
- NPM >= 3.0.0
Usage
Install the "Nerder Index" generator:
npm i nerder-index
and import it in your application:
const { get } = require("nerder-index");
API
get(fn: string)
Get the "Nerder Index" as a float number representing the difficulty of the given function.
Parameters:
- fn
string
Returns:
- nerder index
float
analyse(fn: string)
Get a detailed object containing more information about the difficulty.
Parameters:
- fn
string
Returns:
- Object
object
- nerder index
nerderIndex: float
- parameter count
parameterCount: int
- cyclomatic complexity:
complexity: int
- operator index
operatorIndex: int
- nerder index
TypeScript support
This module supports typescript and is packed with its own type definition file. The analyse
function returns the interface Report
.
How
Following test setup was used to extract difficulty for a given functions (example):
const { get } = require("nerder-index");
const fn = function test() {
return 1;
};
const result = get(fn.toString());
Info: The function to test has to be named, otherwise the resulting string is no valid JS on root level, needed for esprima to parse the code to an AST. result
is an object containing multiple values calculated by escomplex.
Values relevant to calculate a difficulty level for one specific function are:
- Cyclomatic complexity (C): Defined by Thomas J. McCabe in 1976, this is a count of the number of cycles in the program flow control graph. Effectively the number of distinct paths through a block of code. Lower is better.
- Number of parameters (Pn): Analysed statically from the function signature, so no accounting is made for functions that rely on the arguments object. Lower is better.
- Operator index (o): The number of total operators divided by the number of distinct operators. Lower is better.
Cyclomatic complexity
The "cyclomaticy" is C{1,...,n}
. A function without control constructs still has a complexity of C = 1
. The following examples will demonstrate:
// C = 1
function fn1() {
return 1;
}
// C = 1
function fn2(p) {
let a = 13;
a = (2 * p) / a - 5 + 42;
return 42;
}
// C = 2
function fn3(a) {
if (a) {
return a;
}
return 1;
}
Number of parameters
Number of parameters P{n}
can be every natural number, but it should be restricted to max value. The parameters are a multiplier.
Operator index
The operator index is defined by o = oT / oD
. The following functions defines 8 (function
and return
keyword are excluded) distinct operators (let
, =
, ()
, .
, +
, -
, /
, *
) and a total of 10.
function fn2(p) {
let a = 4;
a = (2 * p) / a - 5 + 42;
return 42;
}
The operator index for this function is o = 10 / 8 => 1.25
.
Nerder Index (N)
N = o * Pn * C
Examples
Here is an example setup to calculate the "Nerder Index" for 4 functions:
const { get } = require("nerder-index");
const fns = [
function fn1() {
return 1;
},
function fn2(c) {
let a = 42;
a = (2 * a) / a - 5 + c;
return 42;
},
function fn3(c, d) {
let a = 23;
a = (2 * a) / a - d + 42;
return a + c;
},
function fn4(a, b, c) {
if (a === 0) {
return b;
}
return c;
}
];
fns.forEach(fn => {
const result = get(fn.toString());
console.log("N =", result);
});
These methods produce the following results:
- Nfn1 = 0
- Nfn2 = 1.1
- Nfn3 = 2.4
- Nfn4 = 7.5
Result
The "Nerder Index" is a float where 0
is an invalid index (no parameters defined, so no difficulty). Which index is "easy" or "hard" needs to be tested. All of this is just a first test to calculate the complexity of a method.