Okay. So, this is my generic title. I use it for every talk I give, because it means nothing. It's good to have some, to be semantics three sometimes. And as said, I'm going to do rather than one long boring talk, I'm going to do instead two short boring talks. So, if you don't like the first one, just nap for a while, and then you'll see if the second one is any good. For the first one, I'm going to look at what I see as the essence of Agile software development. We're here at an Agile conference. We hear a lot of talk about Agile. When we started doing this stuff, we made the big thing about Agile software development, because we were kind of the rebels. And now, Agile is everywhere. Well, actually, Agile isn't everywhere. Pseudo Agile is everywhere. But I think there's still some benefits that we've seen. And I'll talk about that as we go. But in particular, I think it is at times worth reflecting on what the essence of Agile is about. And to begin with, it really has to start with thinking about where software was in the 1990s.  I.e., as a consultant, I ran time in time with these kinds of situations. I'm not saying this stuff has gone away, but I think it has been significantly reduced. But at the time, certainly this was seen as a big problem. And many people felt they knew what the cure was. And the cure was the big plan-driven processes. We need to have these highly defined everything stepped up front, big methodology with a capital M and a capital E and all the rest in double caps, and very defined approaches to doing things. That was seen as the cure to the software ills at the time. If you weren't talking about this in the late 1990s, you were clearly unprofessional and not really a part of the future of software development. But there were some people who had a different kind of approach. And that's where Agile was born in very much in reaction to this notion that the true way of doing things was these defined processes. Now, the manifesto, obviously, is one way of trying to describe what tied these people together. I mean, because there's a bunch of different people here for the extreme programming crowd, the scrum crowd, Alistair Coburn, the pragmatic programmers, various different people who came up with this notion of Agile as an umbrella to cover the different ideas that were around. Just before we had this meeting, about a year or so before, I wrote an article called New Methodology, which was my attempt to try to look at what was going on in this scene. Also together with some other stuff like open source software and pull out what I felt were the common characteristics. The article is still around, or at least an updated version of the article is still around. And basically, I said to myself, there's a difference between what came to be called Agile methods and this plan-driven, defined process, engineering-oriented process that we saw. And it really came down, I felt, to two different separations that were interesting. The first one was the attitude towards planning. In the plan-driven world, the idea was that if you wanted to carry out some kind of project, the first thing you do is you come up with a plan. That was both in terms of a project plan, how long the project was going to be, who was going to work on it, et cetera, et cetera, and also a plan in terms of the architectural design for the software. You would have a group of people doing that. And then that plan would be handed over to some separate group of people in order to execute and produce the software. There was definitely a big difference between this, the plan and the execution. And what this was, of course, modeled onto a large degree was how people imagined that real engineering was done. You know, you have the architect drawing up the diagrams and everything and the blueprints for a building, having to hand it over to a separate company to actually build the thing. And that was, that kind of model was often talked about. I remember being told someone who said, software isn't really very valuable. As long as we've got the designs, the architecture for the software, we can hand it over to any old company to build it. The actual code is unimportant. Now, I think of this as a kind of predictive planning approach. Because what you're trying to do with that plan is you're trying to predict how things are going to go. And it also has a consequence about how you measure success. Success means the plan, everything went according to plan. And that model you still hear even in supposedly agile circles today. When anybody talks about a project being successful or not, based on did it go according to plan or not, that is plan-driven thinking. It most certainly isn't agile thinking. Agile thinking is much more about have we delivered value to our users, are our users happy? Are they able to be awesome? Those are the kinds of things that outcome is really what matters to an agile thinking. But in a plan-driven world, it's much more, well, did everything go the way it's supposed to be. Now, why is it that we pushed against this notion of planning? Because actually, it is quite a strong human desire to kind of say, well, we can plan what's going to happen and then things will just go according to it. Lots of people like that kind of way of thinking. Well, the problem is that if you come up with this kind of approach, it really depends on you coming up with stable requirements. If you don't know what it is you're going to build, then you can't really plan in any kind of stable ways how you're going to build it. And that's not just true of the plan, it's true of the entire software development approach that you follow. But of course what we saw and what we see now is that was a big question of whether you could get the requirements stable. And so plan-driven approaches came up with all sorts of techniques to try and stabilize requirements. All sorts of meetings and sign-offs and all the rest of it to try and reduce that requirements churn or requirements creep. The agile community reacted against this by saying, well, you know, one of the things we ought to know about software is if we've got a situation where we're dependent upon something that's very unstable and difficult to work with, maybe we should think about breaking that dependency. And hence the idea that in our approaches we don't try to come up with, we don't need stable requirements, we need to come up with a process that's tolerant to requirements that are changing. It's in many ways how in the same way that when you're doing with large distributed systems today, you have to assume that failure always occurs. You have to be able to recover from failure. Here you have to recover from churns and requirements. And in fact, not just can you be stable or can you survive instability in the requirements, you can actually take it a bit further. Hence one of my favorite phrases of Mary's. Actually saying that a changing requirement is actually an advantage. Another phrase I rather liked, I think it was, we encourage requirements to creep around until they actually find something valuable for people. The point is that we react very well to change and we use the whole process as a discovery process. And that to me is one of the big shifts that the agile world beckoned in. And when I look at pseudo agile stuff, often you see this kind of notion we need to have some kind of stability. There is perhaps a grand list of all the great backlog that has to be managed and changes to the backlog as seen as a bad thing. But if that's the case, that goes back to that plan driven thinking again. We're constantly altering and shifting things. It's okay to have a plan, but it's that plan has a different role. It's now a baseline to assess, well if I make this change, what consequences does I have? If I have this change, what consequences does it have? It acts as a thinking tool to manage the consequences of change and to be able to make decisions. Do I take this path or this path instead of a situation where you're seeing it acts as a kind of sign of goodness, a sign of health for you. So that's the first shift that I basically looked at and summed it up. And it's probably the one that is most talked about. But the second shift is perhaps even more important, the role of people and process. So if we think of the plan driven world, we're actually following the leader of this guy. How many people recognize this picture? A few people do. This is one of the most important people in the 19th and 20th centuries. It's had more influence upon 20th century about life and work than most politicians that you've heard of. His name's Frederick Taylor. He came up with the idea of scientific management. And at the heart of scientific management is the notion that the people who are doing the work are not the best people to figure out how to do the work. But instead you need a separate group of planners who figures out how things should be done. So if you look at these plan driven defined methodologies, one of the things that they do is they say what are all the tasks that you need to do? What are all the deliverables that you need to come up with? What are all the roles that need to be played in a project? They define all of this stuff and what makes a good project execution.  The agile thinking twists this around and says no, instead the teams should decide what process they're going to follow. Because it's the people who are actually doing the work who are best qualified to understand what's going on. And software projects vary too much. They vary in, you know, the pressures of exactly how the needs of the users have to be met. They vary and depends on different technologies that you're using. And quite frankly, they vary depending upon the team personalities. Different people like to work in different kinds of ways. And therefore they should decide how best they're going to do things. Certainly it's helpful to listen to clever, loud people like myself who kind of whitter on about how things should be done. Often we come up with okay ideas that can be brought into the project. People can try them, see how well they work and sometimes decide, yes, they're useful and we can go with that. But it's the team's decision how they need to operate. And whenever you see someone saying, oh, we've got a agile process that's going to standardize things across different parts of your organization for you, then that's an immediate warning sign. Because that's immediately going against this autonomy of teams. That's such a vital part of how agile thinking operates. This is usually where I say something rude about safe. You know what safe stands for, right? Shitty agile for enterprises. But I don't want to do that this time. Because actually we should be grateful to safe. Because thanks to safe we now think that scrum certification wasn't so awful after all. So that's how I see the distinction between the agile world and the plan driven world that is the heart of where things come from. And the wonderful thing that agile has moved so much more beyond the kinds of things that we were thinking about in that scary sort in snowbird where we came up with a manifesto. Lots of people have come into the agile community since then. They've come up with all sorts of ideas. The whole world of lean has come in. We see database evolution. We see the UX world integrating in. The whole DevOps thing has exploded out of that. None of this was foreseen by us. And rightly so. All we were trying to do was make it safe for people to explore this territory and to see where it could lead us to. And I'm sure that if we look in ten times this time we'll look at all sorts of other nice things that have come in as well. The whole point is we can't predict that future. I'm often asked, you know, what's after agile? What's next for agile? I haven't got the foggiest. I mean all we were trying to do and all we can do is allow a space for us to experiment. Not just do teams decide how they're going to work. They decide how things change. Individual teams experimenting with those ideas, pulling interesting things in. And then when they find things that work they talk about it and the knowledge spreads around. That's really the most important thing a conference like this can do is to allow people to exchange ideas and pass them through. I'm a kind of conduit for that at ThoughtWorks. I go around, listen to people, listen to what they're up to, different projects, and then try and pull together the more interesting things. My first choice is then to get somebody else to write about them for you. But if nobody else will and I think it's interesting enough I do it myself. But that is the way that we should be working. Channeling from each other's experiences. So one of these things that particularly struck me, not from any colleagues at ThoughtWorks but extremely good, was the idea of fluency in the agile fluency model. This was developed by Diana Larson and James Shaw, two people I've known for quite a long time who are very active in the agile world. And what they did is they observed the projects that they'd been helping and people they were talking to and noticed that there was a typical sort of different styles of how people operated within agile projects. Commonly they passed through a set of stages as they went through. And the note of fluency was to say this is what people do when under pressure, when they have to revert to their way of operating. It's one thing to kind of learn how to do something, but you only really fluent in it when that is your default when pressure comes up. And their modeler, I like their model a lot because it resonated very well with what I'd heard and seen in terms of how projects operated. So the one-star level focuses very much on what we might call the management practices, where people are using things like sprints and backlogs and cam-band boards and things of that kind. You might also think of this as scrum in its kind of default state without any technical stuff thrown in. What they saw is that although a lot of people easily sniff at this, particularly us more seasoned Agilists, you actually do see benefit from it. People find that they get a greater visibility as to what's going on. And people begin to think about progress more in terms of business value than in terms of that following that plan checklist. And most teams, the largest, the plurality of projects that they saw, nearly half the projects that they run into, they reckon operated at this level, who called themselves Agile. But it still took a certain amount of time to get there. And this is, I think, a generally important point. Getting used to know about Agile techniques and things takes time. And even to operate at this level of working is an exercise of many months. But this is only the first step. And ideally, you want to move the step further. And that step further means bringing in a whole bunch of additional practices which are much more to do with the technical side of things. This is where things like knowing how to do the automated testing and continuous delivery, refactoring, techniques like this come into play. In many ways, you can think of this as like the extreme programming picture, which says the combination. In extreme programming, there was no difference between management and technical practices. They were all just practices. And one of the things I've always loved about extreme programming is that it had things on both sides. It had both the technical and management stuff together. Now, once you bring in the second step, you begin to get some very nice benefits.  Now, one of the great annoyances to me is how so many organizations seem to think that if you want to move quickly, if you want to be responsive and agile, you have to tolerate lower levels of quality. You've probably heard of this thing around these days called bimodal IT or two-speed IT, or as I sometimes refer to it, bipolar IT. Now, one of the fundamental things about this is that the idea is that you've got a fast, responsive, but unreliable element, which is kind of the agile bit, and your back-end systems have to be reliable and as a result can't move quickly. But anybody with any experience in doing this knows that if you want to move fast, you have to have high quality. You have to have high reliability. You can't move fast if all the time you're tripping over defects. So, in fact, one of the most interesting things for many people is to realize that using these kinds of techniques, this two-star agile level, drastically lowers defects. I was talking with a colleague of mine, they were doing some work actually, fairly close to here, for an agency where they said that the corporate-wide reporting system people came in and said, well, you've got a problem with the way you're giving us your reports because one of your numbers is clearly wrong. You're saying you've got no defects going from month to month. Zero. That's obviously an error because if a defect appears and you spot it on the last day of the month, it's obviously going to carry over to the next day of the month. And our team said, no, not an error. We fix every defect the day it's spotted. We're that fast because we use continuous delivery. We have the tests. We're able to quickly find what the problem is, push the whole thing through to production and get the whole thing cleared within the day. That's the kind of thing that is needed in order to operate effectively in an agile way. But it takes investment. It takes time. Teams can take a couple of years to reach this level of fluency. It's not an easy thing to do. And now I think it's one of the things to bear in mind. Learning how to do software development is not easy. Learning it how to do it well takes time and effort and dedication. And it's not a thing to expect to see instantly. Now another way of thinking about these first two fluency points is the first is requires the shifting culture. A culture that shifts you from the following a plan to this notion of, oh, we've got to be value focused and talk about success in terms of delivering useful things. The second shift is a shift in terms of skills. It says now we've actually got to up our skills considerably and that's why, of course, it takes so much longer. The third level of the fluency model, although I don't like using the word levels, it's hard to avoid it, this is the one that takes things even further. This is actually heading into the territory of one might say the modern agile approach that Josh talked about yesterday. Because now we're getting into a situation where the team themselves are making more decisions about what to do, they're tracking metrics, they're using things like A-B testing, sophisticated monitoring to find out to what extent they're delivering that value. Now when they came up with a fluency model which was a couple of years ago, this is only a very small amount of projects that reached that point. And it took a long time to get there. And part of the reason is because this requires order organisational changes than just a single team. In order to pull this off, it takes a lot more effort. It's easier in smaller companies, start-ups, things of that kind, because the organisation hasn't sort of acquired all the scar tissue of life over the years. But in any case, it can still take a long time. And they posited a fourth level which took it even further. But they hadn't really seen it, they were more hypothetical. Although talking with James more recently, he says he's beginning to get a better picture of what that further level begins to look like. The important thing of thinking in terms of this fluency model, though, is not necessarily saying it's a sense of the worth of the rest of it, but a common progression as to how teams go. Not all teams will follow through those steps, but most seem to. And to realise, I think, also the degree of time required to take you through it. This is not a rapid process. It takes time to get through this and it requires patience and dedication and resilience. But it's also a very doable and possible thing to do. People, a lot of people in the course of the conversations I have here and other places get frustrated with the big amount of pseudo-agile out there, but let's face it, probably 80% of what's out there. Agile software development is a subject to Sturgeon's law as anything else.  I mean, that's true with Agile too. But the important thing for me about the wider acceptance of Agile software development isn't so much that. It has given the ability for teams who want to work in this way to be able to work in this way. It's a lot of work. We used to have to really hide that we were doing Agile stuff most of the time. It was a constant battle to do things like testing and continuous delivery and things of that kind. Now people want us to do it. We're able to find places. And we don't succeed all the time and we fall down from here time from place to place. And you know, you still got arguments between should we use sprints or should we use continuous flow or often working in this kind of style of work than we were 10, 15 years ago. And that's the most important victory for me that the Agile movement has had. So if you want more on this, the new methodology article and the Agile fluency articles are on my website. Don't bother with the slides because they make no sense without me speaking. But there are videos of me giving this talk elsewhere. In general, if you want background stuff to any of my talks, go to the videos page on my website and there's links to supporting articles and things. So that was the first one. For the second one, I thought I'd move into something a bit more programmary oriented. How many people here call themselves programmers? As in you generate stack traces on a regular basis. Well, this is not just for you for everyone who didn't put their hand up. This is important to know about as well because what this is an vital part of programming is the process of refactoring. And it's something that, even after all of these years, is not necessarily as well understood as it should be. So many people, when they get introduced to what refactoring is, they get it introduced on the basis of talking about test-driven development. You haven't heard of the red-green refactor cycle of test-driven development where when you're writing some new functionality, you start by adding a test. You then go, your test suite goes red because it fails because you haven't written new functionality yet. You then make it pass, then everything goes green. And then, of course, at the beginning, people will skip over that the next step. But actually, vital step is then to use refactoring on the code base to make that pass code clean. And you constantly go through that cycle. Now, the interesting thing to bring out of this is that as you're going around this cycle, you're going to be able to operate. And this was characterized by Kent as the two-hats metaphor. He said, when you're working, you can either be adding new functionality or you can be refactoring. You can't do both at the same time. And there's a change of mode when you switch from one hat to the other. In red-green refactor cycle, when you add the new test and when you're making that test work, you are changing what the overall system does. But when you're in that refactoring step, you're in this slightly different mode. You're not changing what the system does. You're just changing how it does it. And you use different techniques and tools. In particular, you should be following the refactoring credo of Take Small Steps, none of which changes the overall behavior of a program. Very small steps. If you went to any of the talks on refactoring during this conference, hopefully that should have come through loud and clear. I would say the biggest surprise that most people have when I show them refactoring is how small the steps are that I take. There's a bunch of articles about refactoring on my website where I actually go through chunks of these. And the common reaction is, wow, I didn't think you'd take such tiny steps. But I do. Because that's really the essence. Refactoring is all about taking very small steps that if you keep them small, they'll compose cleanly to allow you to make big changes. This style of refactoring and this way in which refactoring is done, I think of it refactoring in the context of TDD. But it's only one of the ways that refactoring can fit into somebody's workflow. A more common way, perhaps, in many ways of doing it, is when I'm looking at some code and I go, oh, that's pretty awful. I do this frequently because I work on my own code. And so I see lots of awful stuff. You were supposed to laugh in a sympathetic way when I said that. And awful may mean all sorts of different things. I mean, it may mean some convoluted logic, but this just seems messy.  I should have named this method differently. Vital part of refactoring is that as soon as you spot something that's not right, you deal with it. I think of this like picking up litter. As soon as you see it, you get rid of it. There's a lot of litter on the ground.  There's a lot of trash everywhere. But on the other hand, if you constantly keep the place clean of trash, then you're more inclined to spot and clean it up next time. So an important part of refactoring is as soon as you see a problem, you fix that problem. And that's true across all of the code base that your team is working on. And that, by the way, is one of the reasons why it's kind of sort of more than a day-length period. Because that kind of approach tends to discourage this kind of activity. Because people don't like the consequences of a merge if you're doing that kind of cleanup. But that constant cleanup is an important part of what makes refactoring work. Now, a slight variation on this is when you look at some code and you don't immediately understand it. If you're ever in a position where you're looking at a bit of code and you can't quite see what it does and you have to think through it a little bit, it might be for 30 seconds or so. It might be a few minutes. At some point you get, now I understand what's going on in that code. At that point, you should refactor. Because what you should do is what's happened is some understanding of the software has appeared in your brain. Wood Cunningham likes to say, whenever that happens, you've got to take it out of your brain and put it into the code so you won't have to puzzle it out again. I think Steve McConaugh who said, you know, reading something and puzzling out what's going on, that's a good thing in a detective novel. It is a bad thing in code.  And any time you have to think to puzzle it out, that's a sign that you can improve it. And I think of this as a comprehension refactoring. As soon as you understand something that's going on in the code, you put that understanding into the code itself so that it clarifies it. Now, I've said straight away there's a kind of common flow to both of these approaches. You don't necessarily do it right away, but you always have to think about it and say, do I do it right now? If you're in the middle of adding some function that's a bit tangled, you might not want to do it straight away. In which case, you might finish, get to a reasonable stopping point, get to where you've got a green bar and then the results are all passing and at that point, you can carry out the refactorings. A lot of people like to make a little note of refactorings that need to be done on a card as they're working or a little note, a list on a buffer. It's important to get to them quickly though, because if you don't get to them quickly, then you'll forget to do them. On the other hand, if you're already in a position where you're actually not too tangled, just get quickly to a point where your tests are green, then do the refactoring and then carry on and finish the feature you're working on. Sometimes this might mean just stashing what you're working on. You're in the middle of something, do a stash, get back to a green point, do the work and then you can reapply the feature change work you're doing on. A useful part of this, by the way, is if you're using a distributed version control system like Git, you should be locally committing lots of times. My rule of thumb is every time you get a green bar, commit. Green bar, commit. Write a little thing, fix a little thing, do a little bit of refactoring, extract one method, commit. I'm committing all the time when I'm working in this way. I don't... I then, you know, before I push to the master, I'll squash the commits together and make a logical change out of it, but the great thing about a distributed version system is you can constantly make checkpoints. You can never make enough, really, because you can always squash them together before you share them. And that way, should you make any mistakes, you can always roll back quickly, because if you ever get into trouble in the middle of a refactoring, the best thing to do is to roll back to your last green bar. And so if you've got the commits, you make that easy to do. So another common case is when you look at some code and you say, you've got a new feature to add and before you even start adding that new feature, you say, you've only written the code differently, it will be so much easier to add this feature. If you ever get that feeling, then refactor. I think of this as preparatory refactoring. Essentially, what you're doing here is you're saying, is the existing code base a good fit for this new change that I want to apply? If it is, that's fine. Apply the feature. But if it isn't, refactor it so that it is easy to add the feature. Kent sums this up really well. I should include the tweet on the slide. I've forgotten to do it. He says, when you want to make a change, first make the change easy, then make the easy change. That is a really useful technique and should be a regular part of how you work. Certainly it's something I do regularly when I have to modify my code, is I look and say, okay, how can I make what I've got to do forward?  Well, I'll do the refactoring. And you would do this, the reason we separate refactoring from adding new features is refactoring is much more smooth process. Because you're not adding anything, all the tests are always working before. And afterwards, you've got a, you're following a set of these small refactoring changes, you can make quite big changes at a relatively low stress level and at a much less chance of screwing anything up. That's why I want to spend as much time as I can with my refactoring hat on. Because when I'm refactoring, everything's cool and easy. It's when you're adding new things that things will get a bit uncertain and awkward. So, when making a change, I really like to get it so that it's nice and straightforward to put the new change in and then go in and do it. And as I said that, you may only discover that halfway through adding the feature, in which case you're afraid to roll back, stash your changes to one side, make the refactoring and then make the easy change instead. Another kind of refactoring that people do a lot is a case where you have refactoring cards on your wall that are all about making changes to the system. And you schedule them, they plan them as part of your work. I actually say that a good team should hardly ever have to do this. Refactoring is something that should never be big enough to need a story card to capture or a task or something of that kind. Refactoring is a constant process that you're doing all the time. Every time you pass through some code, you should make it that little bit better. And actually stopping even for a story's worth of work is not something a good team should be doing. But I'm not saying that that means it's always a bad thing to do. Particularly when you're learning how to do this process sometimes you'll find you've built up some crud in the software and you need to clean it out.  Even good teams occasionally run into this. But ideally you should minimize the amount of planned refactoring. Most of the refactoring should do, should operate as a kind of regular process as what you're doing. But that doesn't mean that you can't sometimes see some large-scale refactoring. I mean, spy were this one by something that was done many, many years ago on a ThoughtWorks project where people got unhappy with the way the dependencies between various modules were. And they had a short design meeting. It was over-lunch or whatever. And they sketched out how things ought to be. But they didn't stop work in order to refactor from one to the other. What they said was, we'll get this to be state. We'll stick it on a wall in the team area. And what we'll do is we'll say over the next few months any time you're in the encode that doesn't match the new model refactor it towards that direction. You don't have to get all the way there but make sure you're taking a step in that direction. And over the course of several months, while there were shipping features and doing all their regular work the code slowly moved in that direction. And at some point the tech lead said, oh, we're nearly there. I'm just going to spend a couple of days and finish it off. That's how to do a long-term refactoring. Lots of little steps over the course of time. Because one of the beautiful things about refactoring is when you're refactoring, if you're doing it if you are actually refactoring, you can't break the code. You shouldn't be breaking it. Refactoring by definition does not change the observable behaviour of the software. If somebody ever tells you, oh, the code is all broken for a couple of days because I'm in the middle of refactoring the only thing you can be sure of is that they're not doing refactoring. They're doing some rewriting restructuring stuff. But refactoring is all about lots of little changes and at any point you can stop and everything still works. And that's one of the things about refactoring is a lot of the time you don't necessarily have a vision of what the end state exactly looks like. Often when you're refactoring you're just trying, you're just a sense of, well, I can make things a little bit better. I can name things a little more clearly. I can clean up some convoluted logic here or there. And particularly when I'm working on some more messy code I might just refactor for a while without any idea of what the hell I'm doing. But I'm making the code a bit better, a bit clearer, and then I can once I've done that for a bit I can say, oh, now I know where I need to take it further on. And then over the course perhaps of weeks I'll actually get there. Refactoring is all about these little steps and it's all about making the code that much clearer. Reducing the amount of times you've got to look at this, get and stretch your head to try and figure out what's going on. And if you don't do this really you'll never get to that two-star level. Because refactoring is the key to being able to shift and change, to be able to react to new things as they come in, new demands, new spotting how the users can be worked, can have been made better by the use of your software. You can't have that reaction if you're not able to refactor. But despite this people still say well is refactoring rework? And my answer to that is really comes down to a little pseudo-model, a pseudo-graph I made a while ago. Under the perhaps rather ugly name of the design stamina hypothesis. So if we plot this pseudo-graph of functionality, cumulative functionality against time most software projects that don't put a lot of effort into architecture and design and refactoring they follow a graph like this the more you grow the software the harder and harder it is to add new features. And you feel that you're slowing down, getting slower as the project goes on again and again. How many people have been on a project that is like that? Usually most people get their hands up at this point. A lot of you didn't which is a bit suspicious but that's okay, it's late. But you do run into projects where the reverse happens where not where you can in fact speed up as you're going on because new features, to add a new feature well I'll just plug this, plug that make a few changes over here with some refactoring and everything plugs through and I can quickly bring. It seems like I'm speeding up rather than slowing down. How many people have been on a project like that? Less hands but there's still some hands going up. That's what refactoring does for you. It allows your ability to add code more quickly to come through. It gives you that ability to be fast in the medium to long term. And a medium to long term really is sort of anything from weeks to months to years. And really that's the essence of why refactoring is so important. When you are talking about justifying refactoring you have to be wary of a bit of a trap. A lot of people when they say why should we bother about refactoring? Why should we bother about clean code? They'll say, well it's the right thing to do. It's being a proper professional. You may say, I'm going to wear a little badge around my wrist or so I'm a true professional. I refactor. And to ask me to write code that isn't really well structured and well factored that's wrong. That's sort of sinful. If you use that argument you're screwed. You've lost. Because management and customers, they don't care how clean your code is. It doesn't matter to them. It's just irrelevant. The answer the justification, the only justification for refactoring is the economic argument. It says we refactor because that way we go faster. We build more features over time. We're able to be more effective and efficient. Be more responsive to change. That's why we refactor. We refactor because it's cheaper because it allows us to go better. Remember that comment I made early on when I was criticizing bipolar IT. It's all about the fact that in order to go fast we need good quality. In order to get good quality a key part of that is regular refactoring. So remember that. Whenever you think of justifying refactoring always use an economic argument. And on that note, I'm done.


wn that also. Not able to do it in your assignment. Please do not try to attempt. If you are attempting, that's fine, but don't attempt the technometric part because I'll be dealing with identities first with you. Then only you should be able to attempt it. But if you feel you're able to, you'll be able to manage it with expansions. Then go for it. I'm not stopping you. I'm not stopping you. So could you repeat how you got one for the first one? See, a simple Oshik, what I did was, Sinex expansion already I've given to you in the list. Just check out the list. I don't want to go and search for the board, but I'm sure you would have written this guy. Okay. Divide it by x. So when you divide by x, what happens? There's always an x present in all the terms in the top. So all of these terms will lose out 11x. So this guy will become a 1. Okay. This guy will become x square by 3 factorial. This guy will become x4 by 5 factorial and so on. Now when you substitute limit extending to 0, leaving this one aside, everything else will become 0, 0, 0, 0, 0, 0, 0. Okay. Oro is getting 0 for this. Why Oro? Let's check. Cosx expansion is what? 1 minus x square by 2 factorial plus x4 by 4 factorial minus x6 by 6 factorial. Don't have to write a lot of terms. I think just few terms are sufficient. If you open the brackets, you'll see that 1 and 1 will get cancelled off. So it will become x square by 2 factorial minus x4 by 4 factorial plus x6 by 6 factorial dot, dot, dot to infinity. Okay. Divide it by x square. Now, since x is extending to 0, you need to get rid of this x square term from the numerator and denominator. And thankfully, all the terms in the numerator are higher than x square. So you can cancel x square easily. So you'll get 1 by 2 factorial, x square by 4 factorial, x4 by 6 factorial and so on. And finally, when you take the limit extending to 0, you'll realize all these terms start getting 0, 0, 0. Only this 1 by 2 factorial is left off, which is half. That's how you get that result. Okay. Fine. So this is the standard trigonometric limit. Now, I'll also talk about some standard exponential limits. Under standard exponential limits, there is one limit that we need to know. Limit of a to the power x, a should be greater than 0. a to the power x minus 1 by x, this limit is given by LNA. This limit is given by LNA. Now, what is the proof for this? Very simple. Expansions. Okay. So a to the power x, let's recall a to the power x expansion is 1 plus x LNA plus x LNA the whole square. Let me write it separately so that we can adjust with the terms. Got it. Okay. So when you do this a to the power x minus 1, so you bring this one on this side. So I'm just removing this one now. Okay. Divide by x. That means you divide by x here. Okay. Take the limit as x tends to 0. Take the limit as x tends to 0. So what will happen? This x will cancel off with this x. It'll cancel off with one of the x's. And the next term will be like x square LNA whole cube by 3 factorial and so on. So it doesn't matter. Anyways, once you have cancelled it and you put x as 0, you'll realize that these terms will start getting 00H. Okay. Leaving you only with the LNA part, which is your this term. Okay. So this is it also you need to remember all the standard limits result you need to remember because they're going to make your life very, very easy because they're going to form the smaller units of your bigger problem. Okay. So derivation is clear. Anybody has any question on this? Let me just pause here for a few seconds. If you have any questions, please shoot again. Thanks to expansion. Thanks to expansion that we are able to get such answers. Okay. Now there is a cousin of this expansion, which is where your a is replaced with an e. Nevertheless, the answer is not going to change. It is still going to be L and e. L and e is nothing but one. So this is also a very, very important type of limits. As of now, I have just substituted a as e, but you can try proving it by expansions also. Try proving it by expansions also. Any questions? Yes, you can apply Lopital. You can apply other rules also. Okay. To prove it. You can apply the concept of yes, Lopital and all without Lopital and without expansion. Without Lopital without expansion. I think so it will be. I don't think so. There's any other method to do it. Do you know of any such method? I would love to know that. Yeah, I don't think so. Any other method will work here. Especially when you're dealing with transcendental functions, it leaves you with not much of an option. Okay. So coming to the last part of limits chapter, standard logarithmic limit standard logarithmic limit under standard logarithmic limits. There's only one type of limit that we are going to talk about, which is L in one plus X by X as X is to zero. This is one. Okay. Now, what is the proof for this proof for this is very simple. All we need to do is use your expansions of L and X. That is X minus X square by two plus X cube by three minus X four by four and so on. Okay. Now people ask me sir, didn't this work only for X lying between minus one to one? Yes, it does and we are very much in that interval. So when you're close to zero, you are satisfying this radius of convergence criteria. So you are very much under the radius of convergence. So we can definitely use this particular formula or expansion to solve this problem. So let me just put this expansion in place of L in one plus X. So you can realize that more or less the approach is very static.  Okay. So more or less the approach is the same as we had done in the previous problem and as X sends to zero, you realize all these guys will go towards zero. Okay. Leaving aside one as the answer. Leaving aside one as the answer, but don't expect questions to come of the similar nature in your board exams, sorry, in your school exams. There will be of course a lot of tweaking around this concept. Okay. In the last two minutes, I would like you to just ask a question from you. Just one simple question. Okay. Since you claim that you have understood limits. So before closing this chapter, I would just like to ask you this question. So you have two minutes to answer this just as a thing like as a test to end this chapter limit extending to zero for X plus mod X whole divided by 3x minus 2 mod X. Yeah. Those who want to leave they can leave. It's just a question for people just to close the topic so that I'm also happy that the boys have understood it next class will be a hardcore derivative, you know, three and a half hour sessions. So do not miss that. That's going to be very, very crucial. Done. Anybody? Okay. So I'm getting different different answers 5, 4 by 3, etc, etc, etc. Okay. Guys, here comes your final blow. Whenever there's a mod terminal, always be cautious. Evaluate the limit left to it. Evaluate the limit right to it, especially when the mod is at the point where the limit is tending to or where the X is tending to. Okay. So when you are slightly left to zero, please remember mod X behaves as minus X when X is less than zero and it behaves as X when X is greater than equal to zero. So when you are at zero minus, it will becomes four. This will become a minus X and this will become minus of 2 minus X. So it actually becomes 3X by 5X. So 3 by 5. But when you are dealing with X tending to zero plus, it becomes 5X by X, which is actually 5. So the answer is limit does not exist. Okay. Anyways, we didn't end on a very good note. But that's fine. That's fine. This is just trying to, you know, you're not understanding the nitty-gritties of things. So anything contains mod X. No, not like that. Not like that. It depends upon where you're evaluating it. Okay. So here you are evaluating it at a point which was actually the critical point for that. Right. For example, let's say if I said the same question extending to one, when you're evaluating it at extending to one, then what will happen? They will happily assume XX for mod. So it'll become just 5X by X. So there you don't have to worry about left to one, right to one, because 0.999 also it will be X. 1.001 it'll also be X. So let's not make a general rule like this that whenever there's a mod, a limit will not exist. Not like that. Yes, if the mod is having a critical point where the X is tending to, then probably it may not have a limit. Okay. Thank you so much guys. Thank you. Good night. Namaste. Shabba Khair. Stay safe. Bye-bye.


Good morning folks. This is Steve Rhodes coming to you live from the shores of sunny Delray Beach, Florida with your Lebanese update and currently we have a market that is dead and red Got the Dow down 242 points that's up nearly eight tenths were sent one and a quarter percent for the S&P or 49 points One and nine tenths percent for the Nasdaq 100 232 points there to in three tenths for the Russell 2000 42 points the downside 112 for the summice. That's over four percent trend is a down seven tenths 96 points golds off 23 bucks. That's one and three quarters percent 1703 20s the print there Silver's down 2% 37 cents trade at 1751 lights recruit up to 50 trade at 87 11 natural gases up 20 cents at 932 30 or Treasury down two points and 13 ticks at straight at 134 even Stephen. So let's go try to figure out what all this means well Here we'll put up the nine panel market update chart You've got the a to b equal CD pattern inside the ES mini today is going to be the bar following bar number nine as price Approaches the support of its weekly profile and that's at the 38 87 level We take a look at the spot, but it's still well above its 50 day exponents moving average That's always a bearish directional signal for the S&P 500 the NQ Formed a TD nine count two days ago yesterday was the bar following bar number nine That's as a close today below 12 to 47 15 negates that signal It does have an a to b equal CD to the downside But it would then need a bullish reversal candle to confirm a buy the D pointer a currently buy pattern Short of that price may be targeting the bottom of its profile and that's at the 11 891 area US dollar index is taking out It's TD a roadsman to Mindicator top close above 109 14 will accomplish that and that'll suggest higher price during the Trader Z show we'll take a look where that set it to gold has made in essence the one to one a to b equal CD That one to one price projections 1694 the actual low so far today has been 1699 10 silver Trading blow daily and weekly profiles looks like you want to continue to head lower like to be crude is tested a support area That's the rising trend lines as well as the bottom of its profile 86 51 being the key level there And even though we got a nice little bounce here in natural gas just consolidating with inside its daily profile It does have a TD 9 count top in place But it just been a sideways movement and a third of your treasury we'll take a look during the traders that show to figure out What patterns are in play what a to b equal CD price projections There might be prices trading below the bottom of its daily profile here before we got close out the 11 o'clock update Here are your primary a to b equal CD patterns for those indices that you and I can trade ETFs on So you'll see those patterns in play here each of them need bullish reversal candles to confirm a Please stay Oversold bottom with a counter trend out folks stay tuned for the trader's ed show And but if you're off to start your Thursday have a terrific one day tomorrow We're gonna record the show at 8 o'clock, so please join us early. We'll see you soon


