Just a quick show of hands so I understand who is in the room. How many people here come from an object oriented background? Quick show of hands, pretty much everyone, okay. This session is mostly about trying to understand what is the right balance between object orientation and basically taking some of the functional concepts and applying it. So we can take advantage of some of these things while we are still working in a typical object oriented language and specifically how to use test driven development as an approach to kind of help you, you know, implement some of these practices, implement some of these techniques in your programming. One of the common things that we hear a lot is O equals modeling the real world, like object orientation is about modeling the real world. How many people think of object orientation this way, okay? So one takeaway hopefully by the end of this workshop is you will understand why this is actually wrong or why this is not the case or it should not be the case. So obviously soon you end up with stuff like this, right? Suddenly a truck is inheriting from a car because it has to reuse some of the functionality that is there in the car or you have all kinds of other deep nested hierarchy and other kinds of problems that you end up with, which just does not make sense, you know, but you end up doing that because you originally started by trying to model your software on the real world and at some point, you know, that fell off but you wanted to reuse code and you ended up basically, you know, bending over your back to get stuff done. I'm sure people would have seen, you know, code bases like this where you try and pull up a hierarchy and this looks as scary as this. So for me, like the main tipping point from O and kind of understanding what really is a challenge with O was when I was working on a medical system, which basically is about automating the stuff that happens at a hospital. And one of the classic debates in our team we had is, you know, basically a patient comes in and the patient needs to get certain vaccinations, right? So, you know, the debate was, okay, you read through the requirement and then you look at, okay, all the nouns.  And so the debate that happened in our team was like, you know, should the doctor have a give shot method, right, give, you know, rabies vaccination or some vaccination shot or should the patient have a take shot method, where do you put this method, right? And the debate went on because both sides had a valid argument and suddenly there was a third side which said, well, nurses also give shots, right? So now the case for having this method on the patient became stronger, but then the case was can patients give a shot to themselves? And the point I'm trying to get at is that with O, we end up with a lot of these kind of debates and we try and model the real world and then we are confused because we all have different perspectives of the real world. And so our software becomes as complicated as a real world when, in my opinion, software is about abstracting, you know, it's about abstraction and it's about trying to simplify things. So eventually the whole debate ended saying, who cares, who gives a shot to whom? All we care is whether we charge the patient or not, right? The patient could might well as give a shot to themselves, we are interested in basically charging the patient, like that's what should be our focus. So I think basically OO gets a lot of bad name for behaviors that you see like this. But you know, if you really think about it, is it because of OO itself or is it because of people's interpretation of what OO is? But then what is the right interpretation of OO, right? And hopefully this session is going to give you a view of what probably in my opinion is the right interpretation of OO and how, you know, functional concepts can very well coexist with some of these concepts, right? I mean, we will talk about mutability, we will talk about some of these core concepts and how those can be very well achieved with OO languages. It's a little harder in some cases than they're not. But then adding test driven development as a thing on top of it, how does that actually push you towards pure functions, towards side effect free, towards, you know, other kinds of things, method chaining, a little bit of, you know, we'll talk about a maybe monad kind of a stuff. So how you kind of get into that kind of a mindset. So in a gist, this is kind of the focus of this workshop is what's the right way to think about object orientation, how can, you know, you take some of the functional concepts and apply it and can they actually coexist with an object oriented word and really to tie everything together, how does test driven development kind of help you tie all these pieces together. So that's kind of what the focus will be. So basically it's a 120 minute session. I did this last time at the jQuery conference and it was about 90 minute session and we couldn't get through a lot of concepts. So we kind of extended it to 120 minute session. This is supposed to be a hands on code along kind of a workshop. So you actually get, you know, some of the benefits of understanding some of these concepts. So that's the idea.  If we do get time, I would like to actually show how we can stub out Ajax calls, how to, you know, deal with side effects from those kind of things and stuff like that. What we are kind of trying to build is basically this particular plugin. It's a jQuery plugin for basically comments. It's a part of what we built as part of the conference. And so it's a real world example. So you know, for commenting, how, you know, how do we build a plugin which can basically, you know, build your comments out on any page kind of a thing, kind of pretty much like discourse. If you've seen discuss, if you've seen that, so this is kind of a plugin that helps us achieve that. So this is what we will try and achieve in this workshop. It's a bit ambitious. There's a lot of moving parts in this, but we'll see how far we can get. All right. Let's quickly touch upon test-driven development as a concept before we dive in, just so we all are on the same page of what we mean by test-driven development. How many here are familiar with the concept of test-driven development? Okay. That's pretty cool. So I probably don't need the next slide, but I'll do it any which way is all right. So what's the real concept with test-driven development? What do you know about test-driven development? A lot of experts raised their hands, so what do you guys know about test-driven development? Let's make this interactive. Write the test first and then write the code to make the test pass. Okay. Write a failing test first. That's more important. So write a failing test. So when you're saying failing, I am assuming you mean an automated failing test. It's not a Excel file somewhere, right? It's focusing on what you want rather than focusing on the implementation or the how part of it and kind of having that clear focus separation in some sense. Most often when we talk about test-driven development, people think it is a testing practice. It is a thing that we do for testing, right? That's one of the problems with the name test-driven development. This people think it's about testing, but actually TDD is about design. It is a design practice, not a testing practice. And so a lot of times people start focusing on all the edge cases and all of those things when you know the point is about does it help me flush my design out, right? So it's a design exercise and we'll look at that. So just quickly recapping, we add a test. It's obviously an automated test so we can run the test. When we run the test, we expect the test to fail. What happens if the test passes? You've got to be suspicious. Something's wrong. Maybe your test is not right. So idea is the test should fail. And if the test fails, then what do we want to do? So make a little change or add some code. Make a little change to your code to make it pass, right? So focus right now is to get the test to pass. The focus is not can I architecturally build an awesome thing? Can I really have a great performance, you know, I'll go for this. That's not the focus at this point, right? Our focus is to make the test pass and if it fails, continue running it till it passes. And once it passes, what do we do? Good, so now is the time to actually focus on the design. Now that you have a basic working thing, now let's look at how to make this design better. I'm not saying you write sloppy code and then try to make the code better. But in spite of putting in your due diligence and writing good code, you will always find that design is an iterative process. It's not a one-stop thing, right? So you will still find ways of improving the design. You might think of better abstractions. You might think of better things. And so you would refactor and we refactor always on passing tests. And you go back and repeat this cycle and that's kind of in a nutshell what TDD is. I first read about this in 2001 and I actually fell off the chair laughing. I thought this must be a joke. Someone's like pulling off a real good one here, right? How is this even practical? How can I even write a test without knowing what my implementation or what my design looks like, right? So it just seemed impossible at that point. But the more I practice, I think it took me about four years before I could say, give me any problem and I can test drive it. So it's about four years before I could actually get that real comfort of what test-driven development is all about. And it's been about maybe two years I don't write any tests anymore. So I've kind of moved on from test-driven development. But I still think it's a very important practice, especially when you're working in large teams. My context is I work in a really small team and it's a team of really sharp developers and pretty much not stepping on each other most of the time. So we are okay to kind of do stuff on our own. But if you're in a large team, some of these things become more important. From safeguarding your code from others, changes from communication point of you and other good practices that come along with it. Anyway, so that's a quick background about TDD. And let's kind of, I don't know, like anyone who's done test-driven development have you asked the question, why such a fundamental change in the way we're doing development? Because this is in my opinion a fairly fundamental change in the way we do software development, right? I mean, we're kind of, at least I was used to doing analysis, design, then coding, and then if any time was left testing. But I was a good developer, so I never needed testing, right?  And then this seemed like a fundamental change in what I believed how to do software development. So has anyone wondered why such a fundamental change? So what I'm hearing is basically it's about early feedback, right? It's ability to have something quick and early feedback, not just for the programmer, but also get something quick and running, get it up and running. So you can actually demonstrate it to someone and see what someone wants is kind of what you're trying to build. So a lot of people talk about this as a tool for rapid development. Which is kind of contrary to what a lot of people who look at this think about because they say now it's going to take double the time to do software development than it used to be. So there's some very interesting non-intuitive aspects about test driven development, but the most important thing for me about test driven development is how it helps me design thing or how it gives me a way to design things and to learn things very quickly because of the shorter feedback cycle. If I have a doubt and I want to try out something, I write a test and I quickly try it out, right? So it gives me the ability to try out things. And that's going to be very important as we go in because we will say, okay, this doesn't look, this has some side effects. So can I change this so that I can get rid of the side effect? And can I experiment that very quickly? Right, so it gives you a platform to experiment things very quickly and give you feedback about that. To me, that's a very important aspect that we will look at, all right? Let's kind of jump into some basic setup. How many people want to code along? Right, that's good.  All the slides are already available online. So in case, if you want to make notes, don't worry, it's already up there. Okay, done. Once you've got that, run an NPM update. It might take a little while to run the NPM update, but just fire it up and let it run in the background. The idea is to have this completely self-contained so we can work on this. And then we're going to get into basically installing the Karma command line in case you want to run things from the command line, and I've just installed it at a global level so I can use it in any other place. And once we have done that, I'm going to switch now and I'm going to show you all these steps I've already done. I'm going to switch now and start from the Karma init step here. Okay, is this visible to everyone? All right, so let's do Karma init. It says what framework you want to use for this demo. I'm going to be using Jasmine, which is a TDD slash BDD framework for JavaScript. It says, do you want to require JS? No. What browsers do we want to run our tests against? One of the nice features about Karma is you can run your test against multiple browsers simultaneously. So as you're developing, you can get feedback around the different browser combination. I'm going to go with Chrome, Firefox, Safari, and Phantom JS, right? It says what locations do you want to include whereas your source file. So I have something in Lib, which is all my external dependencies. Lib.js, I have stuff in my source slash, this is not there, that's fine. And then finally, my spec slash, star, star, slash, star, spec.js. So this basically takes the stuff. I don't need anything to be excluded. Do you want Karma to watch files? No. And that's pretty much it. So it's generated a config file. We can quickly jump into the project here. And we can see where the config file is generated. So this is not source, this is JS.  And here are all the browsers that we want to run the test against, right? Now what we can do is we can simply right-click and run these tests. It's going to spin off different browsers that we mentioned there. And right now we have a very basic spec, an empty spec. I guess the spec that I had in here, which is an empty, just a basic spec. What it does is it basically makes sure that jQuery is available to you. Just a very basic stuff. Everyone's with me so far? Is this getting the basic stuff out of the way so we can start focusing on building the jQuery plugin itself and trying to build this more in the functional style? So this is good. Let's get this out of the way. We don't need this. So this is our spec and this is our basic jQuery plugin, just the shell, nothing inside this as of now. This is a pretty standard way of writing a jQuery plugin where you basically try to scope yourself the dollar within a function, an anonymous function, and then directly just call that.  This is our jQuery commences, our plugin that we're going to be building. So what is the first thing we can think of from a functionality point of view that we would want to achieve? I would say the simplest thing I can think of is what happens if there are no comments to be displayed. Is it possible? There will be always a case when I have no comments on a page and I want to basically show some kind of a nice message. So should show a nice message when no comments are present. So we need to call our jQuery. So I have, I am hoping that there would be some kind of a div called commence div and I basically want to call the jQuery comments on top of that and once I do that then what do I expect to see? I expect that the commence to have element, I am thinking what should be the right thing to do. I want to basically want to figure out on the commence if I have a commence then it should contain, to contain element. What element do I expect this to contain? So I could say this should contain an element, some kind of a empty div, some kind of an empty div with a message saying that no comments are present, something like that. So I would expect this to be a dot or a div dot empty, let us say and then I would also expect, find the same thing div dot empty to contain some text, what kind of text? Be the first one to write a comment, something like this. This is what my expectation is that once I actually have my plugin built, if I run this, then it should contain a div with an empty inside it and the empty div should contain some kind of a message. Now one of the things we need to do is we need to actually have a page on which we are going to have this commence div. So we are going to use a quick thing over here, so I am going to set fixtures and I am going to add a div with an id commence, so this is going to add whatever this framework is going to build an in-memory page and on that in-memory page it is going to add a div with commence which is what we are going to operate on. Notice it is actually not going to, you do not need anything more fancier than this to be able to test this out. So it is pretty simple, we have got that, we have got this. So now let us go back and run our tests and see what happens. Is this looking okay to you guys? What do we expect now?  So should find jQuery is still passing, however it says cannot find a reference, oh okay, it cannot find set fixture. So that is basically, we need our karma config file and let us add one other thing this needs. This needs jasmine jQuery, this is another plugin for the karma framework which allows us to write stuff on the jQuery specific stuff which is where these methods, the set fixture methods would come from. Let us run this, there we go. So now we are seeing that should have contained this element but we do not see this element, that is what it is telling us. So what do we do? What is the next step? Write the code to make this test pass. So it is complaining that we basically expected the commence container selector to contain an element div.mt. So right now we do not have a div.mt because our jQuery plugin is not doing anything at all. So we need our plugin to actually, so we need to write some code inside our plugin, right now we are just saying return this. So what do we do? Basically we can say something as simple as this. What class is this? mt.append and what was our message? Let us copy the message, this is what we want. So this is going to give us a mt div, right and then we want to say this.append the mt div. That is it, that got our very first test to pass, right. That is basically saying whenever you call this plugin, it is always going to give you an empty div because there is no way you can pass anything into it. So let us do something a little bit more interesting now, right. What is the next thing we want to do? So I am going to say should display a single command, right. So I want to display a single command. So I am going to first time copy some of these things and then we are going to refactor later in the once we got the test passing. So I have the comments, I have got this thing and then there needs to be some way to pass the comments, right. So there are possibly in our plugin there are two ways you can pass it. One is you can pass in a list of comments into the function when you call it or you could pass a URL and it will basically fetch the comments from that URL. So we will start with the easier one which is we are giving it the comments, the data. Next we will look at basically fetching using Ajax from a URL the comments back, right. So what we need to do is we need to pass comments this thing. So let us say comments and our comments is going to contain, it is going to contain an array, right, an array of comments. So what is the first element? So this might have something like the message itself of the comment, we are going to say first comment and then this probably will also have the user who put in the comment, right. So this is going to put my name here which I cannot type. So we are right now passing one comment which has a message and a user and we are passing that into our comments. And then what do we expect? We expect that the, this should not contain this div empty, it should actually contain a div with comment, right, we want to nest it inside a comment and then we are saying find this comment and this should contain an element, what element would this contain? So I am going to say actually that might, let us do this, this is a simpler one. So this is going to say this should contain our comment, right, first comment by, something like this, our comment div should contain something like this, we are going to evolve this, we are going to make this a little bit better, but just take some quick baby steps to get this to work. Let us run this, expect what to fail, first two tests are continuing, passing the third one is failing, it says you know you did not want this empty div, but it is there, you wanted comments, but it is not there. Everyone with me so far, taking really small steps, but we will pick up pace as we get more comfortable with this. So what do we need to do in our plugin? First of all we are taking some options here, right, and you know the jQuery standard way of doing this is you are going to have some defaults. This is also very functional in style, I will talk about that a little bit, but what we are going to do is we are going to take some defaults in which we are going to say comments is an empty array in case the user did not pass anything, just take this and then we are going to say var options equals extend defaults and then override it with the options. So if some options are passed in then map it on to this defaults, override the defaults, if nothing is passed in then just take the defaults, right. So now we have options which basically should contain the comments or nothing. So if options.comments.length, is it length or size, length equals, now I do not want because equals 0, then we want to do something like this. So I am just going to rename this to a better name, so let us call this content and possibly what I want to do is, notice I am intentionally not really trying to write the most elegant code right now, I am just trying to get this to work, so then I can make it much better, so I am going to put an if else and all of that stuff but eventually rather in the next one or two minutes we are going to get rid of that. So next what do we want to do, so if the comments this thing then we are going to say, we want to loop over all the comments now, right. So we are going to say options.comments.or each, I say the function which we will get an element and inside this we are going to take each element and basically plonk it on into our top level container div right, we will need something similar to here, right now it is safe to assume that we only have one comment, so I am just going to directly try and plonk into this, we said we want to take the element.comment, not comment, element.message by element.user. Would this work, yeah, no, should right, let us run the test, so enough that work, obviously it does not work if you pass more elements and all of that stuff but right now our test is not forcing us to implement those kind of logic as of yet, actually I am going to reduce the size a little bit, so it fits little better on the screen, is this still visible to you guys, okay cool. So we got the test passing, now what is the next step in this cycle, so we move on to the next test or do we want to refactor and clean up some of the things that we have done, right, so now is the ideal step where we want to actually clean up some of the stuff, improve the design, right, so the very first step we can see is there is a bunch of duplication here, here and here, right, so let us get rid of that, we will use something called for each or before each, before each what do we want to do, we want to set these two guys up, end up making this over here, so it is accessible downstairs, so we can get rid of these two lines, okay, what else can we get rid of, quickly run the test, still should be passing, expectations could be cleaned up a little bit, right, I will leave that for the moment because you know we are going to revisit this in a minute, let us come to a production code and see what can be improved here, I would be inclined to take this whole thing out into a separate thing and deal with it over there, right, so I am going to simply extract this into a global function, I am going to call this as commence html, so what I just did is I pulled out all that stuff from here, so that this function remains as simple as this as we go building on, here we do not want, here we only want jquery specific stuff and then we have, we want to decouple ourselves from any jquery specific stuff and we want the rest of it to be kind of clean, more specific to the domain that we are working on, right, this is actually a very important step from here onwards, we will see how this is actually going to drive our design in a very functional style, if you will, right, so let us get this thing going, we can obviously run the test, hope everything should still continue to pass, now what are the kind of things we can do, one pretty straight forward thing you could do because you extract this out is that, get rid of this guy, let us keep content here, is this cool, there is a typo, I would say for now this is good enough, this will be forced to change again when we write the next test, so what is the next test we want to write, actually let me pause, is this okay with everyone, this looks decent enough, right, for now, we need more work to be done and which is where we need the next test, which will force us to do more work, so should display multiple comments, we only had one comment, now let us see what happens if we have multiple comments, does it work for multiple comments, we could see the output in the browser as well, let us do that in a minute once again, so whatever, John Doe and hang on, do you want to actually see the output first in the browser, before we, I can leave this in here, let us, one of the things while we are doing test driven development, occasionally it is good to actually see if we are not working off completely in ether, right, so let us actually bring up the browser and see how does this look in the browser, so if we, we have a basic stuff over here and this guy would need, let us say R, we need to pass in some comment, right, into this guy, what did I take extra, that should be, so all I have is a basic just boilerplate thing here, it includes the javascript library, the jQuery library, the comments thing and then we are going to call our comments guy on this, so let us see how does this look in Chrome, be the first one to comment, why is it showing, be the first one to comment, oh, there we go, so I missed out that portion, so comments, right, so first comment by, so does this work, we are not just fantasizing on our own, it does actually work, actually now that I look at this, this does not look all that good, maybe we want to give it a little bit better styling, before we kind of continue doing more stuff, so maybe you know it is actually a good time, before we jump off on to the next spec to finish off this, so I am actually going to roll back that adding a new test and how do we want this to be styled, so let us say we want to say that this contains this div and this particular div I would say, let us say we want to say that this contains another div within it, inside the comments, let us call that header and similarly we have the body and in the header I would expect, in the header I would expect something like whatever by this guy and the body I would actually expect the actual comments, first comment, does this make sense, we just trying to put a little bit of structure to it, before we run, now obviously if we run the test this should fail, yeah sure enough it does fail, it fails because that structure what we have is we just plunking in straight right away into this, so let us actually build that same structure that we wanted, so first of all we said that we are going to have some kind of a div which is going to say add class, what was the class name, we said header and header we said should append by element dot user and then we said we need a body which contains the message and no by, just directly the message and then those two things then getting appended on to the, store this as a header, store this guy as the body and then here we are going to add the header and then we are going to add the body, now got the test to work, let us make sure this guy still works, there was a little bit of styling that we want to make sure works, let us actually make that just header and body, some kind of basic styling seems to be working as well as we go along, there is a library for testing just CSS itself, if that is working correctly, right now I am just focusing on the java script and the jquery side of things, so we are not really testing the CSS part, is everyone okay with me, is everyone with me so far, any questions, any doubts so far, does this seem like a lot of effort, there are libraries for testing CSS, so James Shaw has actually built one, if you google for James Shaw, there is a CSS TDD library that is built, okay, shall we continue, let us go to the next test now, I could actually get rid of these two things, it is not really required because if those two divs are not present automatically these guys are going to fail, saying I cannot find the element, so sometimes you know just writing unnecessary stuff in the test is not really helpful, so we can just get rid of that, now let us try and write the next one which is a little bit more interesting issue display, multiple comments, we got the first comment, let us take the second comment, so what do we expect here, here we specifically expect like one thing we expect is that when you find for this div.comment then oops, when you expect this size to be what, you want two elements, two divs, so we want two divs to be present and then we are going to say comments first should have this and then oops, right now it is only two, so we can simply say last, here what do we expect, John Joe and here we expect second comment, makes sense, will this work, should work right, now why, expected one to be two, expected two elements but it got only one, why, if you notice here while we are looping we are simply overriding the previous value, which worked well for case of one but the moment we have multiple this is not going to work, right, so it is a good way to basically catch issues like this, so I am going to do something interesting, so I am going to say comments dot append this whole thing and now what will happen is it will return this element with an extra div, so we can simply do the html of it, now this did not work, why it did not work, undefined is not a function, I know what is going on, let us get this guy to be the comment, you want to append the comment, now what am I missing, it is not dollarized, that is good to know why would not this work, because it is a string, there we go, all about the money, all right, this works pretty well, time to see if there is any scope for refactoring, the tests could be improved, there is bunch of repetitive stuff that could be removed but I am more interested in looking at how can we improve the design of this, what can be done over here, this is where I think we are going to go a little bit of balancing the o and the functional aspect here, so I am going to try and wrap this into some kind of a immutable object and then kind of turn that to happier functions inside that, all right, so what I mean by that is I am going to simply say new commence and then pass the dollar to it, actually let us take this guy out, that is our commence and then I am going to call a method on the commence say the 2 html by passing the options to it, something of this nature, so all tend to create a function the global scope, actually that should be jq and here I can say this dot jq equals jq or you could call this dollar if you go and then it says this is the function is not there, so create this function not there, so this is going to be commence dot prototype that 2 html which takes the option does whatever it needs to do, right now it is basically going to simply call the commence guy with the options and going to pass this dot jq, will this work, sure enough, so we just started pulling out some abstraction that then we can work with that abstraction, right and this is in my opinion going to be remain pretty much like this for the rest of the entire building the whatever your entire plugin the jquery portion is going to remain as is, right and we are essentially passing in the jquery you know the handle to jquery from here which could be swapped with anything else jquery whatever else you want to use, so you could swap it out and then rest of your logic that is out here should continue to work without being bothered about jquery specific stuff itself, I mean there is obviously some dependencies if there is some other library that you use does not have this kind of a functionality maybe you run into some challenges but otherwise this should be fine, in fact now that I am looking at it do I even need this method anymore probably not, right, so I could simply inline this function and it should work fine, inlining would not work, so we will have to do this inlining manually but it is not a big deal the only difference is here we are saying it is dollar while here it is jquery just going to rename this quickly to jquery and then actually it is just a jquery I should be able to long this in get rid of this stuff and it is complaining that inside the for each you cannot find this because this will be different let us just hold self which is a pretty common pattern people use in the jquery world or in general in javascript, okay, so that inlining worked no big deal can we start giving this a little bit more structure than what it is right now, right, one thing is we are dealing with this elements which is basically what is this, this is some kind of a comment thing, right, which has user messages possibly other kinds of things that is one abstraction that we could pull out and may be this portion then would move to its own place, its own function, right, this is basically building taking a comment and displaying that, right, which we ideally want to do in its own place we could do any number this is dealing with when no comments are present, so some kind of a null comments kind of a feature, so let us do one thing at a time here what can we do basically want to convert this into a comment, right, so we are going to say new comment and pass the element to it, let us call that as a comment and then all of this stuff could be moved into that and then we could simply say dot 2 same, right, 2 underscore html function on it, like we had a 2 html function on the comments, we have a 2 html function on the comment itself, so we need a comment similar to this and what does the comment take, it does not take a dollar, it takes an element which is nothing but json object, right, at this point, so here then we can start giving some meaning to this, so we are saying this is basically we have a message and then what else do we have, we have a user, yeah, and the function that was missing, interestingly it does not let me create that, okay, now big deal, comment dot prototype dot 2 underscore html, what was this taking, nothing and then this is supposed to build out, oh this guy also would need the jq, right, so when we build the comments we will also need to pass self dot jq, so there is another thing that we are going to have here, not elements dot jq, so self dot jq all of this should work, the only other thing that would not work here is this, that is my comment, new comment 2 html, undefined is not a function, self is not there, why do I still have self, ooh, of course need to return the comment, right, so what we have just done is done a little bit of separation, a little bit more kind of trying to flush out a little bit of the domain that we are working in, so we have the top level container which is the comments container and within that we have a comment container, a comment object, why do all of this stuff, why not just leave it in one method like we originally had, it was long complex, not really I mean this was not that long and complex, but remember we talked about this being a design exercise, right, so do we want to flush out what our domain looks like or do we want to leave it all convoluted into one big method, one of the big things to me about functional programming is the whole notion of basically expressive code, right, something that is very easy for anyone to read and understand, expressiveness is very important and then the whole aspect of composition, being able to compose things very quickly. Now to me this is kind of taking us towards that direction, another thing that we could do here which is basically, let us leave this for now actually, let us work on the next feature and then it will become a little bit more apparent, so the next feature if we go back some of the features that we were kind of talking about which actually we are going to talk about is yeah should be able to accept a comment json or url and fetch it from a server, the other thing was to display the most recent comment on the top, this is a little bit more interesting where which gets us more in the transformation kind of a mindset, right, where you have a list of something you want to transform into something else and display that, right. Now when we start working on this it will become little bit more apparent of why we had to make some of these changes, so let us take this and we are saying should display most recent comment on top, how do we know it is the most recent comment, you will need some kind of a time stamp coming in with the comment, right, so let us call it something like last posted or last updated and let us say the server is going to send us some kind of a time stamp like this, same thing we obviously need to put here, but we are going to make this more recent than the other one, so if this is 20 let us make this 21, which means that our expectation now is kind of reverse, right, so this should become last, this should become first, do you agree, we are reversing the direction, the other thing we also still need to do is just make sure the other places we update, so this remains 18 and 19 and last place to update, so with this all the other tests should continue passing except the last one should fail, let us make sure that works, should display most recent comment, so it is showing that it is actually giving us the other way round, so who wants to help me implement this, we want some kind of a sort, right, sort based on the date, the last updated time, so here we are basically saying for each and we are looping over here, right, while we are doing this for each we ideally want to do what, to sort and then do for each, right, now this is let us see if we can do this, so I have a list, I am going to say map is going to take a function, right, this is going to get an element, what do I do with that element, turn it into a comment like this and then what do I do, I can say sort, yeah, that should give me the comment in a sorted order, this might not work because we still need to implement the function which takes in C1 and C2 and then what basically sort based on those two, should we actually implement the sort function here or should we push it to the comment itself, that is a good question, let us first implement it here and then we will figure out where it actually belongs, I would say actually we have not stored in it, so last updated minus C2, I am actually not sure what order it will be but again we have the test to help us figure that out, so this is going to map this, sort this and then give us back our comments right and then I can take this comments and for each do this, is this going to work, complaining that does not have for each, so first let us make sure we add that, updated, last updated, see that, just make sure here we have passed this last updated, so we have got the last updated, we have sorted it based on some order, we need to figure out if this is the right order but also this is a string, so we cannot really do something on the string itself, so I think we will need to pass this into a date, so date dot pass is going to convert this and then I think we could do a subtraction directly, that should work, will this work for each, does not need a comment, you are right, we already got a comment, the element itself is a comment, I want to get rid of this for each as well, change it before the sort and then that would not return anything, so this still does not get rid of the for each but let us get this to work first before we jump off too much, so both these tests failed now, why did both these tests fail, should it be C2 minus C1, the order needs to be flipped, is everyone with me so far, so now the next question is can we actually push this functionality into the comment itself, so can I say C1 dot greater than C2, this is now what C1 is, comment sort of type let us call this other, so this would be other, so this is another dot this and so we are saying return C1 greater than C2, the method name, this should work, the method name is what I guess you are saying, what is the right method name for that, what is the right function, so this is actually less than or we flip it around, actually before, we are basically asking a C1 before C2, that is a good name, that should work, so let us quickly pause here, like what have we got so far, I would even say that this method of all of these conversions is probably not in the right place, in my opinion, there should this whole map all of that stuff go, should it not be in the constructor, when you are constructing this from the list, that is when probably you want to convert it to whatever type and store that sort of map, so then you can simply just display that, I would say that this portion right here actually does not belong in this particular place, ideally this should have been something like this dot commence dot for each, something like that and then in the constructor of commence, you want to say, actually we do not pass the commence here, we only pass this particular thing, so we will need the commence here, but then we could simply make this commence this dot commence equals C1, C2, C1, C2, C2, C2, this was options dot, this will start complaining, we do not have ideally to describe, we are not passing any commence, so here you would not have commence, so how do we deal with this, sorry, this will become this of commence, if that is equal to 0, then just return that, this self, all of this business that we were doing, do we really need that now, probably not, just making sure we have done all the changes, so true HTML does not take anything in both the cases, true HTML and the commence takes the dollar and the commence or ideally it should just take the options, whatever options you might have and here you are ideally getting the options and then the options dot commence, options dot commence dot map, construct a commence array, sort that and store that in commence and then whenever true HTML is called, you simply iterate over it and if the length is 0, return nothing else, append that and return the HTML, something I missed, this dot j cube, undefined is not a function evaluating this dot j cube in line number 9, that is line number 9, so we are in comment, comment should have this dot j cube, what am I missing, what am I missing, let us go back here, we build the comments correctly, I could simply say dollar, that is the problem, what do you think of this last refactoring that we just did, is this giving it a little bit of a functional feel to it, but it is still object oriented in some sense, we are doing kind of a hybrid here, but notice all these objects that we have here, are they doing anything that is you know having side effects, true HTML, again true HTML is just building something in memory and returning, it does not really have a side effect in that sense, I mean it is not yet manipulating the DOM, it is not updating the DOM, it is not producing any side effect, it is everything whatever it is doing, it is doing in memory and just returning something, I mean yeah I mean returning the string could be you know something that we would say is you know a side effect in some sense, hang on what did I just do, I said in line this, why is it saying two local variables, sorry this should just be, so what I was saying is that this is not really having a side effect in the sense that it is not mutating anything that you are passing or updating the DOM or any of that stuff, this is pretty much working on its own, right and then the last step this is where we are actually having a side effect, this line is the only line where we are actually having a side effect, on the DOM itself, we are manipulating the DOM itself, but everything about this, if you look at it is essentially side effect free and technically these I would call most of these functions and pure functions, yeah. So what I am trying to get here is that basically these tests kind of started driving me in a certain direction, so you know the testing of this becomes easier, ideally if you were really a TDD purist what you would do now is you would pick up your comments and you would start writing tests around that and start building more and more logic in it by just using the comments and not even being worried about the jQuery itself, right having to go through the plugin or any of that stuff and this would all just be in memory, you send something it gives you back a string you keep asserting that, so none of this would require any side effects and the tests really kind of start pushing you in the direction where you can keep getting you know pushing yourself towards a pure function. Let's do a quick time check, we have another 35 minutes left. So far is everyone with me any quick questions at this point before we move on? Is TDD helping here? How has it helped us so far? Let's do a quick recap. So it helped with refactoring, so remember one of the points we started when we started I was talking about like it is about you know design and why is it about design is because now I have the safety net where I have the courage to constantly keep refactoring and I could pull out the abstraction, I could pull out things, I could do things and we said okay SOT does not belong here let's move it out, this does not belong here let's move it out.  So that's the important part in my opinion, right and because of that I would say then you start applying your functional concepts on top of it and it starts pushing you in that direction, yeah. Any other observation, any other things that you think this is helping or hindering I don't see how this is applicable in real life, okay. So like there are couple of questions in there, let's break it down. One is if you have external factors which are outside your control, right, whether the internet is available or not or some other kinds of parameters, right and you have some logic written around that. How do you design such that you know you can safeguard yourself in some sense against all these variables and still be quite confident that your logic itself seems to work fine, right. To me that's the first step. Overall app itself we are not really talking at that level here in terms of the overall app but let's say I can safeguard myself and within those boundaries can I at least make sure my stuff works correctly. To me that's the first step and there again whatever external dependencies you have let it be internet, let it be you know availability of let's say GPS is on or not other kinds of parameters, right. How would you deal with that? I want to turn this into more of a discussion like what would you do based on what you have seen so far. Is there a way you can abstract that into some kind of a system? What I guess what I am kind of hinting towards is that you know you have these dependencies which are outside your control. Can you wrap them into some kind of object, some kind of a container, right and pass that in to your logic and then let your logic do what it needs to do depending on the values is going to get from this guy. So when I am actually building this when I am trying to design this I can simulate all these different values and see how my logic itself works. It also helped me design in a better way because I don't want in random different places inside my code suddenly going and calling off some system libraries or some other libraries right. I want generally one layer where I am doing those kind of things because that could change tomorrow. iOS new version could come in or Android new version could come in and they might change some of those APIs and things like that. Do you want to then go hunt around in all the places and go change it or rather have adapter is the right name for it an adapter where you would make those changes, right. So to me that's the first step and again testament development would push you in that direction because otherwise it would be extremely hard to test because it's extremely hard to test you will be forced to write some kind of an adapter on just on things that you depend on and then pass those in and that that you know in general is referred to as the dependency inversion principle right where instead of from within your code you deciding where you're going to get something it's given to you from outside and then let your code work inside that. So it kind of pushes you in that direction of dependency inversion which is again a good thing from decoupling point of view. So tomorrow you could take the same logic and run it on a different version and the only place probably you need to change the adapter. So maybe that kind of gives you a certain direction in terms of how this will help where you have a lot of other parameters that are also changing but you know that's the general direction I would take. The overall app itself whether it works or not there are a lot of other criterias like the look and feel whether it's actually being displayed correctly or not those kind of things is a separate thing and again there are different kinds of testing that would focus on that level of assurance right but to me the key is if my logic itself is not working there's no way the app as a whole will work together. Let's make sure these nuts and bolts of your application are actually plugged in and working correctly. Alright that's a good question. Any other questions so far? What does that mean? What's the difference between TDD and BDD? Old wine, new bottle kind of a thing to some extent depends on who you ask if you ask Dan North who coined that term. So Dan and I used to work together who coined the term BDD. His whole thing is the word tests in TDD is misleading okay. So let's call it behavior driven development because what we are really trying to flush out is the behavior of the system and it is not only just a programmer thing let's involve if you're working in a bank for example. Let's involve the business analyst who understand how trade work because as programmers we don't understand the nitty gritties of those. So let's build some kind of non-technical platform where people can collaborate and then use that as a way to flush out the behavior of the system. While TDD again there are different levels at which you can apply TDD you can apply at the unit level kind of what we are trying to do. You can also step back and apply it at a much bigger level. Actually what we did is not really at a unit level because we are actually testing the whole plug-in in some sense right. But now we could take each of our command and each of our commands object and then we could test drive that that would be more of a unit level thing right. So like this you can see that you can actually apply TDD at a much higher level as well. And there's a difference between outside in TDD and an inside out TDD. So if we started with the command object and we started test driving it and slowly flushed out the commands object and then something else and then something else that would be an inside out way of doing test driven development right. While what we did here is an outside in which is kind of similar to what you would do in a behavior driven development. So if you really talk there's not much difference in terms of you know it's more of a naming thing and reducing confusion. But honestly it's created more confusion. Now people are all confused what is the difference between TDD, BDD, all of that stuff. So I would actually to be purist I would say BDD is a style of TDD okay. So as the DOM structure gets complicated right again if you look at where the whole thing is moving you know let it be react or any of these guys what they're trying to do is componentize it right. So you would essentially componentize each of those things and work in components. In fact this is kind of taking you in that direction. Now I could go one step further and talk about virtual DOM right which is like the big new thing that everyone seems to be talking like how easy would it be for us to apply a virtual DOM on this right. Really what we need to do is do a diff between what the diff what changes we've made on the DOM so far and then look at the real DOM and apply only the diffs. That's oversimplifying what a virtual DOM is but that's the core idea behind it right. You're working throughout in memory DOM which is what we are doing and then look at the diff with the actual DOM and apply that diff right. So to your question if your DOM structure starts getting more complicated you know componentize it and each component can be tested right and then you will need a higher level test which will make sure these components on the DOM itself works correctly but then you wouldn't need 50,000 of those tests right because each of those components itself is well flushed out. I think that should work if you look at a lot of react kind of stuff it's kind of going in that direction a little bit. Any other questions shall we move on? Do you want to look at the Ajax one? We have another 15 minutes or so. Actually what I can do is I can quickly jump and show you instead of doing the whole thing I'll show you a ready example that you can look at it's how do you isolate yourself from Ajax request and things like that okay. Let's quickly jump here. There are other things about whether private comments should be visible to other people or not and things like that. So that again is implemented by having a JSON structure and marking something as a private on it and then making sure that's not visible to you but I'm more interested in the Ajax one. So let's get to that quickly. Okay here's one. So should fetch data from a URL and display the comments. So what we are saying here is expect this Ajax response which is going to give you this three comments. When you're saying jasmine.ajax.stub requests to a particular URL. So if a URL you know if your app request for this URL simply return 200 whatever HTTP status the content type and the JSON string. This is literally all you need to do just about Ajax call from within your application. And then here we are passing so earlier we were passing comments. If you don't pass comments and you pass in a URL then ideally you want to go fetch from a URL and get this right. So we pass a URL and then we would expect that you know whatever Jack should be first, James should be last and the size should be whatever your length was that you passed in that length. So how does the code actually look for this? So have new view and then I'm saying apply comments. Here we're doing a little bit of a passing a call back kind of a implementation and this is simply saying that apply these comments with these options and here's a call back that you know will actually do the append or whatever. So in the apply comments we are saying if option.url then fetch the comments else simply get the HTML from the comments and then call the call back. Another common question people ask is how do you test call backs and stuff like that you know can that be done with TDD. Can TDD drive that kind of a design and stuff like that. So again this is an example where we essentially ended up with a call back kind of a mechanism and that's kind of tested fully. So fetch is basically just doing our standard whatever JSON get JSON from the server and that's whenever it actually does this get JSON it will end up getting stubbed out because of the setting we have here. Jasmine will intercept that call and then just reset that. That's it that is as simple as how to do stubbing out of your HACs request. So this is again another example where you know you have an external dependency and you've stubbed out the external dependency and you're basically you know making sure for different values this works correctly.  So here when you're trying to fetch and you get an error message how does your code respond to that? Does that handle it? One of the big things about this is the negative part testing becomes so much more easier with this kind of this level of you know behavior specification rather than doing it at the end to end level.  We expect a div with error and say fail fetching commands from URL. So I'm pretty much done. I think this covers most of the stuff. I went a bit too fast because of the last time's experience. I ran short of time so this is the time I went faster. So any other questions? Otherwise this is pretty much what I had. It depends what level your requirements are changing or what your design what level your design is changing. So again what I would recommend for this particular thing is don't write all your spec at the jQuery plugin level right. You would write your tests at lower levels which is your commands, your command those levels and what might change is let's say one of those things not the entire thing. Maybe something in the command might change. Then only that needs to be tested and the tests for that needs to be updated. The rest of the stuff should work as normal. So what I have found is that this actually helps you deal with changes in design and requirements much more efficiently than the other way around because there you assume you know everything and you design something and then even a small thing changes then there might be a lot of repercussion. Here also because of the way we have built this incrementally we took one thing at a time. We didn't have the last updated time when we started. Let's say there was a new requirement that came in. That was in my opinion relatively easy to implement because the design was fairly decoupled. So that to me is an advantage. So when you have design changes, when you have requirement changes this would actually be much easier to deal with because of the decoupling that you have achieved. So yes some tests might need to be changed a few places but not everything. The more important thing is when you change the confidence that you have that actually I didn't break anything is much more important. Otherwise you end up spending a lot of time manually checking that as a developer. So it will at least save that time that you are going to be spending. Any other questions? If not the lunch is waiting. Thank you then. Something about the Ajax request, what do you want to know? This is basically a jsnin.ajx.stub request give the URL and say what do you expect in return? What is the JSON that you expect in return?  So that's what karma the framework itself is doing. It's not technically karma itself. There is a little framework called jsnin.ajx. That's essentially what is doing that. So it's the jsnin.ajx plugin in karma which actually blocks out the call and returns that. All right. Thank you guys.


