All language subtitles for pragstudio-ruby-13-conditionals-1 (Transcribed on 27-Apr-2023 20-40-09)

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified) Download
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

So as our game stands now, the same thing happens for every player.

One blam, two woots.

In other words, there's only one path through the game.

But we know from real life that things happen based on different circumstances.

If this is true, then we do this, and if this is true or false, then we do another thing.

Yeah, and in programs, the way we do that is we use conditionals to control the flow

of the program, which is sometimes why we call it branching.

We go down one branch of the code or a different branch of the code, depending on some condition.

So to look at that, let's just start with a simple example.

Let's say we want to determine if our movie is a hit or a flop, and then do something

based on that.

So I just created a new file here called Conditional, so we can play around with conditionals.

And we're going to use our movie class to do that, so I'll just go ahead and require

that in.

We'll have a movie variable.

We've seen this a number of times now.

Actually, I'm going to change this movie name to Godfather, and it has initial rank of 10.

So conditionals are pretty straightforward.

Let's just play around with a couple of them here.

Let's print out if we have a movie whose rank is equal to 10, what does Ruby print out here?

Well, Godfather, its rank is equal to 10, so if we print that, we just get true.

What if we try something like movie.rank is greater than or equal to 10?

Well, that's true as well, because it's equal to 10.

What if we test that the movie's rank is less than 10?

Well, you probably guessed that we would get something like false.

So these true and false are used to control the flow of our code.

We can use these to do comparisons and then make decisions in our program as to which

parts of the code we want to run.

So let's do that.

I'll just remove these, and we're going to start an if statement here.

We're going to say if the movie.rank is greater than or equal to 10, then inside of that,

I'm going to print out.

It's a hit.

It's a hit.

All right.

And if we run that code, it prints hit, because what happened was it evaluated this expression,

and the movie's rank is greater than or equal to 10, it returned true.

So the if statement runs, and that part of the code that's inside of that if block actually

executes.

Now, there's another way to do this if you have a single line if block like this.

We can just put the put as on the front.

We say put as hit, and then put this statement at the end.

We call this a statement modifier, because this is going to modify whether this statement

runs or not.

So if the movie's rank is greater than or equal to 10, then go ahead and print out hit,

which is what we get.

So what if the movie's rank is less than 10?

Well, movie.rank less than 10.

Oh, then it's just a flop.

Okay.

Give it a flop like that.

Now if we run it, we see that hit is still printed, because the movie's rank isn't less

than 10.

This returns false.

So this code won't run, because the if statement evaluated to false.

So if we switch this around a little bit, we'll change Godfather to a nine now.

Now when we run it, we get flop instead of hit.

So you notice that this did not run, because that if condition wasn't satisfied.

Now we often want to do one thing if the expression is true, and another thing if the expression

is false.

Yeah, let's just combine this all together.

So we can say if movie.rank is greater than or equal to 10, then we're going to print

a hit.

Otherwise, or else, we're going to print flop, just like that.

Now we've got Godfather set to a nine, so if I run that, we get a flop.

If I set it back to a 10, no surprise here, it prints hit.

So it's easy to see how we would use conditionals to control the flow of a game.

It's a fairly straightforward concept.

And since there isn't a lot to conditionals, we thought we would take this as an opportunity

to show you another programming style, test-driven development.

So how is this different than the way we've been doing programming so far?

Well, in the last section, we learned how to write unit tests.

And we wrote our code, and then we wrote our unit test afterwards.

Now we want to turn things around.

We're going to start by writing the test that expresses the code that we want.

So we're going to write our expectations about the code first.

Then we're going to run the test, and it's going to fail because, well, we don't have

that code.

Then we'll go back in and write just enough code to get the test to pass.

And then once we have a passing test, we can safely refactor, knowing that we haven't broken

anything.

And we'll just do that.

We'll rinse and repeat, do that in really small increments until we have the features

we want.

So coming back to this code that we just wrote, we noticed that we're getting the rank from

a movie and then determining whether it's a hit or a flop.

So a question here is, where should this code live?

Because right now, it's violating the tell-don't-ask principle.

We're asking a movie for some attributes, and then we're making a decision based on

its behalf, and then we do something with that.

Instead, we would rather just tell the movie to do that.

So this code really belongs inside of the movie class.

But since we're going to do this test first, we need to write the test first.

So let's just go over to our movie spec file where we've been writing some specs.

I'm just going to create a bunch of space down here.

And we're going to set up a new context here.

And the context is going to be a movie with a rank of at least 10.

And then we're going to have a before block in here.

And we're going to have a movie.

And the movie is going to be Goonies with a rank of 10.

That's fine, because that's a rank of at least 10.

And then we want a code example.

So it's going to be ItIsAHit.

So how are we going to express that a movie is a hit?

Well, we're going to take our movie object, and we want to call some method to determine

whether it's a hit or not.

So we can just think about the name right here, because we don't have this code yet.

I'm just going to call the method Hit?

Because we know that question mark methods return a true or a false.

So then we can tack on Should, and it should be true, just like that.

So if we run this back now, of course it fails, because we haven't defined the hit method

yet.

That's OK.

We'll go over to our movie class.

And just right up in here, I'm going to define the method Hit.

