Welcome to part 2 of the lecture on machine independent optimizations, today we will continue our discussion on data flow analysis. So, we covered illustrations of code optimizations in the last part, to do a bit of recap a data flow value for a program point represents an abstraction of the set of all possible program states that can be observed for that point. So, the issue is when the program is executing at every point in the program there may be several possible program states and when we do a data flow analysis we are statically examining the program. So, we compute an abstraction of this set. So, that is an approximation of this set in other words it is possible that this approximation includes certain program states which can never be reached at that point in an actual execution, but because of our static analysis this extra information will be included in the abstraction. The second important point is the set of all that the set of all possible data flow values is the domain of for the application under consideration. So, for each one of the applications this domain is going to be different for the reaching definitions for example, it would be sets of all subsets of definitions and for the available expressions it would be the sets of all subsets of expressions for the live variables problem it would be the sets of all sets of all subsets of variables etcetera. We also have two quantities in and out. So, these are the data flow values before and after each statement yes and as I mentioned we are going to be interested in a larger grain size that is a basic block rather than just a single statement. The data flow problem is to find a solution to a set of constraints on in and as sets. So, what kind of constraints can we provide? We provide two types of constraints the constraints based on the semantics of statements are called transfer functions and the constraints based on the flow of control are also going to be provided that is if there is a join of different paths in a program then what do we do about the computation of in and out that is going to be the question to be answered. So, a data flow schema consists of five components one is the control flow graph itself then a direction of data flow forward or backward has to be indicated a set of data flow values is to be provided a confluence operator usually set union or set intersection should be given and the transfer functions for each basic block as I said instead of statement we are going to provide the transfer functions for each basic block will also be provided. When we compute the estimates of data flow values that is the approximations or abstractions of data flow values we want to make sure that these estimates are safe. So, again safety is with respect to a particular application. So, in our case we want to perform several optimizations. So, safety is with respect to these optimizations. So, an estimate is safe or conservative if it never leads to a change in what the program computes after the change is carried out in the program by a transformation. So, in other words if we perform an optimization then the optimized program should provide the same output as the unoptimized version. So, that is precisely what we mean by safety. So, in doing the optimization we would have used a lot of data flow information. So, and we would have made decisions on transformations using that data flow information. So, this type of a decision is said to be safe if there is no change in what the program computes. So, this will become clear as we go on and take up more examples. These safe values may be either subsets or supersets of actual values based on the application. So, to get into the problem of reaching definition analysis. So, we need to define two quantities one is what we mean by generation of a definition and what we mean by killing a definition. So, we kill a definition of a variable a if between two points along the path there is an assignment to a. So, let us take up this example. So, here we have a equal to b plus c and later in the program in the same you know program we have another definition a equal to k minus m. Obviously, a equal to k minus m and a equal to b plus c are both definitions of a and you know it is possible suppose these two are in the same basic block. So, in such a case it is never possible for a equal to b plus c that is the value of a computed by this particular definition to be available after the definition a equal to k minus m. This kind of overtakes the previous definition. So, in such a case we say that this definition kills this particular definition. Now, what is the definition of reach ability what is a reaching definition. A definition d reaches a point p if there is a path from the point immediately following d to p such that d is not killed along that particular path. So, if there are there may be many paths from d to p, but we are only considering existence of just one path. So, if there is more than one path it does not add to reach ability, but if there is no path then the definition is not reachable. So, from d we must be able to go to point p by a particular path that is all it really means. So, if there is a path then the definition reaches the point p. So, remember again more than one path for the same definition does not add to reach ability, but if there is no path from the definition to point p then the definition is not reachable. We must also distinguish between unambiguous and ambiguous definitions of a variable a equal to b plus c let all the three a b and c three entities b names. So, in such a case this is called as an unambiguous definition, because we are explicitly defining the variable a. Later in the point of in the in the program at some point we have a definition such as star p equal to d this is called ambiguous definition of a. The reason being p may point to many variables it may point to p, it may point to b, it may point to x. Therefore, we cannot you know concretely say that p is defining a particular variable of course, if we already know that p points only to x then we can say p this statement defines a is a definition for x, but in general during static analysis we can only determine that p points to a couple of variables we can hardly say p points to exactly a particular variable it. So, if this is so this is called ambiguous definition and because it does not definitely define a particular variable we cannot say that an ambiguous definition kills the previous definition.  So, this kills this unambiguous definition again this ambiguous definition you know may not kill this definition ambiguous definition, because p may never point to a. So, in that case this is not a definition of a at all. So, we do not want to kill such definitions either, then in the reaching definitions problem we as compute supersets of definitions as conservative or a safe values. So, as I said you know we want to compute safe estimates. So, in this case a safe estimate would be a superset what does it mean to compute a superset. So, it says it is safe to assume that a definition reaches a point even if it does not. So, this is what happens if we include more definitions into the set of reaching definitions than the definitions that actually reach. So, there may be some definitions which do not, but it is ok to include them this is our definition of you know safety here. So, for example, the let us say we have if a equal to b then a equal to 2 else if a equal to b then a equal to 4. So, let us analyze what happens during execution. During execution we compare if a equal to b then you know if it was true then we would have taken a equal to 2 and exited suppose a equal to b was false we would have taken the else part and we are comparing a equal to b again. That means if it was false here it has to be false here as well because we have not assigned anything to either a or b. So, this statement will never be executed. So, at this point during actual execution a equal to 4 will never this definition of a will never reach this point during actual execution, but because we know that you know by this execution path we will never take this particular branch, but static analysis does not know that. So, in static analysis we are going to assume that both a equal to 2 and a equal to 4 will reach the point after this semicolon. So, this is the conservative estimate. So, we know that during actual execution a equal to 4 will never reach this point, but because of our static analysis we have no idea that a and b we do not take the value of a equal to b here and then use it here as well we do not do that in static analysis. So, we will have to assume that both a equal to 2 and a equal to 4 will reach this particular point after the semicolon. So, this is an example of you know a super set that is being computed. So, here I present the data flow equations or constraints as they are called and I am going to explain these equations in great detail in the coming slides. The first constraint or the equation says in of a basic block that is the set of definitions reaching the entry point of a basic block that is what in b is will be a union of the out sets of all its predecessor blocks. So, p is a predecessor. So, this is what this says I will explain this very soon out b the set of definitions reaching the exit point of a basic block that is what out b is will be gen b the set of definitions generated by the basic block union in b minus kill b.  So, remove from in b the set kill b and that will also be coming out of the basic block and in b is initialized to phi for all basic blocks. So, these are the constraints these are the equations. So, in these equations gen and kill are constraints. They will be computed only once and then they will not be modified again and let me go ahead with the definition of gen and kill before I explain these equations. So, if some definitions reach b 1 then in of b 1 is initialized to that particular set instead of phi. This is a forward flow problem the nature of the flow is obtained using the equation for out. So, if the equation for out is in terms of in then this is called as a forward flow problem. If the equation what turned out to be an equation for in in terms of out then it would become a backward flow problem. The direction of flow of the data flow values does not imply that we traverse the blocks in a particular order to compute the sets no any order is fine with us and the final result does not depend on the order of traversal of the basic blocks either. I have still not told you how to compute this how to compute the values for in and out typically once we compute gen and kill we compute in and out values in a loop you know we compute them again and again making sure that we reach what is known as a fixed point. So, at the fixed point you know after we cross the fixed point the values of in and out do not change again for any basic block. So, for the reaching definitions problem the fixed point is guaranteed to be reached in a couple of iterations. So, otherwise formally it is necessary for a new data flow analysis problem will have to formally prove that this sort of a thing fixed point can indeed be reached, but this is not a part of our course. So, we are not going to discuss the theory of data flow analysis in this course. So, again just repeating that so we compute in and out sets again and again until a fixed point is reached. So, let me define gen and kill before I go on to the explanation of the two data flow equations. Gen b is the set of definitions inside the basic block that are visible immediately after the block they are called as the downwards exposed definitions. So, let me explain that suppose a variable x has only one definition in the block then obviously the definition will be downwards exposed used you know at exposed and it will be visible immediately after the block, but suppose the variable x has two or more definitions in the block then only the last definition of x is downwards exposed and others are not visible outside the block. So, this is what is important we actually take the last definition of the variable. So, we can even compute gen b by doing a traversal from the end of the basic block to the beginning of the basic block no problem with that.  So, in other words if a variable x has a definition d i in a basic block then d i kills all the definitions of the variable x in the whole program except of course, d i my picture in the next slide will explain this in a better fashion.  The basic block has five you know four definitions d 1, d 2, d 3 and d 4.  So, the set of all definitions in the program would be d 1 to d 10 right. So, four here and the next six in the other blocks. So, this is our universal set of all the definitions to compute gen so, let us look at the various definitions d 2 and d 3 compute b and c they are the only definitions of b and c in the basic block. So, d 2 and d 3 will be definitely included in the gen set they are generated by the basic block. Now, d 1 is a definition of a d 4 is also a definition of a, but as is very obvious this definition the value here will not be visible after the redefinition of a, this is you know just ordinary program sense. So, it is d 4 which will be visible outside the basic block at this point and not d 1. So, we include only d 4 in the set of generated definitions of the basic block b, what about the kill set.  So, what we need to do is consider each definition in the basic block then consider all the definitions of the variable a in the entire program. So, we have we have a definition you know which is d 4 here which is the definition of a, we also have the definition d 9 which is also a definition of a. So, our definition of kill says take d 1 then it kills both d 4 and d 9. So, we include d 4 and d 9 in the kill set then d 2 defines b. So, it kills d 5 in the other basic block. So, d 5 gets included in the kill set then we have d 3 which defines c. So, it kills d 10 which is also included in the kill set now we come to d 4 which is a definition of a. So, it kills not d 1 and d 9 d 9 has already been included in the set. So, only d 1 gets included in the kill set. Why are we you know computing the kill set in this fashion even though we do not consider whether there is a control flow from this basic block to any other basic block which defines that variable or not. The answer is simple we are computing gen and kill before the reaching definitions problem is solved. To compute the exact kill set in fact to check whether there is a flow from one basic block to another and so on and so forth. We may end up solving the reaching definitions problem or a variant of it before we compute the exact kill set that is the one first reason why we have such a big set of definitions for the kill. The second reason is even if we include many definitions which are not relevant to the basic block b in the kill set it is not going to actually affect our computation of in and out.  So, I hope this clarifies the computation of gen and kill. Now, let us move on to the data flow equations. So, we have two equations here one is the in set of the basic block b is the union of the out sets of the basic block predecessors of b. So, this is the meaning we want to compute the in set of the basic block b 4 there are three predecessors to this basic block b 4 b 1 b 2 and b 3. So, there are three sets here out b 1 out b 2 and out b 3. So, in of b 4 will be the union of out b 1 out b 2 and out b 3. This is actually quite intuitive the reason is you know suppose we consider the set of definitions reaching this point that is out of b 1 from here to here there is nothing to stop the definitions from reaching right. So, all the definitions which reach this point will take this edge and reach this point as well. So, all the definitions of out b 1 should be included in the in b 4 set the same is true for out b 2 and out b 3 as well. So, this is the intuitive reason why we take a union here the other reason you know the actually what happens is the reaching definitions problem we are not really worried about the definition reaching along all paths. We are interested in knowing whether the definition reaches along at least one path. So, it may reach along this path or this path or this path. So, reaching along any one of the paths is fine for us in fact if it reaches along this path and does not reach along these two paths we are still happy there that is the reason why we want to take the union of all the definitions which reach this particular basic block. Then what about the computation of out of b is computed as gen b union in b minus kill b let me explain why this is. So, we have the same basic block b 4 there is a set in b 4 which is already computed let us say using this equation. Now, the set gen and kill has already been computed we want to compute the out set. So, here are some values given for in and gen kill. So, let us say the set in b 4 is p q z the gen set is a comma b and the kill set is z. We need to you know take the gen values and put them in the out set that is very clear because whatever is computed within the basic block b 4. Obviously, by definition reaches the end of the basic block and that will be in the out set. So, that is the explanation for including gen of b 4 in the out set the second is the in part. There are lots of definitions reaching this point right the in part and a few of them get destroyed because of the kill set why there are definitions which are coming in then some of these variables will be you know redefined here. So, the definitions corresponding to those variables in the inset will all be will have to be removed. So, that is why recall the definition of kill if z is defined here then it is z kill that definition kills all the definitions corresponding to z right. So, I have not named the definitions here let us assume that these are the variables just for the sake of example really speaking I should have given the definitions numbers corresponding to these variables, but it helps if we actually keep the variables for the sake of under here. So, let us assume that there is one definition corresponding to z here you know another definition corresponding to this z another definition corresponding to a one more corresponding to b etcetera. So, the out set now will contain the definitions corresponding to a and b of course, it will also contain the definitions corresponding to p and q because they are not killed and the definitions corresponding to z will all be removed from the inset and that is the reason why this has only a b p and q. So, this is how we compute the outset in terms of gen and kill gen kill and in. So, remember if the kill set contains certain you know definitions then they will be removed from the inset that is what this really means. So, we have removed the definitions of z from here we have included the definitions of p and q only the definitions of a and b only. So, the outset will contain a b p and q. So, that is what this equation says include the definitions of gen take away the kill set from in and include it in the outset of b 4. Let us take a big example and this has been adopted from the book by Aho Seti Indulman. So, the first thing to do is to compute the gen and kill sets and then make initializations appropriately.  So, computing gen here we would include d 1 d 2 d 3 in the gen set that is very obvious because they are all visible here and kill set of b 1 you know if you consider the definition d 1 it kills all the definitions with i. So, it kills d 4 right and then it kills d 7 as well. So, d 4 and d 7 are included in the kill set. The second definition d 2 corresponds to with a variable j. So, it kills the definition d 5. So, that is also included in the kill set. The third definition corresponds to variable a. So, it kills the definition d 6 involving a. So, that is also included in the kill set. So, this is the computation of gen and kill. Initialization in of b 1 is made phi and in fact in the practical implementation we can say that out b will be initialized to gen because of this equation right. So, ignore this part we will still include a minimum of gen b in any out computation. So, we can initialize out b to the gen set d 1 d 2 d 3 in this case. Coming to b 2 this is a bit tricky gen is easy.  So, there is d 1 here then you know we have d 7. So, and then corresponding to j we have d 2. So, all the 3 are included in the kill set and then the in set is phi and the out set is initialized to d 4 d 5. So, you must observe here that the value of i which is used on the right hand side of this assignment actually arrives from the value i here you know the old value i here or the value here. This is a new value which is computed and the same is true for j this j arrives from this particular value and then of course, after it is computed it will also arrive via the loop. The third basic block gen is just d 6 and kill corresponds to the definition of a which is d 3 in will be phi and out will be d 6. Gen of b 4 is d 7 and kill of b 4. So, we look at the definition of i. So, that would be d 4 and then we also have d 1. So, these are the two definitions which are killed. So, it is very probably very clear that you know d 1 will never reach this particular point here you know it never reaches here. The reason is it is redefined already at this point. So, we must compulsorily take this path. So, only d 4 will perhaps reach this point it will d 1 will never reach this point. So, this is not a relevant definition as far as the kill set is concerned, but as I said since we cannot compute exact kill sets without solving the reaching definitions or similar problem we take a superset and it is not going to matter to us. So, now pass two. So, this was the old value of in and out gen and kill down change old values of in and out are here. These are the new values what does the new value require the equations are here. So, the in set is a union of the out sets of the predecessors. So, in this case there is nothing coming from here. So, in b will always remain 5 always. What about out b you have to include a part of you know one part is corresponding to gen which is already included that is d 1 d 2 d 3 and the in set corresponding to this is 5. So, there is nothing to take away and this is the old value of in b right it is 5 and therefore, we still have d 1 d 2 d 3 as the out set here. So, so far from here to here there is no change, but once we consider b 2 we see changes these are the old values of in and out. So, when we compute the new value of in for this particular basic block b 2 we take the union of the two out sets coming from b 1 and another coming from b 4. So, the out set of b 1 here. So, that would be d 2 d 1 d 2 d 3 and the out set of b 4 is d 7 and therefore, the in set of b 2 would be d 1 d 2 d 3 d 7 it is the union of the two. So, remember the old value as 5 and the new value is different even though there was no change of anything here there has been a change here. So, what about the out value of b 2 obviously, as usual the gen value d 4 d 5 gets included in the out set of out set then we take the in value and remove the kill value.  So, only d 3 remains and that gets included into b 2.  Then the basic block b 3 again the in value is 5 out value is d 6 whereas, here the in value will be the new out value of b 2 the new out value of b 2 is d 3 d 4 d 5. So, the new in value of b 3 will become d 3 d 4 d 5 it is different from in the out value of course, is the gen value first that is included that is d 5 and then. So, that is d 6 sorry that is d 6 which is included and then we take the in value d 3 d 4 d 5 and remove the kill that is d 3. So, d 4 and d 5 will also be included in out.  So, that is what out b 3 signifies. So, what comes out here is this definition and these two definitions which are coming out the last one is b 4. So, if you consider b 4 in of course, was 5 as usual now the in value of b 4 is the union of the two outsets one coming along this direction and other coming along this direction out of b 3 is d 4 d 5 d 6 and the out of b 2 is d 3 d 4 d 5. So, we get d 3 in of in will be d 3 d 4 d 5 d 6 the union of the two. What about the outset it includes d 7 because it is gen and then we take in and remove the kill part.  So, we include d 3 d 5 d 6 and d 7 as the outset. So, these are the four new values that have been computed for b 1 b 2 b 3 b 4 and in doing. So, we have actually is looked at the basic blocks in a particular order b 1 b 2 then b 3 and b 4. Actually we could have looked at the basic blocks in the reverse order also b 4 b 3 b 2 and b 1. Since we are going to iterate through the basic blocks in the control flow graph a number of times and make sure that none of the values of the in and outsets of any basic block you know remain the same. The order in which we visit the basic blocks is immaterial, but it so happens that you know the even though the values do not change values do not depend on the order of traversal of the control flow graph. The number of iterations required will definitely change depending on the order in which we visit them. The heuristic one of the heuristics which is used is to use a depth first search order we will discuss this a little later. So, assuming that we use a depth first search order the iterations converge to the fixed point value very quickly. So, this is the final result I would encourage you to verify it you know look at the this block this set of result and then apply the same data flow equations once more and then get these values. And after this values are reached any number of iterations further will not give you any changes will not provide any changes. So, these are the fixed point values and these happen to be the reaching depressions for the various basic blocks. So, let us just take a look at them out b 1 is d 1 d 2 d 3 which is very clear. So, all these depressions reach this point out b 2 is d 2 d 3 d 4 d 5 d 6 d 4 d 5 are very clear then d 3 is also very clear it comes out of this right. And then d 6 is some value which is defined here it goes through the loop and then comes back again. So, there are two definitions of a one here and one here neither overtakes or overrides the other one in the first iteration this is relevant and then onwards in some of the iterations if this path is taken then this a becomes relevant. So, both the definitions of a reach this point then out b 3 here for the basic block with is d 4 d 5 d 6. So, d 6 is very clear d 4 d 5 also come out then finally, out b 4 is d 3 d 5 d 6 d 7. So, d 7 is very clear d 6 is very clear d 4 d 5 you know d 4 does not reach because i is redefined here, but d 5 definitely reaches the end of the basic block here. So, this is how the definitions reach the end of the basic block. So, remember even though we have no idea of the execution path you know we take the definitions which column along all paths take a union and then say that these are the definitions which reach this particular point. So, this is a conservative estimate because at execution time exactly one path will be taken whereas, during static analysis time we are going to consider all the paths. So, now it is time to look at the algorithm in a program like fashion the algorithm is quite simple this is as I said an iterative algorithm. The first of all initialization for each block b do in b equal to 5 and out b equal to gen b. So, that completes the initialization then to detect whether there has been a change in the computation of values we use a flag change equal to true initially and then we loop while change do. So, set change to false and then for each of the basic blocks apply the data flow equations in b equal to something computed then store the old value of out and recompute the new value of out. So, if out has changed then you know change is if out b not equal to old out that means, out has changed then we reset change to true again and then loop once more. So, we keep doing this until none of the out values change the reason why we are checking only the out and not the in is out is dependent on in. So, if there is a change in in it will automatically be reflected in the change in out. If we had reverse these two equations out first and then in then we would have checked in here instead of and store old in instead of old out. So, of course, there is nothing wrong in storing both old in and old out and checking them, but that is not really necessary. Now, we still have to look at the data structures which are necessary to store the various data flow values. So, this iteration will go on until there is no change and once there is no change we quit. So, we actually use bit vectors for the with one bit for each definition in the program. Let me show you an example. So, here the there are actually only seven definitions in the whole program in the control flow graph. So, a bit vector of size seven with one bit for each is sufficient to store all the definitions. So, the first bit always stores the corresponds to d 1 second bit corresponds to d 2 etcetera etcetera. So, the position of the bit itself gives you the definition number. So, all over sets gen kill in and out will also be seven bit vectors bit vectors. So, for example, the set gen b 1 actually has d 1 d 2 d 3. So, it has once in the three places one d 1 d 2 d 3 and the rest of them as zero. The kill set has you know d 1 d 2 d 3 as zero and d 4 d 5 d 6 d 7 as once then in b was initialized to phi. So, this is and remains phi as I said. So, these are all zeros and the out b 1 value d 1 d 2 d 3 is represented here. So, this is how the. So, this is how the data flow values are stored as bit vectors. The same is true for this basic block this basic block and also this last basic block. The data flow analysis problem that we are going to deal with is called as the available expressions computation. So, here this problem becomes a very important problem to perform the global common sub expression elimination optimization. The sets of expressions constitute the domain of data flow values here. In the reaching definitions problem it was the set of definitions. Here we are going to look at the sets of expressions and they constitute the domain of data flow values. This is a forward flow problem and the confluence operator is intersection. By the way the confluence operator in the reaching definitions problem was the union operator. So, let me show you this is here. So, we have an equation for out in terms of in. So, as I said this determines the direction of the data flow and we have the confluence operator which is union here. Whenever we combine the values at a joint point in the control flow graph we must use the confluence operator. So, in the available expression computation problem it is a forward flow with a confluence operator as intersection. In the previous case it was union here it is intersection. This will become clear very soon. Now, the schema for the data flow analysis requires the equations. We will provide the equations very soon and it also requires gen and kiln sets. But, before that let us define what exactly is availability of an expression. An expression x plus y is said to be available at a point p if every path not necessarily cycle free. So, we could go in cycles. But, what is important is the path must begin from the initial node of the control flow graph. So, from the initial node to p. So, we must consider every path here. In the reaching definitions case we considered any path here we must consider every path from the initial node to p and it must evaluate the expression x plus y. So, and after the last such evaluation prior to reaching p there are no subsequent assignments to either x or y. The important point here is there must be you know a computation of x plus y from the initial node to p along every path that is number 1 and the other important point is after the last such computation modifications to expand by x or y should not happen. If you modify either x or y or both then the value of x plus y changes. So, therefore, changes to x first x or y or both should not happen after the last computation of x plus y otherwise the value of x plus y would have really changed. Then so this is availability in most important it must be along all paths and after the last computation of x plus y no changes to either x or y. What do we mean by killing an expression here? So, a block kills x plus y if it assigns or may assign to either x or y or both and it does not subsequently recompute x plus y. So, the point is we have a computation of x plus y then we have redefined x let us say if we recompute x plus y then the block does not kill x plus y, but if it simply modifies x and then does not recompute x plus y then it kills x plus y. So, let me show you an example here here is 4 star i a computation here is another 4 star i another computation and here there are two possibilities one possibility is to go along you know it is not that both the blocks are present at the same time I have just written the second block as an alternative in dotted lines. So, either this block is present or this block is present. So, if there is no assignment to i obviously 4 star i will not get changed along this path at all. So, we can say it is available along this path and also this path. So, it is available along all paths at this point and suppose we redefine i. So, we have defined 4 star i computed 4 star i here now we have redefined i here, but then we also computed 4 star i again. So, in this case also 4 star i is available along this path we have because we have recomputed 4 star i 4 star i is available along this path 4 star i is available along this path also. Remember we are not considering looking at the exact value of 4 star i here. So, what we are saying is whether we use 4 star i along this path or this path we do not have to recomputed it here that is all we are trying to say during the common sub expression elimination we want to avoid computation of 4 star i here either by reusing this value or this value it really does not matter, but suppose there was no recomputation of 4 star i here right it was just a modification of i then this value 4 star this expression 4 star i is not available along this path. So, we say 4 star i is not available at this point what about the generation of x plus y a block generates x plus y if it definitely evaluates x plus y and does not subsequently redefine either x or y or both. So, this is very simple we just compute x plus y and then do not modify either x or y.  So, let us assume that the equations you know the statements are of the form x equal to y plus z we are trying to compute it for each one of the statements in the basic block. So, this must be done one statement at a time and then the effect of the entire basic block will be felt at the end for the point q let us assume that the e gen is given. Obviously, at the beginning of the basic block this will be empty. So, let the e gen for this point q be a now we have this statement x equal to y plus z. So, what do we do we act now y plus z gets computed. So, it is actually generated by this statement. So, we do a equal to a union y plus z then x is being redefined here. So, all the you know expressions involving x will have to be removed from a. So, we that is the killing part. So, a equal to a minus all expressions involving x at this point therefore, e gen p is the new value of a. So, this is how we compute e gen p and now if there is another statement after this you know the effect of that statement will be computed exactly like this because e gen p is now available.  So, let us say that is a now x equal to y plus z is the statement for which we have to compute the effect. So, now you know y plus z is being computed here. So, it is not killed it must be removed from kill even if it was killed before now it is just being recomputed. So, we must remove it from kill now x is being redefined here. So, x kills all the expressions involving x. So, they will all be added to a. So, this is the complement of what we did here. So, a equal to a union all expressions involving x and at this point e kill of p will be the new value of a. So, this is how we actually compute the gen and kill for each of the statements in the basic block they are all combined together and used. So, the set of all expressions appearing on as the right hand side assignments in the flow graph is assumed to be available. So, we must. So, this is our universal set of all the expressions right, but then you know what do you do with these we have used a bit vector representation for the reaching definitions and using bit vectors the union and intersection operations are all trivial right. In the case of expressions we cannot directly use a bit vector what we do is to store all the expressions using a hash table. So, we hash them and put them into a table and the index of that hash table is the used as the bit position. So, we make a bit vector out of these index positions of the various expressions and that will be used as our bit vector for various union and intersection operations. So, we let us stop here and then continue with the discussion of available expressions problem in the next part of the lecture. Thank you.