Don't be running this now. It doesn't help you have a sound. Optimistic. This is yours. General Spilcroft, do you think he has votes on the Hill? I think this is a phone watch. No, but this is for the President. I am scared. God, it's contagious. I always call him a President. No matter where he is. of the National Economic Growth. And as you know, in February of this year, I sent to the Congress our federalism package comprising four megablock grants. And included as part of the federal local block grant is the preservation of general revenue sharing for five years at current funding levels. Now, knowing how the clock runs on the hill and putting that all together and knowing also that you need to plan your budgets, many of which begin in July, with that in mind, I've sent to the Congress a separate revenue sharing bill which reauthorizes that program for three years. Maybe that can move faster than the other one. But another issue which I know is important to you is the result of the recent Supreme Court ruling in the Boulder case, municipal antitrust liability. And I share your concerns about intrusions into state and local autonomy. We support legislation which would provide an exemption to federal antitrust laws for local governments provided that the following conditions are met. Local governments are acting under the authority of state law and localities are acting within their government or police power capacity. And lastly, a subject which I know Gary Jones discussed with you earlier, but one which is very important to me is our education system. The time, I think, has come for a grassroots campaign for educational renewal. We must restore parents and local governments to their rightful place in the education process. Quality education can best be achieved through decentralization of education decision making rather than continued federal direction and control. I almost said decoration there. And I think a lot of their controls are just about that, decoration. Many claim the solution to the problem is to pour more money into it. Now, I know you've heard stories about major spending cutbacks. But the total expenditures in the nation's public schools this year are expected to reach $116.9 billion. That's an increase of 7% over last year. And that's more than double what was spent just 10 years ago. While throwing money at the problem is not the solution, there is much the federal government can do to help set a national agenda for excellence in education. We should reward excellence. Teachers should be paid and promoted on the basis of merit and competence. And we can also encourage excellence by encouraging parental choice. And that's why we're trying or what we're trying to do through our programs of tax credits and vouchers, allowing individual parents to choose the kinds of schools that they know to be best for their children's needs. But I didn't come here today for a monologue. I came for a dialogue, so I'd like to hear your comments and questions. May I just before you do that say that yesterday I was speaking to the day before yesterday to a university graduation? And when that great number of students who had majored in education and were going to become teachers, when I spoke to them about pay and promotion being based on competence and merit, I got a standing ovation from the graduates and their caps and counts who were going to be teachers. But some of you must at some time have said, if I ever had a chance, would I ask him? Yes, ma'am. Yes, Mr. President, I've all been said if I ever had a chance, I'd like to tell you how much I approve of your initiatives for the nation, for our cities. And I'll wait for you 100% to continue to be with me. Thank you very much. Thank you. That's it. I'll take this young lady and then you. Mr. President, Lillian Ware from Georgia, I would just like to say how much we appreciate all you have done for us through the state of Georgia, but specifically with the Small Cities Black Grant Program through the Community Development Program. We want it to retain its same posture, the same mandates that are in it. It has been one of the most workable programs for our people. And I was happy to have chaired the policy procedure through our department of community affairs through the state of Georgia and setting it out. And it has been a most desirable program. And I hope it retains the same. Thank you very much. These are the best questions I've got. Mr. President, Mike sitting from Florida. It's our indications that the Federal Revenue Sharing Program has generated quite a bit of support. And there's a good possibility that the bill may come to you with additional money. Would you be supportive of that or would you be inclined to be? I'd have to look at that as to where it fit with the other things that they're asking for up there to see very frankly whether we could afford it or not. I have a great affinity and affection for general revenue sharing having been a governor. And my whole impression of federal programs then could be summed up in one in which I vetoed. If you remember a governor could veto a federal program. And if it wasn't overridden in 60 days by Washington, it stuck. And this one wasn't overridden. I think public relations had something to do with it. I remember it was a block grant that was going to put, or not a block grant, it was a grant that was going to put 17 of our workers in one county to work in helping with the county parks. Well now that sounds like the very thing, these were welfare recipients, the very thing that I would want to do, except that half the budget was going for 10 administrators to make sure that 17 got to work on time. Mr. President, Don Griffith, Mayor of the City of Levin Pennsylvania, and President-elect of the Pennsylvania League of Cities, we in the Commonwealth pride ourselves in trying to do our homework. And I wanted to let you know that we provided for you through, I believe, his name is Rick Neal, some homework that we did on the impact of revenue sharing on local government broken out by congressional districts in the state of Pennsylvania. The Commonwealth of Pennsylvania had one of your representatives work with this. I should look forward to reading that. Thank you very much. All right, yes? Mr. President, I'm by Joe Swap from Tennessee, and I guess on behalf of Senator Baker, I'd be tempted to ask you and the Vice President if you're planning to run again. But I think that wouldn't be appropriate. I would like to hear, Mr. President, your idea in the effort to return power and money back to local governments, the idea that sometimes we get that if you return it back to the state, that that solves the problem. Very often we find, I think, gas-saving taxes, example, $84 million going back to the state of Tennessee, and none of it going to local government, all being used by the state government. I would like to hear your comment on this. Well, no, we have called for mandatory pass-throughs of funds that have been an unblocked grant but that have previously been distributed to other echelons of government. If there'd be a mandatory pass-through on those, and then I think we have some of the grants that are going directly to local levels of government. We're aware of that, that problem, and we've heard this before, I can tell you. So we're going to make sure of that. The other thing is that over the long haul, the whole theory back of federalism, in my mind, has been to not only get the funding back, but eventually transfer that in the line of tax sources so that the level of government that is then responsible for the program is responsible for also for the raising the money, because I've believed from my own previous experience that part of the fault has been the federal government and why it has to now turn money back in grants is because the federal government usurped so much of the taxing authority that you at the local and the state level didn't have tax sources that you could call upon. But I think that that would be better and then I think that it even ought to continue through the state level because we also tried to do this in California before it got here, and that is that there should be a constant study and review of what level of government is best qualified to perform certain functions. And that's the dream of federalism and where I hope it winds up. And I know that he's going to tell me this is the last question I can take. Mr. President, I'm Bill Gorman. I'm the mayor of Madden, Kentucky, and president of the Kentucky Municipal League. In Kentucky and throughout the nation, we've had this deregulation of natural gas and I would request that you have your administration look into it. The price of natural gas, for instance, has gone up 400% to our people. And we're in Appalachia, we've got a lot of people who have a few problems and I request that of you, sir. We think that we remember the storm that was raised when we proposed a deregulation of oil and it turned out the prices didn't multiply and double as everyone said they would, they went down. And we think that if regulation of natural gas was doing what it was supposed or designed to do, no opposed to what it was supposed to do, not designed, it was designed like a camel that was made by a committee. The idea that the gas prices increased so many times and so substantially under control, I can't believe the decontrol couldn't be an improvement. The natural gas pipelines are controlled by monopolies in the areas such as ours. There's two gas lines and all of these to conduct and we have no chance to buy from other sources. It's not like buying gas at the corn filling station. But you do have some controls through your own statewide and local public utilities commissions, don't you? Well, at least you must say that in our decontrol we have provided for that there's not going to be any, they're not going to be allowed to pass increased costs through to the customer. We're protecting the customer against that in the decontrol that we've proposed. Well listen, they've told me that I can't take anymore and I have to go. Just for whatever you may need sometime in my discussion here or my mention of the federal government and the proper echelons of government, I have a little story that you might use at some time in speaking to a Rotary Club or a Kiwanis Club or something of your kind and that is the local community that was going to raise its traffic signs, warning signs from five feet above the turf to seven feet above the turf because they'd be more visible then from automobiles and for traffic and the federal government came along and told them they had a program that they'd do it for them, wouldn't cost them anything, the federal government had paid for it. The federal government's program called for lowering the payment two feet. All right, thank you. Okay Mark. Thank you.