Hey guys, good evening. This is Modit. I am VP Engineering at Hansel.io. We are a command center for your live mobile apps. We let you change your UI. We let you diagnose the issues in the live app. We let you fix those issues by which I mean we let you fix your crashes.  We let you change the behavior in certain cases. So do check us out. But then today it's not about us. It's about you guys. I'll be letting you build a simple version of Hansel.io, which will let you do the same things for yourself. So as mobile developers, we work in an environment which is constrained by the memory, low memory, limited disk space, low battery power, bad network, which is especially in India. We have bad network. And then the devices, the kind of devices that are there in the market, they make the whole ecosystem quite fragmented. You have devices with different screen sizes. You have devices with different form factors. Devices with different kind of processing powers, low memory. And the way these handset manufacturers give out the updates for the new APIs, that adds to more fragmentation every year as Google releases another version of the API. Beyond fragmentation, since we're developing for apps, not for web, the release cycle for us is quite long. We develop the app, then we give it to the QA, QA does its own set of testing for the version, for the feature that you're releasing, then do a regression testing. And then by the time it goes out, it even for a smaller feature, it's a matter of days. Now, so you created an app, you released it. As it goes out in the wild, then it gets tested. So you tested on a certain set of devices, and the app will work fairly well. But in certain cases, when the device is running on a low end, or say some new device crops up in the market, the APK that you've released starts to behave not in the way that you wanted to behave. You start facing logical issues, by which I mean the UI doesn't work well, the performance is not good enough. And then the most dreaded happens, you have crashes. The problem with, why does it happen? So you never provisioned for a better version of Android, which has gone live a month back. You probably forgot to add some permissions. You probably didn't provision for your app getting installed on an external SD card. And of course, you made some changes in the code, which you might want to call them features, but they are bugs. So because of all this, the app starts to crash. So all this leads to a lot of revenue loss, bad ratings. You have ranks on Twitter and Facebook. And then the loss of users. So I was discussing with the gentleman outside the presentation and he had a different insight to it. What this guy told me that there is a study which tells you that there are only five or seven apps, which a user uses. And beyond that, all the apps which are there on your phone, they are there, but they are waiting to get uninstalled. So if any of these things happen, you lose the users. So what do we need as developers? We cannot afford to lose users because as soon as you lose a user, you are losing revenues in the longer run. So basically what we need is reduction in the response time to any issue in the app. If there is a crash or if there's a logical issue, what you need is a new app going live as soon as possible. But the way the app ecosystem works, this is not a matter of minutes. It's a matter of days. Until then, the user which is having your app is getting frustrated. It has the old app which doesn't work at all. It crashes or it behaves in a way which you don't want the user to see. So what we need is a tool which can help us diagnose the issue really fast and not just diagnose the issue. We need something which can fix these issues in real time. By issue, I meant logical issues that you're facing and of course the crash and all that, of course, on the live app in real time. There are certain tools which do help you do this. These are crash reporting tools. A lot of you must have been using one of these tools.  It's from Fabric. Then a lot of people use Hockey app. Firebase is the new kid in the market. But it's catching up. Then you have criticism. But all these tools have multiple issues. They are more of a reporting tool. They let you know what happened in a really objective manner. They let you know that a crash happened and this is the stack trace. They won't let you diagnose the issue. They won't let you know why this crash happened. They don't talk about anything related to logical issues. And when you start diagnosing an issue, there are certain cases wherein you need to know the flow because of which this crash happened. So I'll give you an instance. As in one of my previous companies, there was an issue in the login page. We tested it a lot and we tried to reproduce the issue a lot. But after two, three days, we figured out that this issue was not in the login page directly. But it was when people used to come to login page through a special flow. So what I'm trying to say over here is like we wasted two, three days of developer time just to figure out that there is a crash happening on a login page. We could have figured it out easily if we had known what the flow is through which these users are getting these issues. So yes, none of the tools that I mentioned let you do that. Let's you do that. So we are back to the same state. We need a tool which does fast diagnosis of the issues for us and let's us solve these issues in real time on the live app. Is there anything available? Yes, there is. It's called Hansel.io. But of course we won't be talking about that here. I'll be enabling you to create something similar to what we have built. I'll be letting you create the miniature version of Hansel. So let's go back to the topic. What I was telling you, so what I started with was instrumentation and how instrumentation works in Android. So let me tell you what instrumentation is. Most of us might have used it, but let's go to the root of it. So instrumentation is addition of bytecode to the existing methods. And in most of the cases, we have used it to gather data. I'll tell you the instances where we have already used this concept. In Android Studio, you must have seen Android Monitor. You must be using it. So Android Monitor lets you monitor the performance of the app which you're about to ship. During the development time, it lets you figure out how much network you're using, what is the CPU usage, what is the GPU usage, and how much memory your app is consuming. So this tool works on the concept of instrumentation. Beyond this, these are the other tools. We have Dex Maker, we have ASM Dex. And there is a really beautiful tool called Aspect J. So today we'll be using a tool called Aspect J. It's a part of Eclipse Foundation. It's an open source tool. And we'll be using it to create what we are intending to create. So Aspect J works on the concept of aspect-oriented programming. Aspect-oriented programming. We have all been working over Java or C++ since we're all Android developers. So in any object-oriented programming, each class has a primary function. So say you have a VC. So wherein you have models, then you have views. They have their own predefined functionality. Models have to keep the data. Views have to display the data. View is the display component. But say you want to figure out the performance of each function inside a model or the performance of each function inside your view. So what you would do is you'd start logging these functions. So logging is a feature which is being shared by both these components. Aspect-oriented programming lets you modularize this logging part in a separate concern. So each of them is a concern. As in your model is a concern, your view is a concern, and logging is a different concern which is being used by these two concerns. So logging is called a cross-cutting concern. Now the code which you write inside logging is called advice in the case of Aspect AOP, Aspect-oriented programming. So the way Aspect-oriented programming works is like you write your code, in our case it's the model and the view, and you separate out the logging part. Now there is an expression which will tell the compiler of AOP that this logging has to go into these particular functions. So this expression is called point-cut. So just remember these three things, these would be used later. So you have cross-cutting concerns which is the intent in our case it's logging. Then you have an advice which is the code which is inside that logger. Then you have point-cut which is an expression which lets you know where to put this advice. The whole thing is called weaving. So this is what I was talking about. On your left side you have your classes, your code, your logic. On the right side you have the cross-cutting concerns. So we have modularized the cross-cutting concerns and these get pushed inside your code based on the point-cut, which is the expression which tells the Aspect-J library wherein this code should get injected. Fine, so let's move further. So this is how Aspect-J works. This foo was your function. This foo gets converted into foo-o, which is foo-original. Then there is another counterpart function called foo which gets created. So throughout your code you must be calling the function foo. Instead of your function now the new function will get called and inside the new function you may choose when to call your original function. We will get to know more about this when we see the code. So what we are trying to build over here is we take the point-cut, we take the advice. All these come from Aspect-J. Now we will try to control this point-cut and advice through configuration from the server. So let's go back to the example that I gave. You are trying to log the performance. You don't want to log the performance all the time. What you want is you want to log the performance once, get the values and then switch it off. So we will do the same thing. We will have a point-cut which says inject the code of logging everywhere. Of course the code of logging is your advice and we will control that code through configurations. So this is what we are trying to do. We are trying to take control of your function before it gets executed and trying to take control of it before the execution finishes. We will create a diff. We will get a diff of the timing and print it out which will give you the performance of the function. So this concept can be used for multiple things. Debugging issues which I told you. We will do it through logging. Arrest crashes. We will try to fix logical issues as well using the same concept. You can even disable a function using it. I talked about advice. So in case of aspect j, aspect j has three kinds of advices. An advice can run before a function call, an advice can run after a function call or an advice can run instead of a function call. Which means is if you have an advice which is called around advice that will run instead of your function foo. We will be using around advice. So if you see this advice is running around your function foo o which was the original function. So before you call your original function we will first log the input parameters then call your function and then log the return value. So this logging can be used to diagnose issues. I will tell you how. Say you press a button, something happens on your screen and then the whole rendering, as the whole rendering stops in between this rendering you figured out that there is some problem somewhere and you have no clue how to reproduce it. So on the press of a button you can start the logging. In our case what we are doing is we are logging the input parameters and output parameters of all the functions. So this is what we are trying to do. So when you switch on this kind of logging this will give you this state of each method and the flow it took. The flow it took from the press of a button till the rendering stops. Essentially the functions that you have most of the time these functions are stateless. If you log the input parameters and log the return value there is a huge chance that you will be able to figure out which function started behaving badly. We will use something similar to put in a try catch around the function. If you remember as I said we are using around advice so you are free to call your original method as and when you need and we can also choose not to call it for switching off the call completely. So this is how the final advice will look like. You have config coming from the server then you have the big advice which has one portion of code which does logging for you. There is another portion of code which has a try catch then there is a portion of code which disables a function and all these portions are controlled by configs which are coming from the server. This could be a sample configuration which you can think of you have given. So this essentially has to come from the server and it will have the name of the class the name of the method, action and the data. So let me go to the code, piece of code that we have written. So if you essentially see the first line is the point cut. Let me go deeper into this. It's the expression as I said this will let you control which which function on which function should this advice run. So in this expression, if you see there is execution and then there's a star. This star tells you whether you want to apply this point cut for public or private. The next is the package name and the star after that tells you all the classes inside the package should be weaved and then the other dots inside the parenthesis which say that any kind of parameter is acceptable. Then on the fourth line, you can see the around. This is the advice that I was talking about. This is the function which aspect gives you. You can write this function and the control will fall inside this function. So if you see this, there is a class called preceding joint point. So aspect J while running this joint point will give you all the data inside this object from this object. You can figure out on which function this point cut this advice has got applied. So if you see, I'm trying to get the name of the class, the name of the method. And then towards the end, these snippets tell you how to these snippets are the examples of how would you call the real function. I told you about the function called for original in the case of aspect J that get that that function gets called through joint point or proceed. So once I figured out what's the name of the class and what's the name of the function, I'll write my code, which will, which would be the last two snippets. They will go inside and the code will work based on the action that I have specified in the configuration. So if I go back to the configuration, I'll get through the configuration. I'll pass on the name of the class and the name of the function and of course the action. So if you see here, the action would be logging action would be try catch action could be disable the function. One of the other actions, which I'll be talking about today would be change in input parameters and change in return value. Why do we need this? So I promised you in the beginning that we'll also be fixing logical issues. So crashes can be handled, but most of the times the issues inside your code are because of the bad input and output parameters. So functions ideally have to be stateless and the inputs which you get inside the function is what defines what will how the function will run. In a lot of cases, if you just fix the input to that function, your issue will get fixed. So we'll try to do that as well. So let me give you a demo. Okay. So this is the screen of my handset. I'll just bring it towards the right. Fine. So I've taken an open source code of an app called open Sudoku. It's a normal app. It's available over GitHub. What I've tried to do, I've introduced a few crashes inside this code. I'll start playing. Oops, it crashed. Let me play it a little longer. No, it's crashed. So it's randomly crashing. There's no way for me to figure out what went wrong. I'll show you the stack trace which gets printed. Let me play it again so that you can see the graph. Okay. So the stack trace gives me the name of the function. The name of the function, but even if you go to the name of the function, there could be certain scenarios in which you'll not be able to figure out what's going wrong. It would be really good if I could have added some logs, but then your app is running. And of course you won't be leaving logs in the production app. So it would be really, it, it would have been really helpful. But of course I didn't write the logs. I tell you how to write logs in the live app. So I've written a simple logger. The logger should be logging the issue and sending it to you over your server. Just for simplicity, I'm not sending it to any server. I'll just be printing those logs on my console. These are mind you have already told this log is something which has, which was never there. And I'll be logging this whole thing from the config coming from the server. So this is just a file which I'll be pulling from which I've put on my draw box. I'll be pulling it from there. Let's go to the console. Let me exit the full screen mode. So now you can see both the things. What I'll do is I'll just give the app. I'm fetching the data as in when I restart the app. Cool. If you see, you have got the data. Now let me start playing. So if you guys notice, there are certain, certain logs which are getting printed now. So I'm not built the app. The app has already always been there. This is a live app. And if you see, I press here, oops, it crashed. So these logs can help me figure out what went wrong. Oh, sorry. I kind of removed them again. So essentially what happened is the way I'm printing these logs, see this is the log which got printed when the app crashed. So through the logs, I can figure out that there is a value called four. If I press on something, if I press on the box, which has a value called four, or if I'm putting something, sorry, if I'm putting a value of four inside any of the boxes, it will crash. So these are the logs which were never there. I printed those logs on the live app through this tool. Fine. You have the logs. You have kind of figured out what the issue is. Now how do you fix it? So they could be certain scenarios in which just by adding a tri-catch, your app will start working. In this case, I was trying to put an Easter egg inside my Sudoku app. So Easter egg is something which is a goodie kind of thing inside any game, which will spring up something. I was trying to put a special feature which I don't need. It was a goodie. But if it doesn't work, it's fine for me as long as my original functionality works. So what I'll do is I'll just apply a tri-catch. Let the line beyond the line which is crashing not run. So I'm fine with that. So I'll just apply a tri-catch and I'll show you how this gets fixed. So again, this is my configuration. If you see the first line is not visible. So it's visible from back there. It's not. Okay. So I'll read it out. So the first line gives you the name of the class. The second line is the name of the function. The third line is the action. So the first piece of code which I wrote earlier was for the logging. The action is log over there. In the second case, the first line is the name of the class. Second line is the name of the function. Since it's not visible, the name of the function in the second case is called Easter Egg. This was a function which is crashing. I could have shown you the stack trace, but yeah. So this is something which I figured out from the stack trace. There's a function called Easter Egg which is crashing and I'll be applying a tri-catch over it. Cool. So I'll just restart my app. Let me kill it. I forgot to save. Cool. I've got... I'm printing the logs for the result which I'm getting from the server. This says that I've got a patch which is of the type tri-catch. This is the function on which it has to get applied. Let's play again. This time I'll directly start playing with four. See, it's working. The patch got applied. Now it's not crashing at four. So what it means is like we have fixed the most dreaded enemy that a developer has. It's the crash. The app is not crashing now. The users would be happy, you would be happy. So this was the first thing, logging. Second thing is the crash. Now let's do a bit... Let's take it a bit forward. I'll show you how to fix the logical issue. So if you have played the game of Sudoku, what it says is you are not allowed to enter numbers of the same type as in a smaller box or in the same row. So if you see on the left, on the left bottom, there are four has been entered thrice. So the developer forgot to give a different color to it. Ideally if you're playing or if you're playing in an easy mode, you should get notified that this four will not work at all. This is a logical issue that you've put in. So there's a function inside my code that gives me the color. There's a function called get invalid cell color. I'll show you in the code as well. So this function, if you see, is returning a color called white. It should ideally be returning a color called red. If it does that, we are cool. So through this patch, I'll show you how you can change the return value of a function in a live app at runtime. So again, this is my patch. The first line for those who couldn't see it. Of course, it's not visible from back there. So the first line is the name of the class, which is all dot more dot open Sudoku, GUI dot Sudoku bold view in the function function is get invalid cell color. The action is set return value. And of course, the data that you have to pass is red. I'll show you how it works. Let me restart the app. The color has changed. Fine. So we have done three things. We have done the logging. We have fixed a crash. We have a logical issue. Any customers would be happy. Now let me show you the code which I wrote for all this. The game code never got modified all this while. This is the class called trace aspect. This is the function which I was talking about. We've joined point. There's a library called aspect J that you have to put in inside your gradle. And whenever it gets compiled, it looks for this kind of this. It looks for a class which has the point cut and the weaving. As I showed you, this is the object will join point which comes in. In the advice through this joint point, you can get the name of the class. You can get the name of the function. This is the action. These are the actions that I was talking about. So what I've done is when I make a network call, I get the configuration. I get a load the configuration in a hash map called class method map through this hash map. I get all the data. And when the advice is being run, I just check whether this function needs any advice to be done. If there is no advice, I don't do anything. If there is an advice, I run it. These are the advices that I have. It's called log. If the first advice is log, which we did in the beginning. If the advice is log, I start a stopwatch. I end the stopwatch and do the logging. If the action is set return value, I run the actual function. See, this is how the actual function is run in aspect 8. It's called joint point. I let it run. I throw off the return value of the original function and I use the return value which I've got from the server. Similarly, what you can do is I have written the code for try and catch. Then you can call. There's an action called call self. There could be an action which says do nothing. So if I don't get any of these actions, I don't do anything. In that case, you just have to tell me what a return value should be because someone else who's calling this function is expecting a return value out of it. So if there is no action, the function will not be called at all beyond that is pretty simple piece of code which just makes a network call and some classes for logging. Cool. So this is what the demo was about. So we have improved this a lot in Hansel. We have kind of made it a lot faster with a lot of features. We let you change a lot of things which I can't talk from me. Now we can take it after the discussion. So this code is present in the GitHub repo have kind of made it available. Please go through the code, use the code which I have written or go to Hansel.io register yourself for a better tool. Thank you. When you showed that we are planning a solution to a problem, won't that be a temporary solution for us because the actual code is not getting changed, right? Yeah, so this code will run every time your original code runs. So it's not a temporary solution. All this, all that has gone to the app, you can use some kind of caching or persistence to it and save it. And as in when the app loads, the whole thing will get applied again. No, my question is when you are changing the color of the test, okay, in the code, it is written as white. Yes. By applying some patch, you are changing it to red. Yes. Okay, but that is not permanently getting changed. Yes. Okay, so the developer needs to, that is a temporary solution. That's what I'm saying. The developer needs to go to the code back and then they handle the condition, right? So he has forgot to mention that if there are multiple numbers present in the same row, then the developer needs to set that color back to red. Okay, that condition is missed by developer. Okay, so this developer has to do this as in when you have your next release. So you don't have to do anything for this release from the next release. If you want, you can, you should ideally be setting your code, right? So that whenever the next thing gets shipped, you don't need to apply a hard match. But for this release, you're all set. Whatever you have will always run as red from now on. Yes, but that can be a risk for like production deployment because if in case this is the temporary solution, which we have applied to currently, and if developer forgets to include that in the code. Okay. And if again the client might face the same issue. So yeah, if you forget, that's what the solution is for. You have already forgotten it once. You should ideally not be forgetting it the next time. But if you forget again, this tool is there for you. You can apply another patch for this. Hi. So aspect j uses reflection, right? I saw some code when where it was dealing with class names and types. Oh, this code was this code was to get the name of the class and names of function. Okay. So aspect j does a lot of things. If you go through the code of aspect j, it hardcodes the name of the class over there. So the reflection reflection is not used to get the name of the class. Okay. So my main concern is since we are fetching configuration and that configuration could contain any possible class in my code. So basically we are the will have to inject aspect in every class of my code. Yes. So that we can work with this configuration. Yes. So won't that affect some performance? Yeah, of course. So the way I've told that we have shown the performance impact is around five milliseconds for 100 calls, which is not a bad thing for a normal app. But if you have an extensive app, it changes a lot. I've been wearing the UI changes a lot. Then of course you'll start seeing the performance drag. I'm using a really. So this whole demo was on a device called Redmi. It's not a high end device. And I don't think you could have seen any change in the performance. Okay. This was really fluid. But yes, come to Hansel. It has. So we have improved the performance of aspect j every in our own library. We have made it 100 times better than aspect j. Is your product pro guard ready? Yes, it is. It is pro guard ready. Can you explain with some situation? I'm not allowed to speak about it here. We'll take it offline. Can we inject any Java codes based on the JSON file? You can only enable or disable your features. You can. You can. But can we inject some Java code? Yes. So there are two things to it. When you say code injection, it's not allowed. Android doesn't allow you. But then as long as this code already exists, it's all out. So if you are somehow sending a dot, sorry, a compiled code from the server, Android will ban you. If you are sending something which already exists, you're good to go. Thank you for the awesome session. I want you to ask, you are there, right? So you have already inserted some code. Yes. And also, so first you have changed the code. As you are saying that you cannot insert the code, but you have inserted tri-cat. Second thing, if you have inserted a tri-cat, the line number would change. And again, if I get a crash on some next line or somewhere, the line number will be mismatched and the crash log that I see, that won't be for that line. Not exactly. So what happens is, I'll show you the line the way it works. And I'll show you directly in the code. So if you see this, joinpoint.proceed, this actually calls your function. So when the crash happens, the crash will still give you the final line. Though you see this class and this function inside somewhere in the stack place, but the final crash will happen in your actual function. So the stack place will definitely lead you to the final value, final function. Hey, I'm kind of a beginner in terms of Android. So to basically put, I mean, as far as, like, this hotfix and kind of things, like, I'm just trying to understand, just correct me if I'm wrong. Is it something like you have some Boolean values for every step and you send those configuration files from the server and if you want to stop something, you send faults for the particular step and that won't get executed. Is it something like that? Yeah, this is, in the example, yes. This was exactly the thing that we showed, yes. So you have a lot of advices already written. Now you switch them on or off based on what you're getting from the server. What you're getting from the server is the name of the class and the name of the function and the action. If the action says open it up, you open only that piece of code. Thank you. But then there is a lot which you can do. This is a really small sample. Thank you guys.