The commander of U.S. 7th Fleet has temporarily modified the Liberty Policy for all U.S. military personnel assigned to the 7th Fleet due to recent incidents that have occurred, all of which involve the use of alcohol. A curfew is now in place, requiring all sailors to be on base or in their homes between the hours of 11 p.m. and 5 a.m. and between the hours of 10 p.m. and 8 a.m. drinking alcohol is prohibited. One asked if he thought the restrictions on alcohol would lead to more alcohol related incidents due to binge drinking. The admiral said he was confident that the temporary restrictions will only help to reduce the risk. The vast majority of sailors are the solution. They are not the problem. So those that consumption of alcohol is such an important part of their lifestyle and decide to binge drink, those are the very sailors that are putting us at risk. So this is an opportunity to identify them before they create an issue out in town that ends up putting all of the rest of us at an increased risk of having more draconian measures. And for those who may be considering duty in the 7th Fleet or may already have orders to 7th Fleet, Admiral Swift doesn't want you to become alarmed by the current restrictions. Duty in forward deployed naval forces has always been a challenge. But those sailors that accept those challenges look at those challenges as opportunities. These are temporary measures. We will work our way through that and through this and return to the measures that we had in place. And I'm convinced that sailors when they walk through that calculus, they like the majority of sailors in the Navy will make the decision that they are up to the challenge of serving in FDNF forces. From the Defense Media Activity, I'm Petty Officer Brandy Wills.


