Skip to main content

A python implementation of the ABC Software metric

Project description

Python ABC

Python 3.9.5

A python implementation of the ABC Software metric:

The ABC software metric was introduced by Jerry Fitzpatrick in 1997 to overcome the drawbacks of the LOC. The metric defines an ABC score as a triplet of values that represent the size of a set of source code statements. An ABC score is calculated by counting the number of assignments (A), number of branches (B), and number of conditionals (C) in a program. ABC score can be applied to individual methods, functions, classes, modules or files within a program.

Fitzpatrick's original paper is, at the time of writing, only available via the Wayback Machine, so a copy of it is included in this repo as well.

The paper lists the counting rules for C, C++ and Java, so here are the rules this repo uses for Python:

  • Add one to the assignment count when:
    • Occurrence of an assignment operator (excluding default parameter assignments).
  • Add one to the branch count when:
    • Occurrence of a function call/await or a class method call/await.
    • Occurrence of a class instantiation.
  • Add one to the condition count when:
    • Occurrence of a conditional operator.
    • Occurrence of the following keywords: else, elif, except.
    • Occurrence of an assert statement without a conditional operator.

Usage

Install the requirements in your virtual environment of choice, then you can see the command line arguments that are available:

$ python -m python_abc --help
usage: python_abc [-h] [--debug DEBUG] [--sort SORT] [--verbose VERBOSE] path

A python implementation of the ABC Software metric: https://en.wikipedia.org/wiki/ABC_Software_Metric

positional arguments:
  path               path to directory or file

optional arguments:
  -h, --help         show this help message and exit
  --debug DEBUG      display AST output for each element in the parsed tree
  --sort SORT        sort files from highest to lowest magnitude
  --verbose VERBOSE  display marked-up file

Given file.py that contains the following text:

if a and b:
    print(a)
else:
    print(b)

a = sum(i for i in range(1000) if i % 3 == 0 and i % 5 == 0)

def f(n):
    def inner(n):
        return n ** 2
    if n == 0:
        return 1
    elif n == 1:
        return n
    elif n < 5:
        return (n - 1) ** 2
    return n * pow(inner(n), f(n - 1), n - 3)

You can get the barebones output as follows:

$ python -m python_abc /path/to/file.py
/path/to/file.py         <1, 7, 10> (12.2)

Passing the verbose flag will give more detail:

$ python -m python_abc file.py --verbose=true
cc    | if a and b:
b     |     print(a)
c     | else:
b     |     print(b)
      |
abbcc | a = sum(i for i in range(1000) if i % 3 == 0 and i % 5 == 0)
      |
      | def f(n):
      |     def inner(n):
      |         return n ** 2
c     |     if n == 0:
      |         return 1
cc    |     elif n == 1:
      |         return n
cc    |     elif n < 5:
      |         return (n - 1) ** 2
bbb   |     return n * pow(inner(n), f(n - 1), n - 3)
file.py          <1, 7, 10> (12.2)

If you want to inspect the abstract syntax tree for the file you can pass the debug flag, which will print out each node from the tree and the vector that resulted from it.

The path argument can also be a path to a directory, in which case all Python files in that directory (and its sub-directories) will be scanned, at which point it can be useful to pass the sort flag to rank the files by ABC magnitude:

$ python -m python_abc . --sort
./calculate.py                              <18, 56, 23> (63.2)
./vector.py                                 <12, 23, 11> (28.2)
./main.py                                    <10, 23, 8> (26.3)
./tests/test_vector.py                       <4, 19, 10> (21.8)
./tests/__init__.py                           <4, 12, 1> (12.7)
./tests/test_radon_test_cases.py                <1, 2, 1> (2.4)
./tests/test_calculate_condition.py             <1, 2, 1> (2.4)
./tests/test_calculate_empty.py                 <1, 2, 1> (2.4)
./tests/test_calculate_assignment.py            <1, 2, 1> (2.4)
./tests/test_calculate_branch.py                <1, 2, 1> (2.4)

Finally you can pass a cores argument to tell the library how many CPU cores to use. By default the library will try to use all the cores that are available on your machine.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python-abc-0.2.0.tar.gz (7.4 kB view details)

Uploaded Source

File details

Details for the file python-abc-0.2.0.tar.gz.

File metadata

  • Download URL: python-abc-0.2.0.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.5

File hashes

Hashes for python-abc-0.2.0.tar.gz
Algorithm Hash digest
SHA256 90017d09fbac7bde4b64b2c7e1b5d22da9055b64b821d1a2b4dc805b450b251a
MD5 ac059f6103feb9045b0b95ef797a554a
BLAKE2b-256 17e35973ccea7302dfe994331e2824bfc8cc4e4c8ba7f0b9d1f16bcda5ef26a3

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page