We just made this four foot porch leaner using our desktop laser for a good profit and we'll show you how we did it right now. What is up? Welcome back. Do like to do it, be able to make it. So do we. And we have a new video each week. This week, summer is around the corner and craft shows are in full swing and our customers are begging for porch leaners. So this week, we're going to use our omtech desktop polar laser to make a vertical porch leaner. A couple of weeks ago, we designed this summer door round and we're going to make the perfect matching porch leaner to go with it. Step one, we're going to gather all of our supplies. We needed a four foot one by 12 but I thought I would save some money by getting an eight foot one by 12. That was still expensive. I did a little bit of shopping around and I did find an eight foot one by 12 that was labeled shelving. We're going to cut that in half, making that board only $8. Then I needed five quarter inch MDF boards that are sized for my desktop laser. This was about $10. We also needed some glue. We're going to use this Starbomb thick. This stuff is great. You can find this in our store at kngmakeit.com and we're using exterior house paint. These are not pressure treated boards. These are unfinished boards. So this exterior house paint will help seal this board. And it will also seal the MDF. Step two, we're going to make all of our cuts. I'm going to cut the one by 12 in half using a miter saw.  From Lightburn, we're just going to import the SVG. I have a version that's for desktop lasers. It's broken up into chunks that will fit inside the desktop laser bed. There are 12 by 20 chunks. Actually, they're like 11. We're just going to zoom out, grab the whole thing and move it up so we can cut our first part. And then everything in blue, all the blue score lines are score lines. So all the blue is score. And my speed for that is 200 millimeters per second and 15% power. All of my red lines are for cuts. And for that, I use five millimeters per second and 50% power. And I'm using a 50 watt laser. And it cuts through just fine. So let's go power up and get this first section cut. All right, the first section cut beautifully. So we're going to select everything again, control A, let's zoom out so we can grab the middle, move it down to the next section fits in the laser bed, just going to select the stuff that's in the laser bed. And we're going to cut this section out using the same speed and power for score and cut. And we're just going to do the same thing for the rest of the cuts. Once I'm done, I'm going to drag it down, cut the next section, drag it down, cut the next section. Time to shape it up. We're going to use this little Dremel tool here and kind of give everything some rounded edges, try to make his beak look rounded. So what we have here is a little standing gnome porch leaner, except our little gnome here is ready for the beach or ready for the pool. He can go either way. And he's got himself a little flamingo floaty around the waist. And it's really cute. It's round. So I thought we could round the edges to really make it look like, yeah. It's filled with air. Yeah, yeah, I get it. And I think that will look cool. We got the beach ball. We could do the same thing with the beach ball. Beach ball. I think the floaty beach ball and then maybe the sun. We carved the sun up a little bit. OK, look real. All right. We're going to use these little foam rollers to roll everything. Yeah, you can get these at any hardware store. Again, we're using that exterior house paint, which I have put in one of these FIFO bottles. You can get these in our store at kngmaker.com too. But these are a great way to store your paints and something usable that you can just squirt out. And then they sit in here. I actually have never cleaned the inside. So, you know, at least it's not ketchup. You just keep filling it out. It is. It's like a paint condiment bottle. So we're just going to apply it right to our board here. We use one that we've already used to keep them in these little baggies. You don't even have to touch them. Keep them fresh for a couple of days. A couple of weeks. A couple of weeks. Yeah. All right, I went a little light because I know you sometimes go heavy, so I'll put another coat on. I think we can get this done in one coat. Yeah, I know. Oh, one coat garret. Oh, one coat garret. That's what they called me in college. I'm just trying to get the hands. So for our little pieces, we're going to put some tape down on our table here. This is just painter's tape. Ours happens to be green. You'll often find it in blue. We're just going to lay down some strips of it with sticky side up. And then you can put all your pieces on it, paint them, and they won't roll away when you're trying to hit them with a roller. And then I'm going to put a little piece at the top and the bottom to tape them down so they don't move while you're working on your pieces. I'm going to start with my hat. So the cool thing about this hat is the one set of stripes is already held together with this frame here. And then we'll just paint the other set of stripes separately and put it back in its frame. If you don't have a desktop laser, you can still purchase this as an unfinished kit. Just like you see here, all of these pieces come in an unfinished kit. And you can find that in our store at kngmaket.com. And we have the matching door round to go with it.  All you need to do is buy the one board, the 48 inch board. And another thing, the home improvement store, we'll cut that 8 foot 1 by 12 in half for you. You know, you could get all of our files behind the scene content and even a Kim and Garrett After Dark podcast. As well as monthly Zoom calls, access to a secret Facebook group. And we'll even send you one of these fancy t-shirts, all for $20 a month. It's the best way to support this channel. So join us over at patreon.com. Step, we're going to bring it all together with some star bond thick. This is the thick stuff. That way it'll fill in the gap between the board and the MDF. All right, I think we should lay it all out first. I agree. I think we should lay it all out first. Make sure it fits. See where everything goes, known as glue finger. Look at that. I mean, I might have just invented a new thing, a glue holder. You just glue it to your finger to get going. And then you don't need to ever set your glue down. You just look at me go. I mean, I think I'm going to start using this technique. This is a good technique. I don't have to reach for it. It's just here. Woo. I feel like one of the Harlem glue trotters. It's pretty stuck. Time was about 90 minutes.  That looks like those little knobby knees. I love this sanding technique. Look at how it really made this thing look rounded like a floaty. Look at this beach ball. It looks awesome. You could probably get 65 for this. So that's a $44 profit. That's a good chunk of change. Now, if you don't have a laser and you're still feeling these summer vibes, you can get this kit in our store at kngmaker.com. And you can make one for yourself. All right, this guy's got me feeling some pool vibes. So I'm going to go hit the pool. It is 84 degrees here today. I think it's 86. So I am about out of time. Still sticking with my glue. It just came off. So if you're not going to join us for the patron after show, we will see you next week. We'll do it. Build it and make it again. Don't forget on Tuesdays, we go live with a new test cut. You know, something like this or a door round. Yeah, we have a pool version. See that it has beach at the bottom. We have a pool version of this one coming up too. All right, so join us on Tuesdays. Oh no. This one's not bad. When we repair this one after- It's well balanced. It has a well balanced sign.