Hello everybody, thanks very much for coming. I know the social event was pretty successful, so I'm even more glad that you made it. I will try not to shout too much during the talk. So before I go through the topic of this talk, first I'd like to talk about something more important. So my name is Mark Smith. I am a developer advocate at Nexmo. I run the user group for Python in Edinburgh. My handle on most social networks is Judy2k for reasons that aren't as funny as you might think. I am known for writing silly Python code and then showing it to people for my own amusement. And despite the Viking helmet that I kind of use as my general brand, I'm not a Viking or Norwegian or Scandinavian in any way. So talking about Nexmo, briefly, we're a sponsor of the conference. You've probably maybe spoken to me on the booth, if not, and you would like to come and talk to me some point later today. We've got REST APIs for sending and receiving SMS messages and making phone calls. Can I just do a quick show of hands? We generally do this because not many people have heard of us usually. So before this conference, who had heard of Nexmo? Yeah, it's getting better. So my job at Nexmo is to maintain our client libraries for Python and Java, and in my own time I maintain a library for Go. And so I think a lot about compatibility and maintaining compatibility. My job is really to communicate with developers and find out what they want and try and feed that back into product pipeline. So this talk really ended up not quite being about refactoring. It's related, but it's not quite about refactoring. If you do want to know more about refactoring, I highly recommend this book. It's been around for a while. I think it popularized the concept generally. It contains 72 refactoring recipes for modifying your code in order to improve the quality of the structure and the architecture of the code. It's very Java centric, but it's got lots of experience in the pages of the book. It's got lots of good advice, but some of the patterns also don't really transfer to Python. Java's a very different language to Python. The main theme of the book is to be prepared all the time to be modifying your code to keep it clean and to allow new architectures to emerge as you discover them through developing and extending the library. What the library's not really worried about is whether you break your user's code. It doesn't worry so much about interfaces. It's more worried about code that you're allowed to change at any time. This isn't really true of libraries. This talk is really about Python library maintenance. It's got this assumption that you have released code with two or more users. What that results in is you've got a one-to-many relationship. If you break backwards compatibility in your one code base, your users in order to upgrade are going to have to change their code, and that's going to be many changes. That's something that should be avoided. The other part of this talk is about hiding change from your users. It allows you to change things internally without affecting your users in two negative ways. What we're really talking about is keeping our interface stable while changing the code. The reasons you'd want a stable interface, I think they're pretty obvious, but I'll go through them anyway, is really to keep your customers happy, to keep your users happy. Every time if you keep breaking backwards compatibility, they're going to get unhappy in general because you're making more work for them. Nobody likes being given work that they didn't necessarily want. Also, every time you break backwards compatibility, you're giving your users an opportunity to switch to a competing product, competing open source library. If they're going to have to rewrite their code in order to keep on using your library, why not just switch to the new hot thing? This has happened in web frameworks certainly a long time ago, frameworks which I don't really want to name because I feel like I'm maybe demonising them a little bit. There was a big glut of frameworks about 15 years ago, and nobody was really sure what the right way to do things were. As they learned, often they broke backwards compatibility, and really what ended up the successful frameworks, the ones that we're still using today, were really the ones that worried a lot about maintaining backwards compatibility with their users. So really libraries only survive if they're stable, and that's why we want stable interfaces. We talk about this idea of an interface. What is an interface? I think of it as the boundary of your code, so it's the code that your user interfaces with, so it's where your user uses your code. If you change it, it's where your user will be affected, and it consists of various components. The obvious one is a module. They'll be importing your module or package, so if you change the name of that, that's going to break things. The thing we usually think about is that the module consists of classes and functions and methods, and that's our interface, our agreement with the user. To go slightly finer grained, we've got the parameters that our functions and methods call. If you change the names, the expected types, return values as well, this is going to affect your user in negative ways. We've got global variables that are usually static, but potentially you might want to change them with something dynamic, and that may cause problems. Something that people often don't think about up front is exceptions, so if you change the names of your exceptions or the hierarchy of your exceptions, that's going to cause problems for your users. We've got the structure of our code, so this is really where your code lives. If you start off with a big single namespace and you've got a kind of utility function in there, your user might find it, decide it's useful, start using it, and then if you decide to tuck it away in a sub-package later on, that's going to break your client's code, but it's not something you necessarily expected. Finally, this is a little bit of a silly example, but we've got byte code as well, so potentially even changing your byte code could cause problems for your users. I don't know if people saw Sebastian Dax go-to hack the Lightning Talks a couple of days ago, but he's got a decorator that decompiles a function and modifies the byte code and recompiles it again in order to allow you to use go-tos in the code. Potentially changing the structure of your code might also break your compatibility with your users. This isn't really something you have to worry about because really they've broken all the rules if they do that kind of thing. But this is really kind of the bigger topic of the talk, is making an agreement with your customer. So ideally, interfaces, your deal with your customer is as strict as possible. I think of it as kind of one of these kids toys. So you've got the idea of well-defined objects passing through the wall of the interface. They're validated on the way in. You may call functions and methods with these objects, and then ultimately, well-defined, stable, well-understood objects are passed back or exceptions are raised. In the ideal world, it's impossible to refer to classes, methods, functions or variables that aren't exposed by the interface. A couple of days ago in Hinex Talk, he used the analogy of ravioli, which I think is particularly appropriate given where we are, and the idea that your interface is like the pasta that keeps the filling of your ravioli separate from the tasty, tasty sauce.  But the concept here, really, the idea is that even if you're not publishing your library, even if you don't have external customers, your code should be divided up this way. It's much easier to understand small, well-contained code libraries. Talking about strict interfaces, here are some things that are like that, like that definition of a strict interface like the toy. There'll be a few sniggers, I suspect, looking at this list of technologies, because none of these are technologies apart from maybe the first one that we particularly enjoy working with. They're all a little bit painful. If you want to define interfaces with J2EE, you essentially define your client code, your server code and a third module that's shared between the two that is your well-understood interface. With SOAP, you define a Wizzdle file, which defines, again, incoming and outgoing objects. So you're defining your interface separate from your implementation, and these ideas have been around for a long time. The dates on there are kind of 16, 17 or 18 years ago. But it goes back to Cobra as well, which is a hideous technology. It's enormous and horrible to deal with, but that's 26 years old. So these are things that are getting towards our ideal world. Python isn't like that. Let's have a look at a quick example. This is a bit silly, but I've imported requests, and I'm just listing the stuff that's inside the requests library. I'm sure we've all used it. At some point, we've got a magic thing that begins and ends with a double underscore. We've got a private thing that starts with a single underscore. We've got some things with interesting names, like get, which is a function, compact, which is a submodule and models. And it's not immediately obvious with some of these, whether they're private or public, whether we're really supposed to be using them. And something stupid we can do with it is we can import the module, we can then define a function, and then we can modify the request module that we've imported with our own get function. And then anywhere else in our code base where somebody imports requests, so they get our modified requests, and when they call get, it doesn't make an HTTP request, it just prints out a silly message. But it gives the idea you can dig as deep as you want into somebody else's Python code and switch out things that they may not want you to. And so we've gone from another appropriate seaside analogy. We've gone from the idea of our library as having a kind of tough shell that's difficult to break through that only gives you access to things on its terms to what Python is, which is really just kind of a box of Lego. You can reach in, you can grab anything you want, you can take it apart, you can put it together in different ways and then put it back in the box. So what we really need to do is kind of build our own. So we need to work with the tools that we have in order to build an agreement with our users. So we need to make our interface knowable because we can't stop people from digging into our code so we have to make sure they understand what we expect from them. And how do we do that? We've got a few conventions and so here I've got a private method. We know it's private because it begins with a single underscore. The single underscore doesn't change the behaviour of the method at all. We can still call it, you can see the last line of code, I call it, it works. But we know just by reading the name of the method that it is considered to be an internal detail that we're not really supposed to call it from outside this code base. So we should be using these. This is something that you kind of get for free, an agreement with your customer that this is a private implementation detail. What you sometimes see in less experienced developers' codes is that they've read a book, they've discovered that there's this double underscore prefix and then they start to use that for private methods especially. And that isn't what this was designed for, this was designed to avoid namespace conflicts. So this does change the behaviour of the class, the method name internally has changed and it's just prefixed with the name of the class and a single underscore. So you can still call it, you haven't stopped to be from calling it, you've just made it a little bit more difficult. And ultimately if your user really wants to call that method they're going to call it anyway. Although by this point they've probably copied and pasted the code into their own code base so it's a different kind of problem. And a third convention we have in the Python world is just to kind of move the code out of the way. So often you'll find in some quite popular libraries there's a public module or package at the top and then there's a sub-module internally that really contains all the code and then in the public module there's the thing that the user is expected to import. They've just kind of imported the public interfaces, the public functions and classes from the private sub-module. So it just puts it out of the way, if somebody imports your public module and then does a DIR everything they see is something that they're expected to work with and that's good so I recommend that too. But these are kind of, you get these for free. These are conventions in the Python world. Something a little bit more expensive but infinitely valuable is documentation. Documentation is the primary way that you communicate with your users. And the Python ecosystem has excellent documentation so much so that it's spawned a series of international conferences dedicated to the documentation, the read the docs conferences, that I would say spawn largely out of the Python community. And the reason documentation is so popular in the Python world is that we've learned that users will use the interface that you document. We usually distribute source code, our libraries as source code so somebody can read the code but you don't really want to. If you don't write documentation users will read your code. If you don't write documentation users will guess your interface and they'll guess it wrong which is not something that you want. So for documentation I recommend Sphinx or MakeDocs. MakeDocs is supposed to have a capital D, Google the maintainer of MakeDocs is sitting in front of me and has warned me about this before. I don't recommend auto generating your documentation. It's a really bad idea. By default everything is going to be published as documentation. That's not what you want. You want to filter your documentation down to the things that you want your customers to use. Slightly related to this is type hints. It's a recent addition to the language. I think it's still pretty controversial. It doesn't change the behaviour of the code at runtime by default. But it is used by IDEs to help users use the right types. In going types into your functions and return types as well. It gives the user an idea of what they're working with. So in general I think they're a good idea. Whether they're worth the cost of maintenance is difficult to tell. But I'm trying it out in the next mode of Python library to see whether that's something we want to expand and take forward. But once again we're sharing an understanding with our users, which is a good thing. So in answer to our original question, what is our interface, the answer really is code that's documented. Because that really is what the users will see. It gives them no reason then to dig into your code to get confused about what they're supposed to work with. So this is a good place to be. So once we've created an agreement with our users, then how do we stop ourselves from breaking the promises that we've made? And the answer is testing. So this is a famous quote, which although I've attributed it to Jacob Kaplan Moss, he denies ever having said it. So really it should be anonymous at the bottom there. So I would say there's a corollary to this, which is that if you're not testing your interface definition, then you don't have an interface definition. And to look at this standard testing pyramid, the idea here is that at the bottom we've got unit tests. We want as many of those as possible, or we want more of those proportionally, because they're quick to run, they're cheap to write, they're easy to maintain. And then at the top you've got manual tests, which are heavy and slow and you don't want to do those. So in the middle somewhere I would say you want fewer than integration tests, but you definitely want to have your interface tests divided out. That means that when you find yourself changing your interface tests, you know you've changed your interface, which means then you need to work out what you're going to do later on. You need to communicate these changes to your users. The way you communicate changes to your users is through versioning. I recommend semantic versioning. So the thing here is that your major number, which is the first number in this, I mean we've all seen this, but the major number indicates backwards compatibility. So whenever you break backwards compatibility that first number changes this is going to cost them some effort to upgrade. Minor and patch numbers are less aggressive changes and usually won't change the compatibility with the user. This is documented in detail on semver.org and it's there on version 2.0.0 of the specification, so they're reading their own dog food. Along with versioning, we've got release notes. I recommend you check out KeeperChangeLog.com. They offer a guidelines for maintaining your release notes. They say that every release you should divide your changes into a list of the things that were added, changed, deprecated, removed, fixed for our security changes. So the two that we're really interested in here are changed or removed. Those are things that are changing backwards compatibility so the things that we need to, we really, really need to make sure our users know because it's going to break their code. Although we're talking a lot about not breaking code, it is okay to break backwards compatibility but you want to do it occasionally. I recommend keeping a branch of breaking changes and pushing them unless they're essential, pushing them in a block so that you're not drip feeding changes to your users. That's a pretty negative thing to do. In general, add new functionality alongside the existing functionality and deprecate the existing functionality so that they should be migrating their code. Have a deprecation policy. I quite like Django's deprecation policy. Anything that they mark as deprecated gets removed apart from a couple of caveats gets removed in the next major release but you could leave it two releases so it gives the user more time to adjust to the changes that they need to make. So the real theme of this so far is that good engineering practices allow you protect your users from changing your library. Documentation, testing and versioning things you should do. I'm going to skim through some technical solutions now. The last time I ran this talk it ran over 40 minutes so I'm really going to be giving you some ideas but I'll give you a link at the end of the talk which links to some code that demonstrates all the examples that I'm about to give. The first one is pretty common. I suspect everybody in the room has used it at some point or not. You've got a class with a static attribute so it's pre-generated and you want to change it to a dynamically generated value and the way to do this is to use the app property decorator which just makes something look like it's a static attribute lookup but in fact calls a function instead so you can generate the value at that point so you can have it generated based on network value or time or calculated value inside the class. That's pretty straightforward but it's a good example of one of the things you can do in Python that you can't do in many other languages and the way that that works is down to something that you can read about in the Python documentation called the descriptive protocol which I highly recommend. It gave me a real understanding of what's going on beneath the surface of classes and attribute lookup. The next kind of refactoring thing you might want to do so this might be so that you only ever have one instance of a class essentially a singleton or so that you have a factory so objects that may be expensive to produce are pooled when they're not in use and then you return something from the pool if there's one available or you generate a new one on demand if there's not one available or possibly block until one's put back in the cache. In the refactoring book this is actually called replace constructor with factory method but the nice thing about Python so we can implement the lesser used dunder new method and then inside there we can either return a new class by calling new on the superclass or we can look something up and just return that value. There's no kind of prerequisite that you have to create a new class when you call a constructor which is kind of neat. So we can make these changes transparently to the user which is switched from instantiating each time to returning stuff from a pool you've done that under the hood which is good. The third example is replacing functions with methods. So when I start a new module design I tend to start with functions I prefer those to classes generally but sometimes what you find is you end up with some global state in your module which then if you change in the module it's essentially a singleton value and so you can't have multiple configured modules so really the way that you do that is to define a class inside your module and then instantiate that for the different cases that you have. So if you've published your library already with these top level functions that's kind of a problem but we can get around this because Python's got some pretty cool features. So this is the end result of this so the idea is that you had a module with the do the thing top level function and what we want to do is put it inside a class. We've taken the top level function and we've moved it under the app class so this is great. We can now instantiate an app and we can call the method but this is broken backwards compatibility so we need to fix that. The way that we fix that is we create a default instance of our class. We can either make that a public thing or a private thing. I think it's quite nice to make it public so that people can start to use module.default to refer to it and then what we do is a bit of magic to make the method which can just be assigned to a variable so that's what we've done. We've assigned it to the global variable do the thing and now it looks like a function. It's not a function, it's a bound method on your instance and it's just quite a nice way you would do this with each one of your top level functions that you've put inside the class. And finally and this is a slightly silly example but it's neat and again it shows how flexible Python is with being able to switch out certain types with other types when necessary so in this case I have a module which I really want to replace with an object so this is the module and it's got a single global variable in there called salt and you can see it's static, it's number four but somebody comes to us and tells us actually that shouldn't be four, that should be generated that should be the result of time so that's awkward because people are already using our module and they're calling module.salt or in this case important.salt to get access to that value and you need to generate it dynamically so you really want to replace that with a function but you can't do that because that breaks your interface with your user and if it was inside a class you could use the property decorator but you can't do that because they don't work on top level functions, they only work inside classes and so what we need to do is replace the module with an object instance so this is like crazy stuff I don't want to do this in your code but I just want to show how you might do this so here we've got a class called fake module because it's going to pretend to be a module and then we've defined our property on it so if we had an instance of this we can refer to the instance.salt and get back our value as if it was an attribute rather than a function and then here we instantiate our silly object and then we define it to the module so every module you've loaded inside your application is put into this dictionary insist.modules, you can have a list you can list it at any time you want to and see the modules that have been loaded but like many things in Python it's mutable so you can replace the module that's been loaded with an instance so now anywhere in the code that refers to this oops I don't actually have a slide for this excuse me so anything that refers to that code will continue to work but it will get back a dynamic value from this point on so just to run through some further techniques really what this comes down to is understanding the Python execution model and there's various of these magic methods and variables inside Python that you can use to replace one thing for another to essentially objects pretending to be other types of objects so we've already seen using DundunU to change the construction of a class we can make objects behave like iterators behind the scenes this is how iterators and iterables work we can make method calls look like attribute access using dundaget this is what property uses behind the scenes we can make classes that act like functions by implementing dundaget calls so you can replace global state with essentially an instance that's callable which is kind of neat and then there's manually extracting parameters so we can be extremely flexible about how we extract parameters inside a function normally you list the functions that you want sometimes you have an asterisk args to kind of collect random stuff that people might send into your function if you're particularly flexible but he's just shown me a number and now it's distracted me it's completely throwing me up but we can be much more flexible about that we can kind of define the rules of what's accepted inside a function and kind of almost deal with different sets of functions different sets of parameters that are provided so if you were to look at the low level documentation for flask for example almost everything in there takes asterisk args or asterisk asterisk kw args and then it just kind of pulls out the values that it needs to make the call behind the scenes and if you don't provide the right set you'll get an exception of some kind to tell you that you didn't follow the rules that have been defined in the documentation many of these special methods are described in Dive into Python which is free and available online and I highly recommend having a look through the list to see what's possible when using these tricks especially the last trick you have to be aware that every change you make has risks attached to it and the more magic you use the more risk you're really taking that you're going to break compatibility accidentally with your users sometimes it's better often it's better to break code than to use magic I would say generally default to the straightforward changes but if you have a lot of users that might stop you from making changes at all so just be aware that there are opportunities sometimes to use a little bit of magic to help you in your relationship with your users the use of exceptions in code varies wildly between different code bases it's very difficult to know what your user is going to do in their code base to handle the exceptions that you throw so I don't really have any advice for this it's just be aware that any changes you make to the set of exceptions that you throw may cause problems for your users it's another issue for documentation make sure you document clearly what the exception conditions are and what will happen in those cases type assumptions because it's a dynamically typed language are slightly scary in Python so when you switch out one type it's a supposedly compatible type so you change a string for a list of characters or you change a string for an iterable of characters or something like that they often look compatible and your tests might continue to pass but suddenly you can't loop more than once because you're dealing with an iterator rather than a data type that you can loop through multiple times so just be aware that these do have different properties and make sure that either your documentation changes to match that you don't make the change at all really monkey patching is always a risk people do crazy stuff especially for finding a bug in your code that you don't respond to quickly enough they will inject their code into your code base there's not really anything you can do about this they've broken the deal with you so it's not something to worry about there's just something to be aware of that will happen there's no silver bullet you will break client code Python is such a dynamic language and so open and transparent any change you make carries some risk but ultimately it's a question of documenting to your users what the assumptions are and trying as much as possible to keep to that agreement so to sum up if you want your interface to be strong and stable you need to know what it is you need to document it so your users know what it is you need to test it so that you're keeping the promises that you've made when you need to change backwards compatibility you need to communicate that with your users it's better to do that upfront than after the fact and it's helpful to know some tricks for swapping out code in a dynamic language like Python so there's a github repository on that bit.ly address which contains more low level details of some of the tricks that I was showing and the PDF of these slides if you're interested you can contact me on that email address or feel free to follow me on Twitter if you've ever seen me around the conference I'm usually wearing a pink hat feel free to talk to me about Nexmo or this talk or anything else thank you very much


