<commit_before>/*:

 # Optionals

 You use **optionals** in situations where a value may be _absent_. 
 
 An optional represents two possibilities: 
 - Either there is a value, and you can unwrap the optional to access that value
 - or there isn’t a value at all
 
 We put _a question mark_ (`?`) after the type to indicate that this variable has
 an optional value.

 */
/*:
 
 Take following lines as example, converting strings into numbers may fail when
 the string is not composed by digits.

 */
let possibleNumber1 = "123"
let convertedNumber1 = Int(possibleNumber1)
let possibleNumber2 = "ABC1"
let convertedNumber2: Int? = Int(possibleNumber2)

/*:
 
 ## `nil`

 We use `nil` to denote that the value is absent.

 */
var concreteNumber: Int = 42
var optionalNumber: Int? = 42
optionalNumber = nil
//concreteNumber = nil  // Try to uncomment this line to see what Xcode yields.

//: --------------------------------------------------------------------------------------------------------------------
/*:
 
 ## Unwrapping optional values
 
 We have to unwrap the value from optionals before using it. 
 
 ### Forced unwrapping
 
 Use `if` statement to check whether it's `nil` or not, and then put a 
 _exclamation mark_ (`!`) after optionals to force unwrapping it.
 
 We called this way, using the `!` mark, as "forced unwrapping".
 
 */
func convertToNumber(from input: String) -> Int {
    let convertedOptionalNumber = Int(input)
    if convertedOptionalNumber == nil {
        return 0
    } else {
        return convertedOptionalNumber!
    }
}
convertToNumber(from: "1")
convertToNumber(from: "A")

/*:
 
 You should always check whether the value is nil or not before force unwrapping an optional.
 
 */

let answerString = "42"
let forcedUnwrappingNumber1 = Int(answerString)!
let helloWorldString = "Hello World!"
//let forcedUnwrappingNumber2 = Int(helloWorldString)!
// Try to uncomment the above line to see what happened.

/*:
 
 ### Optional binding
 
 You use optional binding to find out whether an optional contains a value,
 and if so, to make that value available as a temporary constant or variable.
 
 Optional binding can be used with `if`, `guard`, and `while` statements to 
 check for a value inside an optional, and to extract that value into a constant 
 or variable, as part of a single action.

 */
func parseInt(_ string: String) -> (isInteger: Bool, value: Int) {
    let possibleNumber = Int(string)
    /* Alternative Unwrapping and Assign method */
    /*
    if possibleNumber != nil {
        let actualNumber = possibleNumber!
        return (true, actualNumber)
    } else {
        return (false, 0)
    }
     */
    if let actualNumber = possibleNumber {
        return (true, actualNumber)
    } else {
        return (false, 0)
    }
}
parseInt("12")
parseInt("XD")
//:
//: The `if` statement in `parseInt(_:)` could be read as
//:
//: “If the optional Int returned by `Int(possibleNumber)` contains a value,
//: set a new constant called `actualNumber` to the value contained in the optional.”
//:
//: > Try to "option+click" on `possibleNumber` and `actualNumber` to see their types.

func squareFloat(_ string: String) -> String? {
    guard let floatNumber = Float(string) else {
        return nil
    }
    return "\(floatNumber * floatNumber)"
}
squareFloat("16.0")
squareFloat("A")
<commit_msg>Refine the example of optional bindings<commit_after>/*:

 # Optionals

 You use **optionals** in situations where a value may be _absent_. 
 
 An optional represents two possibilities: 
 - Either there is a value, and you can unwrap the optional to access that value
 - or there isn’t a value at all
 
 We put _a question mark_ (`?`) after the type to indicate that this variable has
 an optional value.

 */
/*:
 
 Take following lines as example, converting strings into numbers may fail when
 the string is not composed by digits.

 */
let possibleNumber1 = "123"
let convertedNumber1 = Int(possibleNumber1)
let possibleNumber2 = "ABC1"
let convertedNumber2: Int? = Int(possibleNumber2)

