[Swift 1] Day 2 - Code Exercise Solution


#1

Please share your code or answers with your classmates for the Day 1 Code Exercise and related Notebook Activity questions.

Day 2 Course Videos
Day 2 Code Exercise

Share code using


#2

Here is my code + bonus:

    var width = (widthTextField.text as NSString).doubleValue
    var height = (heightTextField.text as NSString).doubleValue
    
    println("Valid input! \(width) x  \(height)")
            
    var area = width * height
    var perimeter = 2 * (width + height) // calculate perimeter
    outputLabel.text = "\(area)"
    outputPerimeterLabel.text = "\(perimeter)" // output perimeter

Question 1: Int is an integer, a whole number, including negative. example 0, 1, -22, etc
Question 2: A string is a collection of characters. Example: “December 22”


#3

This link leads to a zip file with all the code exercises and bonus exercises for Day 2.

An Int is an abbreviation of the term integer. An integer is a number that can be written without a fractional component.


#4

Code for solving for the perimeter with floating values:

  println("Button 2 Pressed")
  var width = (widthTextField.text as NSString).floatValue
  var height = (heightTextField.text as NSString).floatValue
        
  println("Valid Input! \(width) x \(height)")
  
  var perimeter = (2 * width) + (2 * height)
  outputLabelPerimeter.text = "\(perimeter)"
  1. Int is short for Integer, which is any whole number 0-9
  2. String is any group of characters (including numbers). IE “April 01”

#5

Here is my solution for Day 2 exercise - not sure if this is the most efficient or more-Swift way of doing it but it seems to work.

@IBAction func buttonPressed(sender: AnyObject) {

    println("Button was pressed")

    var widthString = NSString(string: widthTextField.text)
    var heightString = NSString(string: heightTextField.text)
    var widthDouble : Double? = widthString.doubleValue
    var heightDouble : Double?  = heightString.doubleValue

    if (widthDouble != nil && heightDouble != nil) {
        println("valid input - width= \(widthDouble) and height = \(heightDouble)")
        var area = widthDouble! * heightDouble!
        outputLabel.text = "\(area)"
    }

}

#6

I’m lost here. I found this

var string = NSString(string: mySwiftString)
string.doubleValue

but I don’t know what to do with it.

Paul did you post the answer ?


#7

Change the code to use Double numbers, instead of Int numbers. Bonus: Add a second UILabel to display the perimeter of the rectangle when the Calculate button is pressed.

UI:

Code:
(Using this new Swift extensions thing, which is pretty cool. “Extensions add new functionality to an existing class, structure, or enumeration type.”)

//
//  ViewController.swift
//  Day Two
//
//  Created by Fernando Fernandes on 10/7/14.
//  Copyright (c) 2014 Blue Spell. All rights reserved.
//

import UIKit

// Adds new functionality to Swift's String class
extension String {
    func toDouble() -> Double? {
        return NSNumberFormatter().numberFromString(self)!.doubleValue
    }
}

class ViewController: UIViewController {
    
    // Input
    @IBOutlet weak var widthTextField: UITextField!
    @IBOutlet weak var heightTextField: UITextField!
   
    // Output
    @IBOutlet weak var areaOutputLabel: UILabel!
    @IBOutlet weak var perimeterOutputLabel: UILabel!
    
    @IBAction func calculateButtonPressed(sender: AnyObject) {
        
        if let width = widthTextField.text.toDouble()
        {
            if let height = heightTextField.text.toDouble()
            {
                // Calculate area
                var area = width * height
                areaOutputLabel.text = "\(area)"
                
                // Calculate perimeter
                var perimeter = 2 * (width + height)
                perimeterOutputLabel.text = "\(perimeter)"
            }
        }
    }
}

What does Int mean? Write down some examples.

In Swift, “Int” means a 64-bit signed integer value type.

  • “integer” is a number that can be written without a fractional component (1, 5, -235)
  • “signed” means positive or negative values
  • A 64-bit register can store 2^64 different values

So an example would be any number from −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

What does String mean? Provide an example string using your next birthday.

In Swift, “String” means an arbitrary Unicode string value.

  • “Unicode” is a computing industry standard for the consistent encoding, representation and handling of text expressed in most of the world’s writing systems.

So an example would be any character (or group of characters) covered by the Unicode standard: “h”, “word”, “123”, “!”, “>”, “05/03/2015”…

Strings in Swift can even hold Apple’s emoji characters:

:smiley:


#8

I tried the same class extension method (I saw it on stack overflow), but I found that if you enter a non-numeric value in the text field you get a crash to to an unexpected nil while unwrapping an optional value. I fixed it by changing this:

return NSNumberFormatter().numberFromString(self)!.doubleValue

to this:

return NSNumberFormatter().numberFromString(self)?.doubleValue