We're rolling. Okay. Mike Reynolds are on? Yeah. You're good. Hey guys. It's Jenny with Arkansas Farm Bureau. We're here for another episode of Jenny on the Street at State Convention. Fall along as I ask people some tough questions about day one session. All right. Let's go. What color tie was the governor wearing? Red is for me. Okay. They were actually paying attention to that. What tie was President Richelman wearing? Oh, guess you don't know everything, do you? Do you know who sang the national anthem today at all? It was a young lady with 4-H, but I don't remember her name. Annabelle Farah, but that's good. That's good. Would you like to answer some questions for me? Okay. Okay. It's all about the details today. Details? Yeah, the details today. So who was the announcer in the booth during the session? Do you know? Yes. Some lady. That's not wrong. That's not wrong. Not wrong. Okay. Okay. Laura McCullough. Let's go through. Would you like to answer a question, Todd? Todd, Todd is walking off from us right now. Todd does not want to answer a question. All right.  All right. Don't look this way. Just look, you can look at me, but not pass me. What three tractor companies are here at the trade show today? Is that right? Any 4-H officers were there today? Six. It's four. It's four. Okay. Oh, I should not. I should not ask her. She seemed like a prime candidate. Oh, sorry. I'm so sorry. Do you remember who Rich brought on stage? He bought on the president of the National Farm Bureau, and he also brought the president of... Jeffertubbs. Okay. Jonesboro Country, yes. Jeffertubbs. Jeffertubbs and Zippy Duvall. Excuse me. Hi. Excuse me. Hi. Excuse me. You're paying attention pretty well. Yes. Yes, I was. You get it. Okay. All right. Okay. So first question. First question. Do you know the theme of today's conference? Past, present, future. Looks like we did our marketing job right. Go us. Do you hear that? Steve Eddington? Hear that? Excuse me. Excuse me. Oh, hey, what's up? Well, too bad you interned for us, so now you have to be on this. Everyone, say hi to Madison. She was our intern. Hey. She's obviously very enthusiastic about our intern. Madison, who was your favorite staff member at Farm Bureau? You and Rob. Ha! Take that. I'm the favorite staff member. What's up? All right. All right. Just ignore all the other names she just said. She said my name, so that's all that matters. Thank you guys for joining us today for these strange questions and Virginia on the street. We appreciate it.


All our development priorities as a county are very sensitive to the variability in the climate. And for that it will be very important that to meet our development objectives, we must be able to track the effects of climate change into these development priorities. In other words, whatever we do, the M&D on the climate issues will help us improve on our projects by making them a climate proof. Okay, termed. In first mainstreaming, the termed process into our county integrated development planning process and then we have to integrate termed into our own county monitoring and evaluation system. So it will help us. The main purpose is for us to want to see the progress and also check the adaptation and also look at the indicators that we've already developed and be able to link now at the world level together up to the county, what those linkages up to the national world, the framework that we've already developed. We are using the termed framework from the local level, that is from the words of the county because we've already developed indicators and also at the output, the outcome and the impact level and we are using the termed framework to ensure that these are linked. The monitoring and evaluation of the adaptation is important to improve capacity and to enhance their livelihood and to attract the international climate related fund to improve their livelihood of the poor people in our country context. So how to measure adaptation, linking with development. In this regard, academically and technically termed will support to the countries and share exchange with the knowledge and ideas with country to country. So I think termed will be useful on this regard. As I understand the termed is a new knowledge system to relate to the monitoring and evaluation, it gives us to see the things in one step better than our previous monitoring and evaluation system. It's based on the theory of change, it's a new theory we are going to adopt. Before we, as in our conventional system now, our vision is or will be changed as the track one and track two system. We see our works in this morality. Utopia has been trying to build up green economy and for that reason it develops climate change, climate reserve green economy strategy and as per that strategy there are several projects which are working on climate change, adaptation and mitigation and one of the projects which contributes to climate change adaptation is the sustainable and manageable project with the Ministry of Agriculture and termed is working with the Ministry of Agriculture and it is applied in this project because this is a project which contributes to climate change adaptation. So that termed will be very useful to track whether the project contributes to climate change adaptation or not. Basically so far the MNE's are concerned and we are going to implement it in our planning country system, planning of the projects and we have different planning commission performers from one to five and the planning commission performer three is all about the monitoring and evaluation and hopefully we will be able to implement the adaptation, measurement of adaptation and development through a PC3 in our country system. I think it is important for evaluate the process of the project working in Cambodia because we have a lot of projects that work in Cambodia so basically on adaptation, climate change adaptation but we don't have yet about monitoring and evaluation framework in order to work to analyse the process and how it's going on. Actually Cambodian we don't have a MD framework yet so TAM can help us to develop the framework in order to work with the local government for the national and sub-national. TAM measure or TAM tool is a very good methodology that we can apply within my country especially within the Department of Climate Change because right now we have also developed what we call Cambodia climate for finance framework, Cambodia climate action plan to support Cambodia climate change strategy. So one of the things that we left is MNE so I think TAM methodology is very good to develop harmony system to support Cambodia climate change strategy. Right now we develop only the national level. In the future time maybe we can mainstream to the sector level or at the sub-national level. I hope this tool or this methodology from TAM is a very good one for our department and our ministry.