/*:
 
 ## `nil`

 We use `nil` to denote that the value is absent.

 */
var concreteNumber: Int = 42
var optionalNumber: Int? = 42
optionalNumber = nil
//concreteNumber = nil  // Try to uncomment this line to see what Xcode yields.

//: --------------------------------------------------------------------------------------------------------------------
/*:
 
 ## Unwrapping optional values
 
 We have to unwrap the value from optionals before using it. 
 
 ### Forced unwrapping
 
 Use `if` statement to check whether it's `nil` or not, and then put a 
 _exclamation mark_ (`!`) after optionals to force unwrapping it.
 
 We called this way, using the `!` mark, as "forced unwrapping".
 
 */
func convertToNumber(from input: String) -> Int {
    let convertedOptionalNumber = Int(input)
    if convertedOptionalNumber == nil {
        return 0
    } else {
        return convertedOptionalNumber!
    }
}
convertToNumber(from: "1")
convertToNumber(from: "A")

/*:
 
 You should always check whether the value is nil or not before force unwrapping an optional.
 
 */

let answerString = "42"
let forcedUnwrappingNumber1 = Int(answerString)!
let helloWorldString = "Hello World!"
//let forcedUnwrappingNumber2 = Int(helloWorldString)!
// Try to uncomment the above line to see what happened.

/*:
 
 ### Optional binding
 
 You use optional binding to find out whether an optional contains a value,
 and if so, to make that value available as a temporary constant or variable.
 
 Optional binding can be used with `if`, `guard`, and `while` statements to 
 check for a value inside an optional, and to extract that value into a constant 
 or variable, as part of a single action.

 */

func parseInt1(_ string: String) -> (isInteger: Bool, value: Int) {
    let possibleNumber = Int(string)
    if possibleNumber != nil {
        let actualNumber = possibleNumber!
        return (true, actualNumber)
    } else {
        return (false, 0)
    }
}

/*:
 
 The two lines for checking nil and unwrapping could be merged as one line by
 **optional binding**, like:
 
 */

func parseInt(_ string: String) -> (isInteger: Bool, value: Int) {
    let possibleNumber = Int(string)
    if let actualNumber = possibleNumber {
        return (true, actualNumber)
    } else {
        return (false, 0)
    }
}
parseInt("12")
parseInt("XD")

/*:

 The `if` statement in `parseInt(_:)` could be read as

 “If the optional Int returned by `Int(possibleNumber)` contains a value,
 set a new constant called `actualNumber` to the value contained in the optional.”

 > Try to "option+click" on `possibleNumber` and `actualNumber` to see their types.
 
 Also, we use `guard` for optional binding too:

 */

func squareFloat(_ string: String) -> String? {
    guard let floatNumber = Float(string) else {
        return nil
    }
    return "\(floatNumber * floatNumber)"
}
squareFloat("16.0")
squareFloat("A")

/*:
 
 The `optional binding` could be chained together, like:
 
 */

func getAnswer() -> String? {
    let someOptionalString: String? = "42"
    if let concreteString = someOptionalString, let answer = Int(concreteString) {
        return "The answer is \(answer)."
    } else {
        return nil
    }
}
getAnswer()!

func stringPower(base: String, exponent exp: String) -> String? {
    guard let baseNumber = Int(base), let expNumber = Int(exp) else {
        return nil
    }
    var result = 1
    for _ in 0..<expNumber {
        result *= baseNumber
    }
    return String(result)
}
stringPower(base: "2", exponent: "5")
stringPower(base: "2", exponent: "B")

{'fraction_non_alphanumeric': 0.12406360888421605, 'fraction_numerical': 0.008148245498751478, 'mean_word_length': 2.9125964010282774, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5650215', 'n_tokens_mistral': 2187, 'n_tokens_neox': 2053, 'n_words': 893}