And just to get the test to pass, I'll just have it return true, just like that.

We'll go back to the test.

We'll run it.

And now we've got green.

So we went through the cycle.

We wrote the test first, then we went and wrote the code that makes it pass.

Well, clearly that's not going to stand up for very long.

So let's write another test to drive out more functionality.

We want a context where the movie has a rank of less than 10.

Inside of that, we'll create a before block.

And inside of this before block, we'll have a movie.

It's going to be movie, Goonies, and we'll just say it's 9 in this case.

All right.

Write our it structure.

It is not a hit.

So then, oops.

So then down in here, we can just say movie.callingTheHit method should equal false.

Let me just clean this up a little bit.

There we go.

So there's our two contexts.

One that's a hit and one that is not a hit.

If we run this now, well, now it fails again because we're always returning true in this

method.

So let's go back to our movie.

Now we have to make a real decision here.

So how are we going to know if a movie is a hit or not?

Well, we're just going to look at the rank.

And if it's greater than or equal to 10, it's going to return true.

Otherwise, it's going to return false.

So go back to the spec file here, run it, and we've got green across the board.

So I want to show you a couple shortcuts that RSpec has for testing expectations that are

true or false.

We see this should equal equal true.

Another way to do this is just to use should be underscore true.

That's called a matcher in RSpec.

And in the same way, down here, we could say should be false.

And those still pass.

But there's another way we can do this as well.

We can just say movie.should, and then we can say be a hit.

And what RSpec does there is it drops the be part of it.

It takes the hit.

It automatically appends a question mark.

So it expects to call a method called hit question mark.

In the same way, down here, we can drop hit from here.

We can say movie should not be underscore hit.

It's going to call the same hit method, but now it's going to expect it to return false.

If we run that, our tests are still green.

So that's a glimpse at test-first programming.

We wrote the test first, and they failed.

Then we went back in and we wrote the code to make the test pass.

And then once everything was green, we went back through.

We refactored stuff.

And then we got back to a safe spot with green again.

So let's go through that cycle again.

But this time, we want to get the status of a movie and return the string hit or flop.

So we need some more code examples for that.

So if we go back in, let's see.

We've got this context with a rank of at least 10.

Well, in that case, our code example is going to be that it has a hit status.

So the expectation is when we call movie status method, we'll just make up that name now.

We'll have to implement the method later, but sounds like a good enough name at this

point.

It should return a string equal to hit.

We run that.

The tests fail.

We don't have a method called status.

Back over to our movie class, we'll add one in.

Status and we'll just return the string hit just to get it to pass.

Back over to the test again.

Sure enough, that works.

But we just faked the test to get it to pass.

So let's add another code example to really drive out the functionality here.

When our context is a movie with a rank of less than 10, then it has a flop status.

So our expectation is when we call movie.status, it should equal the string flop.

Run that.

Of course, it fails because we're always returning the string hit.

So back over to our movie.

Now we've got to add a conditional here.

We want to return hit.

If it's a hit, we want to return flop if it's a flop.

So let's use a conditional.

We can say if we already have this method called hit question mark that returns true

or false, so we can just piggyback on that right here.

String hit, else the string flop.

And remember with a conditional, if this fires, if it's true, then it's going to return this

string.

It's the last expression that's evaluated in this method, so it's going to be automatically

returned.

Otherwise, this path in the code is going to be run and that's the last expression that's

returned.

So let's see if that worked.

Let's back over to our specs, run them, and we've got everything green.

The last step of TDD is that we can refactor because we know that everything works.

We can clean up our code just a little bit.

So back in our movie class, instead of using the FL structure like this, if you've got

a really simple branch, something like this, you can use the ternary operator in Ruby.

And the way you do that is you call a method that returns true or false or you evaluate

some expression that's true or false.

If it's true, then we're going to return hit.

If it's false, we're going to return flop.

And this does exactly the same thing as this construct.

It looks a little odd because we have two question marks, but that question mark is

part of the method name.

This question mark denotes that the thing that follows is what happens if the thing

on the left-hand side is true.

This is kind of like the else statement.

This is what is going to be returned if hit question mark returns false.

Next step, we go back over to our movie spec.

And thankfully, after doing that refactoring, our tests still pass.

You know, it would be kind of nice if the status was included in the movie listing.

Oh, so the word hit or flop in the actual movie listing.

Right, right.

OK, well, let's change our spec for that.

OK.

So our spec for that is up here.

It has a string representation.

And so we're expecting the status not to be in here.

So let's say, well, this one has a rank of 10, so it's going to be a hit.

And we want the status or the printout to look like that.

So we run that.

Sure enough, it fails because it doesn't include that word.

So we can come back over to our movie.

And now in our 2S method, which is right here, we can just include in parentheses.

We've got this status method at the top.

So we'll just call it right here.

It's going to return a string for us back over to the spec.

And sure enough, we've got that.

It's all neatly nested.

We've got our conditions for with a rank of less than 10, it's a hit, and it has a hit

status.

With a rank of, or actually with a rank of at least 10, it's a hit and a hit status.

With a rank of less than 10, it's not a hit, and it has a flop status.

So you can almost see how this is generating a little bit of documentation about what this

object should do.

Thank you, guys.

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.