Action! What a day on. Hi guys! Welcome back to my channel. If you're new here, hi, hello, my name is Lydia. And today I thought I'd show you what is in my distraction box. So a few nights ago now I filmed a clip where I was using this. I'm not sure it's still on my camera though. But basically I was using it and it recorded me using it. Then I thought I'd give you a pretty in-depth look into what I've got in mind. But before I get into that, I am going to give away one costume. Completely custom.  I'm doing a giveaway because I hit 5K on here. All you have to do is be subscribed. The competition is linked down below. It's all done through Gleam so you can see everything you can do to gain and follow and be a part of the giveaway. The more times you interact with me on social media the more you get towards winning. Yes, I am keeping track also in a notebook of all the comments of the username. I've got a little telly next to each username. So I do know who is doing what. So if you're only part of that, the link is down below. Make sure you're subscribed because I will be announcing it on YouTube and Twitter only. So I have two boxes. This one I got like my toiletries and change of clothes. Bits of makeup and just generalised like health, like body care stuff. Here's where the toys are. So let's start with this box. I've got half a hairbrush in here. It's one of the ones that normally the mirror on it but obviously it's my last admission. The mirror got taken off.  So it's got like sample shampoo, conditioner and all that stuff. I then have these two things which are eye callers. You can put them in the fridge and then you can put them on your eyes and it just relaxes everything. I've got one of my Anastasia lip glosses. I've got some eye shadowers that I've got no mirrors with so they're suitable. I've got a t-shirt and some tight leggings. I've got a mini conditioner, a plastic bottle spray because you can't have glass when you're on a ward. I've got one makeup brush just so I can put the eyeshadow on. I've got mouthwash, tea, roll on deodorant, hand cream, lollipop, hand warmer.  This is shampoo, this is just mouth spray. This is a soap bar and that's pretty much it for this. Now we're going to move on to this box. This box is currently empty. I took everything out. I could show you guys what I have. So I've got the notebook. I tend to get my notes from the works because they're cheaper, they're affordable and they don't have a ribbon in this volume. There's no staples so you're allowed that. I have a book which for me I've got one that's about unicorns. Very main if I'm being honest. This is about as many as you can get. I have this sketching thing that's got a few pencils and something to draw on. I have these little friendship cards that Louise sent me and draw it out to Louise. I'm going to link Louise's channel down below. Love Louise's content, she currently posts loads on TikTok so I'm going to recommend you go check that out too. Again, link down below. So then we get on to the new puzzles right here. So I got this which is one you spin round and it's a puzzle. It's like a spinny rubik's cube. I have my little maze thing. I've had this in here for ages. I love stuff like that. I have this which is a circular rubik's cube. Loud, distracting. I love it. Moving on, I've got this little camera and my mini charging cable. The reason I have this in here is because sometimes I find talking to a camera helpful. I don't want to get out my big camera that I'm using right now. Or if I don't have my phone on me for some reason I've got a mini camera. I don't know, it's just one of my things that I like having. I also put in a sleeping mask because you'll know I like my sleep. And in wards, they did check on you and the lights wake me up all the time. So having a face mask. Highly recommend it. I have some Orbeez. Not sure if I'd be allowed these on a wall or not. I don't think they're toxic so I think I would be. But I have Orbeez in here. What I should point out is I have my box ready for admission and at home. Because if I get taken to A&E, right here I've got micropens and everything. Like, I've got pens, I've got glow sticks. I have this box ready for just in case an emergency admission happens. I've got some stuff to do and distract myself with and a change of clothes. That's the main important thing for me. I have it, I've got a new ball. My old ball got a bit destroyed. Last time I was in hospitals I ripped all the these bits off. So I've got a new one. I just got this from the works. Honestly, I'd highly recommend going into the works if you try to build a distraction box. Because they have loads of pretty cool stuff. I have a freezable, reusable ice cube. My slingy. Flingy is a fun. Again, wouldn't be allowed best in hospital but at home it's great. I have my old iPhone, which is not capable of reading SIM cards and can't connect to the internet. I have this in here just in case I want to play games, listen to music etc. Because obviously it's got a headphone jack and speaking of headphones, I have my Bluetooth headphones in here. Because if you see when you're in hospital you're not allowed to have cable, long cables anyway. I've got them, which are Bluetooth, so I couldn't listen to music. Trying to fit everything into this box is a challenge. Someone won't mind me, I'm an extra student alone to buy a bigger box. So carrying on. I also keep another hairbrush in here just because this one's not really that great, you know, obviously. I then have sand animals. I love my sand animals. I have three different ones. I have a sea horse and two lizards. This was my first ever sand animal, which is why I have it in there. I've won someone for years and then I finally got one and I was so happy. And one of the only happy associations I really have with my childhood, I keep that in there. I then have squishies because they're great if you're in, you know. I have a textured tangle toy. This is the one I keep in here. I do have other tangle toys as well. I have a light up ball. You might notice that I've got a lot of, like, veggie toys. My favourite thing. The light up unicorn. Bubbles. Plasters. I keep them there because always case scenario, I need a plaster. I have colouring crayons. All my colouring books are kept next to, they're actually on that shelf there. They're kept next to where I keep my distraction boxes. So I just grab one of them if I was ever taken to hospital from here. I have this little mini aqua beads thing, which is small again.  We have a little nice card thing that I got in, a thing that I ordered. I have loads of these little fiddly things that I keep in because they remind me of my little sister and they make me very happy. So I keep them in here. Then also I have fiddle cues. I put this one in my distraction box and then this one to my handbag. Then, like, stationary wires, I keep some sticky notes in because sticking out is a useful, believe me. Like, you get told so much information when you're in wards.  Then I put my actual crisis plan on top. I also have this mini Rubik's cube. It's like a cube. I hate Rubik's cubes, but sometimes I need to release anger in Rubik's cubes for me. The best way for me to release anger. Then on top of all of that, I put this bag. This is where I keep them, so I keep my main distraction box here. And up here there are just some positivity cards. Here are some books that are next to it. And then it's health books. And then my other box there. This box here has got my scrapbook and stuff in. And I just keep that there because if I did need to, they are easy enough to just wrap or tell someone to get. And also on here I'd say get my DBT book. And possibly this book and this book. They're the books that I choose to take in if I went into hospital. I'd also choose possibly this one. Because it's clean so short, my old support worker got it me. And it's a really good read. If you do subscribe, I'm doing a giveaway. And I'm doing a giveaway of a crisis box basically. And it's pretty custom to what you want. So that's linked in the description down below. Ignore the fact that I've got a collapsed vein on my arm. That's a long story. But yeah, thanks for watching and I'll see you guys soon. Peace. Bye.


