SlideShare a Scribd company logo
Magic behind the
                            numbers

                       Software metrics in
                            practice



Sebastian Marek, Software Architect
@proofek

•  a Pole living in Sheffield
•  over 10 years PHP
   experience
•  co-author of 2 PHP books
•  big fan of process
   automation
•  TDD and CI
•  occasionally contributes
   to open source projects
•  wants to be a knight
Agenda

What I will be talking about
•  Code metrics
•  Design metrics

What I will not be talking about
•  Project metrics



                https://joind.in/4758
Most effective code quality measure
What is a metric?




  “It is the mapping of a particular
characteristic of a measured entity to
          a numerical value”

      Source: Object-Oriented Metrics in Practice
Software design




 “Good design quality metrics are not
necessarily indicative of good designs.
 Likewise, bad design quality metrics
 are not necessarily indicative of bad
               designs”

                        Source: Jdepend Docs
System maintenance

•    Obsolete documentation
•    Convoluted design
•    Intensive patch mechanism (hacking)
•    Large size
•    Severe duplication
•    Obsolete parts (dead code)
•    Long build times
•    Loss of original developers
Simple metrics

•    CLOC – comment lines of code
•    ELOC – executable lines of code
•    LOC – lines of code
•    NCLOC – non comment lines of code
•    NOP – number of packages
•    NOC – number of classes
•    NOM – number of methods
Cyclomatic Complexity (CYCLO)




   Cyclomatic complexity measures the
amount of decision logic in a single software
                 module.
Cyclomatic Complexity Number (CCN)

Conditional statements:
•  ?
•  case
•  elseif
•  for
•  foreach
•  if
•  while
CCN2

Conditional statements:
•  ?                         •    &&
•  case                      •    ||
•  elseif                    •    or
•  for                       •    and
•  foreach                   •    xor
•  if
•  while
Cyclomatic complexity

