# Conditions and While Loops

### Boolean Operators

#### Or

Use the `||` infix operator to use an inclusive or operator between two booleans

```swift
let myBool = false || true
myBool: Bool = true
```

Both `or` and `and` operators in Swift are short-circuit meaning that the operator will operate on its parameters until it has guaranteed result in which case it will return. This means, in some cases, they will not operate both conditions.

```swift
let anotherBool = true || 0 / 0 == 1
```

Due to short-cuircuit rules, we would expect this to evaluate to `true`. When an `or` operator reaches an expression that evaluates to `true`, it can stop evaluation because no matter what the other expression is, it will be `true`. Thus, it will never encounter the error.

I slightly lied... This is actually a special case because the compiler knows to look for division by 0, so this actually does not compile (but if we ran it, it would evaluate to `true`). We can silence this error by hiding the fact that we are dividing by 0 with a function:

```swift
func hiddenZero() -> Int { 0 }
// hiddenZero: () -> Int

let hiddenErrorBool = true || 0 / hiddenZero() == 1
// hiddenErrorBool: Bool = true
```

This compiles and runs without error. Although, if we used `false` instead of `true` for the first expression, the second expression would need to be evaluated, and the program would then throw an error.&#x20;

You may think this is an odd piece of dynamic symantics (how code runs) to analyze, but this can produce puzzling behavior in object oriented programming. If the expressions change the state of your program, this is something you must keep in mind.

#### And

`And` is similar to the `or` operator–it's a short-circuit operator. But, we use the `&&` symbol instead.

```swift
let marthaControlsTheWeather = true && true
marthaControlsTheWeather: Bool = true
```

In contrast, the `and` operator can only short-circuit if the first expression evaluates to `false`.

```swift
func hiddenZero() -> Int { 0 }
// hiddenZero: () -> Int

let hiddenErrorBool = false || 0 / hiddenZero() == 1
// hiddenErrorBool: Bool = false
```

#### Not

Unlike `or` and `and`, `not` is a unary prefix operator. This means that we can apply it to a singular boolean expression by placing an exclamation point (or bang) `!` in front of the expression:

```swift
let isWeatherBot = !false
// isWeatherBot: Bool = true

let multipleNots = !(true && true)
// multipleNots: Bool = false
```

### Control Flow

#### If-Else Statements

If-else statements are standard in Swift. You just write `if`, followed by an expression, followed by an execution block. If you want, you can follow this with an `else` statement or an `else if` if you want another condition.

```swift
func welcomeMartha(name: String) -> String {
    if name == "Martha" {
        return "What should the weather be today?"
    } else if name == "Justin" {
        return "Shouldn't you be working on lecture?"
    } else {
        return "Who are you :|"
    }sw
}
```

#### Ternary

Ternary, for 3 expressions, can be though of as in-place if-else expression. Ternaries are written as `<insert boolean expression> ? <expression 1> : <expression 2>`. This only works if `expression 1` and `expression 2` have the same type. If the boolean is `true`, `expression 1` is returned, otherwise, `expression 2` is returned.

```swift
let color: UIColor = true ? .blue : .red
// color: UIColor = .blue

let anotherColor: UIColor = false ? .blue : .red
// color: UIColor = .red
```

#### Toggle

You often use booleans to store states. In these cases, you will want to be toggling this state on and off. You could write that like this:

```swift
var myState: Bool
func toggle() {
    if myState {
        myState = false
    } else {
        myState = true
    }
}
```

We could also do this with a ternary:

```swift
var myState: Bool
func toggle() {
    myState = myState ? false : true
}
```

We could even do it in fewer lines with `not`:

```swift
var myState: Bool
func toggle() {
    myState = !myState
}
```

But actually we don't need to do any of these because is already done in Swift. If we want to toggle a boolean, we can simply use the toggle method.

```swift
var myState: Bool = true
// myState: Bool = true

myState.toggle()
// myState: Bool = false

myState.toggle()
// myState: Bool = true
```

### While

While loops exactly what you'd expect them to be. A loop the executes while some expression evaluate to be `true`, with the syntax `while <insert expression> { <code block> }`. Just make sure you're making progress towards termination!

```swift
func factorial(_ n: Int) -> Int {
    var result = 1
    var n = n // This is necessary because the parameter n is a let-constant
    while n > 0 {
        result *= n
        n -= 1
    }
    return result
}
// factorial(10): Int = 3628800
```
