Elevators Transcript
[00:00:01]
INSTRUCTOR: Let’s help bit solve the elevators problem. So bit needs to climb to
the top of the building using the green elevators. So you can see bit starts here in
the corner, it’s going to move until it hits a green square.
Start visual description. Screen reads elevators.py. Bit needs to climb to the top of the building, using the green elevators. There are two images of grids that show what the output should look like. End visual description.
[00:00:14]
That’s the cue that bit needs to rise before proceeding. So once again, a nice
event stream style problem. And so let’s set up that pattern and then let’s talk
about the details. So if I come into PyCharm, you can say bit moves to the end of
the screen going up green elevators along the way.
[00:00:45]
So what’s the final condition? How do we know that Bit should stop? You look at
this, here Bit never runs into any walls until the very end. So it looks like maybe
front clear is a good choice. So I can say, well, now, maybe even easier is we can
just say, you know, while should keep moving bit.move.
[00:01:12]
And then if onElevator bit, bit dot, let’s say, go in elevator, bit, there, there’s our
overall structure. If we should keep moving, move, and if we’re on an elevator, go
up, maybe we should go up, go up elevator.
[00:01:40]
Okay, so keep moving, come back, show context actions, create a function. In this
case, it could be quite simple. Return bit.front clear is actually the only criteria
we have for moving forward.
[00:01:56]
So sometimes I’ll sketch out a problem like this. I should keep moving. I’ll deal
with what that means later. Find out it’s actually quite simple. Could I instead put
front clear back in here? You could.
[00:02:08]
Or you can leave the function there. That’s not necessarily a problem. It helps
document or communicate the intent of what’s happening. And that’s fine. So
while we should keep moving, we’re going to move along.
[00:02:25]
And then if we’ve hit an elevator, we want to go up it. How do we know we’re on
an elevator? Back again. If we hit a green, go. Right? So we can show context.
Create a function on elevator.
[00:02:43]
Say return bit.isGreen. And that tells us. Okay. If bit is green, we’re supposed to
go up. Great. What does it mean to go up the elevator? This is maybe where we
want to think through things.
Start visual description. Instructor types the following code:
@Bit.worlds(‘elevators’)
def run(bit):
"""Bit moves to the end of the screen, going up green elevators along the way”””
while should_keep_moving (bit):
bit.move()
if on elevator(bit):
go up elevator(bit)
End visual description.
[00:03:00]
So, if bit is landed on the green square, then we can see there’s some turning
and some painting. Where does it stop? Where does bit finish? So let’s come
back over to our drawing board here and get rid of our last sketch.
[00:03:20]
So I’ve got some platform here, and I’ve got some platform down here, and some
green block right there. So bit’s going to come along, hit this green block.
Obviously we’re going to turn and move up, and according to this image, the
green stops flush with the black.
Start visual description. Instructor sketches out the elevator grid. End visual description.
[00:03:42]
So let’s put a little bit right here. Say that’s the last spot that we’re painting
green, and I can see that that spot’s different from all the rest in that the left is
blocked, whereas everything else, the left is not blocked.
[00:03:56]
So that sounds like a promising condition to use as the stopping spot. So we’re
going to have some turning, we’re going to move into the left as block, we’re
going to paint as we go, but before bit moves on, we can see we’ve got some
turning to do.
[00:04:11]
So there’s a little bit of glue code that all works together into this, go up the
elevator function. Let’s come back to our function in document, we just
captured. So bit starts on green square facing left.
[00:04:33]
Bit ends on black square facing left. We’re saying we want bit to be up here at
the top, all finished, but we know what the individual pieces are going to need to
be.
[00:04:50]
And so we have this idea, bit’s facing left, we’re going to have to turn right,
bit.right, we’re going to go until left blocked and then from that point we know
we need to make a move, a turn, and a move to get to the final position we want.
[00:05:13]
So bit.move, bit.left, bit.move, and that is what go up an elevator means. Now
we need to find well what does it mean to go into the left is blocked? Well let’s
create that function. This one’s simple while, bit.leftclear, bit.move, and maybe
we should comment again where does the paint need to happen?
Start visual description. Instructor types the following code:
def go_up_elevator(bit):
"""Bit starts on green square facing left
Bit ends on black square facing left”””
bit.right()
go_until_left_blocked (bit)
bit.move()
bit.left()
bit.move()
End visual description.
[00:05:43]
Right? And so we need to paint each of these, it’s during that go into the left
clear phase that we’re painting. We might pause for a second and ask, is this a
paint and move, or a move, then paint, come back to the drawing.
[00:06:04]
So right now, I’ve got the code set to move, then paint. So we hit the green, we
turn, we move, we paint, we move, we paint, we move, we paint, and then
maybe we stop, and then move forward. So that looks about right.
[00:06:16]
If it was paint, then move, paint, then move, paint, then move, stop, that last one
wouldn’t get painted. So we like the code we have. That looks like it should work
fine. And all the pieces are implemented such that we can run it.
[00:06:32]
Maybe let’s throw in some snapshots, though, so that we can step through this
and make sure everything’s right. So we can right here, we could say bit.snapshot
foundElevator. And then here we could say bit.snapshot finishedElevator.
[00:06:56]
And then that would let us step through to those interesting places where the
functions come together, and we can say, hey, is our go up elevator working or
not? And then if we find we need more snapshots, we’ll put some more in.
[00:07:08]
Let’s run it. Hey, in this case, we got it right. Isn’t that nice? It’s like getting a two
guess wordle or something. You feel a little lucky. Let’s go to the beginning and
just kind of step through this.
Start visual description. Instructor adds bit.snapshot(“Found elevator”) and bit.snapshot(“Finished elevator”) to the run function. Instructor then runs the code line by line to se the behavior of the grid. End visual description.
[00:07:22]
So we jump, we found the elevator, and the elevator finished. And that’s exactly
where we expected we would be between those two steps. And that’s good.
When you know exactly where your code is supposed to be, when some
maneuver is finished, and you are, then everything works.
[00:07:42]
That’s a good place to be. So we found an elevator, we finish, everything’s
correct. Great. Now, you’re ready to ship this, your product manager comes in
and says, oh, by the way, there’s now more elevators to deal with.
[00:07:59]
Elevators. A whole other world just got shipped in and your code needs to solve
it. Well, first thing is, what does this even look like? So let’s run it and take a look.
All right, this compare is correct, but on the other one we see there’s a problem.
[00:08:19]
First thing we notice is, wait a minute. Bits go in the wrong direction in this one.
In elevators, bit starts on the right side moving left. In more elevators, he starts
on the left side moving right.
[00:08:33]
And so what’s the problem? So if we jump, we found an elevator, but the next
step, he turns right and runs into the floor instead of rising. So now we need to
rethink, okay, so what does it mean?
[00:08:48]
Defining the elevator part seems to work, but the going up needs some
addressing. Let’s look at our going up code. Go up in elevator. So here, we say go
up means you turn right, you go left until block, you move, go left, etc.
[00:09:02]
But that only works when bit’s going the other direction. So the two questions
are, what are the two ways to rise? And then how do we know which one we
want to use? And so we can compare for just a second.
[00:09:19]
Here versus there. What’s the difference? Well, bit doesn’t know which way he’s
facing. We can’t say if is facing left or is facing right. But we can check his left and
right sides. So here I can see the right side is blocked versus in this one, the left
side is blocked.
[00:09:42]
Or the right side is clear versus the left side is clear. So maybe we just need to
check and see, well, which direction am I able to move? You know, if I find an
elevator and I’m able to move to the right, then let’s rise to the right.
[00:09:54]
If I find an elevator and I can move to the left, then let’s move to the left. So this
go up elevator, that little logic right there only is really go up a right elevator. So
let’s make a little function, def go up right elevator elevator bit.
[00:10:17]
And let’s steal this code right here and take it. Okay, great. Now, while we’re at it,
I’m just going to copy that whole function right there and go up a left elevator. So
it starts on a green square facing right and ends facing right.
[00:10:43]
This is for the scenario right here. So instead of turning right and moving, I’m
going to want to turn left, go up until right blocked. Then I’m going to to move
and turn right and then move. So now we need this new function.
Start visual description. Instructor types the following code:
def go_up_left_elevator (bit):
"""Bit starts on green square facing right Bit ends on black square facing right”””
bit.right()
go_until_left_blocked(bit)
bit.move()
bit.left()
bit.move()
Instructor runs the code line by line.
End visual description.
[00:11:01]
Go right until right blocked. But that’s probably going to look an awful lot like,
let’s see, I’m going to come over here highlight these lines of code and cut it. Cut.
And I’m just going to paste it right here so I can mimic this exact same code but
just do it the other way.
[00:11:22]
While bit.rightClear, bit.move, bit.paint. Great. So we can go up a right elevator,
we can go up a left elevator. So what does it mean to go up an elevator? Well we
got to make a decision. And so, again looking at this, we have to decide is the left
versus the right clear?
[00:11:47]
So if bit.leftClear go up left and you can see PyCharm is, notice that’s probably
the function I’m trying to type. I can hit tab and it’ll just fill it in for me, give it a
bit, and if the left isn’t clear then the right’s got to be clear, bit.rightClear, at least
in our situation.
[00:12:13]
So we’re going to go up a rightElevator bit. You could, in theory, you could say,
elif bit.rightClear, and then else, but then you run into the situation, I don’t know
what to do in that situation, it should never happen.
[00:12:33]
Well, if it should never happen, then do we really need this condition right here?
No, you don’t, you can just get rid of it. Okay, so we can go up an elevator now,
either on the left or the right, let’s see how that looks.
Start visual description. Instructor types the following code:
def go_up_elevator(bit):
if bit.left_clear():
else:
go_up_left_elevator (bit)
go_up_right_elevator (bit)
Instructor runs the code line by line to show the completed grid.
End visual description.
[00:12:49]
So run our elevators, give it a moment, and here we go, compare is correct, more
elevators, compare correct, yay! There you go, that process is real, all the time in
real life.
[00:13:09]
You solve a problem, and then the problem changes, and that’s okay, that’s the
way the world works, the world is constantly changing, and our code needs to
change too, to keep up with what the world is doing, and so going in and
redefining, refactoring your code in order to handle new requirements, that’s
alright.
[00:13:32]
You shouldn’t think that you can write code that’s going to handle all possible
future scenarios before you’ve seen the future.
[00:13:39]
Write the code that handles the current problem, and then have that resilience
and that determination that when the world changes and the requirements
change, and your code must now change, that you’re going to get in there and
you’re going to change it, and you’re going to keep up with it.
[00:13:54]
And with that, I wish you all the best, see you on the next video.