So we have sliced here the quadriceps tendon, the patellar ligament, we have sliced the iliotibial tract and we have sliced the capsule and we have reflected the patella along with the quadriceps tendon and the ligament and the patellar. First let's take a look at the reflection of the fibrous capsule. When we are cutting the fibrous capsule, we can see the remnant of the fibrous capsule attached to the margin of the femoral condyle here. We can see it here and I'm picking it up the remnant of the fibrous capsule here. So the fibrous capsule was attached here and from there the fibrous capsule got attached to the margins of the patella here on the lateral side and on the medial side. The fibrous capsule got reinforcement from these structures here. This is the lateral and the medial patellar retina column respectively which got attached to the sides of the patella and to the tibial condyle and we can see the remnant of the fibrous capsule here also to the tibial condyle. So this is about the fibrous capsule and inside the fibrous capsule of course is the reflection of the sinusoidal membrane. Having reflected the patella, we can see the surface of the femur which was articulating with the patella. So these are the femoral condyles. This is the lateral femoral condyle, this is the intercondylar groove and this is the medial femoral condyle covered by highland cartilage and we can see because this is an elderly kid ever, the highland cartilage is partially degenerated. So just to bring up to speed, this is the base of the patella, this is the apex of the patella, these are the sides of the patella. This is the outer surface, this is the articular surface which is covered by the highland cartilage which also shows signs of degeneration. Now let's take a look at the articular surface of the patella. We can see that there's a ridge here. This ridge fits into the groove here between the two condyles of the femur. This is the lateral articular surface, this is the medial articular surface. The lateral articular surface is larger because it articulates with the larger condylar surface of the femur. The textbooks describe it as having two ridges which divided into an upper middle and a lower portion. This is the medial portion of the articular surface of the patella which articulates with the medial femoral condyle here and there's a small vertical ridge on the most part of the medial portion which is the non-articular part of the medial surface. This is what constitutes the femoro-patellar articulation. At this point, let me mention a few words of clinical correlation. There's something called a q-angle. The q-angle is the angle between the long axis of the femur and the mid-patellar line. When we have a condition known as gyru-valga or knock knee, the line of weight-bearing goes through the lateral femoral condyle to the lateral tibial condyle. The knees are bent inside. In such situation, q-angle, which normally is 9 degrees, q-angle becomes more than 17 degrees in which situation there's a tendency for the patella to dislocate laterally. There's an opposite condition known as boleg or gyru-varum when the line of weight-bearing goes through the two medial condyle, the medial femoral condyle and the medial tibial condyle and in such situation, q-angle, it becomes less than 9 degrees and that is known as boleg or gyru-varum. There's a theoretical tendency for the patella to dislocate medially, however, lateral dislocation of the patella is more frequent. This is an x-ray of the knee to show transverse fracture of the patella. We notice that the proximal fragment has been widely pulled apart from the distal fragment by the proximal pull of the quadriceps tendon. It typically occurs in sudden violent contraction of the quadriceps muscle. So that is about the femoral-patellar articulation. Now let's take a look at the interior of the femoral tibial articulation or the knee joint proper. We are going to flex the open-out knee and we can see the interior of the knee much more clearly. So we have cut open the capsule as you can see here to see the structures in the front. Let's start off from the lateral aspect. We can see this muscle here. This is the bicep femoris and the bicep femoris gets inserted onto the head of the febola, which is here. And we can see that the bicep femoris tendon is split by this strong stout ligament which I have lifted up here, this ligament. This is the febola or collateral ligament which extends from the lateral femoral epicondyle. It splits the bicep femoris tendon and gets attached to the head of the febola. First of all, it's a short stout cord-like structure. Number two, we can see, since I can put my instrument here, it is free from the lateral side of the capsule of the knee and it is also free from the lateral meniscus of the knee. And the reason why it is free is because from behind one of the tendons of the popliteus muscle passes through here and it separates the febola collateral ligament from the knee joint. This is the febola collateral ligament. Now let's take a look at the corresponding ligament on the medius. Now the camera person has moved to the opposite side, to the right side of the cadaver, to show the medial side of the left knee. This is the febola collateral ligament which I have picked up here. We notice that in contrast to the febola collateral ligament, the febola collateral ligament is a flat band. It extends from the medial epicondyle of the femoral to the upper medial surface of the tibia. Between the febola collateral ligament and the upper medial surface of the tibia, there may be a person. The next thing we notice is that febola collateral ligament is situated just under the insertion of the pest ancerinus. This is the sartorius. This is the gracilis. Further posteriorly, we have the semitendinosis. So sartorius, gracilis semitendinosis, these three triple insertions which constitute the pest ancerinus are located just superficial to the tibia collateral ligament. Between these three tendons and the tibia collateral ligament, there may be a person which is referred to as the ancerine person. We can see that we can pick up the tibia collateral ligament only in the lower portion. We notice that in the upper part, the tibia collateral ligament is densely adherent to the medial part of the capsule of the knee joint and is also adherent to the medial meniscus. This is the coronal MRI of the knee to show the internal structure of the knee including the ligaments. Please take special note of the fact that the febola collateral ligament is free from the lateral meniscus while the tibia collateral ligament is adherent to the medial meniscus. So this brings me to a very important clinical coordination. Tibia collateral ligament is much more frequently ruptured compared to the febola collateral ligament and when this is ruptured, it can also produce a bucket handle tear of the medial meniscus because it is fused here. That's about the two collateral ligaments.