Conditional statements:
•  ?                      •    &&
•  case                   •    ||
•  elseif                 •    or
•  for                    •    and
•  foreach                •    xor
•  if                     •    catch
•  while
Cyclomatic complexity - example
class Foo {
    public function example() {
        if ($a == $b) {
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {         4
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {         4
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {               5
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {         4
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {               5
            for ($n = 0; $n < $h; $n++) {   6
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {
        if ($a == $b) {
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }                               6
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
phploc
phploc 1.6.1 by Sebastian Bergmann.	
	
Directories:                                      6	
Files:                                           20	
	
Lines of Code (LOC):                           5478	
  Cyclomatic Complexity / Lines of Code:       0.13	
Comment Lines of Code (CLOC):                  2143	
Non-Comment Lines of Code (NCLOC):             3335	
	
Namespaces:                                       0	
Interfaces:                                       1	
Classes:                                         18	
  Abstract:                                       2 (11.11%)	
  Concrete:                                      16 (88.89%)	
  Average Class Length (NCLOC):                 191	
Methods:                                        151	
  Scope:	
    Non-Static:                                 143 (94.70%)	
    Static:                                       8 (5.30%)	
  Visibility:	
    Public:                                     116 (76.82%)	
    Non-Public:                                  35 (23.18%)	
  Average Method Length (NCLOC):                 22	
  Cyclomatic Complexity / Number of Methods:   3.72	
	
Anonymous Functions:                              0	
Functions:                                        2	
	
Constants:                                        4	
  Global constants:                               3	
  Class constants:                                1
Cyclomatic complexity - thresholds




                Low     Avg      High    V.High
Complexity      1-4     5-7      8-10    > 11
JAVA



Metric                Low               Avg                High               V.High
CYCLO/Line of code    0.16              0.20               0.24               0.36
LOC/Method            7                 10                 13                 19.5
NOM/Class             4                 7                  10                 15

                     Source: Object-Oriented Metrics in Practice (based on 45 Java projects)
C++



Metric                Low               Avg                High              V.High
CYCLO/Line of code    0.20              0.25               0.30              0.45
LOC/Method            5                 10                 16                24
NOM/Class             4                 9                  15                22.5

                     Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)
WMC and AMW

Weighted Method Count – total complexity of a class




Average Method Weight – average complexity of a method
JAVA



Metric       Low               Avg                High               V.High
WMC          5                 14                 31                 47
AMW          1.1               2.0                3.1                4.7
LOC/Class    28                70                 130                195

            Source: Object-Oriented Metrics in Practice (based on 45 Java projects)
C++



Metric       Low               Avg                High              V.High
WMC          4                 23                 72                108
AMW          1.0               2.5                4.8               7.0
LOC/Class    20                90                 240               360

            Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)
Coverage report
C.R.A.P
C.R.A.P



Change
Risk
Analysis and
  Change Risk Analysis and Predictions




Predictions
C.R.A.P formula




Code coverage = 100%




 Code coverage = 0%
NPATH – acyclic execution path complexity




NPATH is an objective measure of software
 complexity related to the ease with which
 software can be comprehensively tested
                                    Edgar H. Sibley
NPATH – acyclic execution path complexity




expressions         Number of && and || operators in expression	
	
if                  NP(<if-range>)+NP(<expr>)+1	
if-else             NP(<if-range>)+NP(<else-range>)+NP(<expr>)	
while               NP(<while-range>)+NP(<expr>)+1	
for                 NP(<for-range>)+NP(<expr1>)+NP(<expr2>)+	
                    NP(<expr3>)+1	
	
    break           1	
    continue        1	
    return          1	
    sequential      1	
    function call   1
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();                   1
            } else {
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();                   1
            } else {
                fiddle();                   2
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {               2
                fiddle();                   1
            } else {
                fiddle();                   2
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                        2
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                        2
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {                     2
            if ($a1 == $b1) {
                fiddle();
            } else {                            2
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {                     2
            if ($a1 == $b1) {
                fiddle();
            } else {                            2
                fiddle();
            }
        }                                   3

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                        3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                            3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();                   1
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                            3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {   1
                fiddle();                   1
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                            3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {   1
                fiddle();                   1
            }                               2
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                        3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();                   2
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                        3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();                   2
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                            3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {         3
            for ($n = 0; $n < $h; $n++) {
                fiddle();                       2
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                            3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {         3
            for ($n = 0; $n < $h; $n++) {
                fiddle();                       2
            }
        }                                   4

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                        3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();                   4
            }
        }

        return true;
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {                            3
                fiddle();
            }
        }

        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();                       4
            }
        }

        return true;                        1
    }
}
NPATH – example
class Foo {
    public function example() {

        if ($a == $b) {
            if ($a1 == $b1) {
                fiddle();
            } else {
                fiddle();
            }
        }
                                            12
        if ($e == $f && $g == $z) {
            for ($n = 0; $n < $h; $n++) {
                fiddle();
            }
        }

        return true;
    }
}
PHP Depend
PHP_Depend 0.10.6 by Manuel Pichler	
	
Parsing source files:	
....................                                      20	
	
Executing CyclomaticComplexity-Analyzer:	
.............                                            261	
	
Executing ClassLevel-Analyzer:	
............                                             247	
	
Executing CodeRank-Analyzer:	
.                                                         28	
	
Executing Coupling-Analyzer:	
.............                                            267	
	
Executing Hierarchy-Analyzer:	
............                                             246	
	
Executing Inheritance-Analyzer:	
.                                                         30	
	
Executing NPathComplexity-Analyzer:	
..............                                           283	
	
Executing NodeCount-Analyzer:	
........                                                 174	
	
Executing NodeLoc-Analyzer:	
..........                                               205	
	
Generating pdepend log files, this may take a moment.	
	
Time: 00:05; Memory: 25.50Mb
PHP Mess Detector
Overview pyramid
Size and complexity – direct metrics
Size and complexity – computed proportions
System coupling – direct metrics
System coupling – computed proportions
System inheritance
Complete Overview Pyramid
PHP

Metric         Low          Avg       High
CYCLO/LOC      0.16         0.20      0.24
LOC/NOM        7            10        13
NOM/NOC        4            7         10
NOC/NOP        6            17        26
CALLS/NOM      2.01         2.62      3.2
FANOUT/CALLS   0.56         0.62      0.68
ANDC           0.25         0.41      0.57
AHH            0.09         0.21      0.32

                                   http://pdepend.org/
Metrics visualisation with Sonar
Metrics visualisation with Sonar
Violations reporting
SIG Maintainability Model




--   Very bad
-    Bad
0    Average
+    Good
++   Very good
Technical Debt
Summary

“We believe that software metrics, in general, are just tools. No
  single metric can tell the whole story; it’s just one more data
                              point. “

“Metrics are meant to be used by developers, not the other way
  around – the metric should work for you, you should not have
                     to work for the metric. “

“Metrics should never be an end unto themselves. Metrics are
     meant to help you think, not to do the thinking for you.”

                                                  Alberto Savoia
Resources

•    PHP Depend - http://pdepend.org/
•    PHP Mess Detector - http://phpmd.org/
•    Manuel’s home page - http://manuel-pichler.de/
•    PHPUnit - http://www.phpunit.de/
•    phploc - http://sebastianbergmann.github.com/phploc/
•    Sonar - http://www.sonarsource.org/
•    “Object-Oriented Metrics in Practice” by Michele Lanza
     and Radu Marinescu (ISBN 978-3540244295)
Questions




Questions?

https://joind.in/4758

More Related Content

What's hot

Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
Nikita Popov
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядом
Andrey Akinshin
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Fedor Lavrentyev
 
Php in the graph (Gremlin 3)
Php in the graph (Gremlin 3)Php in the graph (Gremlin 3)
Php in the graph (Gremlin 3)
Damien Seguy
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
Paulo Morgado
 
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Abu Saleh
 
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Codemotion
 
Python Puzzlers
Python PuzzlersPython Puzzlers
Python Puzzlers
Tendayi Mawushe
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
tdc-globalcode
 
C# 7
C# 7C# 7
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
Sanketkumar Biswas
 
Voce Tem Orgulho Do Seu Codigo
Voce Tem Orgulho Do Seu CodigoVoce Tem Orgulho Do Seu Codigo
Voce Tem Orgulho Do Seu Codigo
Victor Hugo Germano
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
Paulo Morgado
 
12. stl örnekler
12.  stl örnekler12.  stl örnekler
12. stl örnekler
karmuhtam
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
osfameron
 
SQL Devlopment for 10 ppt
SQL Devlopment for 10 pptSQL Devlopment for 10 ppt
SQL Devlopment for 10 ppt
Tanay Kishore Mishra
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
Paulo Morgado
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
tdc-globalcode
 
More on Classes and Objects
More on Classes and ObjectsMore on Classes and Objects
More on Classes and Objects
Payel Guria
 
Fee managment system
Fee managment systemFee managment system
Fee managment system
fairy9912
 

What's hot (20)

Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядом
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
 
Php in the graph (Gremlin 3)
Php in the graph (Gremlin 3)Php in the graph (Gremlin 3)
Php in the graph (Gremlin 3)
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
 
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
 
Python Puzzlers
Python PuzzlersPython Puzzlers
Python Puzzlers
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
C# 7
C# 7C# 7
C# 7
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
Voce Tem Orgulho Do Seu Codigo
Voce Tem Orgulho Do Seu CodigoVoce Tem Orgulho Do Seu Codigo
Voce Tem Orgulho Do Seu Codigo
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
12. stl örnekler
12.  stl örnekler12.  stl örnekler
12. stl örnekler
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
SQL Devlopment for 10 ppt
SQL Devlopment for 10 pptSQL Devlopment for 10 ppt
SQL Devlopment for 10 ppt
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
 
More on Classes and Objects
More on Classes and ObjectsMore on Classes and Objects
More on Classes and Objects
 
Fee managment system
Fee managment systemFee managment system
Fee managment system
 

Viewers also liked

SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
triagens
 
One Click Deployment with Jenkins
One Click Deployment with JenkinsOne Click Deployment with Jenkins
One Click Deployment with Jenkins
Mayflower GmbH
 
Scrum, Kanban oder vielleicht beides?
Scrum, Kanban oder vielleicht beides?Scrum, Kanban oder vielleicht beides?
Scrum, Kanban oder vielleicht beides?
Dominik Jungowski
 
The Original Hypertext Preprocessor
The Original Hypertext PreprocessorThe Original Hypertext Preprocessor
The Original Hypertext Preprocessor
Drew McLellan
 
Localisation typo3
Localisation typo3Localisation typo3
Localisation typo3
Daniel
 
Verlernte Agilität - Schleichende Fehler in agilen Prozessen
Verlernte Agilität - Schleichende Fehler in agilen ProzessenVerlernte Agilität - Schleichende Fehler in agilen Prozessen
Verlernte Agilität - Schleichende Fehler in agilen Prozessen
Sebastian Bauer
 
Open a window, see the clouds - php|tek 2011
Open a window, see the clouds - php|tek 2011Open a window, see the clouds - php|tek 2011
Open a window, see the clouds - php|tek 2011
Rafael Dohms
 

Viewers also liked (7)

SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
 
One Click Deployment with Jenkins
One Click Deployment with JenkinsOne Click Deployment with Jenkins
One Click Deployment with Jenkins
 
Scrum, Kanban oder vielleicht beides?
Scrum, Kanban oder vielleicht beides?Scrum, Kanban oder vielleicht beides?
Scrum, Kanban oder vielleicht beides?
 
The Original Hypertext Preprocessor
The Original Hypertext PreprocessorThe Original Hypertext Preprocessor
The Original Hypertext Preprocessor
 
Localisation typo3
Localisation typo3Localisation typo3
Localisation typo3
 
Verlernte Agilität - Schleichende Fehler in agilen Prozessen
Verlernte Agilität - Schleichende Fehler in agilen ProzessenVerlernte Agilität - Schleichende Fehler in agilen Prozessen
Verlernte Agilität - Schleichende Fehler in agilen Prozessen
 
Open a window, see the clouds - php|tek 2011
Open a window, see the clouds - php|tek 2011Open a window, see the clouds - php|tek 2011
Open a window, see the clouds - php|tek 2011
 

Similar to PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Development by the numbers
Development by the numbersDevelopment by the numbers
Development by the numbers
Anthony Ferrara
 
Lec 42.43 - virtual.functions
Lec 42.43 - virtual.functionsLec 42.43 - virtual.functions
Lec 42.43 - virtual.functions
Princess Sam
 
Functional php
Functional phpFunctional php
Functional php
Jean Carlo Machado
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
Seri Moth
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
Joshua Thijssen
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
Nate Abele
 
Clojure Linters
Clojure LintersClojure Linters
Clojure Linters
Kent Ohashi
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
Stoyan Stefanov
 
Document Classification In PHP
Document Classification In PHPDocument Classification In PHP
Document Classification In PHP
Ian Barber
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
Andrew Shitov
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
Nikita Popov
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
Lin Yo-An
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
Nikita Popov
 
PHP 5.4
PHP 5.4PHP 5.4
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
✅ William Pinaud
 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
Lucas Witold Adamus
 
Hiphop php
Hiphop phpHiphop php
Hiphop php
rajesh_bakade65
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
Development By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo EditionDevelopment By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo Edition
Anthony Ferrara
 

Similar to PHP Benelux 2012: Magic behind the numbers. Software metrics in practice (20)

Development by the numbers
Development by the numbersDevelopment by the numbers
Development by the numbers
 
Lec 42.43 - virtual.functions
Lec 42.43 - virtual.functionsLec 42.43 - virtual.functions
Lec 42.43 - virtual.functions
 
Functional php
Functional phpFunctional php
Functional php
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Clojure Linters
Clojure LintersClojure Linters
Clojure Linters
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Document Classification In PHP
Document Classification In PHPDocument Classification In PHP
Document Classification In PHP
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
 
Hiphop php
Hiphop phpHiphop php
Hiphop php
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Development By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo EditionDevelopment By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo Edition
 

More from Sebastian Marek

The Journey Towards Continuous Integration
The Journey Towards Continuous IntegrationThe Journey Towards Continuous Integration
The Journey Towards Continuous Integration
Sebastian Marek
 
CodeClub - Teaching the young generation programming
CodeClub - Teaching the young generation programmingCodeClub - Teaching the young generation programming
CodeClub - Teaching the young generation programming
Sebastian Marek
 
Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPl
Sebastian Marek
 
Managing and Monitoring Application Performance
Managing and Monitoring Application PerformanceManaging and Monitoring Application Performance
Managing and Monitoring Application Performance
Sebastian Marek
 
Ten Commandments Of A Software Engineer
Ten Commandments Of A Software EngineerTen Commandments Of A Software Engineer
Ten Commandments Of A Software Engineer
Sebastian Marek
 
Continuous Inspection: Fight back the 7 deadly sins of a developer!
Continuous Inspection: Fight back the 7 deadly sins of a developer!Continuous Inspection: Fight back the 7 deadly sins of a developer!
Continuous Inspection: Fight back the 7 deadly sins of a developer!
Sebastian Marek
 
Test your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceTest your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practice
Sebastian Marek
 
Effective code reviews
Effective code reviewsEffective code reviews
Effective code reviews
Sebastian Marek
 
Effective code reviews
Effective code reviewsEffective code reviews
Effective code reviews
Sebastian Marek
 
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practicePHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
Sebastian Marek
 
Ten Commandments Of A Software Engineer
Ten Commandments Of A Software EngineerTen Commandments Of A Software Engineer
Ten Commandments Of A Software Engineer
Sebastian Marek
 
Magic behind the numbers - software metrics in practice
Magic behind the numbers - software metrics in practiceMagic behind the numbers - software metrics in practice
Magic behind the numbers - software metrics in practice
Sebastian Marek
 
Back to basics - PHPUnit
Back to basics - PHPUnitBack to basics - PHPUnit
Back to basics - PHPUnit
Sebastian Marek
 
Back to basics - PHP_Codesniffer
Back to basics - PHP_CodesnifferBack to basics - PHP_Codesniffer
Back to basics - PHP_Codesniffer
Sebastian Marek
 
Sonar - the ring to rule them all
Sonar - the ring to rule them allSonar - the ring to rule them all
Sonar - the ring to rule them all
Sebastian Marek
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking
Sebastian Marek
 

More from Sebastian Marek (16)

The Journey Towards Continuous Integration
The Journey Towards Continuous IntegrationThe Journey Towards Continuous Integration
The Journey Towards Continuous Integration
 
CodeClub - Teaching the young generation programming
CodeClub - Teaching the young generation programmingCodeClub - Teaching the young generation programming
CodeClub - Teaching the young generation programming
 
Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPl
 
Managing and Monitoring Application Performance
Managing and Monitoring Application PerformanceManaging and Monitoring Application Performance
Managing and Monitoring Application Performance
 
Ten Commandments Of A Software Engineer
Ten Commandments Of A Software EngineerTen Commandments Of A Software Engineer
Ten Commandments Of A Software Engineer
 
Continuous Inspection: Fight back the 7 deadly sins of a developer!
Continuous Inspection: Fight back the 7 deadly sins of a developer!Continuous Inspection: Fight back the 7 deadly sins of a developer!
Continuous Inspection: Fight back the 7 deadly sins of a developer!
 
Test your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceTest your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practice
 
Effective code reviews
Effective code reviewsEffective code reviews
Effective code reviews
 
Effective code reviews
Effective code reviewsEffective code reviews
Effective code reviews
 
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practicePHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
 
Ten Commandments Of A Software Engineer
Ten Commandments Of A Software EngineerTen Commandments Of A Software Engineer
Ten Commandments Of A Software Engineer
 
Magic behind the numbers - software metrics in practice
Magic behind the numbers - software metrics in practiceMagic behind the numbers - software metrics in practice
Magic behind the numbers - software metrics in practice
 
Back to basics - PHPUnit
Back to basics - PHPUnitBack to basics - PHPUnit
Back to basics - PHPUnit
 
Back to basics - PHP_Codesniffer
Back to basics - PHP_CodesnifferBack to basics - PHP_Codesniffer
Back to basics - PHP_Codesniffer
 
Sonar - the ring to rule them all
Sonar - the ring to rule them allSonar - the ring to rule them all
Sonar - the ring to rule them all
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking
 

Recently uploaded

Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
AstuteBusiness
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
Postman
 
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
saastr
 
Dandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity serverDandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity server
Antonios Katsarakis
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
DianaGray10
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Precisely
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
Edge AI and Vision Alliance
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
Alex Pruden
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
Ivo Velitchkov
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
Fwdays
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Neo4j
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 

Recently uploaded (20)

Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
 
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
9 CEO's who hit $100m ARR Share Their Top Growth Tactics Nathan Latka, Founde...
 
Dandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity serverDandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity server
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 

PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

  • 1. Magic behind the numbers Software metrics in practice Sebastian Marek, Software Architect
  • 2. @proofek •  a Pole living in Sheffield •  over 10 years PHP experience •  co-author of 2 PHP books •  big fan of process automation •  TDD and CI •  occasionally contributes to open source projects •  wants to be a knight
  • 3. Agenda What I will be talking about •  Code metrics •  Design metrics What I will not be talking about •  Project metrics https://joind.in/4758
  • 4. Most effective code quality measure
  • 5.
  • 6. What is a metric? “It is the mapping of a particular characteristic of a measured entity to a numerical value” Source: Object-Oriented Metrics in Practice
  • 7. Software design “Good design quality metrics are not necessarily indicative of good designs. Likewise, bad design quality metrics are not necessarily indicative of bad designs” Source: Jdepend Docs
  • 8. System maintenance •  Obsolete documentation •  Convoluted design •  Intensive patch mechanism (hacking) •  Large size •  Severe duplication •  Obsolete parts (dead code) •  Long build times •  Loss of original developers
  • 9. Simple metrics •  CLOC – comment lines of code •  ELOC – executable lines of code •  LOC – lines of code •  NCLOC – non comment lines of code •  NOP – number of packages •  NOC – number of classes •  NOM – number of methods
  • 10. Cyclomatic Complexity (CYCLO) Cyclomatic complexity measures the amount of decision logic in a single software module.
  • 11. Cyclomatic Complexity Number (CCN) Conditional statements: •  ? •  case •  elseif •  for •  foreach •  if •  while
  • 12. CCN2 Conditional statements: •  ? •  && •  case •  || •  elseif •  or •  for •  and •  foreach •  xor •  if •  while
  • 13. Cyclomatic complexity Conditional statements: •  ? •  && •  case •  || •  elseif •  or •  for •  and •  foreach •  xor •  if •  catch •  while
  • 14. Cyclomatic complexity - example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 15. Cyclomatic complexity - example class Foo { public function example() { 1 if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 16. Cyclomatic complexity - example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 17. Cyclomatic complexity - example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 18. Cyclomatic complexity - example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 19. Cyclomatic complexity - example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { 5 for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 20. Cyclomatic complexity - example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { 5 for ($n = 0; $n < $h; $n++) { 6 fiddle(); } } else { fiddle(); } } }
  • 21. Cyclomatic complexity - example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } 6 } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 22. phploc phploc 1.6.1 by Sebastian Bergmann. Directories: 6 Files: 20 Lines of Code (LOC): 5478 Cyclomatic Complexity / Lines of Code: 0.13 Comment Lines of Code (CLOC): 2143 Non-Comment Lines of Code (NCLOC): 3335 Namespaces: 0 Interfaces: 1 Classes: 18 Abstract: 2 (11.11%) Concrete: 16 (88.89%) Average Class Length (NCLOC): 191 Methods: 151 Scope: Non-Static: 143 (94.70%) Static: 8 (5.30%) Visibility: Public: 116 (76.82%) Non-Public: 35 (23.18%) Average Method Length (NCLOC): 22 Cyclomatic Complexity / Number of Methods: 3.72 Anonymous Functions: 0 Functions: 2 Constants: 4 Global constants: 3 Class constants: 1
  • 23. Cyclomatic complexity - thresholds Low Avg High V.High Complexity 1-4 5-7 8-10 > 11
  • 24. JAVA Metric Low Avg High V.High CYCLO/Line of code 0.16 0.20 0.24 0.36 LOC/Method 7 10 13 19.5 NOM/Class 4 7 10 15 Source: Object-Oriented Metrics in Practice (based on 45 Java projects)
  • 25. C++ Metric Low Avg High V.High CYCLO/Line of code 0.20 0.25 0.30 0.45 LOC/Method 5 10 16 24 NOM/Class 4 9 15 22.5 Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)
  • 26. WMC and AMW Weighted Method Count – total complexity of a class Average Method Weight – average complexity of a method
  • 27. JAVA Metric Low Avg High V.High WMC 5 14 31 47 AMW 1.1 2.0 3.1 4.7 LOC/Class 28 70 130 195 Source: Object-Oriented Metrics in Practice (based on 45 Java projects)
  • 28. C++ Metric Low Avg High V.High WMC 4 23 72 108 AMW 1.0 2.5 4.8 7.0 LOC/Class 20 90 240 360 Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)
  • 30.
  • 32. C.R.A.P Change Risk Analysis and Change Risk Analysis and Predictions Predictions
  • 33. C.R.A.P formula Code coverage = 100% Code coverage = 0%
  • 34.
  • 35. NPATH – acyclic execution path complexity NPATH is an objective measure of software complexity related to the ease with which software can be comprehensively tested Edgar H. Sibley
  • 36. NPATH – acyclic execution path complexity expressions Number of && and || operators in expression if NP(<if-range>)+NP(<expr>)+1 if-else NP(<if-range>)+NP(<else-range>)+NP(<expr>) while NP(<while-range>)+NP(<expr>)+1 for NP(<for-range>)+NP(<expr1>)+NP(<expr2>)+ NP(<expr3>)+1 break 1 continue 1 return 1 sequential 1 function call 1
  • 37. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 38. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); 1 } else { fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 39. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); 1 } else { fiddle(); 2 } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 40. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { 2 fiddle(); 1 } else { fiddle(); 2 } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 41. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 2 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 42. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 2 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 43. NPATH – example class Foo { public function example() { if ($a == $b) { 2 if ($a1 == $b1) { fiddle(); } else { 2 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 44. NPATH – example class Foo { public function example() { if ($a == $b) { 2 if ($a1 == $b1) { fiddle(); } else { 2 fiddle(); } } 3 if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 45. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 46. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); 1 } } return true; } }
  • 47. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { 1 fiddle(); 1 } } return true; } }
  • 48. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { 1 fiddle(); 1 } 2 } return true; } }
  • 49. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); 2 } } return true; } }
  • 50. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); 2 } } return true; } }
  • 51. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { 3 for ($n = 0; $n < $h; $n++) { fiddle(); 2 } } return true; } }
  • 52. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { 3 for ($n = 0; $n < $h; $n++) { fiddle(); 2 } } 4 return true; } }
  • 53. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); 4 } } return true; } }
  • 54. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { 3 fiddle(); } } if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); 4 } } return true; 1 } }
  • 55. NPATH – example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { fiddle(); } } 12 if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }
  • 56. PHP Depend PHP_Depend 0.10.6 by Manuel Pichler Parsing source files: .................... 20 Executing CyclomaticComplexity-Analyzer: ............. 261 Executing ClassLevel-Analyzer: ............ 247 Executing CodeRank-Analyzer: . 28 Executing Coupling-Analyzer: ............. 267 Executing Hierarchy-Analyzer: ............ 246 Executing Inheritance-Analyzer: . 30 Executing NPathComplexity-Analyzer: .............. 283 Executing NodeCount-Analyzer: ........ 174 Executing NodeLoc-Analyzer: .......... 205 Generating pdepend log files, this may take a moment. Time: 00:05; Memory: 25.50Mb
  • 59. Size and complexity – direct metrics
  • 60. Size and complexity – computed proportions
  • 61. System coupling – direct metrics
  • 62. System coupling – computed proportions
  • 65. PHP Metric Low Avg High CYCLO/LOC 0.16 0.20 0.24 LOC/NOM 7 10 13 NOM/NOC 4 7 10 NOC/NOP 6 17 26 CALLS/NOM 2.01 2.62 3.2 FANOUT/CALLS 0.56 0.62 0.68 ANDC 0.25 0.41 0.57 AHH 0.09 0.21 0.32 http://pdepend.org/
  • 69. SIG Maintainability Model -- Very bad - Bad 0 Average + Good ++ Very good
  • 71. Summary “We believe that software metrics, in general, are just tools. No single metric can tell the whole story; it’s just one more data point. “ “Metrics are meant to be used by developers, not the other way around – the metric should work for you, you should not have to work for the metric. “ “Metrics should never be an end unto themselves. Metrics are meant to help you think, not to do the thinking for you.” Alberto Savoia
  • 72. Resources •  PHP Depend - http://pdepend.org/ •  PHP Mess Detector - http://phpmd.org/ •  Manuel’s home page - http://manuel-pichler.de/ •  PHPUnit - http://www.phpunit.de/ •  phploc - http://sebastianbergmann.github.com/phploc/ •  Sonar - http://www.sonarsource.org/ •  “Object-Oriented Metrics in Practice” by Michele Lanza and Radu Marinescu (ISBN 978-3540244295)