Instead of unwrapping the optional value, it preserves the optional-ness and handles a nil gracefully. :smile:

I do think that the class extension is a great and very elegant option!


#9

Very good catch!

Since I set my keyboard type to “Number Pad”, I did not face that issue. Thanks for sharing. :smile:


#10

I added another Button “Calculate perimeter” and it doesn’t work : <<<< Expected declaration >>>>>>>>>> Any ideas ???

@IBAction func perimeterButtonPressed(sender: AnyObject) {
println(“Perimeter Button Pressed”)

    if let width = widthTextField.text.toInt() {
        if let height = heightTextField.text.toInt() {
          
            
           var perimeter = 2 * (width + height)
            perimeterLabel.text = "\(perimeter)"
            
    }

}

}


#11

Could you share the entire code, @anderssongreene? You can use Gist.


#12

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var widthTextField: UITextField!

@IBOutlet weak var heightTextField: UITextField!

@IBOutlet weak var outputLabel: UILabel!


@IBOutlet weak var perimeterLabel: UILabel!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func buttonPressed(sender: AnyObject) {
    println("Button Pressed")
    
    if let width = widthTextField.text.toInt() {
        if let height = heightTextField.text.toInt() {
            
            println("Valid input! \(width) x \(height)")
            
            var area = width * height
            outputLabel.text = "\(area)"
            
        }
    }
    
    
}

@IBAction func perimeterButtonPressed(sender: AnyObject) {
       println("Perimeter Button Pressed")
    
    if let width = widthTextField.text.toInt() {
        if let height = heightTextField.text.toInt() {
          
            
           var perimeter = 2 * (width + height)
            perimeterLabel.text = "\(perimeter)"
            
    }

}

}


#13

Thanks. The code you pasted here is missing a curly bracket. I just added a “}” and the end and it ran fine.


#14

I see now, newbie mistake. Thanks a lot Fernando.


#15

Code

@IBAction func buttonPressed(sender: AnyObject) {

        println("Button pressed")
        var width = (widthTextField.text as NSString).doubleValue
        var height = (heightTextField.text as NSString).doubleValue

        var area = width * height
        var perimeter = 2 * (width + height)

        areaLabel.text = "\(area)"
        perimeterLabel.text = "\(perimeter)"

    }

Questions:

  1. Int is for Integer, any whole number 0-9, positive or negative
  2. String is any set of characters and numbers like “April 30”

#16

Not sure why I’m getting a fatal error… it says:

fatal error: unexpectedly found nil while unwrapping an Optional value

looks like there is something wrong with the last line. Can’t quite figure out. :frowning:

@IBAction func perimeterPressed(sender: AnyObject) {
    
    println("perimeterButtonPressed")
    
    var width = (widthTextField.text as NSString).doubleValue
    var height = (heightTextField.text as NSString).doubleValue
    
    var perimeter = 2 * (width + height)
    
    perimeterLabel.text = "\(perimeter)"

#17

I changed my initial attempt to use the cool extensions feature shown by @Fernando.

The only addition I did was to output an “Invalid” message when the input is <=0 or not numerical (if somehow possible with the keyboard setting). I don’t think it makes sense to allow negative input! :smile:
I’m not sure whether there is a more efficient way to do this error trapping.

@IBAction func buttonPressed(sender: AnyObject) {
    
    var validInput = true
    
    if let width = widthTextField.text.toDouble() {
        if let height = heightTextField.text.toDouble() {
            
            if width <= 0 || height <= 0 {
                validInput = false
            }
            else {
                
                println("Valid input! \(width) x \(height)")
            
                var area = width * height
                var perimeter = 2 * (width + height)
            
                areaLabel.text = "\(area)"
                perimeterLabel.text = "\(perimeter)"
            }
        }
        else {
            validInput = false
        }
    }
    else {
        validInput = false
    }

    if !validInput {
        areaLabel.text = "Invalid"
        perimeterLabel.text = "Invalid"
    }


    
}

#18

Nice!

You may not need that validInput at all. You could write:

if let width = widthTextField.text.toDouble() {
    if let height = heightTextField.text.toDouble() {

        if width <= 0 || height <= 0 {

            areaLabel.text = "Invalid"
            perimeterLabel.text = "Invalid"

        } else {

            println("Valid input! \(width) x \(height)")

            var area = width * height
            var perimeter = 2 * (width + height)

            areaLabel.text = "\(area)"
            perimeterLabel.text = "\(perimeter)"
        }
    }
}

Less is more. :wink:


#19

Thank you! However, I also tried to catch the scenario where non-numeric input was given.

I think your solution will simply leave the previous result, without showing the “Invalid” message if non-numeric input was given. Do you agree?


#20

Oh, I thought you were using the number pad keyboard:

With this setting you don’t need to validate non-numeric input.

But if not, then you are right. You need to check that too. :wink: