Here's another Helper function role. It says that when we shift knowledge
domain we should use a Helper function. That sounds kind of weird, but really all
it's saying is that if we're in the middle of designing a function about one
thing. Maybe this function is about apples.
And then we need to do a very different kind of thing, maybe oranges.
Then right there is where we should put helper function call.
Maybe the apples and oranges doesn't explain it, but I think you can look at
the examples in this video. You'll be able to understand when to use
this rule. Now I'm working on finishing the insert
function. We've already got the wishlist entry.
So the next thing to do is to work on the examples.
And at this point in this program, what I'm going to realize is, gee, you know?
I've got a lot of examples involving images of different sizes.
And they get kind of cumbersome to write, so I'm going to do something that I might
have done earlier. It's fine that I didn't do it earlier,
and I don't absolutely have to do it now. I'm just doing it so that you can see it
happen. What I'm going to do is, I'm going to
take these examples that I've been using. And I'm going to take the images that
I've been using, and I'm going to turn them into named constants.
So for example, this shows up in a lot of my examples.
I'll just go up here to constants and I'll make a special section of them
called for testing. And I'll say define i1 is this thing and
then what I'll do is I'll say let's find every occurrence of this thing and we'll
replace it with I1. We're not going to replace that one
because that would be circular. But we will replace this one and this one
and this one and this one and this one and this one and this one.
There were a lot of them. Not that one.
And then will do it again for the other ones.
20, 30 solid red. And then 30, 40, solid green.
[BLANK_AUDIO].
And one important thing here is I ran it, and unfortunately the program wasn't
working. When I ran it, because we knew that we
were in the middle of working and so I'm not certain that I didn't make any
mistakes. But I did it so systematically using
finer place that I probably didn't make any mistakes.
Whenever you do something like this you want to at very least re run it.
To make sure your program is still well formed.
And what I probably would also do is take the trouble to redo the line breaking.
And in some programming environments, you would get some more automatic support for
this kind of thing. Basically you're taking a recurring
constant expression and replacing it by a named constant.
That's a refactoring that some tools will give you automatic support for.
And that kind of support has been in programming environments for years and
years and years. Larry McCenter put that in the inter less
D programming environment in the '80s at least that long ago.
Alright, now we're back to insert. So let's do some examples, so we're
going to insert some image, well, now we've got names for images.
So we'll insert I1 into, we need the base case example first so if you insert an
image into an empty list. You know, there's only one place for it
to go which is the beginning of the list. That's the result there.
Now let's see. Another example is to insert I1 into a
list that already has I2 and I3 in it. And in that case it goes right at the
beginning. And now that I've got these nice named
constants I can really do all three cases.
That's also Insert i2 which goes in the middle.
And will produce that result. And let's also insert i3.
Which produces that result. So now we've kind of got the full space.
It either goes at the beginning of an empty list or it goes at the beginning of
a non-empty list. Or it's somewhere in the middle of a
nonempty list, or at the end of a nonempty list.
That looks pretty good. Now we've got some examples.
Let's run them to make sure they're well formed.
Oops. One of my example isn't well formed.
huh, and since I copied and pasted, it's going to happen a bunch of times.
There that empty. That's okay, we'll fix it quickly.
Lets try it again. Okay now they're well formed but of
course they're failing. Cause of the stub.
Let's see, let's go get the template. And we'll copy the template down here.
We'll comment out the stub, oh dear. When we, we're designing this we name the
parameters lst and we tend to name them loi.
There's two ways to fix this. One is to go ahead and name it lst
throughout this function. The other way is to be more consistent
with what we were doing in other functions...
Both work, but I think what I'll do here is just tell, I'll take the approach of
being more consistent. I'll change that to loi, and that to loi,
and I'll do it to in the stub even though the stub has been commented out.
Now, I just like being consistent. So now, loi has the right name, but I do
need to rename the function itself and rename the natural recursion.
And this is a function that takes two arguments, whereas the template of
course, only takes one. So we have to add the second argument
image, and remember if you go to the design recipes page.
And you go to the data driven templates page, there's a rule that when designing
functions that consume additional atomic parameters, the name of that parameter
gets. Is added after every dot dot dot in the
template. So, we gotta do that here, so let's see
img is going to go there, and it's going to go there.
And something has to happen here, because Insert wants two arguments.
So, I'll just put ...img. You could put that.
Sometimes I would just put that, but I'll put ...img in this case.
Okay, they're both equivalent. Both are a note to myself saying, hey,
remember, insert needs two arguments. So, now let's get going.
In the base case, we're inserting image into an empty list.
And that corresponds to this first example.
And so, we just put this image on the front of an empty list, like that.
The next three examples are telling me that sometimes the inserted image goes
right at the front of the list and sometimes it doesn't.
In this first case, i1, the image that we're trying to insert, is not larger
than i2, and so that means that i1 has to go before i2.
That's what it means for the items to be in increasing order of size.
Because i2 is bigger than i1. And i2 has to be after i1.
But in this blue case, we're trying to insert i2.
And the first item in the list is i1. And i2 is bigger than i1.
So that means i2 has to go after i1 somewhere.
Again that's what it means for them to be sorted in increasing the order of size.
And the same is true for this blue case, i3 is larger than i2, so i3's got to go
somewhere after i2 in the list. So what these examples are telling me is
that at the very least there's gotta be an F here.
Because there is a case where i1, the inserted item, goes at the beginning of
the list and there's cases, the i2 and i3 cases where the inserted item doesn't go
at the beginning of the list. So there's gotta be an if.
And if there's an if there has to be a question so what's the question?
Well the question has to do with comparing the sizes of the image to be
inserted, with the first item of the list.
So we need to do something here, with these two things to know, is image bigger
than the first thing in the list. And you might put a note to yourself here
is bigger now the question is how we going to do that.
Well you know we need to determine if the area is different so we're going to have
to get, width and height of the image. And the width and height of the first
thing on the list and, and we kind of have to determine their size their
relative sizes. But thats kind of complicated.
And not only is it kind of complicated, but its about a different kind of issue.
This function is really about inserting into a sorted list.
Whereas this little piece of code here is about comparing sizes.
And sorting a list is one kind of knowledge and comparing sizes of images
is a different kind of knowledge. So what we've got here is a knowledge
domain shift. We're shifting from knowledge about
sorting lists to knowledge about comparing the size of images.
And there's a helper rule that says when the knowledge domain shifts you use a new
helper. So I'm going to wish that there was some
other function called larger. That compares the size of these two
images. And produces true if the first image is
larger than remaining images. And if image is larger than the first
thing on the list then what happens? Well that means image is going to go
somewhere after the first thing in the list.
So, what we're going to want to do is say something like, cons the first thing in
the list, i two is bigger than i1. So, i1 the first thing in the list, is
going to come first and then, we'll have the natural recursion.
And the natural recursion will just take image as its first argument.
And what this says is it says, put image somewhere in the rest of the list and put
the current first of the list in front of that.
Otherwise, if image isn't larger than the first thing in the list, then this is
where it goes. So, we are just going to to put image
right here at the front of the list, here it is.
Now, we wish for this function larger, so let's make the wish list entry.
It consumes an image and another image and it produces a Boolean.
Produce true if image one is larger than image two by area.
That's a wish list entry. There's a stub.
Let's get rid of Hydro place now and run and see if we're well formed.
We are well formed, but a bunch of tests are failing.
So what's happened here in this function is we made some name constants in order
to make our tests look better. We just methodically generated all
possible variants for the tests, copied the template as usual, added a parameter.
And then it was all pretty clear what we were going to do, we needed to know the
relationship in size between image and the first thing and the last.
But that involved a knowledge domain shift.
We were switching from the domain of sorting lists to the domain of comparing
the size of images. Those are two different kinds of
knowledge, and so there's a rule that says that's a good place to put a helper
function. So we wished for larger, and that's where
we are right now. Turning again to this overview diagram.
Where we're at is that arrange-images is done but it's waiting for sort-images to
be done. But sort-images is done except its
waiting for insert to be done and insert is waiting for larger to be done.
But so arrange-images, sort-images, and insert are fully coded.
But until larger is done we can't really be sure that those other functions are
done. And larger is what we're going to do in
the next video.