 Alright, I think we're going to get started here. Hello, my name is Mike Nielsen, and I'm the Coding and Development Track Chair, and I'm here to introduce the Coding and Development's featured speaker, Anthony Farah. Anthony Farah is a core PHP contributor. His specialty, correct me if I'm wrong, is encryption and security. In his spare time, he does swift-water rescues. He's an avid white-water guy, a couple of other neat little factoids about him. He got his pilot's license before his driver's license. He's flown a military jet. He's also a volunteer firefighter. EMT has two CPR saves to his credit, so that's really awesome. In 2008, he traveled over 300,000 air miles, and apparently he totaled a car three years old, which is something he and I have in common. So, everybody give a quick hand for Anthony Farah. Thank you very much. Okay, and everyone hear me because I like to move around a lot. So, in the back, what we're going to talk to you about today is a whole lot of science. Okay, not really. Everything I'm going to talk to you about is based in science, and there's a lot of people who do research on this. But for our purposes, all we really care about is that it's close enough. Okay, so I'm going to talk about a lot of things, but consider them heuristics. They're not really, yes, your code is bad or yes, your code is good, but more of trends and being able to identify trends. So what we're really going to measure today, what we're going to talk about, is measuring the complexity. Well, there's a quote that I love. The central enemy of reliability is improved. The more complex a piece of software is, in order to be maintained, the more likely you're going to be able to have bugs in it. The harder it's going to be to add new features, and you're going to grind down into technical debt. So we want to reduce complex to higher the quality, or at least it's hard to have complex code that is also high-quality. Now, I want to make a caveat. The only definitive measure is what the S per minute. But again, we want to get an idea. We want to get a concept by some kind of scientific method. The first basic metric I'd like to talk about is called cyclomatic complexity. And it's actually really, really simple. It's a number of decision points or branch points in a routine. By routine, I mean either a class method or a function. So what else if and another if? But we also need to add one for the function itself. So this function has a cyclomatic complexity of four. Simple, straightforward, right? So some basic numbers. If you have a complexity between one and four, we say it's low complex. It's not complex, it has low complexity. Five to seven, eleven, blah, blah, blah. The point here, though, is if you look at a function and you see more than eleven if statements, that function is probably doing too much. Right? Common sense. And that's really what this metric is about, is a way of putting a number to common sense. Now note up here I've said for a single method, because we can also aggregate this concept, complexity, per method. And the reason they change is because if you look at a function and it has four-ish statements, pretty easy to tell what's going on. If you look at an entire code piece and every function has four-ish statements, it's a lot harder to realize what's going on. So it has an average complexity of 6.2, which, if you remember here, is very highly complex. I actually did this slide before, I did the next slide, so I'm not biased here, I promise. 8 is actually very good at 2.1, 7.2 is 1.8, and Laravel is 1.7. Now it's worth noting that having too low of a number here, if this number is too low, that can indicate that your code base is too wide, meaning it's too spread out and it's not doing enough decision making. So generally I like to say between 1.6 and 2.5 is a good target to be at. So Drupal 7 is a little complex for my tastes, but Drupal 8 is perfectly in the money. So the other way we can actually analyze this is if we look at the average complexity per line of code. This handles code bases that are functional or code bases that are mostly procedural a lot better than the previous method. So again, what this number actually means, and this is really easy to look at in real life, so local complexity is between .01 and .05. Well, what does that mean? Well, it means that 1% to 5% of your lines of code are decision points. Running the same analysis, .2 for WordPress, .7 here now looks really good. So it kind of gives us a picture to say, hey, we start looking to say why is Drupal 7 slightly better than Drupal 8 in this metric but significantly worse than the other metric? So we're not really sure yet whether we have a good idea or not, so we need some other metrics. So let's talk about empath complexity, which on the surface is very, very similar to cyclomatic complexity. It's the number of unique paths in a routine. So what does that mean? Well, if we take the original code base that we had and we run through it, we can execute it without going inside of any of these. That's one path. We can go into only the first one. It's a second path. We can go into the else or we can go into the first of the else. So we have four paths. Simple. Straight forward. Notice that for that example, they're the same, but in general, they won't always be the same. So let's take a slightly different example. Basically, what this function does is it adds three numbers together conditional. In PHP, you could just return 8 plus B plus C, but for purposes of the demonstration, I want to show that cyclomatic complexity and empath complexity are related, but they're slightly different. So with this function, and if I'm going too fast for anybody, I can ask a question. So for this method, it's pretty easy to see cyclomatic complexity is four. But let's count the number of paths. We have no is, the first one only, the first one and the second one, the first, second, third, the first, third, so on, so on, so on. So it turns out we have eight unique paths through the code base. So the limit on empath is two raised to the cyclomatic complexity minus one. Again, don't be overly concerned. Just realize that they're related, but they're not the same measurement. They actually measure different things. So with empath complexity, we have similar ranges, and these ranges are basically pulled from the other list. And you can find this stuff on the internet, but I'll get to some resources in a little bit. So what does this mean? What does empath really mean? Really translated, it's the minimum number of tests required to completely test a routine. So if you only have one test for a method that has a empath complexity of eight, you're missing seven test cases. So now we can use this interesting metric to really look and dive deep into some code, some interesting code. So if we think about it for a second, if one test per method, well, let's apply it to triple seven. Let's take a look at some triple seven metrics. The first one, the first function I want to analyze, is entity underscore load from triple seven. Really simple, has one if statement, and it returns. Clear what it does? Very good. Can anyone tell me what the cyclomatic complexity of this is going to be? Two. Very good. Which is load complexity. And the empath complexity, again, two. Two. Awesome. This is what you want. Look at a different function. Also from triple seven in chord. So page one, page two, page three, page four. Cyclomatic complexity of 41. There's 41 decision points in this function. Now this is why I love empath complexity. Because it takes, well, okay, very highly complex. What does that mean? 25 billion tests to completely test that one function that we just saw. I want to put this in context. So if we assume a test is one line of code, okay, it would take two terabytes worth of tests to test this one function. Pretty impressive, huh? That's 412 DVDs. Or 670,000 Drupal installations. Heck of a lot of tests. We might want to do something about that function. Thank God it's gone. But so that's not the worst one. It's the worst one in chord, but the worst one of these functions I've ever seen is actually in, well, let me rephrase that, the worst of these functions I've ever seen in an open source project is in a Drupal control module. Yeah. The date module has a function called date-repeat-or-rule-process. I'm not even going to bother putting it on here. It's, I think, somewhere around 3,000 lines of code, 2,000 lines of code. Cyclomatic complexity of 81. Can anyone guess what the impact is going to be? And it goes. And it goes. I was hoping it would fill an entire slide, but okay. So that would require 336,000 times the entire date of volume of 2009 in the world. All the hard drives in the world in 2009? 336,000 times that. Or trillion times that. I'm sorry. Now, that's kind of hard to visualize. So I've created a new unit of measurement specifically for this function. So if you take a 64 gigabyte microSD card, right, and you stack them on top of each other so you'd have a one-inch by one-inch cube, and then you take those one-inch by one-inch cubes and you stack those together and you make a one-foot by one-foot cube. And you stack those together to one yard by one yard and then one nile by one mile, you would need the volume of the Greenland Ice Cap to store just for the tests, for this one function in one module. See how we can now start realizing, wait a minute, this code is not maintainable. Yes, your code is crap. So crap basically is change risk analysis predictions. It's defined as cyclomatic complexity plus cyclomatic complexity squared times one minus coverage cube. Don't worry about the definition. Basically, all it does is it relates complexity with test coverage. Because we basically are analyzing how risky is a change to this function. A high-frap index means if you make a change, it's highly risky. Now, that can be because the function is really, really complex or because it doesn't have a lot of tests. So increasing your test coverage will lower your crap index. Likewise, decreasing your complexity will also lower your crap index. So a low-complexity method with no tests is good. A low-complexity method with good tests is awesome. It's great. And a moderate complexity method with good tests is okay. Kind of, we can colorate it, but not really great. And a moderate complex with no tests is crap. So, again, some rough numbers. Very similar to the cyclomatic complexity numbers because it's based off of it. But yeah, you want to avoid crappy code. So, now what? We've got these basic metrics, and we'll talk about some more as we go on, but how do we use these metrics? What are we going to do on a day-to-day basis? So, for those of you who don't know, this is a German flag, and the German flag is up here for a reason because there are these guys in Germany who are fantastic engineers. And they're preaching something that not a lot of people outside of Germany are preaching, which is test all the things. They're obsessed with quality, and for a good reason to... specific, actually, one quick anecdote. In terms of popular PHP quality tools, there is only one that was not made by a German. Can anyone guess what it is? Very good. PHP code sniffer. The rest were done by a bunch of Germans, one of which I'm just going to put up here and give a plug to because he's vacuuming. Sebastian Bergmann. He's done more for PHP quality, in my opinion, than any single other person in the industry, piping it. Some of the things he's done, PHP unit, which hopefully Drupal you guys are moving to, right? Yes? No? Please? Yes? Very good. And a bunch of other stuff. Some of the things, the two really, really good resources, PHPQAtools.com, KeyMaintains, and JenkinsPHP.org, which is a Jenkins profile. So, both of these leverage the tools that we're going to talk about. So the first one on this list is PHP-LOC, which stands for PHP Lines of Code. It's a really, really, really simple tool. Again, by Sebastian Bergmann. Yeah. It's a command-line tool that gives us a high-level summary of a code base. It's not going to tell us what about a code base is good or bad, but what it's really, really useful for is you have a new piece of code that you've never looked at before, and you want to know what you're getting into. Whether it's because you're sitting at work and they can't do a legacy system you need to maintain, or you're building something new and there's a module on Drupal.org that you're thinking about using, and you want to just get a really quick 30-second glimpse at and say, is this good code? Is this possibly not good code? How is it structured? So by running this tool and running this on Drupal 8 takes about 15 seconds, it prints out three pages worth of data. And I'm just going to go really quickly through. High-level gives you the number of files and directories. Simple. The number of lines of code. The cyclomatic complexity per line of code. Remember that measurement we measured earlier? So on Drupal 7, it gives us that cyclomatic complexity of .04. We can start getting in 15 seconds. We can get an insight on how complex a piece of code that we've never looked at before is. We can also look at the number of non-comment lines of code and the number of comment lines of code. So we can say, hey, wait a minute. Drupal 7 has about 20,000 lines of comments. Seems relatively good comment. So it gives us that high-level inspection. We can also go into the number of interfaces, the number of namespaces, and the number of traits if you're using .54+. The number of classes of abstract versus concrete. And the average lines of code in each class. Again, not necessarily entirely useful on its own, but information that makes comparing two projects really, really useful. Really useful for getting a high-level feel of what's going on. And then the last one is the methods and breakdown by methods, including cyclomatic complexity per method. Really straightforward, but it gives you a really high-level analysis. So this tool is used at the project level. You want to look at a project as a whole. Well, what if you want to go deep? P depend, which was made also by a German. It's like PFLOC in that it analyzes the whole project, but it's granular. By default, it spits out an XML file, which includes everything that PFLOC gives you, except broken down for functions. So you can look at every single function, what the cyclomatic complexity is for it, so it gives you the ability to drill down into not just that something exists, but also why it exists. It's a lot lower level of analysis, but the reason I have this tool up here besides long-term tracking and things like that is it gives us two really, really, really pretty and really freaking confusing graphs. Nobody gets these. I have trouble keeping track of what these mean, but they're really pretty. So the first one is basically abstraction versus instability. Make sense, right? No. The concept here is instability is basically... I'm trying to think of how to phrase this again. Instability is how much a package depends on other packages. So if we say a package is a Drupal module, a purely stable Drupal module down here is one that doesn't depend on anything else, and a purely unstable is one that depends upon a lot of things in the codebase. Then we compare that to abstraction, which means how much logic is in that codebase. Codebase is with a lot of... So basically what this graph is telling us is what we want is very abstract code to be very unstable code. I'm sorry, very stable code. And very concrete, very unstable. It's basically one inverse relationship between them. So things on the line are good, off the line may present issues. Make sense? Kind of? Not really? It's okay. I tried. The other one is a pyramid of metrics. Oh, sorry. Each one of these dots is a package. And the way it reads it is based upon the doc blocks at package head. So what it parses every single file, it looks at the doc block in the file and says this is what this package is, and then it lumps all the classes and everything from that package together. So the next thing is this pretty pyramid. Now, this seems confusing at first, but it's actually really simple. What it is is there's two sides, and also if we cut it in half, the lines of code, 6500. Cyclomatic complexity, there's a number underneath this tool. The number of methods gives us that high-level concept, that high-level analysis that you'd be able to see there. But it also allows us to divide the two. So this number right here is cyclomatic complexity per line of code. This is line of code per method. Simple. And it walks up the chart. Now, there's three things on here that aren't self-explanatory. Fan out, which describes the outward dependencies that your classes tend to have. The higher the fan out, the more your classes and your code depends upon code elsewhere in the application. And then finally, these two on the top, ANSI and AHH. ANSI tells you how many classes that you have in your code base extend from other classes. AHH is average hierarchy height. So if all your classes extend from one parent class, average hierarchy height is one. If you have very, very deep inheritance, then your average hierarchy height goes higher. It's really just a rough number to give you an idea. Does this application use a lot of inheritance or does it not? So the final tool is PHP mess detector. Command line tool, also by a germ, it finds messy parts of your code. So you set up your rules and it chips with default rule sets. And you run this tool on your code base and it tells you where the problems are. So the default rules it ships with, and you can extend these both in code and by changing what the rules are, are code size which includes systematic complexity, and path complexity. But it also includes things like the number of methods on the class, the size of each method. So you can set up rules to say, hey, you know what? I want a PHP mess detector to tell me every time a method has more than 20 lines of code. I want to tell me when I use design, when I use an eval state, because I want to flag that. So I don't want to eval my code base. It can find unused code which is actually really, really handy because you want code to be readable and unused code kind of hurts readability because wait, is that code readable, runnable or not? And finally it has some controversial things which typically I turn off just because I don't necessarily read they're controversial for a reason. But again, these are just for the full ones. We can extend them and the default values are pretty good. So the reason we want to use this tool is because we want to prevent complexity from getting into our code base. All of these metrics and all of these tools are really, really, really useful by themselves. You've seen how we can apply them and identify code, problem code, how we can compare and look at and judge code bases and get into it. But over time, and tracking these metrics over time is purely invaluable. So I wrote a script. Basically what I did is I ran phploc. I took the output and piped it into a CSV file and then the script went back 10 commits again and it moved until it ran out of commits. So basically I ran phploc every 10th commit back to all time for whatever project I ran the script on. So the first project was Drupal 8 branch. So this goes back to the first commit of the 8 branch which was somewhere back in 2010. And you can watch the number of non-comment lines of code. It dropped off here in 2011. Maybe there's a refactor or something. And kind of things kind of stayed pretty sane until roughly this time last year at which point it goes straight up to the chart. So there's a lot of development activity. The number of classes. Now this chart is a logarithmic chart because the non-logarithmic chart looked like garbage because all it was was a big spike. But the number of classes skyrocketed. In 2010 there were six classes. In 2013 there's about 2,500 classes. So now let's look at the metrics. How did cyclomatic complexity change through all of this active development? This is what you want to see. This is fantastic. You see high cyclomatic complexity in the beginning and there's some bumps in but the general trend is downward. That is awesome. And if we look at it per line we get this really big jump here. I don't know why we've tried to figure it out. I don't know. But then after that big jump the trend is downward. And you're going to get little spikes here but for the most part this is awesome. And here it's just based on all four charts together. Lines of code, then classes, complexity, complexity for method and complexity for line. So looking at them align we see the story. We see that okay there's a refactor here called a submission, but then afterwards a lot of active development, a lot of work, but it's getting less complex. That is awesome. That is absolutely awesome. But so now I have this script. 2-3-8 is fun. Analyzing some other systems. This chart is cyclomatic complexity for method on the top and per line of code on the bottom versus symphony 2 and word press. Notice anything interesting? Because I sure as heck do. Drupal is tending down. Symphony 2 is tending down. And Drupal and symphony 2 are right about neck and neck pretty much the whole time. Word press? What's word press doing? It's trending up, right? That's not good. That's not what we want. So I didn't stop here. I ran this tool against a whole lot of different methods and frameworks. In fact, 10 of them in all. And then I took all that data and I fed it into Splunk. Anyone familiar with Splunk? All right, for those of you who aren't, Splunk typically is used by like DevOps people to look at logs. But what is really, really, really great at doing is some complex analysis on raw data. So I took those CSV files from a whole bunch of projects and spit it at Splunk and asked it a question and it gives me a nice, really pretty answer. So this one is looking at cyclomatic complexity per line of code. So on the top, so blue we have cakePHP, which is actually really good. I'm completely surprised by all of these methods. If you were to ask me to predict this stuff, there's only one that I would have predicted and I'm not going to tell you that one. If you know me, you know which one I'm talking about. So cake started really complex back in 2007, 2008 and it's getting really, really, really simple. Awesome. Code igniter. Started complex, finished complex. Drupal 8. Over time now. Why is there that big dropout? I have no idea. We've tried to figure it out, we can't figure it out. But overall it's a definite downward trend, which is awesome. Joomla. And about the same as code igniter. Symphony, now there's not as much data for symphony because at Git repo they started fresh with two. But again, downward trend, which is awesome. WordPress. Zen framework too. Pretty much level. And PHPBB. Out level. So you can see most of the majority of the projects are pretty much level or slightly trending downward. Drupal is trending strongly downward, which is awesome. WordPress is trending strongly upward, which is okay. So let's look at a different metric. Let's look at, and with Splunk we can compare anything. So why don't we look at the ratio of comments to non-commented lines of code? So basically the ratio for every line of code, how many lines of code of comments do we have? And this is that graph. Again, there's a really weird dip in Drupal. If someone can explain that to me, please do. But... So cake. Pretty much everything is relatively low. You can see which one. Zen framework tends to be almost one-to-one for a long time. And now it's about 0.6 to one. PHPBB is by far the lowest. And Drupal, for a while, was climbing to ridiculous proportions. There was one point in here where it was 1.75 lines of comment to one line of code. What does that mean? We could argue all day about it. But again, we're just trying to compare it at a really, really high level. So let's look at the non-commented lines of code in general. How big are these projects? Well, by far the smallest one is Codignake, which finished up with about 37,000 lines of code today. And you can see it's generally pretty much the same. The most lines of code today is Julo. And you can see it basically is trending upwards roughly about the same amount. Drupal, we... Symphony, pretty much a solid approach. Now, again, this metric by itself is pretty much useless. I mean, comparing 30,000 lines of code to 200,000 lines of code without knowing why, without knowing what it's doing is kind of pointless. We shouldn't really focus on it. However, using all of these metrics and looking, we start to see a picture. We start to see, hey, wait a minute, wordpress is trending upward in every single one of those, every single one of the categories. What does that mean? We could start making inferences. We can compare it to Drupal and seeing how they change, how they're behaving, and what is this? Cyclomatic complexity per method. And PHPBB starts ridiculously complex by far the most complex that I track and ends up pretty much right underneath wordpress in terms of complexity. But it's a downward trend. The trend is what I care about. This is more complex. This is way more complex than my liking. But it's a downward trend, which means the team is doing a good job with it. Anyone want me to do any kind of analysis here while I have this up? I'll give you the fields I have as everything that PHPLOC has. So if there's anything you want to see over time, now's your chance to ask. Anyone want to see anything and compare all of these different frameworks? I have anonymous functions right here. So this is, by default, what it does is it looks at everything. So this trend right here is the number of anonymous functions over time average across every single project. But with one tiny change, this belt, one tiny change we can see. So wait a minute. There's one project, and this is the first time I'm running it, but there's one project that has, by orders of magnitude, more anonymous functions than anything else. Symphony. Symphony has about 400 anonymous functions today. And the second one on this list is End Framework 2. And then Drupal and a whole bunch of other stuff are basically around zero. Number of classes versus which systematic complexity by method or by line? Okay. So this is going to take a half of a second. So systematic complexity. That's non-common, systematic complexity by line. Well, no, no, that's fine. And then you want by number of classes. If you ever worked with Splunk, it's incredibly powerful. What does it look like, obviously? So basically I took the number of classes and I divided it by the systematic complexity per line. And what this means, I honestly don't know. You have to sit down and think about what are you looking at. But it gives you the ability to ask these kind of questions. And that's the point I want to get across is that tools like this and doing the historical data doesn't give you answers. It gives you the ability to ask questions. So with that said, when I started doing this analysis, I really expected Drupal 7 especially to be towards the bottom. And 7 kind of was towards the bottom what the community was doing. 8 is towards the front of the community by a very long margin in terms of everything. The only thing that comes close to touching it is something. So you guys are doing a kick-ass job. Keep it up. But also adopt these principles. Look at what core is doing. Look at the direction core is going. Because it's awesome. So one more thing to keep in mind here. The only way to get good code, I don't know how to do it. So even though we want to achieve these, keep in mind that at the end of the day, working code is what's important. Profitable code is what's important. We can sit down and argue over the theory as much as we want. If it doesn't work and it doesn't pay the bills, at the end of the day it's bad code. Something to keep in perspective. Any questions? Yes. All right, so the question is based on systematic complexity, if you have a whole bunch of these statements doing things like checking parameters. If parameter one is in return or if not is something, basically where you're ensuring that your inputs are valid or some other state is valid before doing your logic. The answer basically would be to recommend a book called Refactoring of Legacy Code. Basically instead of having all those if statements at the top of your code, instead what I would recommend is to refactor that out. Put that into a separate function. So now you can have a function called IsInputValid or AreInputValid or whatever that code is trying to do. So now that 15 if statements block of input validation is one function. If not input is valid, return. That's how I would handle it. And there's different patterns depending on what you're doing depending on but there's ways and extract method which basically says you take this block of code and you pull it out into a separate function is I think the one that you're looking for there. And in general with cyclomatic complexity that's going to be the better one to use. Honestly, it's refactoring of legacy code. It's got a picture of a brass clock on the front of it. Michael Feathers, that's the one. Michael Feathers. I have about two questions. One. Sorry. Is there a... What's a good point to stop? Like you were saying it will show you metrics about if you're depending on other people's code. So where's the good balance in that because obviously you don't want to rewrite something that somebody's already done. The easy way for me to say this is a bad answer which is there is no right way. You can talk to 20 different developers. You can talk to 100 developers here and 200 different answers. Really what it comes down to in my experience is personal experience and judging the requirements of what you're doing. I'm a big fan. I have a phrase I use a lot which is judging between good and good enough. Yes, good is we want all these things. We want 100% test coverage. We want low cyclomatic complexity. We want all this stuff. But at the end of the day because the other side of the coin is we have to... We're not doing this just for fun most times. We're doing it because we have a reason to do it. Either because we need the tool because we're getting paid to do it. So you need to make a judgment called certain points in time to say, you know what, it would be better if, but we're going to take that technical debt and go forward with this. And my other question was do you have tools for JavaScript because increasingly all of us are using JavaScript? Yeah, we do. So there is a tool for JavaScript. I'm completely blank because I ran these numbers on Node.js. And the only reason I didn't point out what they were for Node.js is they're completely non-interesting. It's just flat level... I didn't find it in trading which is the only reason I didn't put it up here. I do not remember. Follow me on Twitter and I will check a login of my system that I ran all this stuff on. And I could not find anything for Ruby on Rails that was worth the damn that computed these metrics. They may exist. They very well may exist. I could not find them. In about an hour's searching. Thanks. If you want to ask a question there's a mic in the center of the room, so... I was just checking to make sure that your slides are going to be up there because I think I might have missed some stuff. Yeah, I moved pretty quick. I will post them to my blog in the slide share. Hopefully if I can get a decent internet connection within the next half hour. Thank you. Can you go back over abstraction versus stability real quick? I totally missed that. The one slide that I'm not comfortable with. Well, I shouldn't say the one. One of. Instability is the ratio of how much your code or a packages code depends upon other packages. And abstraction is how much logic is provided by your code as opposed to how much you're dispatching to other. So if you have a lot of dependencies you don't want to have a lot of logic. If you have a lot of logic you don't want to have a lot of dependencies. General rule of thumb. Again, the entire what my entire theme behind here is this class here is not bad. It's, hey, this might be something we want to look at or highlight. In addition to the slides, is there any chance that the Splunk scripts and the scripts used for HVMD are going to get out? Well, okay. I will post that that much, I promise. I do not have any of the data with me other than Splunk. And Splunk is a commercial product. What I will do is after I get home next week some point I'm planning to write a blog post about all this analysis. And what I will do is put up a zip file containing every CSV that I analyzed as well as the script they used to generate a little bit. Awesome, thank you. Any other questions? Okay, one more. So when we see, you know, let's just call it Network Presses, negative trend lines. Are we basically saying it's going to be harder and harder for programmers to contribute because their complexity is going up? Is there a possibility this code base they're heading the wrong direction and it's just going to implore us a point? So there's a few ways to look at it. The political way of looking at it would be to say they're trending upwards meaning they're tending to get more complex but you can still work on it. It's just every incremental change is going to get a little bit harder over time for core development. If you're using it from the outside that number probably doesn't really matter other than the velocity of code. Looking at it as a potential contributor I want to contribute to a project that's getting simpler, that's not getting harder because the harder it gets, the harder it's going to be to get into it later on down the road. The harder it's going to be for me to make a meaningful change. The harder it's going to be to produce quality software to prevent bugs from getting in. We can sit here and talk ideals all day long but the bottom line is does the software work? Yes. Is it complex? Okay. It depends upon what you want to do what you want to get out of it with how these metrics are going to relate to you. Thank you. Anything else? One more. That could be a plenty of time. I'm just wondering is there any correlation between the metrics that you've shown with runtime performance metrics? Okay. Now we're starting to get to that's actually a very, very interesting question because all of these metrics in complexity tend towards lower performance software which basically says we want to trade off between maintainability which is what we're tracking here we're tracking maintainability but performance is a very tangential to maintainability so a lot of times we give up performance so that way we can have better maintainability. The usual reason that I give for that is unless you're Facebook scale or Wikipedia scale your servers are more expensive or cheaper than your developers and the answer is this at the given cost of a server let's say a server is expensive and costs you $1,000 a month that's what? $12,000 a year? 10 servers for one developer's time. It's cheaper for me to reduce the number of developers than to reduce the number of servers 90% of the time. That 10% of the time where it's not cheaper that's where you go into in that one little area. So typically what I find is in production code bases you'll have 90% of it that's really maintainable, really pretty and follows all these metrics and then you'll have a little corner 10% or less where all your performance is spent that's what all the time complexity is in the code and that's optimized which is going to throw these numbers off but you're doing it for a reason and for a definitive gain. That's basically how I answer that. Yes, one last? Yeah, just curious about the sort of format and the output of these analysis tools just potentially like how you use all that. What's the CSV? Or it can output to standard out. P to PEND outputs an XML file and PHPMD outputs a XML rule set file. Now these are all standard files so things like Jenkins they have native plugins in fact the PHP QA tools sorry the PHP Jenkins script that was on the slide before parses all the stuff in by default. Last one I promise. I assume that your numbers for Drupal 8 all include symphony? No. So basically the script that I had excluded anything with the directory prefix of vendor so all of the symphony stuff all of the I think a couple others had some really weird dependencies all of that was excluded from these code based analysis. Thank you very much and I do have a YouTube channel for that.