add: questions and exercises for the if statement
This commit is contained in:
@@ -92,8 +92,8 @@ fmt.Println(2.9 <= 2.9)
|
||||
|
||||
## What does this code print?
|
||||
```go
|
||||
fmt.Println(1 >= true)
|
||||
fmt.Println(0 <= false)
|
||||
fmt.Println(false >= true)
|
||||
fmt.Println(true <= false)
|
||||
```
|
||||
|
||||
1. true true
|
||||
|
@@ -25,6 +25,15 @@
|
||||
> **3:** That's right. All the logical operators expect a bool value (or a bool expression that yields a bool value).
|
||||
|
||||
|
||||
## Which expression below equals to the sentence below?
|
||||
"age is equal or above 15 and hair color is yellow"
|
||||
|
||||
1. `age > 15 || hairColor == "yellow"`
|
||||
2. `age < 15 || hairColor != "yellow"`
|
||||
3. `age >= 15 && hairColor == "yellow"` *CORRECT*
|
||||
4. `age > 15 && hairColor == "yellow"`
|
||||
|
||||
|
||||
## What does this program print?
|
||||
```go
|
||||
package main
|
||||
@@ -120,10 +129,10 @@ func duper() bool {
|
||||
}
|
||||
```
|
||||
|
||||
1. "super duper super duper"
|
||||
2. "duper super"
|
||||
3. "duper super duper super"
|
||||
4. "super duper"
|
||||
1. "super duper super duper "
|
||||
2. "duper super " *CORRECT*
|
||||
3. "duper super super duper "
|
||||
4. "super duper "
|
||||
|
||||
> **1, 3:** Remember: Logical operators short-circuit.
|
||||
|
||||
|
@@ -1,11 +1,202 @@
|
||||
## What does control flow mean?
|
||||
## What does "control flow" mean?
|
||||
1. Changing the top-to-bottom execution of a program
|
||||
2. Changing the left-to-right execution of a program
|
||||
3. Controlling which statements are executed *CORRECT*
|
||||
3. Deciding which statements are executed *CORRECT*
|
||||
|
||||
> **1:** You can't change that.
|
||||
> **1, 2:** You can't change that.
|
||||
>
|
||||
> **3:** That's right. Control flow allows us to decide which parts of a program is to be run depending on condition values such as true or false.
|
||||
|
||||
|
||||
## How can you simplify the condition expression of this if statement?
|
||||
```go
|
||||
if (mood == "perfect") {
|
||||
// this code is not important
|
||||
}
|
||||
```
|
||||
|
||||
1. `if {mood == perfect}`
|
||||
2. `if [mood == perfect]`
|
||||
3. `if mood = perfect`
|
||||
4. `if mood == perfect` *CORRECT*
|
||||
|
||||
> **1, 2:** That's a syntax error. Try again.
|
||||
>
|
||||
> **3:** `=` is the assignment operator. It cannot be used as a condition.
|
||||
>
|
||||
> **4:** That's right. In Go, you don't need to use the parentheses.
|
||||
|
||||
|
||||
## The following code doesn't work. How you can fix it?
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// this program prints "cool"
|
||||
// when the mood is "happy"
|
||||
|
||||
mood := "happy"
|
||||
|
||||
if "happy" {
|
||||
fmt.Println("cool")
|
||||
}
|
||||
}
|
||||
```
|
||||
1. Just wrap the "happy" inside parentheses.
|
||||
2. You need to compare mood with "happy". Like this: `if mood == "happy" { ... }` *CORRECT*
|
||||
3. Just directly use `mood` instead of `happy`. Like this: `if mood { ... }`
|
||||
4. This should work! This is a tricky question.
|
||||
|
||||
> **1:** That won't change anything. Go adds the parentheses automatically behind the scenes for every if statement.
|
||||
>
|
||||
> **2:** Yep. In Go, condition expressions always yield a bool value. Using a comparison operator will yield a bool value. So, it will work.
|
||||
>
|
||||
> **2:** You can't change that.
|
||||
> **4:** No, it's not :)
|
||||
|
||||
|
||||
## How can you simplify the following code? You only need to change the condition expression, but how?
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
happy := true
|
||||
|
||||
if happy == true {
|
||||
fmt.Println("cool!")
|
||||
}
|
||||
}
|
||||
```
|
||||
1. `happy != false`
|
||||
2. `!happy == false`
|
||||
3. `happy` *CORRECT*
|
||||
4. `!happy == true`
|
||||
|
||||
> **1, 2:** Right! But you can do it better.
|
||||
>
|
||||
> **3:** Perfect! You don't need to compare the value to `true`. `happy` is already true, so it'll print "cool!".
|
||||
>
|
||||
> **4:** That won't print anything. `happy` will be true.
|
||||
|
||||
|
||||
## How can you simplify the following code? You only need to change the condition expression, but how?
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
happy := false
|
||||
|
||||
if happy == !true {
|
||||
fmt.Println("why not?")
|
||||
}
|
||||
}
|
||||
```
|
||||
1. Easy! Like this: `happy != true`
|
||||
2. `!happy` *CORRECT*
|
||||
3. `happy == false`
|
||||
4. `!happy == false`
|
||||
|
||||
> **1, 3:** Right! But you can do it better.
|
||||
>
|
||||
> **2:** Perfect! You don't need to compare the value to `false` or to `!true` (which is false). `!happy` already returns true, because it's false at the beginning.
|
||||
>
|
||||
> **4:** That won't print anything. `happy` will be true.
|
||||
|
||||
|
||||
## Is this code going to work? Why?
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
happy := false
|
||||
|
||||
if happy {
|
||||
fmt.Println("cool!")
|
||||
} else if !happy {
|
||||
fmt.Println("why not?")
|
||||
} else {
|
||||
fmt.Println("why not?")
|
||||
} else {
|
||||
fmt.Println("why not?")
|
||||
}
|
||||
}
|
||||
```
|
||||
1. Remove one of the else branches. *CORRECT*
|
||||
2. Move the else if as the last branch.
|
||||
3. It repeats "why not?" several times.
|
||||
4. Remove the `else if` branch.
|
||||
|
||||
> **1:** Right. There can be only one else branch.
|
||||
>
|
||||
> **2:** If there's an else branch, you can't move else if branch as the last branch.
|
||||
>
|
||||
> **3, 4:** So? :) That's not the cause of the problem.
|
||||
>
|
||||
|
||||
|
||||
## What's the problem with the following code?
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
happy := true
|
||||
energic := happy
|
||||
|
||||
if happy {
|
||||
fmt.Println("cool!")
|
||||
} else if !happy {
|
||||
fmt.Println("why not?")
|
||||
} else if energic {
|
||||
fmt.Println("working out?")
|
||||
}
|
||||
}
|
||||
```
|
||||
1. It declares the energic variable unnecessarily.
|
||||
2. You can't use more than one else if branch.
|
||||
3. It will never run the last else if branch. *CORRECT*
|
||||
4. There's no else branch.
|
||||
|
||||
> **2:** Well, actually you can.
|
||||
>
|
||||
> **3:** Right. `happy` can only be either true or false. That means, it will always execute the first two branches, but it will never execute the else if branch.
|
||||
>
|
||||
> **4:** It doesn't have to be. Else branch is optional.
|
||||
|
||||
|
||||
## How can you simplify the following code?
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
happy := false
|
||||
|
||||
if happy {
|
||||
fmt.Println("cool!")
|
||||
} else if happy != true {
|
||||
fmt.Println("why not?")
|
||||
} else {
|
||||
fmt.Println("why not?")
|
||||
}
|
||||
}
|
||||
```
|
||||
1. Change `else if`'s condition to: `!happy`.
|
||||
2. Move the else branch before else if.
|
||||
3. Remove the else branch.
|
||||
4. Remove the else if branch. *CORRECT*
|
||||
|
||||
> **1, 3:** Close! But, you can do it even better.
|
||||
>
|
||||
> **2:** You can't: `else` branch should be the last branch.
|
||||
>
|
||||
> **4:** Cool. That's not necessary because `else` branch already handless "unhappy" situation. It's simpler because it doesn't have a condition.
|
144
11-if/questions/4-error-handling.md
Normal file
144
11-if/questions/4-error-handling.md
Normal file
@@ -0,0 +1,144 @@
|
||||
## What's a nil value?
|
||||
1. The dark matter that rules the universe.
|
||||
2. It's a zero value for pointers or pointer-based types. It means the value is uninitialized. *CORRECT*
|
||||
3. It's equal to empty string: `"" == nil` is true.
|
||||
|
||||
|
||||
## What's an error value?
|
||||
1. It stores the error details *CORRECT*
|
||||
2. A global variable which stores the error status.
|
||||
3. A global constant which stores the error status.
|
||||
|
||||
> **2, 3:** There aren't any global variables in Go. There are only package level variables. And, since the error value is just a value, so it can be stored in any variable.
|
||||
>
|
||||
|
||||
|
||||
## Why error handling is needed?
|
||||
1. I don't know.
|
||||
2. To control the execution flow.
|
||||
3. To make a program malware safe.
|
||||
4. Because, things can go wrong. *CORRECT*
|
||||
|
||||
> **1:** Then, please rewatch the lecture! :)
|
||||
>
|
||||
> **2:** Actually yes, but that's not the main reason.
|
||||
>
|
||||
> **3:** Come on!
|
||||
|
||||
|
||||
## How Go handles error handling?
|
||||
1. Using a throw/catch block
|
||||
2. Using a simple if statement with nil comparison *CORRECT*
|
||||
3. Using a mechanism called tagging
|
||||
|
||||
> **1:** There isn't a throw/catch block in Go; unlike Java, C#, and so on... Go is explicit.
|
||||
|
||||
|
||||
## When you should handle the errors?
|
||||
1. After the main func ends.
|
||||
2. Before calling a function.
|
||||
3. Immediately, after calling a function which returns an error value. *CORRECT*
|
||||
|
||||
|
||||
## For which one of the following functions that you might want to handle the errors?
|
||||
```go
|
||||
func Read() error
|
||||
func Write() error
|
||||
func String() string
|
||||
func Reset()
|
||||
```
|
||||
1. Read and Write *CORRECT*
|
||||
2. String and Reset
|
||||
3. Read, Write and Reset
|
||||
4. For neither of them
|
||||
5. For all of them
|
||||
|
||||
> **1:** They return error values. So, you might want to handle the errors after you call them.
|
||||
>
|
||||
> **2:** They don't return error values. So, you don't have to handle any errors.
|
||||
>
|
||||
> **3:** Partially true. Try again.
|
||||
|
||||
|
||||
## Let's say a function returns a nil error value. So, what does that mean?
|
||||
1. The function call is failed.
|
||||
2. The function call is successful. *CORRECT*
|
||||
3. The function call is in an indeterministic state. We can't know.
|
||||
|
||||
|
||||
## Let's say a function returns a non-nil error value. So, what does that mean?
|
||||
1. The function call is failed. *CORRECT*
|
||||
2. The function call is successful.
|
||||
3. The function call is in an indeterministic state. We can't know.
|
||||
|
||||
> **1:** Yep. Later on you'll learn that, this is not always true. Sometimes a function can return a non-nil error value, and the returned value may indicate something rather than an error. Search on Google: golang io EOF error if you're curious.
|
||||
|
||||
|
||||
## Does the following program correctly handles the error?
|
||||
|
||||
**NOTE:** This is what the `ParseDuration` function looks like:
|
||||
|
||||
```go
|
||||
func ParseDuration(s string) (Duration, error)
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
d, err := time.ParseDuration("1h10s")
|
||||
if err != nil {
|
||||
fmt.Println(d)
|
||||
}
|
||||
}
|
||||
```
|
||||
1. Yes. It prints the parsed duration if it's successful.
|
||||
2. No. It doesn't check for the errors.
|
||||
3. No. It prints the duration even when there's an error. *CORRECT*
|
||||
|
||||
> **1:** Yes, it handles the error; however it does so incorrectly. Something is missing here. Look closely.
|
||||
>
|
||||
> **2:** Actually, it does.
|
||||
>
|
||||
> **3:** That's right. It shouldn't use the returned value when there's an error.
|
||||
|
||||
|
||||
## Does the following program correctly handles the error?
|
||||
|
||||
**NOTE:** This is what the `ParseDuration` function looks like:
|
||||
|
||||
```go
|
||||
func ParseDuration(s string) (Duration, error)
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
d, err := time.ParseDuration("1h10s")
|
||||
if err != nil {
|
||||
fmt.Println("Parsing error:", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(d)
|
||||
}
|
||||
```
|
||||
1. Yes. It prints the parsed duration if it's successful. *CORRECT*
|
||||
2. No. It doesn't check for the errors.
|
||||
3. No. It prints the duration even when there's an error.
|
||||
|
||||
> **1:** That's right. When there's an error, it prints a message and it quits from the program.
|
||||
>
|
||||
> **2:** Actually, it does.
|
||||
>
|
||||
> **3:** No, it does not. It only prints it when there isn't an error.
|
71
11-if/questions/5-short-if.md
Normal file
71
11-if/questions/5-short-if.md
Normal file
@@ -0,0 +1,71 @@
|
||||
## How to fix this program?
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err != nil; d, err := time.ParseDuration("1h10s") {
|
||||
fmt.Println(d)
|
||||
}
|
||||
}
|
||||
```
|
||||
1. Swap the simple statement with the `err != nil` check. *CORRECT*
|
||||
2. Remove the error handling.
|
||||
3. Remove the semicolon.
|
||||
4. Change the short declaration to an assignment.
|
||||
|
||||
> **1:** Yes. In a short if statement, the simple statement (the short declaration there) should be the first part of it. Then, after the semicolon separator, there should be a condition expression.
|
||||
>
|
||||
> **2:** You don't want that. That's not the issue here.
|
||||
|
||||
|
||||
## What does this program print?
|
||||
```go
|
||||
package main
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
done := false
|
||||
if done := true; done {
|
||||
fmt.Println(done)
|
||||
}
|
||||
fmt.Println(done)
|
||||
}
|
||||
```
|
||||
1. true and true
|
||||
2. false and false
|
||||
3. true and false *CORRECT*
|
||||
4. false and true
|
||||
|
||||
> **3:** Yes. It shadows the main()'s done variable, and inside the if statement, it prints "true". Then, after the if statement ends, it prints the main()'s done variable which is "false".
|
||||
|
||||
|
||||
## How can you fix this code?
|
||||
```go
|
||||
package main
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
done := false
|
||||
if done := true; done {
|
||||
fmt.Println(done)
|
||||
}
|
||||
fmt.Println(done)
|
||||
}
|
||||
```
|
||||
1. Remove the first declaration (main()'s done)
|
||||
2. Remove the declaration in the short-if (if's done)
|
||||
3. Change the done declaration of the main() to an assignment
|
||||
4. Change the done declaration of the short-if to an assignment. And, after the if statement, assign false back to the done variable. *CORRECT*
|
||||
|
||||
> **1:** That will break the program. The last line tries to print it.
|
||||
>
|
||||
> **2:** The program wants to use it to print true.
|
||||
>
|
||||
> **3:** There will be "undefined variable" error.
|
||||
> **4:** Yes, that will solve the shadowing issue. Short-if will reuse the same done variable of the main(). And, after the short-if, done will be false because of the assignment, and it will print false.
|
||||
|
Reference in New Issue
Block a user