So, some strategies to overcome some of the challenges to teaching learning include really a capacity building within institutions like universities. Oftentimes teaching can be a very kind of isolating experience and things that happen in the classroom don't kind of get shared outside the classroom and a great advantage and it can also be a scary part of online teaching is that what's being done is a little bit more exposed and so that enables you to potentially show a colleague a module that you've developed ahead of time versus requiring that individual to come in and see you teaching in your class and so there's opportunities there to share something and to get feedback on it. We may have training and experience in teaching and learning pedagogy for face to face or lecture in different formats but not so much online and that's where institutional resources, individuals who have more training in these more recent pedagogical tools where they come in very handy so you do get consultation and advice on course design that's really quite different than your traditional face to face class. Another way for addressing challenges is to look and try and inform what you're doing in the classroom with what's worked well what are best practices. I had to use different rapport building strategies in the online environment so I developed a lot of get acquainted activities which I actually have taken from workshop ice breakers that I didn't think would work necessarily in a face to face class but they work really well online surprisingly so I do a lot of ice breaker stuff just to get acquainted and I do some disclosures that are that they're willing to make that I build on later. I like to be recursive so that if they reveal early I come back to it later and pull it forward and connect it to the subject matter that has helped with some of the community building and some of those challenges. That challenge of engaging students then turns into an opportunity because in an online environment for example setting up a kind of a discussion form of some sort you can make sure that everyone participates because they're you know graded on it or something and you can you can create a number of engagement situations. In the early going I have to be engaging with them a lot the first two or three or four the first month of class the engagement is almost non-stop so I mean anyone who thinks you just load it up there and let it go and it'll run itself I have found out no unless it's a it's a very unless it's the type of course that just requires individual sort of participation in a series of projects but the first month I'm heavily involved engaging with them I have office hours that are synchronous so that they can get a bit of a synchronous feel I do podcasts so they can hear my voice. We do avatars we do proverbs we sort of disclose things about ourselves where we're from that kind of thing so I try to do the those types of things early in the course to sort of build rapport because then I find it unfolds better in the second and third month if they've got a feel for each other and not just the people in the class who they find some resonances with or it's not just between me and it's not like it's 30 students having individual relationships with me. One of the strategies for getting students to engage in virtual discussions with the teaching team are online chat sessions especially if there's a reward for them and having TAs more involved in your classroom activities I think that's an important way to to deal with it. I offer students a bonus point if they come to my office hours or if we arrange a Skype or FaceTime session and in doing that I'm trying to communicate to the students that getting to know them even a little bit is really important for me. To overcome challenges in an online environment really consists of ensuring the students that you are there even though they may not be able to see you at all times you need to assure them that you are there you're available if they want to face-to-face meeting that's just fine but for the majority of students who will not come to office hours and prefer to communicate by electronic means that means that you have to be available by electronic means and typically that means that you need to be available after class time so in the evenings and on weekends. I've tried doing an intro video so you talk you know talk to them about who I am so they get a sense because it's also weird for them and disorienting for them for all they know I'm a username on the system they don't really know me they can look me up I suppose but I find it's easier to come across in your or the video help to communicate kind of who I am and what I think about the course and what I'm trying to do. Some strategies for overcoming online challenges I think one of the big ones is that because students have to be able to manage their time and be very self-directed and motivated you have to try and give them as many signposts along the way to keep them informed as to what their progress is in the course you have to be extremely organized so that they know exactly what's expected of them each week for every component of the course and you have to communicate that extremely clearly to them in different ways in different parts of the material through the syllabus and online through the discussion board announcements as many different ways as you can to try and make it extremely clear to them where are they now where are they supposed to be where are they going next.