项目作者: MartinHelmut

项目描述 :
Calculate a difficulty for a given functions.
高级语言: JavaScript
项目地址: git://github.com/MartinHelmut/nerder-index.git
创建时间: 2017-06-08T12:51:40Z
项目社区:https://github.com/MartinHelmut/nerder-index

开源协议:MIT License

下载


Nerder Index (N)

⚠️ Not maintained anymore!

npm
Build Status
Commitizen friendly
Standard Version
styled with prettier

Contents

Dependencies

  • Node >= 10
  • NPM >= 6

Usage

Install the “Nerder Index” generator:

```shell script
npm i nerder-index

  1. and import it in your application:
  2. ```javascript
  3. 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

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):

  1. const { get } = require("nerder-index");
  2. const fn = function test() {
  3. return 1;
  4. };
  5. 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:

  1. // C = 1
  2. function fn1() {
  3. return 1;
  4. }
  5. // C = 1
  6. function fn2(p) {
  7. let a = 13;
  8. a = (2 * p) / a - 5 + 42;
  9. return 42;
  10. }
  11. // C = 2
  12. function fn3(a) {
  13. if (a) {
  14. return a;
  15. }
  16. return 1;
  17. }

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.

  1. function fn2(p) {
  2. let a = 4;
  3. a = (2 * p) / a - 5 + 42;
  4. return 42;
  5. }

The operator index for this function is o = 10 / 8 => 1.25.

Nerder Index (N)

  1. N = o * Pn * C

Examples

Here is an example setup to calculate the “Nerder Index” for 4 functions:

  1. const { get } = require("nerder-index");
  2. const fns = [
  3. function fn1() {
  4. return 1;
  5. },
  6. function fn2(c) {
  7. let a = 42;
  8. a = (2 * a) / a - 5 + c;
  9. return 42;
  10. },
  11. function fn3(c, d) {
  12. let a = 23;
  13. a = (2 * a) / a - d + 42;
  14. return a + c;
  15. },
  16. function fn4(a, b, c) {
  17. if (a === 0) {
  18. return b;
  19. }
  20. return c;
  21. },
  22. ];
  23. fns.forEach((fn) => {
  24. const result = get(fn.toString());
  25. console.log("N =", result);
  26. });

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.