Welcome to the Knuckleheads of Liberty. Right now I'm actually working with them to get campus carry on campus. We have some restrictions still about concealed carry, which is something that I can't imagine. You can't even imagine in California, right? Carrying a gun on campus. Our restriction is that we need to have a license to carry before. And there's still like certain areas you can't go. And so that's what I'm trying to fight against. And that's something that I'm going to be working with Yael to do. Great. Just curious. This is kind of the first I really thought about carrying on campus. But is that something as a student, it would make you feel more secure having more people who are responsible that were armed on campus? Oh, definitely. On our campus, if there's been so many different robberies and like attempted like just assaults, all of that. And so I feel afraid when I go out at night to out in the parking lot towards the evening that I feel like I have to get a permit now and start carrying. Because if I don't, you know, we've had really bad situations happen on campus. So that's why I want to make sure that I can carry on campus. And other students too. Well, you know, it's funny that you talk about that. And I remember at the University of Houston, just off campus, there's Scott Street there. Scott Street was so horrible. I mean, if I got a flat tire at night coming from campus, I would not stop on that place at all.  Yes. Yeah, the campus itself is not very dangerous, but everywhere around it is in the Third Ward in Houston, which is a very, very dangerous place to be in Houston. So, yes, just for context, which is the reason why I want to get more campus carry. Because students, they don't really feel safe on campus.  But that still isn't safe. Like you'd rather have an immediate solution that you can use in case you need it, instead of, you know, hoping that you can get to a booth on time and then the police will come. Exactly. Yeah.  It is true the police is there to protect and serve us and they, you know, they're supposed to protect us. We hope. We hope. Exactly. If they're not defunded, if they're not defunded by the same idiots. But what they don't understand is that the police comes after a crime is committed.  They're not there at the time. They're only after the fact. So you need someone, something to protect yourself.  That you need an immediate solution. Just like you said. Yeah. I think the famous phrase is, when seconds count, the police are only minutes away. Yvaldi showed that the police. True. Are hours away? Yeah. Yeah. They'll sit on their butts for an hour and be passing. Yeah. Yeah. Only arms length, but yet hours away. Life, liberty and the pursuit of happiness always.


This is it. Messi's last world cup. Let that sink in. A moment three billion people will be watching. This thing's bigger than the moon landing. If he comes up short, he's still Messi. But if he brings it home, he's the Messiah.


YouTube.com slash geek comes to freedom guys have you ever wanted a channel dedicated to geek culture things like Comics and anime or maybe tech reviews Well, we can all put it in one place for you to easily find it's the geek channel and it's now run by Adam I'm gonna throw this video over to him because I can't do it as good of justice as he can so take it away at him Hey everyone and welcome to geek geek is dedicated to all things geek comic books toys collectibles trading cards anime TV shows movies Superheroes anything you can imagine We have a plethora of great ideas and video content in the works for you guys right now However, you're a geek. It's not just a one-way street In fact, we are very very interested in what you have to say pick up a new collectible or comic book recently Let us know in the comment section below Send us a tweet shoot us an email send us a YouTube message. We would love to hear from you You have a special Collection or really special item or rare item that you have that you would like to share again Shoot us an email leave us comment shoot us a message We would love to feature it or at least check it out and talk about it with you We are all about discussing geeky things here over a geek The best part about being a geek at least to me is getting to share it with someone else And so that's what we're hoping to be able to do with you guys So we hope you'll join us here geek. We're gonna have a lot of fun We're gonna have a lot of great content and we're really looking forward to working with you all and Disgusting all things geeky. So go ahead click that subscribe button leave us comment. Let us know what you think We'll have a lot of great content up soon. We hope you join us until next time. My name is Adam See y'all later. Are you guys excited as much as I am for this channel leave it down in the comments below I just subscribed to crunchyroll.com and if you don't know what that is It's basically a website where you can watch your favorite anime shows So I'm watching a Kame ga kill naruto sword art online Fairy tale the list goes on and so guys are you fans of these shows as well? I would love to know in the comments down below. What else do you guys watch? I would love some recommendations But yeah, I think I'm gonna close it out here. Please check out the geek channel I'm subscribed myself. I would love it if you guys subscribe give them the freedom hug for me And I'll see you guys next time. I've been Alex Adams senior manager at freedom and you've been watching Click the first video for a fireside chat with George where he shares our future and how he grew from $20,000 to $120,000 in just one month and click the second video to see how to monetize all of your videos With just a few clicks to enable all ad formats and monetize in all countries And we will grow together as a family because this is the freedom family You are part of it. We are all part of it and we're all growing together so grow with us and Partner with freedom that play now button right there on the video bar is all you need to click to get Started your secrets if you really look at yourself, you will be speechless What happened to being doctors and teachers? What happened to being your brothers keep on nowadays?


NAMASKARAN, I am Dr. MALLINA, earth butic surgeon working in Manipal Hospital, Bangalore After the Nearthroscopic Surgery, patient can walk and the next day he can drive after one month, he can run after three months He can participate in sports after four to six months depending upon his recovery