Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:00,000 --> 00:00:07,400
So as our game stands now, the same thing happens for every player.
2
00:00:07,400 --> 00:00:08,840
One blam, two woots.
3
00:00:08,840 --> 00:00:11,800
In other words, there's only one path through the game.
4
00:00:11,800 --> 00:00:15,640
But we know from real life that things happen based on different circumstances.
5
00:00:15,640 --> 00:00:20,040
If this is true, then we do this, and if this is true or false, then we do another thing.
6
00:00:20,040 --> 00:00:24,120
Yeah, and in programs, the way we do that is we use conditionals to control the flow
7
00:00:24,120 --> 00:00:27,280
of the program, which is sometimes why we call it branching.
8
00:00:27,280 --> 00:00:32,080
We go down one branch of the code or a different branch of the code, depending on some condition.
9
00:00:32,080 --> 00:00:35,280
So to look at that, let's just start with a simple example.
10
00:00:35,280 --> 00:00:39,320
Let's say we want to determine if our movie is a hit or a flop, and then do something
11
00:00:39,320 --> 00:00:40,960
based on that.
12
00:00:40,960 --> 00:00:44,680
So I just created a new file here called Conditional, so we can play around with conditionals.
13
00:00:44,680 --> 00:00:47,880
And we're going to use our movie class to do that, so I'll just go ahead and require
14
00:00:47,880 --> 00:00:48,880
that in.
15
00:00:48,880 --> 00:00:50,680
We'll have a movie variable.
16
00:00:50,680 --> 00:00:52,760
We've seen this a number of times now.
17
00:00:52,760 --> 00:00:58,519
Actually, I'm going to change this movie name to Godfather, and it has initial rank of 10.
18
00:00:58,519 --> 00:01:00,480
So conditionals are pretty straightforward.
19
00:01:00,480 --> 00:01:02,560
Let's just play around with a couple of them here.
20
00:01:02,560 --> 00:01:09,479
Let's print out if we have a movie whose rank is equal to 10, what does Ruby print out here?
21
00:01:09,479 --> 00:01:14,280
Well, Godfather, its rank is equal to 10, so if we print that, we just get true.
22
00:01:14,280 --> 00:01:19,280
What if we try something like movie.rank is greater than or equal to 10?
23
00:01:19,280 --> 00:01:23,960
Well, that's true as well, because it's equal to 10.
24
00:01:23,960 --> 00:01:28,160
What if we test that the movie's rank is less than 10?
25
00:01:28,160 --> 00:01:32,040
Well, you probably guessed that we would get something like false.
26
00:01:32,040 --> 00:01:34,540
So these true and false are used to control the flow of our code.
27
00:01:34,540 --> 00:01:38,960
We can use these to do comparisons and then make decisions in our program as to which
28
00:01:38,960 --> 00:01:40,960
parts of the code we want to run.
29
00:01:40,960 --> 00:01:41,960
So let's do that.
30
00:01:41,960 --> 00:01:45,480
I'll just remove these, and we're going to start an if statement here.
31
00:01:45,480 --> 00:01:52,320
We're going to say if the movie.rank is greater than or equal to 10, then inside of that,
32
00:01:52,320 --> 00:01:53,320
I'm going to print out.
33
00:01:53,320 --> 00:01:54,320
It's a hit.
34
00:01:54,320 --> 00:01:55,320
It's a hit.
35
00:01:55,320 --> 00:01:56,320
All right.
36
00:01:56,320 --> 00:02:03,280
And if we run that code, it prints hit, because what happened was it evaluated this expression,
37
00:02:03,280 --> 00:02:06,720
and the movie's rank is greater than or equal to 10, it returned true.
38
00:02:06,720 --> 00:02:11,080
So the if statement runs, and that part of the code that's inside of that if block actually
39
00:02:11,080 --> 00:02:12,080
executes.
40
00:02:12,080 --> 00:02:16,800
Now, there's another way to do this if you have a single line if block like this.
41
00:02:16,800 --> 00:02:19,560
We can just put the put as on the front.
42
00:02:19,560 --> 00:02:24,480
We say put as hit, and then put this statement at the end.
43
00:02:24,480 --> 00:02:28,600
We call this a statement modifier, because this is going to modify whether this statement
44
00:02:28,600 --> 00:02:29,840
runs or not.
45
00:02:29,840 --> 00:02:33,480
So if the movie's rank is greater than or equal to 10, then go ahead and print out hit,
46
00:02:33,480 --> 00:02:34,820
which is what we get.
47
00:02:34,820 --> 00:02:37,680
So what if the movie's rank is less than 10?
48
00:02:37,680 --> 00:02:40,080
Well, movie.rank less than 10.
49
00:02:40,080 --> 00:02:42,200
Oh, then it's just a flop.
50
00:02:42,200 --> 00:02:43,200
Okay.
51
00:02:43,200 --> 00:02:45,240
Give it a flop like that.
52
00:02:45,240 --> 00:02:50,580
Now if we run it, we see that hit is still printed, because the movie's rank isn't less
53
00:02:50,580 --> 00:02:51,580
than 10.
54
00:02:51,580 --> 00:02:53,240
This returns false.
55
00:02:53,240 --> 00:02:57,240
So this code won't run, because the if statement evaluated to false.
56
00:02:57,240 --> 00:03:01,240
So if we switch this around a little bit, we'll change Godfather to a nine now.
57
00:03:01,240 --> 00:03:04,160
Now when we run it, we get flop instead of hit.
58
00:03:04,160 --> 00:03:09,760
So you notice that this did not run, because that if condition wasn't satisfied.
59
00:03:09,760 --> 00:03:14,799
Now we often want to do one thing if the expression is true, and another thing if the expression
60
00:03:14,799 --> 00:03:15,799
is false.
61
00:03:15,799 --> 00:03:17,880
Yeah, let's just combine this all together.
62
00:03:17,880 --> 00:03:25,000
So we can say if movie.rank is greater than or equal to 10, then we're going to print
63
00:03:25,000 --> 00:03:26,000
a hit.
64
00:03:26,000 --> 00:03:31,040
Otherwise, or else, we're going to print flop, just like that.
65
00:03:31,040 --> 00:03:34,600
Now we've got Godfather set to a nine, so if I run that, we get a flop.
66
00:03:34,600 --> 00:03:41,000
If I set it back to a 10, no surprise here, it prints hit.
67
00:03:41,000 --> 00:03:44,560
So it's easy to see how we would use conditionals to control the flow of a game.
68
00:03:44,560 --> 00:03:46,820
It's a fairly straightforward concept.
69
00:03:46,820 --> 00:03:50,280
And since there isn't a lot to conditionals, we thought we would take this as an opportunity
70
00:03:50,280 --> 00:03:53,959
to show you another programming style, test-driven development.
71
00:03:53,959 --> 00:03:56,920
So how is this different than the way we've been doing programming so far?
72
00:03:56,920 --> 00:04:00,019
Well, in the last section, we learned how to write unit tests.
73
00:04:00,019 --> 00:04:03,799
And we wrote our code, and then we wrote our unit test afterwards.
74
00:04:03,800 --> 00:04:05,560
Now we want to turn things around.
75
00:04:05,560 --> 00:04:09,960
We're going to start by writing the test that expresses the code that we want.
76
00:04:09,960 --> 00:04:12,440
So we're going to write our expectations about the code first.
77
00:04:12,440 --> 00:04:15,800
Then we're going to run the test, and it's going to fail because, well, we don't have
78
00:04:15,800 --> 00:04:16,800
that code.
79
00:04:16,800 --> 00:04:21,080
Then we'll go back in and write just enough code to get the test to pass.
80
00:04:21,080 --> 00:04:25,560
And then once we have a passing test, we can safely refactor, knowing that we haven't broken
81
00:04:25,560 --> 00:04:26,560
anything.
82
00:04:26,560 --> 00:04:27,560
And we'll just do that.
83
00:04:27,560 --> 00:04:30,520
We'll rinse and repeat, do that in really small increments until we have the features
84
00:04:30,520 --> 00:04:31,960
we want.
85
00:04:31,960 --> 00:04:35,719
So coming back to this code that we just wrote, we noticed that we're getting the rank from
86
00:04:35,719 --> 00:04:39,440
a movie and then determining whether it's a hit or a flop.
87
00:04:39,440 --> 00:04:42,219
So a question here is, where should this code live?
88
00:04:42,219 --> 00:04:45,560
Because right now, it's violating the tell-don't-ask principle.
89
00:04:45,560 --> 00:04:50,520
We're asking a movie for some attributes, and then we're making a decision based on
90
00:04:50,520 --> 00:04:53,679
its behalf, and then we do something with that.
91
00:04:53,679 --> 00:04:56,320
Instead, we would rather just tell the movie to do that.
92
00:04:56,320 --> 00:04:59,880
So this code really belongs inside of the movie class.
93
00:04:59,880 --> 00:05:04,480
But since we're going to do this test first, we need to write the test first.
94
00:05:04,480 --> 00:05:07,960
So let's just go over to our movie spec file where we've been writing some specs.
95
00:05:07,960 --> 00:05:11,020
I'm just going to create a bunch of space down here.
96
00:05:11,020 --> 00:05:14,200
And we're going to set up a new context here.
97
00:05:14,200 --> 00:05:20,880
And the context is going to be a movie with a rank of at least 10.
98
00:05:20,880 --> 00:05:23,360
And then we're going to have a before block in here.
99
00:05:23,360 --> 00:05:25,680
And we're going to have a movie.
100
00:05:25,680 --> 00:05:29,860
And the movie is going to be Goonies with a rank of 10.
101
00:05:29,860 --> 00:05:34,280
That's fine, because that's a rank of at least 10.
102
00:05:34,280 --> 00:05:35,480
And then we want a code example.
103
00:05:35,480 --> 00:05:39,240
So it's going to be ItIsAHit.
104
00:05:39,240 --> 00:05:41,600
So how are we going to express that a movie is a hit?
105
00:05:41,600 --> 00:05:45,440
Well, we're going to take our movie object, and we want to call some method to determine
106
00:05:45,440 --> 00:05:46,480
whether it's a hit or not.
107
00:05:46,480 --> 00:05:50,160
So we can just think about the name right here, because we don't have this code yet.
108
00:05:50,160 --> 00:05:52,960
I'm just going to call the method Hit?
109
00:05:52,960 --> 00:05:56,640
Because we know that question mark methods return a true or a false.
110
00:05:56,640 --> 00:06:01,380
So then we can tack on Should, and it should be true, just like that.
111
00:06:01,380 --> 00:06:06,080
So if we run this back now, of course it fails, because we haven't defined the hit method
112
00:06:06,080 --> 00:06:07,080
yet.
113
00:06:07,080 --> 00:06:08,080
That's OK.
114
00:06:08,080 --> 00:06:10,320
We'll go over to our movie class.
115
00:06:10,320 --> 00:06:13,840
And just right up in here, I'm going to define the method Hit.
116
00:06:13,840 --> 00:06:18,240
And just to get the test to pass, I'll just have it return true, just like that.
117
00:06:18,240 --> 00:06:21,240
We'll go back to the test.
118
00:06:21,240 --> 00:06:22,240
We'll run it.
119
00:06:22,240 --> 00:06:23,240
And now we've got green.
120
00:06:23,240 --> 00:06:24,240
So we went through the cycle.
121
00:06:24,240 --> 00:06:27,320
We wrote the test first, then we went and wrote the code that makes it pass.
122
00:06:27,320 --> 00:06:30,120
Well, clearly that's not going to stand up for very long.
123
00:06:30,120 --> 00:06:34,820
So let's write another test to drive out more functionality.
124
00:06:34,820 --> 00:06:41,880
We want a context where the movie has a rank of less than 10.
125
00:06:41,880 --> 00:06:46,320
Inside of that, we'll create a before block.
126
00:06:46,320 --> 00:06:48,240
And inside of this before block, we'll have a movie.
127
00:06:48,240 --> 00:06:54,760
It's going to be movie, Goonies, and we'll just say it's 9 in this case.
128
00:06:54,760 --> 00:06:56,600
All right.
129
00:06:56,600 --> 00:06:58,520
Write our it structure.
130
00:06:58,520 --> 00:07:01,040
It is not a hit.
131
00:07:01,040 --> 00:07:02,040
So then, oops.
132
00:07:02,040 --> 00:07:09,480
So then down in here, we can just say movie.callingTheHit method should equal false.
133
00:07:09,480 --> 00:07:13,920
Let me just clean this up a little bit.
134
00:07:13,920 --> 00:07:15,560
There we go.
135
00:07:15,560 --> 00:07:17,480
So there's our two contexts.
136
00:07:17,480 --> 00:07:20,160
One that's a hit and one that is not a hit.
137
00:07:20,160 --> 00:07:25,240
If we run this now, well, now it fails again because we're always returning true in this
138
00:07:25,240 --> 00:07:26,240
method.
139
00:07:26,240 --> 00:07:27,920
So let's go back to our movie.
140
00:07:27,920 --> 00:07:29,640
Now we have to make a real decision here.
141
00:07:29,640 --> 00:07:32,120
So how are we going to know if a movie is a hit or not?
142
00:07:32,120 --> 00:07:34,560
Well, we're just going to look at the rank.
143
00:07:34,560 --> 00:07:37,560
And if it's greater than or equal to 10, it's going to return true.
144
00:07:37,560 --> 00:07:39,780
Otherwise, it's going to return false.
145
00:07:39,780 --> 00:07:46,040
So go back to the spec file here, run it, and we've got green across the board.
146
00:07:46,040 --> 00:07:51,680
So I want to show you a couple shortcuts that RSpec has for testing expectations that are
147
00:07:51,680 --> 00:07:52,680
true or false.
148
00:07:52,680 --> 00:07:55,760
We see this should equal equal true.
149
00:07:55,760 --> 00:08:00,720
Another way to do this is just to use should be underscore true.
150
00:08:00,720 --> 00:08:02,680
That's called a matcher in RSpec.
151
00:08:02,680 --> 00:08:08,480
And in the same way, down here, we could say should be false.
152
00:08:08,480 --> 00:08:09,560
And those still pass.
153
00:08:09,560 --> 00:08:12,740
But there's another way we can do this as well.
154
00:08:12,740 --> 00:08:18,360
We can just say movie.should, and then we can say be a hit.
155
00:08:18,360 --> 00:08:22,040
And what RSpec does there is it drops the be part of it.
156
00:08:22,040 --> 00:08:23,260
It takes the hit.
157
00:08:23,260 --> 00:08:25,660
It automatically appends a question mark.
158
00:08:25,660 --> 00:08:29,580
So it expects to call a method called hit question mark.
159
00:08:29,580 --> 00:08:34,440
In the same way, down here, we can drop hit from here.
160
00:08:34,440 --> 00:08:39,600
We can say movie should not be underscore hit.
161
00:08:39,600 --> 00:08:43,240
It's going to call the same hit method, but now it's going to expect it to return false.
162
00:08:43,240 --> 00:08:46,480
If we run that, our tests are still green.
163
00:08:46,480 --> 00:08:48,600
So that's a glimpse at test-first programming.
164
00:08:48,600 --> 00:08:50,320
We wrote the test first, and they failed.
165
00:08:50,320 --> 00:08:53,680
Then we went back in and we wrote the code to make the test pass.
166
00:08:53,680 --> 00:08:56,040
And then once everything was green, we went back through.
167
00:08:56,040 --> 00:08:57,480
We refactored stuff.
168
00:08:57,480 --> 00:09:00,800
And then we got back to a safe spot with green again.
169
00:09:00,800 --> 00:09:02,720
So let's go through that cycle again.
170
00:09:02,720 --> 00:09:07,940
But this time, we want to get the status of a movie and return the string hit or flop.
171
00:09:07,940 --> 00:09:09,880
So we need some more code examples for that.
172
00:09:09,880 --> 00:09:11,640
So if we go back in, let's see.
173
00:09:11,640 --> 00:09:14,480
We've got this context with a rank of at least 10.
174
00:09:14,480 --> 00:09:21,600
Well, in that case, our code example is going to be that it has a hit status.
175
00:09:21,600 --> 00:09:26,800
So the expectation is when we call movie status method, we'll just make up that name now.
176
00:09:26,800 --> 00:09:30,280
We'll have to implement the method later, but sounds like a good enough name at this
177
00:09:30,280 --> 00:09:31,280
point.
178
00:09:31,280 --> 00:09:35,800
It should return a string equal to hit.
179
00:09:35,800 --> 00:09:37,060
We run that.
180
00:09:37,060 --> 00:09:38,060
The tests fail.
181
00:09:38,060 --> 00:09:40,040
We don't have a method called status.
182
00:09:40,040 --> 00:09:44,000
Back over to our movie class, we'll add one in.
183
00:09:44,000 --> 00:09:49,680
Status and we'll just return the string hit just to get it to pass.
184
00:09:49,680 --> 00:09:51,479
Back over to the test again.
185
00:09:51,479 --> 00:09:52,760
Sure enough, that works.
186
00:09:52,760 --> 00:09:54,599
But we just faked the test to get it to pass.
187
00:09:54,599 --> 00:09:58,339
So let's add another code example to really drive out the functionality here.
188
00:09:58,339 --> 00:10:06,560
When our context is a movie with a rank of less than 10, then it has a flop status.
189
00:10:06,560 --> 00:10:14,079
So our expectation is when we call movie.status, it should equal the string flop.
190
00:10:14,079 --> 00:10:15,079
Run that.
191
00:10:15,079 --> 00:10:18,540
Of course, it fails because we're always returning the string hit.
192
00:10:18,540 --> 00:10:20,459
So back over to our movie.
193
00:10:20,459 --> 00:10:22,640
Now we've got to add a conditional here.
194
00:10:22,640 --> 00:10:23,640
We want to return hit.
195
00:10:23,640 --> 00:10:26,459
If it's a hit, we want to return flop if it's a flop.
196
00:10:26,459 --> 00:10:28,140
So let's use a conditional.
197
00:10:28,140 --> 00:10:31,920
We can say if we already have this method called hit question mark that returns true
198
00:10:31,920 --> 00:10:37,760
or false, so we can just piggyback on that right here.
199
00:10:37,760 --> 00:10:42,000
String hit, else the string flop.
200
00:10:42,000 --> 00:10:47,880
And remember with a conditional, if this fires, if it's true, then it's going to return this
201
00:10:47,880 --> 00:10:48,880
string.
202
00:10:48,880 --> 00:10:52,160
It's the last expression that's evaluated in this method, so it's going to be automatically
203
00:10:52,160 --> 00:10:53,160
returned.
204
00:10:53,160 --> 00:10:58,520
Otherwise, this path in the code is going to be run and that's the last expression that's
205
00:10:58,520 --> 00:10:59,520
returned.
206
00:10:59,520 --> 00:11:00,520
So let's see if that worked.
207
00:11:00,520 --> 00:11:04,760
Let's back over to our specs, run them, and we've got everything green.
208
00:11:04,760 --> 00:11:09,480
The last step of TDD is that we can refactor because we know that everything works.
209
00:11:09,480 --> 00:11:11,860
We can clean up our code just a little bit.
210
00:11:11,860 --> 00:11:16,360
So back in our movie class, instead of using the FL structure like this, if you've got
211
00:11:16,360 --> 00:11:21,120
a really simple branch, something like this, you can use the ternary operator in Ruby.
212
00:11:21,120 --> 00:11:25,300
And the way you do that is you call a method that returns true or false or you evaluate
213
00:11:25,300 --> 00:11:27,660
some expression that's true or false.
214
00:11:27,660 --> 00:11:31,000
If it's true, then we're going to return hit.
215
00:11:31,000 --> 00:11:33,839
If it's false, we're going to return flop.
216
00:11:33,839 --> 00:11:37,280
And this does exactly the same thing as this construct.
217
00:11:37,280 --> 00:11:41,160
It looks a little odd because we have two question marks, but that question mark is
218
00:11:41,160 --> 00:11:42,860
part of the method name.
219
00:11:42,860 --> 00:11:47,339
This question mark denotes that the thing that follows is what happens if the thing
220
00:11:47,339 --> 00:11:49,260
on the left-hand side is true.
221
00:11:49,260 --> 00:11:51,180
This is kind of like the else statement.
222
00:11:51,180 --> 00:11:56,300
This is what is going to be returned if hit question mark returns false.
223
00:11:56,300 --> 00:11:59,300
Next step, we go back over to our movie spec.
224
00:11:59,300 --> 00:12:03,260
And thankfully, after doing that refactoring, our tests still pass.
225
00:12:03,260 --> 00:12:06,459
You know, it would be kind of nice if the status was included in the movie listing.
226
00:12:06,459 --> 00:12:09,020
Oh, so the word hit or flop in the actual movie listing.
227
00:12:09,020 --> 00:12:10,020
Right, right.
228
00:12:10,020 --> 00:12:11,260
OK, well, let's change our spec for that.
229
00:12:11,260 --> 00:12:12,260
OK.
230
00:12:12,260 --> 00:12:13,660
So our spec for that is up here.
231
00:12:13,660 --> 00:12:16,260
It has a string representation.
232
00:12:16,260 --> 00:12:18,660
And so we're expecting the status not to be in here.
233
00:12:18,660 --> 00:12:22,900
So let's say, well, this one has a rank of 10, so it's going to be a hit.
234
00:12:22,900 --> 00:12:26,860
And we want the status or the printout to look like that.
235
00:12:26,860 --> 00:12:27,860
So we run that.
236
00:12:27,860 --> 00:12:30,740
Sure enough, it fails because it doesn't include that word.
237
00:12:30,740 --> 00:12:32,920
So we can come back over to our movie.
238
00:12:32,920 --> 00:12:39,620
And now in our 2S method, which is right here, we can just include in parentheses.
239
00:12:39,620 --> 00:12:41,500
We've got this status method at the top.
240
00:12:41,500 --> 00:12:42,620
So we'll just call it right here.
241
00:12:42,620 --> 00:12:47,340
It's going to return a string for us back over to the spec.
242
00:12:47,340 --> 00:12:48,939
And sure enough, we've got that.
243
00:12:48,939 --> 00:12:49,939
It's all neatly nested.
244
00:12:49,940 --> 00:12:55,340
We've got our conditions for with a rank of less than 10, it's a hit, and it has a hit
245
00:12:55,340 --> 00:12:56,460
status.
246
00:12:56,460 --> 00:13:00,280
With a rank of, or actually with a rank of at least 10, it's a hit and a hit status.
247
00:13:00,280 --> 00:13:04,260
With a rank of less than 10, it's not a hit, and it has a flop status.
248
00:13:04,260 --> 00:13:08,500
So you can almost see how this is generating a little bit of documentation about what this
249
00:13:08,500 --> 00:13:11,500
object should do.
250
00:13:11,500 --> 00:13:40,440
Thank you, guys.
21935
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.