Bronze x2 / Silver Challenge: Ch. 21

Bronze Challenge No. 1:

This was probably the easiest challenge so far: just extend Int to include a property on an int that multiplies itself times 5.

extension Int {
    var timesFive: Int { return self * 5 }
}
5.timesFive // returns 25

Bronze Challenge No. 2:

Pretty straightforward to make this refactor. Add a constant to the Car struct, and then fix the errors that the compiler throws (you’ll have to remove the duplicate value in the extension, fix the init() method, and also fix the instance that is created, since you’ll now be specifying the number of doors upon instantiation). I also added a precondition() in the init() method, just to make sure that you can only choose form 2 or 4 doors for now.

struct Car {
    ...
    let nickname: String
    let numberOfDoors: Int
    ...
}
extension Car: Vehicle {
    var topSpeed: Velocity { return 180 }
    var hasFlatbed: Bool { return false }
}
extension Car {
    init(make: String, model: String, year: Int, numberOfDoors: Int) {
        precondition(numberOfDoors == 4 || numberOfDoors == 2,
                     "You can only have a car with 2 or 4 doors in this example")
        self.init(make: make,
                  model: model,
                  year: year,
                  color: "Black",
                  nickname: "N/A",
                  numberOfDoors: numberOfDoors,
                  gasLevel: 1.0)
    }
}
var c = Car(make: "Ford", model: "Fusion", year: 2013, numberOfDoors: 2) // car is now a coupe

Silver Challenge

To fix this, I just went ahead with implementing a precondition() in the emptyGas(by:) function to stop execution of the program until you put a value less than the current gasLevel.

extension Car {
    mutating func emptyGas(by amount: Double) {
        precondition(amount <= 1 && amount > 0,
                     "Amount to remove must be between 0 and 1.")
        precondition(amount < gasLevel,
                     "Amount to remove is larger than the amount of gas left")
        gasLevel -= amount
    }
    ...
}

That rounds this chapter out.

I took a slightly different tact on the Silver Challenge. Instead of a precondition, I allowed for the tank to be reduced by an amount larger than the current volume, but in that case, it just went to 0 instead of a negative number:

extension Car {
  mutating func emptyGas(by amount: Double) {
    precondition(amount <= 1 && amount > 0, "Amount to remove m ust be between 0 and 1.")
    var amt = amount
    if amt > self.gasLevel {
      amt = self.gasLevel
    }
    gasLevel -= amt
  }
  
  mutating func fillGas() {
    gasLevel = 1.0
  }
}

I’m not sure what is better. In my case, bad input is tolerated, but in your case bad input generates an error…which could be preferred.

I was really stymied by the challenges in the chapter before this on Error Handling…I finally gave up and moved on…but I’ll have to go back and revisit them…or find someone to help me out.

Here is my solution for the Silver Challenge. I tested it and seemed to work fine.

extension Car {
    mutating func emptyGas(by amount: Double) {
        precondition(amount <= 1 && amount > 0, "Amount to remove must be between 0 and 1.")
        if gasLevel < amount {
            gasLevel = 0.0
        } else {
            gasLevel -= amount
        }
    }
    
    mutating func fillGas() {
        gasLevel = 1.0
    }
}

A simpler solution to the silver challenge was to make change the upper limit in the precondition.

mutating func emptyGas( by amount: Double) {
precondition( amount <= gasLevel && amount > 0, “Amount to remove must be between 0.0 and current gas level”)
gasLevel -= amount
}

I took the same route as mlevine but also added the current level to the error message, for even more clarity :slight_smile:

precondition(amount <= self.gasLevel && amount > 0, 
"Amount to remove must be betwen \(gasLevel) and 1")

I’ve taken the same road than bthooper and elev8eng, using a simple math operation.

extension Car {
    mutating func emptyGas(by amount: Double) {
        precondition(amount>0 && amount<=1, "Amount of gas must be between 0 and 1")
        gasLevel -= min(amount,gasLevel)
    }
   ...
}