 Hello everyone. We're going to have Mirca Zetia talk to us, actually start an interactive session about managing technical debt. So questions are welcome, I believe is supposed to be interactive. So by the way, this is the first time the first interactive session ever done at any EuroPython, so hey. As my colleague mentioned, this is the very first interactive session that is on EuroPython. I feel a little bit like a guinea pig, but that will pass. We should have a discussion here. That's what I understand. So I also have some slides and we'll see how this works. A few things about who I am. I am technical manager at Spice. We are a small company located in Cluj, Romania, and we're doing mostly Python development work. For those of you who wonder what a technical manager does, well, we are the people who pretend we can still write code. So that's mostly about it. The talk itself is about managing technical debt. When I started thinking about the subject, I realized that is pretty much like politics or religion. Everyone has an opinion, so that includes myself. So the more opinions, the better. And since I mentioned that this religion, we're going to start with a very beautiful impressionist picture. Our colleagues from classic paintings named this something around developers asking forgiveness for technical debt at the beginning of a sprint. That pretty much describes it, to be honest. Okay. In summary, what we're going to try to do, we're going to try to define the purpose of the presentation, set the stage. We're going to see some short history about the subject itself. We're going to see where exactly the technical debt occurs at which levels, what are the consequences. Let's talk about interest and also about the type of projects where you actually care about technical debt. I'm not saying that you shouldn't, but there are projects where you care more or you care less. All right. First of all, since it's an interactive session, we have one hour. I would like to somehow limit the time for discussions per subject at about one or two minutes, depending on the interest. And by the way, seeing the lineup, what's in parallel with the stock, there's really many sinners around here. Okay. What is technical debt, first of all? It was first defined by word conningum and it was defined in the early 90s as a metaphor, more or less, in terms of describing the extra development work when we choose easy short-term solutions against longer-term or the proper way to implement stuff. It is a metaphor because it's released directly to the finance industry, to loans, and we're going to go and see what exactly is the debt and the interest that I mentioned earlier. There are multiple ways. People have multiple opinions about what technical debt means and what it should mean, what it is. One of those people is Bob Martin. I'm sure you guys all heard about Robert Martin. Technically, he says that messy code is not really technical debt, that's just a mess. Now, towards this purpose, he says that when you make a conscious decision about technical debt, what should happen is that you should try and write even cleaner code, have even cleaner interfaces, and so on. Does this work in real life? Why? The answer was that the people usually do it in Russia and don't think about stuff. That's partially true, I think, because when you make a decision that you're going to have technical debt and you're going to have to live with it, it's because you have constraints, and usually those are time constraints. The time constraint that's required to write cleaner interfaces and so on, it sometimes works, sometimes it doesn't. Next to that, we have Martin Fowler. This is where we have the discussion if we're talking about conscious and unconscious technical debt. His opinion is that the question if a mess is technical debt by itself is the wrong question. The idea is that you will have technical debt in the end. It's more about defining the conscious approach and the unconscious approach, and he splits this into what he calls the technical debt quadrant, and I put it here, this is not mine, so it's copyrighted there. We have the reckless technical debt and the prudent technical debt. On the horizontal line, deliberate and inadvertent. Okay. The reckless one for the deliberate one. We don't have time for design. Of course, what I would like to mention is that these guys are advocates for design patterns, refactoring, writing clean code. So design is there. The prudent approach for the deliberate part is that we must ship and we have to deal with consequences. Now, how many of you here were in this situation? Okay. I raised my hand as well. All right. For the unconscious part, we have the first part of the mess, what is layering. People do not really know what they are doing. I saw autocomplete from Stack Overflow. That might cause technical debt in the end. The other part is actually very, very interesting. Now we know how we should have done it. Robert Martin in the talk that he has, he says something like this, if you have a complex system that you haven't built before, you will know how to build it once you've built it. And it's not going to be the way you built it. So that is the other part. It's prudent. In the end, you do your best. Now, next part is why the quadrant, why did they approach it in this way and what can we learn from these three statements? Yeah. And why calling a technical debt? Let's start with the last one. Why do you think they called it technical debt? Yeah, you pay interest in that. Correct. But why not say anti-patterns? It might look like the right time when you're doing it. Okay? Sometimes you can technically borrow strategically, because if you need to ship today and you, if you don't ship today, for example, maybe you will not have funding to do anything anymore. So you can strategically borrow and then it's not an undie pardon, it's actually, it could be a good thing to do. But at the end of the day, what's the difference between technical debt and an anti-pattern baseline? You can try to avoid technical debt as well. Not always with anti-patterns also. Well, it's easier to discuss with business people. Because if you go to a business owner, someone who is a development manager or who doesn't really have his fingers into the development world, if you're going to him and say, okay, we have anti-patterns here or we have any other kind of terminology or whatever, it doesn't mean anything to them. It means, okay, it works. Why? Why change it? Why fix it? Technical debt on the other hand, as you guys already said, directly relates to the finance part. So when you have a technical debt, you have two parts. You have the principal and you have the interest. This, they do understand. This we all understand because we make a conscious decision to take a loan, right? And we know we have to pay off the principal, we have to pay off the interest. And all the three approaches that I presented are ways that people unconsciously basically look towards advocating what they stand for. And yeah, this is the same with us. Okay. In my opinion, technical debt is a status quo. It's there. It's either there or it isn't and it's no real philosophy around it. It's not something that you might or you might not have. I used to describe this as more as a Schrodinger's cat problem. Before you acknowledge it, you both have it and you don't. But it's a matter of acknowledging technical debt. So once you acknowledge it's there, it actually exists. So once you acknowledge it, don't live in denial. Now, questions or comments? It depends how you, the question is if there is any code that does not have technical debt. It depends how you look at it. It depends how you look at it, to be honest. Does it cause you problems later on? Did you make a conscious decision that you're going to have it? Will you be able to cross that bridge once you're there? How well is your code tested? How clean are your interfaces? You cannot have something specific and I would like to come back a little bit at the purpose of the presentation. I don't have all the answers. I don't think I have all the questions. That's why we're here and was trying to have a discussion around it. But being the first session at Eurofighting that's interactive, we have a lack of microphones also in the room. So Rado is doing his best. Okay. At what levels does technical debt occur? I already put that up there. The first level that I see, it's at code level. And this is what you mentioned. How does technical debt at code level manifest itself? Yes? Missing tests, careless coding. Car less development where you have to ship a picture as soon as possible and you miss a lot of best practices. So spaghetti card. Okay. Very good. A framework that you depend on that becomes deprecated. The question is a little bit larger with the framework because every framework will solve parts of your problems. So when you choose a framework, it's also a type of technical debt. It will take you 80% of the way. It does depend how much you have to spend for the rest of the 20%. So that's another approach. But let's say that you have your code consists of something like 300 lines of code of undocumented functions. So you have functions or methods that are like 300 lines of code. What is the technical debt that you see there? Why? Why is that technical debt? Why the documentation is missing? Why is the technical debt? Correct. It will save you time. So that's a debt. Something else? Readability. Mostly. Okay. Something else? That's true. Okay. How would you test an application that has, you know, functions or methods that are 300 lines of code long? You don't want tests in such code, right? Okay. That's true. Okay. So people who write 300 lines of functions do not have tests. Okay. We have the principle defined here from our technical debt. Once, as our colleague said, we're going to have to go back and figure out every time that we have to change the code, we have to figure out what we wrote in there because it's undocumented. For this part, we have the interest that also our colleague here mentioned in regards that when you have to outsource to someone else, they will not understand the code. But how about ourselves in, I don't know, three, six months' time? Every time that you have to revisit that function, that is no longer technical debt that is already interest. Every time that you have to onboard someone into an undocumented code, that's no longer technical debt that is interest that you pay. Every time that you have to, that you change the functionality within the test, within the function, the test will have to be updated. That is principle at one point and the interest from that point on. So this is one example of technical debt that can occur at code level. What's the impact? How would you see the impact at code level? Is it high? Is it low? High? I think it's the simplest thing to change. If you have broken API and a lot of code depends on it, yeah, that's true. But that is one step further about the broken APIs. We're talking about technical debt at the architectural level. If you have broken APIs and you cannot maintain your code when you change it, that's an architectural decision and you have technical debt at an architectural level. Now, at this point, I see two subdivisions. Application level, what you mentioned, infrastructure level. I worked on a project and at a specific moment I made a decision about the data model and some colleagues here in the room already know it and had to live with the pain. They're booing. Okay. That was the wrong decision. That was a decision that I had to take at an architectural level and we paid a lot of principle, we paid a lot of interest, people working on that application still paid the interest. Yes, Andrei? That's a bad decision. Would I do it again? Probably not. Right now I'm working on an application with a similar problem where I have the feeling that it might go the same way. I don't know how to fix it. It's still data model related. So, okay. What's the impact at the architecture level compared to the code level? If you mess up the architecture, what do you pay? You can't scale. Maybe you can. Maybe you can't. It depends. What kind of scaling? How can you scale? You cannot scale horizontally if your architecture is broken but can you scale vertically? I worked on an application where the only option was to scale vertically because we did a lot of simulations, like tens of thousands of simulations, electronic circuit simulations and we have this big, we had one big object that all the threads share the same big object and it was mutually exclusive. Now, don't ask why that was not possible to have the distributed. It was another decision. Okay. But going back a little bit, at the infrastructure level, how can you have technical data? Okay. Manual setup at the infrastructure? Correct. That's one thing. What if your application depends on local storage, stuff that's on your actual application instance, when you have to scale up? Yes. And you have to share the same file system or you have to have a distributed storage and so on. It's the same with databases. Okay. The next level is at the specification level. This is what I think what I think. Why is it important to, or why do I think that's, why do I think, why is it important to have the specification level sorted out or the specs sorted out? What kind of technical data results from specifications? Yeah. It really does prevent you to finding the best solution. It has automatically impact on the architecture level. On what do you decide that you do and how do you do it? So once you have a set of specifications, make sure you clarify them. Because if you don't know what you're doing properly, the results can bubble up. Okay. We talked a little bit about interest. We touched the subject before. So at all levels that we discussed, we have to pay the interest. We saw that at code level, the amount of interest that we have to pay is relatively low. As we go up to architecture and specifications, we're going to pay more and more interest. Every bad decision that we make at the architecture level will have a snowball effect. Now, one problem that we have while we manage the technical debt is that project manager, product owners, business owners will want to know, how can you measure technical debt? How can you measure the interest? Why is this so large? How can we measure the interest? Because when we have a finance loan, we have the principle and we have the interest. We know exactly the amount of money that we have to put back. Can we do this in software? I would suggest that you would notice that it gets slower and slower to ship features. That's the worst thing. As time goes on, a year later, two years later, it's slower and slower to implement new features. You cannot predict. You cannot say from the start when you say, okay, I acknowledge that I have technical debt. You cannot say what exactly will be the interest of this debt. But as time goes by, it is easier and easier for people to see, okay, I have to fix something. It takes a lot of time. When I fix it, the application will break probably in 10 other places. Usually technical debt makes your system both rigid and fragile. When you have this, it's not open to change and everything that you deliver, be it new features or bug fixes, take longer and longer. That's one way to measure it. The important thing is that every time that you have this, you probably should discuss with the people who want it. Because you're going to have questions. Why is this simple fix take so long? Why does it take so long to have this simple fix ship? Why does it take so long to have this fixed issue and have it deployed on a production environment? Sorry, infrastructure is not ready or you have to do manual stuff. Just a question. Isn't that like too late? I mean, if you've already gotten to the point where features take so long to implement, aren't we just now realizing that it's technical debt that's from two years ago? It's a matter of acknowledging it. If it takes two years for us to realize that this is technical debt, then we did something wrong at some point. Usually technical, you can notice technical debt a lot earlier than that. But probably it was not communicated properly in the timeline. It really takes you two years to figure out that it was a bad decision or when that's changed during the last two years. That is correct. The requirements changed during the last two years. Cool. You can have more of this. Okay. One question. Who's responsible for technical debt? Everyone? Okay. When? Okay. As soon as it's acknowledged. What does it mean that something is everyone's responsibility in a team? Nobody will do it. Exactly. Okay. However, you're correct. Technical debt is everyone's responsibility. And when you encounter it, the least that you can do is communicate it. The least that we can do is communicate it. The least we can do is start discussing around it. Okay. Now, some things that I think that would have some impact on preventing. Search. If you're building something and you don't know how to build it, search for it. If you didn't find the proper solution, ask for help. I encountered the lack of asking for help in numbers occasions and it does lead to technical debt. It has nothing to do with pride or ego because in a team, we're all trying to achieve the same thing. Pocket. What? POC. That's proof of concept. If you don't know how to do it, create a proof of concept. Okay. And that's the line that I put previously. Diligence. Do the bare minimum that will allow you to scale at the infrastructure level. Make sure that you have clean interfaces, your communication interfaces are correct. Be aware of how you're going to scale, how will you have to scale if it's going to have to be horizontal or vertical. It really does depend on your application profile. At the specification level. The very first thing is communication. If you do not have communication, you will not be able to fix technical debt ever. Communicate. Make sure that you communicate properly. Be aware of what, of how you can and you have to communicate with non-technical people. The second line is, well, when we work on projects, when we start a project, usually we have a few steps. That's POC, POV and MVP. Do you guys know the difference between these three things? POV. Proof of value. Proof of value. Well, think about the fact that you're building an application. You own an application. You want to build one. But the market that you're entering is not exactly mature. There is no reference to what you are doing. You want to be sure that before you start building it and releasing it, you can prove yourself. Now, this is done in a number of ways. You can, from simple mock-ups, clickable mock-ups, that will demonstrate the value for stakeholders or for investors. To having an actual application that works and then you can do something like life testing that you interact with your user. You analyze and decide if you're moving forward or not. It's very important that you know the proof of concept, proof of value and the MVP. Do not let yourselves pulled in into a discussion, something like this is a proof of concept that ends up in production. Who saw this? I've done it. Okay. And yeah. Minimum viable product. Yes. Exactly. And do not make assumptions. And this is the famous last words or what could possibly go wrong. Now, what to do when you actually have technical debt. The very first step is to identify it. At least in my opinion. Next, know the exact problem. Communicate it and make sure you translate this to cost. Every time you want to fix something, it's cost. It costs money. Right? Make sure of the cost, not only from the money perspective, but also from the impact of the change that you're doing. If you don't have clean interfaces, if the code that you wrote is used in numbers applications, make sure that you keep your interfaces. Okay. And you can sustain them. Okay. Again, communication. And from the communication part, what results or should result, it would be a plan to pay out the debt. And this is a discussion. Sometimes when you build something and it's wrong, you also have a lot of code that's built on top of it. So it's a decision that you have to see if you have to pay the principal part, the actual bad implementation, or also the interest. And which comes first? Do you have to fix the code that relies on a bad implementation or you have to fix the bad implementation first? How would you approach it? Fix the code first. Why? It's a dependency. Correct. When you change the core part, it's going to break everything. You will have to fix everything else. So you can be smart about it, fix the interfaces, and keep the bad part for later on. Right? Okay. Yeah. Now, collaboration. Yeah. As we discussed already, it's everyone's responsibility for all the team. It's our responsibility to fix it. Collaborate. But when I'm discussing about it, all of us as responsible for the code and for the technical debt and for fixing it, I'm not only discussing about the technical team. It has to be a collaboration with product and so on. We're all the team. We're all the team. You have to have timelines. You have to have a plan and say, okay, this is how we're going to fix it. This is how paying off the technical debt and the interest fits within our timelines, our deadlines, and so on. And this is actually the last part of the presentation. Did you guys ever hear something like, I don't care about technical debt? Literally? Like this? Okay. Did you guys hear something like, this is a problem we acknowledge we're going to fix it later? Okay. Sometimes. What's the context when you hear this? Sorry? True. Business guys usually. But the thing that I saw was that there is a difference between companies and business guys. Companies that live out of delivering software are more interested or should be more interested in paying off technical debt. This is not necessarily true for companies for which software is a helper to their business. It helps develop things. For them, for the second type of companies, having manual tweaks for two, three, five, six, ten releases, having someone actually doing something that can be automated, for instance, it's acceptable. Pushing it to fix it might not be the right solution. It's a business decision in the end. However, if what you do is actually software delivery, and if you live out of software, that's your core business, then technical debt is something that you're certainly interested in and should be interested in more than anything else. Too much people are dependent upon their implementation or their infrastructure, or less of an opportunity, but the application, the IPI, things like that. How can you mitigate the technical debt? The question was what about the usage of open source software within applications where you have the technical debt? How can you mitigate what you get, because you get it for free? First of all, know what you're using, and try to know the library, the application or the open source project that you are using. Know its limitations, know its boundaries. This is something that you do at the beginning of a project, if you can. If you do not do this part of analysis, if you don't take time, it's very likely that at some point you will end up with a lot of technical debt. One thing that I think you can mitigate is once you know what the technical debt is within that project, is try to have an abstraction layer and communicate with your own interfaces for the stuff that you need, if that is possible. That will be one solution. If you guys see other solutions. One thing I had to do was actually go in and fix bugs in open source projects we were using, because that open source project, since it's the core of my product now, in a way, it's also my code. When I'm using it, it's part of my technical debt, so I have to fix it. Correct. Once you fix it, create a pull request, push it mainstream. Don't keep it for yourself. It might or might not get integrated depending on how active the project is. Anything else? Any other questions? Just one second. And for freelancer, our contractors, how they should deal with technical debt when a client doesn't want to pay more for fixing bugs that might be dangerous for him, for his project? How do you think we should handle that when we are freelancers? You have to have a very clean way of explaining the technical debt to your customer. You have to be able to have an argument. Why does this take as long as it takes? Why do you have to fix it? He has to see the fact that not fixing this will cost him this much. This much immediately and this much in the long run. Usually it's very hard if you're a freelance developer to make this argument at the very beginning of a project. First thing that you have to do is earn trust. And even though some people say that, okay, I'm outsourcing your project, I trust you by default, that is rarely the case. Trust is something that you earn and not get by default. Once the client gets to trust you and sees the result, the results of your work, it's going to be easier and easier for you to discuss these kind of issues with him. So it's merely a communication problem and a trust issue. Sir? How do I get a dollar measure of my technical debt? You translate it in time. In time spent. And for this, you have to have historical data. So you actually say we should measure the cost of fixing bugs and so forth? Yes, because you have to log the time somewhere, right? And you have to see, okay, this is a simple fix. Why did it take so long to have it done? Why did it take so long to have it shipped? This translates to cost in terms of dollars immediately. Our search paper here and there talking about how they perhaps tried to measure technical debt. And I'm really interested, how come that we as a developer community and freelancers and a lot of us are living out of this, don't have like some tool that we could just run on a code base and we could get things like, hey, there is some technical debt in that file, that file and that file. I mean, you can already do that, but there are some other metrics and you have to be smart about it. How would you implement such a tool? Yeah. So, good question. Yeah, exactly that. The thing is really you can have indications for technical debt, but there's nothing that really tells you that there's no automatism that allows you to say there's technical debt in there. Because especially given the sentence of the translate to cost, right? There's no direct translation from something you find somehow in code to the cost that takes to fix it. The cost may actually be zero in some cases because you can sometimes say, okay, this is not done the right way. So, it might cost us something to fix it, but not fixing it is actually okay, right? Because we're not seeing anything in the future that might force us into fixing it. Yeah. This is an example that is very good, for instance, in the banking industry. Some of the banking industry actually has mainframes that still run on COBOL. No one's going to fix that code. They're going to maintain it. They're going to build interfaces around it, and they have people who maintain it. It costs too much to have it fixed, for instance. Because sometimes you get in a situation when actually paying interest is the best option because fixing is more expensive. Yeah. Yeah, it was just a comment that sometimes you have situations when paying interest is the best business decision for you because fixing it is too expensive and maybe the project is ending soon and you won't be changing this code. You just pay the interest until the end. It's fine. It's cheaper. Yeah. And if you have technical depth that's isolated in the module, you have your interfaces well defined. It does the job. Yeah. I just want to add to the question about why don't we have a tool that can just tell you there's a technical depth of this time of or this money. There actually are tools that can tell you that if you look, for example, at SonarCube, you can specify a cost of different code violations and it will calculate it in dollars or time. It basically goes through your code, finds all the violations that you specify you want to look into and just sums it up. It's actually a pretty good tool, a pretty good tool. If, for example, you have some legacy application and you are building a new feature, it's so huge you simply cannot eliminate the technical depth from the whole application. You just know that this one new feature you will be working on it all the time. You want to eliminate as much technical depth from that code you are building right now. It can actually tell you what's the difference from the rest of the application. There's a lot of stuff you can specify, but there are tools to do that. One thing that is in regards to tools, they are going to measure your code quality. That's the first thing, that's the first step. You can automate and see, okay, I have these lines of code, I have undocumented code, I know this, I have so much responsibilities here, I have this, this and that. How do you measure technical depth when it occurs at an architectural level or at a specification level? So for basic stuff, yes, you can use tools. It might or might not translate to cost. On the other hand, who's going to fix the technical depth? Within a team, we are all developing on different levels. It takes more or less time depending on who implements it, depending on the experience of the person who implements it. It's not something that is out of the box, you have it out of the box and everyone does it the same way. The plan to pay out the depth, you didn't exactly detail how do we pay technical depth to remove it, so refactoring or rewriting an application from scratch. How can we measure when we should do one or the other at which point? Actually, I did what I mentioned there, but I didn't explain it was all about communication and timelines and deadlines. The decision, if you're going to pay the technical depth and the interest incrementally is a business decision. It's not a technical decision. Unless your code is completely unmaintainable and you're not able to write anything in that code, then the correct decision is to rewrite it. Even then, you're going to have situations when the decision is going to be we're not going to rewrite it, we're going to rewrite it incrementally. It's not something that you can say as a rule when you're doing this and when you're doing that, when you decide to rewrite it, when you decide to fix it incrementally. Think about this, a software piece usually is maintained, developed for five years, actually actively developed, and after five years, you get into maintenance mode. So that's technically the time frame for a software piece, depending on the industry that you work in. You cannot just rewrite a piece of code that is one year old. I mean, it's not necessarily the best decision unless you messed up at the specification level and the specifications were completely wrong. But then you have the proof of value that should have validated this in terms of business. I have a question. Is anyone here a fan of the Boy Scout rule? I mean, that's one of the things I like to do when I get to a piece of ugly code. I need to work on it. I also fix whatever's ugly. I mean, personally, I like to do touches you go refactoring. I think if you get to the point where you need to go back and refactor something after a long time, it's probably so costly that you won't do it. So maybe try to do a bit of refactoring every time you develop. Is anyone else a fan of that? On the Boy Scout rule, I think it's important that you separate the code cleanup from the actual functional changes. That's all. But other than that, I mean, every time you see crap, pick it up, throw it away. At first, I was just skeptic about this rule, and I didn't believe that. But for example, our entire test suite for functional testing in web browser, at first, it was very messy and nobody wanted to touch that. But we started, this was our first internal project when we started using this rule. And after about half a year later, it was in much better design, it was slowly re-implemented. And every time we changed something, we tried to additionally fix a little the tests. There were other parts of our system which were bad designed. And the rule worked also. So I can recommend it. And at first, don't be afraid of it. This will work in time. But it requires much more time than we can imagine at first, just to sit and rewrite it. It will take much longer. Yeah, true. That's one way to put it. So it's about approaching legacy application. The application? You cannot get rid of that. It's about writing clean code and make sure that you don't have, that you don't trigger old bugs. Well, my question is, how do you enter a new project? And this might also, excuse me, this might also be a solution for dealing with legacy applications. When you ramp up on a project that's already being developed, one of the best ways to ramp up is to add unit tests, or add testing. When you have a legacy application, this also might be a good solution to see where your problems are. Because there are, I see two parts in what you describe. One is writing your code that is clean and nice and neat. And the other part is actually making sure that you do not have bugs, regressions, and so on. So you don't break anything that's already there. In order to be able to develop with a certain degree of certainty, you have to have at least the basic flows of an application tested. Be it unit tests, be it integration tests, be it whatever, if it's a web application, I don't know UI, Selenium tests. You have to have a certain degree of testing that will validate that what you build is the good solution. At least it doesn't break anything else. But this is one approach that I would take. Work on the tests, add more tests, set up a continuous integration system, for instance, for that, if it's not already there. I think it's really important too that you have good code review. That within a team, you agree upon certain standards, and yeah, people look at your code, give feedback, things like that. Absolutely. Good code reviews are very important. Now, there are two types of code reviews. Don't try to code review something that can be automated. Don't try to have, I don't know, PEP, stuff pilot and so on within code reviews. Use an automated tool for that. The problem with code reviews is that, well, you know, you have 30 lines of code. Whoever reviews it will say, will find probably 10 or 15 issues. You have a pull request for 500 lines of code. The comment will be, looks good to me. So make sure that this is also enforced. Don't have large pull requests. Do it incrementally. Split things up in such a way that will allow you to have smaller pull requests. It's not always possible. When you submitted 500 lines of code, it says, it looks good to me. Okay. Review it again, please. I would like to make sure that this is actually okay. Because when you look at the code, you do a code review on the code base. Also, I think it's important within the code review process to follow the requirements that led to that code change. Make sure that it also fits the business value or the part where the description, the requirement itself. And this brings up another discussion when you have requirements. And probably if you're working agile, you will have user stories. Make sure that you have, always have the three parts of a user story. As someone, I want to do something because that will allow you to have, at least to start the discussion around the best solution for the problem. I wanted to stress out also in the team and communication part that sometimes or maybe too often we overlook the infrastructure level technical depth. And code people always tend to think that they have to deal with this type of database because it's there instead of just maybe trying to discuss with the ops guys and tell them maybe Postgres would fit better on my pattern and would allow me to avoid this kind of technical depth. Exactly. Be the ops guys. So very often teams are split between the development team and operations team. There are two pains here. One is the operation team who has to deploy your code and the development team who has to deal with the constraints that come from the operations team. If you don't have the communication between these teams, if you have split teams, it's a very hard path. On the other hand, you as developers, I as a developer should live with the pain of deploying what I wrote, right? Everyone should live with that pain, not only the ops guys. And on the other hand, possibly also the ops guys should live with some constraints of the application that we build. That's the only way to go. So be the ops guys. Try to be part of that ops team. See what they have to deal with. Maybe it will allow you to better see why you have some constraints and some limitations within the project or within the teams. But indeed, PotsQuest is the better solution compared to MySQL at first. Also how to avoid technical depth by using techniques like per programming with your team? Or like you said, reading small requests in your room, how do you, what is your take? Per programming versus small request? Yeah, I mean, what are the techniques to avoid technical depth? It depends on how your organization is set up. If you can do per programming, do extreme programming, that's okay. Okay, yeah. So it depends on the context. It's not necessarily something that you enforce. Sorry? Yes, I think we still have a couple of minutes. If I have, sorry. Pair people up who have different level of skills. That will be one thing that I would do. Having an extra pair of eyes is always useful, but in this way, you also grow your team. I think it makes sense to pair up a more junior programmer with a more senior developer, and it also might make sense to have the more junior person typing, so the senior cannot step over the junior. I'm just going to type this up real quick, and the junior doesn't get what's being made. Absolutely, and one thing that was suggested to me in a team that I worked before was actually have junior people review senior people's code, for instance, but that's different from per programming. Both people involved in per programming should follow the business rules. You have to make sure of that. Besides that, if you have automation for everything that's code-based related, you should end up with the best solution from that construction. So you mentioned the Boy Scout rule, and I had some great success, I think, with that, because I ended up basically with my first really big hobby Python project. I ended up with 20,000 lines of codes, almost without tests. So quite some technical depth, and that running on different platforms and so was kind of a pain. So I started to write tests and then I have a script with coverage.py where I have a list of perfect files, so files with 100% coverage, and for those files, the coverage may never decrease, because it was too early to enforce coverage always increasing because there are just some things which are not testable yet, so that's what I did and what worked out very well for me. Yeah, that's one way to set it up. But on the other hand, don't rely on coverage, would be my take, because coverage also depends on how you write the test. Having 100% code coverage is not necessarily a goal, it's having your business properly tested, that should be your goal. It might be 60%, it might be 80%, some things might not be worth testing. At least that's my personal opinion. I know there are people who say, okay, we have to have full system tests, full tests, but it's not always possible. If you write an open source library and people rely on that, and yes, your coverage should be as high as possible, because other people rely on your code. Within your project, it's also a business decision, or not necessarily a business decision, but an educated decision. Have your main flows tested, have your positive negative flows tested, but first of all, make sure that your code is actually testable, input processing output, single responsibility principle, and so on, solid stuff. A new project for making a new project easier to test would be smart or educated to adapt service-oriented architecture. If it fits your requirements, and if it fits your project, sure, you can use a saw. I mean, do you have architecture which are very difficult to test and which becomes a bad decision? Or not? Again, the answer is, it depends. I've seen projects that are a monolith, and people wanted to split them up within microservices, and the reason behind it was that it would be easier to deploy. If you can't deploy a monolith, you will not be able to deploy and maintain microservices, so it depends. Do we still have time? So, officially, no. We're supposed to end about two minutes ago, but the coffee break starts in 15 minutes. I think whoever wants to pop out and the rest of us want to just continue some questions and some discussions, we can just gather at the front and just chat some more. Okay. Thanks. I had one more slide, actually. This is what happens when you try to fix that little bug in a fragile and rigid environment. Okay. Thanks, guys.