diff --git a/Lab - Classes.playground/Pages/1. Exercise - Define a Base Class.xcplaygroundpage/Contents.swift b/Lab - Classes.playground/Pages/1. Exercise - Define a Base Class.xcplaygroundpage/Contents.swift index 8576732..d2e033f 100644 --- a/Lab - Classes.playground/Pages/1. Exercise - Define a Base Class.xcplaygroundpage/Contents.swift +++ b/Lab - Classes.playground/Pages/1. Exercise - Define a Base Class.xcplaygroundpage/Contents.swift @@ -5,21 +5,47 @@ Create a `Spaceship` class with three variable properties: `name`, `health`, and `position`. The default value of `name` should be an empty string and `health` should be 0. `position` will be represented by an `Int` where negative numbers place the ship further to the left and positive numbers place the ship further to the right. The default value of `position` should be 0. */ - +class Spaceship { + var name = "" + var health = 0 + var position = 0 + + func moveLeft() { + position -= 1 + } + + func moveRight() { + position += 1 + } + + func wasHit() { + health -= 5 + + if health <= 0 { + print("Sorry. Your ship was hit one too many times. Do you want to play again?") + } + } +} /*: Create a `let` constant called `falcon` and assign it to an instance of `Spaceship`. After initialization, set `name` to "Falcon". */ +let falcon = Spaceship() +falcon.name = "Falcon" /*: Go back and add a method called `moveLeft()` to the definition of `Spaceship`. This method should adjust the position of the spaceship to the left by one. Add a similar method called `moveRight()` that moves the spaceship to the right. Once these methods exist, use them to move `falcon` to the left twice and to the right once. Print the new position of `falcon` after each change in position. */ - +falcon.moveLeft() +falcon.moveLeft() +falcon.moveRight() +print("New position: \(falcon.position)") /*: The last thing `Spaceship` needs for this example is a method to handle what happens if the ship gets hit. Go back and add a method `wasHit()` to `Spaceship` that will decrement the ship's health by 5, then if `health` is less than or equal to 0 will print "Sorry. Your ship was hit one too many times. Do you want to play again?" Once this method exists, call it on `falcon` and print out the value of `health`. */ - +falcon.wasHit() +print("Health: \(falcon.health)") //: page 1 of 4 | [Next: Exercise - Create a Subclass](@next) diff --git a/Lab - Classes.playground/Pages/2. Exercise - Create a Subclass.xcplaygroundpage/Contents.swift b/Lab - Classes.playground/Pages/2. Exercise - Create a Subclass.xcplaygroundpage/Contents.swift index 69a1117..3b04512 100644 --- a/Lab - Classes.playground/Pages/2. Exercise - Create a Subclass.xcplaygroundpage/Contents.swift +++ b/Lab - Classes.playground/Pages/2. Exercise - Create a Subclass.xcplaygroundpage/Contents.swift @@ -26,21 +26,44 @@ class Spaceship { /*: Define a new class `Fighter` that inherits from `Spaceship`. Add a variable property `weapon` that defaults to an empty string and a variable property `remainingFirePower` that defaults to 5. */ +class Fighter: Spaceship { + var weapon = "" + var remainingFirePower = 5 + + func fire() { + if remainingFirePower > 0 { + remainingFirePower -= 1 + } else { + print("You have no more fire power.") + } + } +} /*: Create a new instance of `Fighter` called `destroyer`. A `Fighter` will be able to shoot incoming objects to avoid colliding with them. After initialization, set `weapon` to "Laser" and `remainingFirePower` to 10. Note that since `Fighter` inherits from `Spaceship`, it also has properties for `name`, `health`, and `position`, and has methods for `moveLeft()`, `moveRight()`, and `wasHit()` even though you did not specifically add them to the declaration of `Fighter`. Knowing that, set `name` to "Destroyer," print `position`, then call `moveRight()` and print `position` again. */ - +let destroyer = Fighter() +destroyer.weapon = "Laser" +destroyer.remainingFirePower = 10 +destroyer.name = "Destroyer" +print("Position before: \(destroyer.position)") +destroyer.moveRight() +print("Position after: \(destroyer.position)") /*: Try to print `weapon` on `falcon`. Why doesn't this work? Provide your answer in a comment or a print statement below, and remove any code you added that doesn't compile. */ - +// falcon is an instance of Spaceship, which does not have weapon property. Only Fighter instances has this property defined. /*: Add a method to `fighter` called `fire()`. This should check to see if `remainingFirePower` is greater than 0, and if so, should decrement `remainingFirePower` by one. If `remainingFirePower` is not greater than 0, print "You have no more fire power." Call `fire()` on `destroyer` a few times and print `remainingFirePower` after each method call. */ - +destroyer.fire() +print("remainingFirePower: \(destroyer.remainingFirePower)") +destroyer.fire() +print("remainingFirePower: \(destroyer.remainingFirePower)") +destroyer.fire() +print("remainingFirePower: \(destroyer.remainingFirePower)") //: [Previous](@previous) | page 2 of 4 | [Next: Exercise - Override Methods and Properties](@next) diff --git a/Lab - Classes.playground/Pages/3. Exercise - Override Methods and Properties.xcplaygroundpage/Contents.swift b/Lab - Classes.playground/Pages/3. Exercise - Override Methods and Properties.xcplaygroundpage/Contents.swift index a25449d..9ad362e 100644 --- a/Lab - Classes.playground/Pages/3. Exercise - Override Methods and Properties.xcplaygroundpage/Contents.swift +++ b/Lab - Classes.playground/Pages/3. Exercise - Override Methods and Properties.xcplaygroundpage/Contents.swift @@ -39,16 +39,37 @@ class Fighter: Spaceship { /*: Define a new class `ShieldedShip` that inherits from `Fighter`. Add a variable property `shieldStrength` that defaults to 25. Create a new instance of `ShieldedShip` called `defender`. Set `name` to "Defender" and `weapon` to "Cannon." Call `moveRight()` and print `position`, then call `fire()` and print `remainingFirePower`. */ +class ShieldedShip: Fighter { + var shieldStrength = 25 + + override func wasHit() { + if shieldStrength > 0 { + shieldStrength -= 5 + } else { + super.wasHit() + } + } +} +let defender = ShieldedShip() +defender.name = "Defender" +defender.weapon = "Cannon" + +defender.moveRight() +print("position: \(defender.position)") + +defender.fire() +print("remainingFirePower: \(defender.remainingFirePower)") /*: Go back to your declaration of `ShieldedShip` and override `wasHit()`. In the body of the method, check to see if `shieldStrength` is greater than 0. If it is, decrement `shieldStrength` by 5. Otherwise, decrement `health` by 5. Call `wasHit()` on `defender` and print `shieldStrength` and `health`. */ - - +defender.wasHit() +print("shieldStrength: \(defender.shieldStrength), health: \(defender.health)") /*: When `shieldStrength` is 0, all `wasHit()` does is decrement `health` by 5. That's exactly what the implementation of `wasHit()` on `Spaceship` does! Instead of rewriting that, you can call through to the superclass implementation of `wasHit()`. Go back to your implementation of `wasHit()` on `ShieldedShip` and remove the code where you decrement `health` by 5 and replace it with a call to the superclass' implementation of the method. Call `wasHit()` on `defender`, then print `shieldStrength` and `health`. */ - +defender.wasHit() +print("shieldStrength: \(defender.shieldStrength), health: \(defender.health)") //: [Previous](@previous) | page 3 of 4 | [Next: Exercise - Class Memberwise Initializers and References](@next) diff --git a/Lab - Classes.playground/Pages/4. Exercise - Class Memberwise Initializers and References.xcplaygroundpage/Contents.swift b/Lab - Classes.playground/Pages/4. Exercise - Class Memberwise Initializers and References.xcplaygroundpage/Contents.swift index a8e5b19..a016f4e 100644 --- a/Lab - Classes.playground/Pages/4. Exercise - Class Memberwise Initializers and References.xcplaygroundpage/Contents.swift +++ b/Lab - Classes.playground/Pages/4. Exercise - Class Memberwise Initializers and References.xcplaygroundpage/Contents.swift @@ -7,6 +7,12 @@ class Spaceship { let name: String var health: Int var position: Int + + init(name: String, health: Int, position: Int) { + self.name = name + self.health = health + self.position = position + } func moveLeft() { position -= 1 @@ -28,6 +34,12 @@ class Fighter: Spaceship { let weapon: String var remainingFirePower: Int + init(name: String, health: Int, position: Int, weapon: String, remainingFirePower: Int) { + self.weapon = weapon + self.remainingFirePower = remainingFirePower + super.init(name: name, health: health, position: position) + } + func fire() { if remainingFirePower > 0 { remainingFirePower -= 1 @@ -40,6 +52,12 @@ class Fighter: Spaceship { class ShieldedShip: Fighter { var shieldStrength: Int + init(name: String, health: Int, position: Int, weapon: String, remainingFirePower: Int, shieldStrength: Int) { + self.shieldStrength = shieldStrength + super.init(name: name, health: health, position: position, weapon: weapon, remainingFirePower: remainingFirePower) + + } + override func wasHit() { if shieldStrength > 0 { shieldStrength -= 5 @@ -53,26 +71,30 @@ class ShieldedShip: Fighter { Then create an instance of `Spaceship` below called `falcon`. Use the memberwise initializer you just created. The ship's name should be "Falcon." */ - +let falcon = Spaceship(name: "Falcon", health: 0, position: 0) /*: Writing initializers for subclasses can get tricky. Your initializer needs to not only set the properties declared on the subclass, but also set all of the uninitialized properties on classes that it inherits from. Go to the declaration of `Fighter` and write an initializer that takes an argument for each property on `Fighter` and for each property on `Spaceship`. Set the properties accordingly. (Hint: you can call through to a superclass' initializer with `super.init` *after* you initialize all of the properties on the subclass). Then create an instance of `Fighter` below called `destroyer`. Use the memberwise initializer you just created. The ship's name should be "Destroyer." */ - +let destroyer = Fighter(name: "Destroyer", health: 0, position: 0, weapon: "Cannon", remainingFirePower: 0) /*: Now go add an initializer to `ShieldedShip` that takes an argument for each property on `ShieldedShip`, `Fighter`, and `Spaceship`, and sets the properties accordingly. Remember that you can call through to the initializer on `Fighter` using `super.init`. Then create an instance of `ShieldedShip` below called `defender`. Use the memberwise initializer you just created. The ship's name should be "Defender." */ +let defender = ShieldedShip(name: "Defender", health: 0, position: 0, weapon: "Cannon", remainingFirePower: 0, shieldStrength: 0 ) /*: Create a new constant named `sameShip` and set it equal to `falcon`. Print out the position of `sameShip` and `falcon`, then call `moveLeft()` on `sameShip` and print out the position of `sameShip` and `falcon` again. Did both positions change? Why? If both were structs instead of classes, would it be the same? Why or why not? Provide your answer in a comment or print statement below. */ - +let sameShip = falcon +sameShip.moveLeft() +print("falcon: \(falcon.position), sameShip: \(sameShip.position)") +// The position of both instances has been changed because they reference the same address in memory. If they were structs, the value would be copied on assignment to another variable. /*: diff --git a/Lab - Classes.playground/contents.xcplayground b/Lab - Classes.playground/contents.xcplayground index 0989436..b3c6835 100644 --- a/Lab - Classes.playground/contents.xcplayground +++ b/Lab - Classes.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + diff --git a/Lab - Collections.playground/Pages/1. Exercise - Arrays.xcplaygroundpage/Contents.swift b/Lab - Collections.playground/Pages/1. Exercise - Arrays.xcplaygroundpage/Contents.swift index fbcf943..0655951 100644 --- a/Lab - Collections.playground/Pages/1. Exercise - Arrays.xcplaygroundpage/Contents.swift +++ b/Lab - Collections.playground/Pages/1. Exercise - Arrays.xcplaygroundpage/Contents.swift @@ -3,31 +3,37 @@ Assume you are an event coordinator for a community charity event and are keeping a list of who has registered. Create a variable `registrationList` that will hold strings. It should be empty after initialization. */ +var registrationList: [String] = [] /*: Your friend Sara is the first to register for the event. Add her name to `registrationList` using the `append(_:)` method. Print the contents of the collection. */ - +registrationList.append("Sara") +print(registrationList) /*: Add four additional names into the array using the `+=` operator. All of the names should be added in one step. Print the contents of the collection. */ - +registrationList += ["John", "Kate", "George", "Ben"] +print(registrationList) /*: Use the `insert(_:at:)` method to add `Charlie` into the array as the second element. Print the contents of the collection. */ - +registrationList.insert("Charlie", at: 1) +print(registrationList) /*: Someone had a conflict and decided to transfer her registration to someone else. Use array subscripting to change the sixth element to `Rebecca`. Print the contents of the collection. */ - +registrationList[5] = "Rebecca" +print(registrationList) /*: Call `removeLast()` on `registrationList`. If done correctly, this should remove `Rebecca` from the collection. Store the result of `removeLast()` into a new constant `deletedItem`, then print `deletedItem`. */ - +let deletedItem = registrationList.removeLast() +print(deletedItem) //: page 1 of 4 | [Next: App Exercise - Activity Challenge](@next) diff --git a/Lab - Collections.playground/Pages/2. App Exercise - Activity Challenge.xcplaygroundpage/Contents.swift b/Lab - Collections.playground/Pages/2. App Exercise - Activity Challenge.xcplaygroundpage/Contents.swift index d9e7443..c9761c3 100644 --- a/Lab - Collections.playground/Pages/2. App Exercise - Activity Challenge.xcplaygroundpage/Contents.swift +++ b/Lab - Collections.playground/Pages/2. App Exercise - Activity Challenge.xcplaygroundpage/Contents.swift @@ -7,26 +7,37 @@ Using arrays of type `String`, create at least two lists, one for walking challenges, and one for running challenges. Each should have at least two challenges and should be initialized using an array literal. Feel free to create more lists for different activities. */ - +let walkingChallenges = ["Walk 3 miles a day", "Walk 5 times a weak"] +let runningChallenges = ["Run 5 times a week", "Run 5 miles a day"] /*: In your app you want to show all of these lists on the same screen grouped into sections. Create a `challenges` array that holds each of the lists you have created (it will be an array of arrays). Using `challenges`, print the first element in the second challenge list. */ - +var challenges = [walkingChallenges, runningChallenges] +print(challenges[1][0]) /*: All of the challenges will reset at the end of the month. Use the `removeAll` to remove everything from `challenges`. Print `challenges`. */ - +challenges.removeAll() +print(challenges) /*: Create a new array of type `String` that will represent challenges a user has committed to instead of available challenges. It can be an empty array or have a few items in it. */ - +var committedChallenges: [String] = [] /*: Write an if statement that will use `isEmpty` to check if there is anything in the array. If there is not, print a statement asking the user to commit to a challenge. Add an else-if statement that will print "The challenge you have chosen is " if the array count is exactly 1. Then add an else statement that will print "You have chosen multiple challenges." */ - +if committedChallenges.isEmpty { + print("Please commit to a challenge") +} else { + if committedChallenges.count == 1 { + print("The challenge you have chosen is \(committedChallenges[0])") + } else { + print("You have chosen multiple challenges.") + } +} //: [Previous](@previous) | page 2 of 4 | [Next: Exercise - Dictionaries](@next) diff --git a/Lab - Collections.playground/Pages/3. Exercise - Dictionaries.xcplaygroundpage/Contents.swift b/Lab - Collections.playground/Pages/3. Exercise - Dictionaries.xcplaygroundpage/Contents.swift index e3d52d8..bc76317 100644 --- a/Lab - Collections.playground/Pages/3. Exercise - Dictionaries.xcplaygroundpage/Contents.swift +++ b/Lab - Collections.playground/Pages/3. Exercise - Dictionaries.xcplaygroundpage/Contents.swift @@ -3,33 +3,40 @@ Create a variable `[String: Int]` dictionary that can be used to look up the number of days in a particular month. Use a dictionary literal to initialize it with January, February, and March. January contains 31 days, February has 28, and March has 31. Print the dictionary. */ - +var daysByMonth = ["January" : 31, "February": 28, "March": 31] +print(daysByMonth) /*: Using subscripting syntax to add April to the collection with a value of 30. Print the dictionary. */ - +daysByMonth["April"] = 30 +print(daysByMonth) /*: It's a leap year! Update the number of days in February to 29 using the `updateValue(_:, forKey:)` method. Print the dictionary. */ - +daysByMonth.updateValue(29, forKey: "February") +print(daysByMonth) /*: Use if-let syntax to retrieve the number of days under "January". If the value is there, print "January has 31 days", where 31 is the value retrieved from the dictionary. */ - - +if let daysCount = daysByMonth["January"] { + print("January has \(daysCount) days") +} /*: Given the following arrays, create a new [String : [String]] dictionary. `shapesArray` should use the key "Shapes" and `colorsArray` should use the key "Colors". Print the resulting dictionary. */ let shapesArray = ["Circle", "Square", "Triangle"] let colorsArray = ["Red", "Green", "Blue"] - +let colorsAndShapes = ["Shapes": shapesArray, "Colors": colorsArray] +print(colorsAndShapes) /*: Print the last element of `colorsArray`, accessing it through the dictionary you've created. You'll have to use if-let syntax or the force unwrap operator to unwrap what is returned from the dictionary before you can access an element of the array. */ - +if let colors = colorsAndShapes["Colors"], let lastColor = colors.last { + print(lastColor) +} //: [Previous](@previous) | page 3 of 4 | [Next: App Exercise - Pacing](@next) diff --git a/Lab - Collections.playground/Pages/4. App Exercises - Pacing.xcplaygroundpage/Contents.swift b/Lab - Collections.playground/Pages/4. App Exercises - Pacing.xcplaygroundpage/Contents.swift index 6b5ba08..859ddfd 100644 --- a/Lab - Collections.playground/Pages/4. App Exercises - Pacing.xcplaygroundpage/Contents.swift +++ b/Lab - Collections.playground/Pages/4. App Exercises - Pacing.xcplaygroundpage/Contents.swift @@ -7,27 +7,34 @@ Create a dictionary `paces` of type [String: Double] and assign it a dictionary literal with "Easy", "Medium", and "Fast" keys corresponding to values of 10.0, 8.0, and 6.0. These numbers correspond to mile pace in minutes. Print the dictionary. */ - - +var paces = ["Easy": 10.0, "Medium": 8.0, "Fast": 6.0] +print(paces) /*: Add a new key/value pair to the dictionary. The key should be "Sprint" and the value should be 4.0. Print the dictionary. */ - +paces["Sprint"] = 4.0 +print(paces) /*: Imagine the user in question gets faster over time and decides to update his/her pacing on runs. Update the values of "Medium" and "Fast" to 7.5 and 5.8, respectively. Print the dictionary. */ - +paces["Medium"] = 7.5 +paces["Fast"] = 5.8 +print(paces) /*: Imagine the user in question decides not to store "Sprint" as one his/her regular paces. Remove "Sprint" from the dictionary. Print the dictionary. */ - +paces["Sprint"] = nil +print(paces) /*: When a user chooses a pace, you want the app to print a statement stating that it will keep him/her on pace. Imagine a user chooses "Medium." Accessing the value from the dictionary, print a statement saying "Okay! I'll keep you at a minute mile pace." */ +if let mediumPace = paces["Medium"] { + print("Okay! I'll keep you at a \(mediumPace) minute mile pace.") +} /*: diff --git a/Lab - Constants and Variables.playground/Pages/1. Exercise - Constants.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/1. Exercise - Constants.xcplaygroundpage/Contents.swift index 8721318..2f22fb0 100644 --- a/Lab - Constants and Variables.playground/Pages/1. Exercise - Constants.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/1. Exercise - Constants.xcplaygroundpage/Contents.swift @@ -3,8 +3,8 @@ Declare a constant called `friends` to represent the number of friends you have on social media. Give it a value between 50 and 1000. Print out the value by referencing your constant. */ - - +let friends = 120 +print(friends) /*: Now assume you go through and remove friends that aren't active on social media. Attempt to update your `friends` constant to a lower number than it currently is. Observe what happens and then move to the next step. */ @@ -13,6 +13,6 @@ /*: Does the above code compile? Why not? Print your explanation to the console using the `print` function. Go back and delete your line of code that updates the `friends` constant to a lower number so that the playground will compile properly. */ - +print("One cannot update the value of the constant after it has been assigned") //: page 1 of 10 | [Next: App Exercise - Step Goal](@next) diff --git a/Lab - Constants and Variables.playground/Pages/10. App Exercise - Percent Completed.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/10. App Exercise - Percent Completed.xcplaygroundpage/Contents.swift index 21166b7..754eddb 100644 --- a/Lab - Constants and Variables.playground/Pages/10. App Exercise - Percent Completed.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/10. App Exercise - Percent Completed.xcplaygroundpage/Contents.swift @@ -5,12 +5,12 @@ You decide that your fitness tracking app should show the user what percentage of his/her goal has been achieved so far today. Declare a variable called `percentCompleted` and set it to 0. Do not explicity assign it a type. */ - +var percentCompleted: Double = 0 /*: Imagine that partway through the day a user has taken 3,467 steps out of the 10,000 step goal. This means he/she is 34.67% of the way to his/her goal. Assign 34.67 to `percentCompleted`. Does the code compile? Go back and explicity assign a type to `percentCompleted` that will allow the code to compile. */ - +percentCompleted = 34.67 /*: diff --git a/Lab - Constants and Variables.playground/Pages/2. App Exercise - Step Goal.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/2. App Exercise - Step Goal.xcplaygroundpage/Contents.swift index b71a821..54ef0ba 100644 --- a/Lab - Constants and Variables.playground/Pages/2. App Exercise - Step Goal.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/2. App Exercise - Step Goal.xcplaygroundpage/Contents.swift @@ -5,11 +5,11 @@ Your fitness tracking app needs to know goal number of steps per day. Create a constant `goalSteps` and set it to 10000. */ - +let goalSteps = 10000 /*: Use two `print` functions to print two separate lines to the console. The first line should say "Your step goal for the day is:", and the second line should print the value of `goalSteps` by referencing your constant. */ - - +print("Your step goal for the day is:") +print(goalSteps) //: [Previous](@previous) | page 2 of 10 | [Next: Exercise - Variables](@next) diff --git a/Lab - Constants and Variables.playground/Pages/3. Exercise - Variables.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/3. Exercise - Variables.xcplaygroundpage/Contents.swift index 1b6fe9b..ae21b0f 100644 --- a/Lab - Constants and Variables.playground/Pages/3. Exercise - Variables.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/3. Exercise - Variables.xcplaygroundpage/Contents.swift @@ -3,16 +3,16 @@ Declare a variable `schooling` and set it to the number of years of school that you have completed. Print `schooling` to the console. */ - - +var schooling = 17 +print(schooling) /*: Now imagine you just completed an additional year of school, and update the `schooling` variable accordingly. Print `schooling` to the console. */ - - +schooling += 1 +print(schooling) /*: Does the above code compile? Why is this different than trying to update a constant? Print your explanation to the console using the `print` function. */ - +print("The value of a variable can be updated after initial assignment") //: [Previous](@previous) | page 3 of 10 | [Next: App Exercise - Step Count](@next) diff --git a/Lab - Constants and Variables.playground/Pages/4. App Exercise - Step Count.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/4. App Exercise - Step Count.xcplaygroundpage/Contents.swift index 4c95fb5..042a3f8 100644 --- a/Lab - Constants and Variables.playground/Pages/4. App Exercise - Step Count.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/4. App Exercise - Step Count.xcplaygroundpage/Contents.swift @@ -5,11 +5,12 @@ Create a variable called `steps` that will keep track of the number of steps you take throughout the day. Set its initial value to 0 to represent the step count first thing in the morning. Print `steps` to the console. */ - - +var steps = 0 +print(steps) /*: Now assume the tracker has been keeping track of steps all morning, and you want to show the user the latest step count. Update `steps` to be 2000. Print `steps` to the console. Then print "Good job! You're well on your way to your daily goal." */ - - +steps = 2000 +print(steps) +print("Good job! You're well on your way to your daily goal.") //: [Previous](@previous) | page 4 of 10 | [Next: Exercise - Constant or Variable?](@next) diff --git a/Lab - Constants and Variables.playground/Pages/5. Exercise - Constant Or Variable.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/5. Exercise - Constant Or Variable.xcplaygroundpage/Contents.swift index 1d38a49..55d919f 100644 --- a/Lab - Constants and Variables.playground/Pages/5. Exercise - Constant Or Variable.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/5. Exercise - Constant Or Variable.xcplaygroundpage/Contents.swift @@ -10,9 +10,9 @@ For each of the metrics above, declare either a constant or a variable and assign it a value corresponding to a hypothetical post. Be sure to use proper naming conventions. */ - - - - - +var numberOfLikes = 100 +var numberOfComments = 5 +let yearCreated = 2021 +let monthCreated = 8 +let dayCreated = 2 //: [Previous](@previous) | page 5 of 10 | [Next: App Exercise - Fitness Tracker: Constant or Variable?](@next) diff --git a/Lab - Constants and Variables.playground/Pages/6. App Exercise - Constant or Variable.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/6. App Exercise - Constant or Variable.xcplaygroundpage/Contents.swift index a9bfc4b..865b7fc 100644 --- a/Lab - Constants and Variables.playground/Pages/6. App Exercise - Constant or Variable.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/6. App Exercise - Constant or Variable.xcplaygroundpage/Contents.swift @@ -11,11 +11,16 @@ - Goal number of steps: The user's goal for number of steps to take each day - Average heart rate: The user's average heart rate over the last 24 hours */ - - - - - +let name = "John" +print("Assuming that a user cannot change their name after registration") +var age = 27 +print("The user should be able to update their age as the times go by") +var todaySteps = 5_000 +print("The numbe of steps will get updated during the day") +let goalSteps = 8_000 +print("The goal should not change during the day") +var averageHeartRate = 67 +print("The average heart rate will change during the day") /*: Now go back and add a line after each constant or variable declaration. On those lines, print a statement explaining why you chose to declare the piece of information as a constant or variable. */ diff --git a/Lab - Constants and Variables.playground/Pages/7. Exercise - Types and Type Safety.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/7. Exercise - Types and Type Safety.xcplaygroundpage/Contents.swift index 6a26c32..8285f37 100644 --- a/Lab - Constants and Variables.playground/Pages/7. Exercise - Types and Type Safety.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/7. Exercise - Types and Type Safety.xcplaygroundpage/Contents.swift @@ -3,21 +3,21 @@ Declare two variables, one called `firstDecimal` and one called `secondDecimal`. Both should have decimal values. Look at both of their types by holding Option and clicking on the variable name. */ - - +var firstDecimal = 4.2 +var secondDecimal = 8.8 /*: Declare a variable called `trueOrFalse` and give it a boolean value. Try to assign it to `firstDecimal` like so: `firstDecimal = trueOrFalse`. Does it compile? Print a statement to the console explaining why not, and remove the line of code that will not compile. */ - - +var trueOrFalse = false +print("One cannot assing a Bool value to a variable representing a Double value due to a type mismatch") /*: Declare a variable and give it a string value. Then try to assign it to `firstDecimal`. Does it compile? Print a statement to the console explaining why not, and remove the line of code that will not compile. */ - - +var aString = "test" +print("Again, type of the variable doesn't match the value that we are trying to assigning") /*: Finally, declare a variable with a whole number value. Then try to assign it to `firstDecimal`. Why won't this compile even though both variables are numbers? Print a statement to the console explaining why not, and remove the line of code that will not compile. */ - - +let anInteger = 12 +print("Even though they are both numbers, Integer and Double are different types so cannot be mixed") //: [Previous](@previous) | page 7 of 10 | [Next: App Exercise - Tracking Different Types](@next) diff --git a/Lab - Constants and Variables.playground/Pages/8. App Exercise - Tracking Different Types.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/8. App Exercise - Tracking Different Types.xcplaygroundpage/Contents.swift index 1badf6b..4c3b12d 100644 --- a/Lab - Constants and Variables.playground/Pages/8. App Exercise - Tracking Different Types.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/8. App Exercise - Tracking Different Types.xcplaygroundpage/Contents.swift @@ -5,11 +5,11 @@ You have declared a number of constants and variables to keep track of fitness information. Declare one more variable with a boolean value called `hasMetStepGoal`. */ - +var hasMetStepGoal = false /*: When you declared a constant for goal number of steps and a variable for current step count, you likely assigned each a value in the thousands. This can be difficult to read. Redeclare this constant and variable and, when assigning each a value in the thousands, format the number so that it is more readable. */ - - +let goalSteps = 1_0000 +var steps = 2_000 //: [Previous](@previous) | page 8 of 10 | [Next: Exercise - Type Inference and Required Values](@next) diff --git a/Lab - Constants and Variables.playground/Pages/9. Exercise - Type Inference and Required Values.xcplaygroundpage/Contents.swift b/Lab - Constants and Variables.playground/Pages/9. Exercise - Type Inference and Required Values.xcplaygroundpage/Contents.swift index 5c81e84..abe601b 100644 --- a/Lab - Constants and Variables.playground/Pages/9. Exercise - Type Inference and Required Values.xcplaygroundpage/Contents.swift +++ b/Lab - Constants and Variables.playground/Pages/9. Exercise - Type Inference and Required Values.xcplaygroundpage/Contents.swift @@ -3,21 +3,21 @@ Declare a variable called `name` of type `String`, but do not give it a value. Print `name` to the console. Does the code compile? Remove any code that will not compile. */ - +var name: String /*: Now assign a value to `name`, and print it to the console. */ - - +name = "Jolanta" +print(name) /*: Declare a variable called `distanceTraveled` and set it to 0. Do not give it an explicit type. */ - +var distanceTraveled: Double = 0 /*: Now assign a value of 54.3 to `distanceTraveled`. Does the code compile? Go back and set an explicit type on `distanceTraveled` so the code will compile. */ - +distanceTraveled = 54.3 //: [Previous](@previous) | page 9 of 10 | [Next: App Exercise - Percent Completed](@next) diff --git a/Lab - Control Flow.playground/Pages/1. Exercise - Logical Operators.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/1. Exercise - Logical Operators.xcplaygroundpage/Contents.swift index e3db378..e41c92d 100644 --- a/Lab - Control Flow.playground/Pages/1. Exercise - Logical Operators.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/1. Exercise - Logical Operators.xcplaygroundpage/Contents.swift @@ -10,46 +10,46 @@ 1. `9 == 9` */ - - +print(true) +print(9 == 9) /*: 2. `9 != 9` */ - - +print(false) +print(9 != 9) /*: 3. `47 > 90` */ - - +print(false) +print(47 > 90) /*: 4. `47 < 90` */ - - +print(true) +print(47 < 90) /*: 5. `4 <= 4` */ - - +print(true) +print(4 <= 4) /*: 6. `4 >= 5` */ - - +print(false) +print(4 >= 5) /*: 7. `(47 > 90) && (47 < 90)` */ - - +print(false) +print((47 > 90) && (47 < 90)) /*: 8. `(47 > 90) || (47 < 90)` */ - - +print(true) +print((47 > 90) || (47 < 90)) /*: 9. `!true` */ - - +print(false) +print(!true) //: page 1 of 9 | [Next: Exercise - If and If-Else Statements](@next) diff --git a/Lab - Control Flow.playground/Pages/2. Exercise - If and If-Else Statements.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/2. Exercise - If and If-Else Statements.xcplaygroundpage/Contents.swift index 5bb5325..2e61414 100644 --- a/Lab - Control Flow.playground/Pages/2. Exercise - If and If-Else Statements.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/2. Exercise - If and If-Else Statements.xcplaygroundpage/Contents.swift @@ -5,17 +5,30 @@ */ var dollars = 0 +if dollars == 0 { + print("Sorry, kid. You're broke!") +} /*: `dollars` has been updated below to have a value of 10. Write an an if-else statement that prints "Sorry, kid. You're broke!" if `dollars` has a value of 0, but prints "You've got some spending money!" otherwise. Observe what is printed to the console. */ dollars = 10 - +if dollars == 0 { + print("Sorry, kid. You're broke!") +} else { + print("You've got some spending money!") +} /*: `dollars` has been updated below to have a value of 105. Write an an if-else-if statement that prints "Sorry, kid. You're broke!" if `dollars` has a value of 0, prints "You've got some spending money!" if `dollars` is less than 100, and prints "Looks to me like you're rich!" otherwise. Observe what is printed to the console. */ dollars = 105 - +if dollars == 0 { + print("Sorry, kid. You're broke!") +} else if dollars < 100 { + print("You've got some spending money!") +} else { + print("Looks to me like you're rich!") +} //: [Previous](@previous) | page 2 of 9 | [Next: App Exercise - Fitness Decisions](@next) diff --git a/Lab - Control Flow.playground/Pages/3. App Exercise - Fitness Decisions.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/3. App Exercise - Fitness Decisions.xcplaygroundpage/Contents.swift index d0d23b3..ce93438 100644 --- a/Lab - Control Flow.playground/Pages/3. App Exercise - Fitness Decisions.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/3. App Exercise - Fitness Decisions.xcplaygroundpage/Contents.swift @@ -5,11 +5,23 @@ You want your fitness tracking app to give as much encouragement as possible to your users. Create a variable `steps` equal to the number of steps you guess you've taken today. Create a constant `stepGoal` equal to 10,000. Write an if-else statement that will print "You're almost halfway there!" if `steps` is less than half of `stepGoal`, and will print "You're over halfway there!" if `steps` is greater than half of `stepGoal`. */ +var steps = 8_000 +var stepGoal = 10_000 - +if steps < stepGoal / 2 { + print("You're almost halfway there!") +} else { + print("You're over halfway there!") +} /*: Now create a new, but similar, if-else-if statement that prints "Way to get a good start today!" if `steps` is less than a tenth of `stepGoal`, prints "You're almost halfway there!" if `steps` is less than half of `stepGoal`, and prints "You're over halfway there!" if `steps` is greater than half of `stepGoal`. */ - +if steps < stepGoal / 10 { + print("Way to get a good start today!") +} else if steps < stepGoal / 2 { + print("You're almost halfway there!") +} else { + print("You're over halfway there!") +} //: [Previous](@previous) | page 3 of 9 | [Next: Exercise - Boolean Practice](@next) diff --git a/Lab - Control Flow.playground/Pages/4. Exercise - Boolean Practice.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/4. Exercise - Boolean Practice.xcplaygroundpage/Contents.swift index 5db9740..a43b59f 100644 --- a/Lab - Control Flow.playground/Pages/4. Exercise - Boolean Practice.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/4. Exercise - Boolean Practice.xcplaygroundpage/Contents.swift @@ -13,7 +13,11 @@ let hasFish = true let hasPizza = false let hasVegan = true - +if (hasFish || hasPizza) && hasVegan { + print("Let's go") +} else { + print("Sorry, we'll have to think of somewhere else.") +} /*: Imagine you're trying to decide whether or not to go on a walk. You decide that you'll go on a walk if it's not raining or if it's 82 degress or warmer and sunny out. Create a constant `isNiceWeather` that is equal to an expression that evaluates to a boolean indicating whether or not the weather is nice enough for you to go for a walk. Write an if statement that will print "I'm going for a walk!" if the weather is nice. */ @@ -21,5 +25,9 @@ let temp = 82 let isRaining = true let isSunny = true +let isNiceWeather = !isRaining || (temp >= 82 && isSunny) +if isNiceWeather { + print("I'm going for a walk!") +} //: [Previous](@previous) | page 4 of 9 | [Next: App Exercise - Target Heart Rate](@next) diff --git a/Lab - Control Flow.playground/Pages/5. App Exercise - Target Heart Rate.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/5. App Exercise - Target Heart Rate.xcplaygroundpage/Contents.swift index 8740e75..b33bc14 100644 --- a/Lab - Control Flow.playground/Pages/5. App Exercise - Target Heart Rate.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/5. App Exercise - Target Heart Rate.xcplaygroundpage/Contents.swift @@ -11,5 +11,15 @@ let targetLowerBound = 120 let targetUpperBound = 150 let currentHR = 147 +let isInTarget = currentHR >= targetLowerBound && currentHR <= targetUpperBound +let isBelowTarget = currentHR < targetLowerBound +let isAboveTarget = currentHR > targetUpperBound +if isInTarget { + print("You're right on track!") +} else if isBelowTarget { + print("You're doing great, but try to push it a bit!") +} else { + print("You're on fire! Slow it down just a bit.") +} //: [Previous](@previous) | page 5 of 9 | [Next: Exercise - Switch Statements](@next) diff --git a/Lab - Control Flow.playground/Pages/6. Switch Statements.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/6. Switch Statements.xcplaygroundpage/Contents.swift index ed3e397..cf51ac7 100644 --- a/Lab - Control Flow.playground/Pages/6. Switch Statements.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/6. Switch Statements.xcplaygroundpage/Contents.swift @@ -3,11 +3,26 @@ Imagine you're on a baseball team nearing the end of the season. Create a `leaguePosition` constant with a value of 1. Using a `switch` statement, print "Champions!" if the `leaguePosition` is 1, "Runners up" if the value is 2, "Third place" if the value is 3, and "Bad season!" in all other cases. */ +let leaguePosition = 1 - +switch leaguePosition { +case 1: + print("Champions!") +case 2: + print("Runners up") +case 3: + print("Third place") +default: + print("Bad season!") +} /*: Write a new `switch` statement that prints "Medal winner" if `leaguePosition` is within the range of 1-3. Otherwise, print "No medal awarded". */ - +switch leaguePosition { +case 1...3: + print("Medal winner") +default: + print("No medal awarded") +} //: [Previous](@previous) | page 6 of 9 | [Next: App Exercise - Heart Rate Zones](@next) diff --git a/Lab - Control Flow.playground/Pages/7. App Exercise - Heart Rate Zones.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/7. App Exercise - Heart Rate Zones.xcplaygroundpage/Contents.swift index 40f36d4..b75f27d 100644 --- a/Lab - Control Flow.playground/Pages/7. App Exercise - Heart Rate Zones.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/7. App Exercise - Heart Rate Zones.xcplaygroundpage/Contents.swift @@ -17,5 +17,22 @@ */ let currentHR = 128 - +switch currentHR { +case 100...120: + print("You are in the Very Light zone. Activity in this zone helps with recovery.") +case 121...140: + print("You are in the Light zone. Activity in this zone helps improve basice endurance and fat burning.") +case 121...140: + print("You are in the Light zone. Activity in this zone helps improve basice endurance and fat burning.") +case 141...160: + print("You are in the Moderate zone. Activity in this zone helps improve aerobic fitness.") +case 161...180: + print("You are in the Hard zone. Activity in this zone increases maximum performance capacity for shorter sessions.") +case 181...200: + print("You are in the Maximum zone. Activity in this zone helps fit athletes develop speed.") +case 201...: + print("You are going too fast. Slow down a little bit!") +default: + break +} //: [Previous](@previous) | page 7 of 9 | [Next: Exercise - Ternary Operator](@next) diff --git a/Lab - Control Flow.playground/Pages/8. Exercise - Ternary Operator.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/8. Exercise - Ternary Operator.xcplaygroundpage/Contents.swift index 24cbb56..0267b7b 100644 --- a/Lab - Control Flow.playground/Pages/8. Exercise - Ternary Operator.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/8. Exercise - Ternary Operator.xcplaygroundpage/Contents.swift @@ -6,11 +6,6 @@ let number1 = 14 let number2 = 25 -var largest: Int -if number1 > number2 { - largest = number1 -} else { - largest = number2 -} +let largest = number1 > number2 ? number1 : number2 //: [Previous](@previous) | page 8 of 9 | [Next: App Exercise - Ternary Messages](@next) diff --git a/Lab - Control Flow.playground/Pages/9. App Exercise - Ternary Messages.xcplaygroundpage/Contents.swift b/Lab - Control Flow.playground/Pages/9. App Exercise - Ternary Messages.xcplaygroundpage/Contents.swift index 5c86dde..d274302 100644 --- a/Lab - Control Flow.playground/Pages/9. App Exercise - Ternary Messages.xcplaygroundpage/Contents.swift +++ b/Lab - Control Flow.playground/Pages/9. App Exercise - Ternary Messages.xcplaygroundpage/Contents.swift @@ -8,13 +8,7 @@ let stepGoal = 10000 let steps = 3948 -if steps < stepGoal / 2 { - print("Almost halfway!") -} else { - print("Over halfway!") -} - - +print(steps < stepGoal / 2 ? "Almost halfway!" : "Over halfway!") /*: _Copyright © 2018 Apple Inc._ diff --git a/Lab - Enumerations.playground/Pages/1. Exercise - Enumerations.xcplaygroundpage/Contents.swift b/Lab - Enumerations.playground/Pages/1. Exercise - Enumerations.xcplaygroundpage/Contents.swift index dc7d938..5b4182f 100644 --- a/Lab - Enumerations.playground/Pages/1. Exercise - Enumerations.xcplaygroundpage/Contents.swift +++ b/Lab - Enumerations.playground/Pages/1. Exercise - Enumerations.xcplaygroundpage/Contents.swift @@ -3,31 +3,71 @@ Define a `Suit` enum with four possible cases: `clubs`, `spades`, `diamonds`, and `hearts`. */ - +enum Suit { + case clubs + case spades + case diamonds + case hearts +} /*: Imagine you are being shown a card trick and have to draw a card and remember the suit. Create a variable instance of `Suit` called `cardInHand` and assign it to the `hearts` case. Print out the instance. */ - +var cardInHand: Suit = .hearts +print(cardInHand) /*: Now imagine you have to put back the card you drew and draw a different card. Update the variable to be a spade instead of a heart. */ - +cardInHand = .spades /*: Imagine you are writing an app that will display a fun fortune (i.e. something like "You will soon find what you seek.") based on cards drawn. Write a function called `getFortune(cardSuit:)` that takes a parameter of type `Suit`. Inside the body of the function, write a switch statement based on the value of `cardSuit`. Print a different fortune for each `Suit` value. Call the function a few times, passing in different values for `cardSuit` each time. */ +func getFortune(cardSuit: Suit) { + switch cardSuit { + case .clubs: + print("You will soon find what you seek.") + case .spades: + print("You will get a rise next month.") + case .diamonds: + print("You will win a lot of money.") + case .hearts: + print("You will fall in love at first sight.") + } +} +getFortune(cardSuit: .hearts) +getFortune(cardSuit: .diamonds) +getFortune(cardSuit: .clubs) +getFortune(cardSuit: .spades) /*: Create a `Card` struct below. It should have two properties, one for `suit` of type `Suit` and another for `value` of type `Int`. */ +struct Card { + + enum Value { + case ace + case two, three, four, five, six, seven, eight, nine, ten + case jack + case queen + case king + } + + + let suit: Suit + let value: Value +} /*: How many values can playing cards have? How many values can `Int` be? It would be safer to have an enum for the card's value as well. Inside the struct above, create an enum for `Value`. It should have cases for `ace`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight`, `nine`, `ten`, `jack`, `queen`, `king`. Change the type of `value` from `Int` to `Value`. Initialize two `Card` objects and print a statement for each that details the card's value and suit. */ +let aceOfClubs = Card(suit: .clubs, value: .ace) +print("The first card is \(aceOfClubs.value) of \(aceOfClubs.suit).") +let queenOfHearts = Card(suit: .hearts, value: .queen) +print("The other card is \(queenOfHearts.value) of \(queenOfHearts.suit).") //: page 1 of 2 | [Next: App Exercise - Swimming Workouts](@next) diff --git a/Lab - Enumerations.playground/Pages/2. App Exercise - Swimming Workouts.xcplaygroundpage/Contents.swift b/Lab - Enumerations.playground/Pages/2. App Exercise - Swimming Workouts.xcplaygroundpage/Contents.swift index de34f32..44450d4 100644 --- a/Lab - Enumerations.playground/Pages/2. App Exercise - Swimming Workouts.xcplaygroundpage/Contents.swift +++ b/Lab - Enumerations.playground/Pages/2. App Exercise - Swimming Workouts.xcplaygroundpage/Contents.swift @@ -5,13 +5,44 @@ Previous app exercises have introduced the idea that your fitness tracking app may allow users to track swimming workouts. Create a `SwimmingWorkout` struct below with properties for `distance`, `time`, and `stroke`. `distance` and `time` should be of type `Double` and will represent distance in meters and time in seconds, and `stroke` should be of type `String`. */ - +struct SwimmingWorkout { + + enum Stroke { + case freestyle + case butterfly + case backstroke + case breaststroke + } + + let distance: Double + let time: Double + let stroke: Stroke + + static var freestyleWorkouts: [SwimmingWorkout] = [] + static var butterflyWorkouts: [SwimmingWorkout] = [] + static var backstrokeWorkouts: [SwimmingWorkout] = [] + static var breaststrokeWorkouts: [SwimmingWorkout] = [] + + func save() { + switch stroke { + case .freestyle: + SwimmingWorkout.freestyleWorkouts.append(self) + case .butterfly: + SwimmingWorkout.butterflyWorkouts.append(self) + case .backstroke: + SwimmingWorkout.backstrokeWorkouts.append(self) + case .breaststroke: + SwimmingWorkout.breaststrokeWorkouts.append(self) + } + } +} /*: Allowing `stroke` to be of type `String` isn't very type-safe. Inside the `SwimmingWorkout` struct, create an enum called `Stroke` that has cases for `freestyle`, `butterfly`, `backstroke`, and `breaststroke`. Change the type of `stroke` from `String` to `Stroke`. Create two instances of `SwimmingWorkout` objects. */ - +let freestyleWorkout = SwimmingWorkout(distance: 1000, time: 1800, stroke: .freestyle) +let backstrokeWorkout = SwimmingWorkout(distance: 2000, time: 3600, stroke: .backstroke) /*: Now imagine you want to log swimming workouts separately based on the swimming stroke. You might use arrays as static variables on `SwimmingWorkout` for this. Add four static variables, `freestyleWorkouts`, `butterflyWorkouts`, `backstrokeWorkouts`, and `breaststrokeWorkouts`, to `SwimmingWorkout` above. Each should be of type `[SwimmingWorkout]` and should default to empty arrays. */ @@ -20,7 +51,11 @@ /*: Now add an instance method to `SwimmingWorkout` called `save()` that takes no parameters and has no return value. This method will add its instance to the static array on `SwimmingWorkout` that corresponds to its swimming stroke. Inside `save()` write a switch statement that switches on the instance's `stroke` property, and appends `self` to the proper array. Call save on the two instances of `SwimmingWorkout` that you created above, and then print the array(s) to which they should have been added to see if your `save` method works properly. */ +freestyleWorkout.save() +backstrokeWorkout.save() +print(SwimmingWorkout.freestyleWorkouts) +print(SwimmingWorkout.backstrokeWorkouts) /*: diff --git a/Lab - Functions.playground/Pages/1. Exercise - Create Functions.xcplaygroundpage/Contents.swift b/Lab - Functions.playground/Pages/1. Exercise - Create Functions.xcplaygroundpage/Contents.swift index 37d509b..50c4eb8 100644 --- a/Lab - Functions.playground/Pages/1. Exercise - Create Functions.xcplaygroundpage/Contents.swift +++ b/Lab - Functions.playground/Pages/1. Exercise - Create Functions.xcplaygroundpage/Contents.swift @@ -3,11 +3,36 @@ Write a function called `introduceMyself` that prints a brief introduction of yourself. Call the function and observe the printout. */ +func introduceMyself() { + print("Hello! My name is Jolanta Soja and I am an iOS developer.") +} +introduceMyself() /*: Write a function called `magicEightBall` that generates a random number and then uses either a switch statement or if-else-if statements to print different responses based on the random number generated. `let randomNum = Int.random(in: 0...4)` will generate a random number from 0 to 4, after which you can print different phrases corresponding to the number generated. Call the function multiple times and observe the different printouts. */ +func magicEightBall() { + let randomNum = Int.random(in: 0...4) + + switch randomNum { + case 0: + print("Hi!") + case 1: + print("Hello!") + case 2: + print("Welcome!") + case 3: + print("Good morning!") + case 4: + print("Good afternoon!") + default: + break + } +} +for _ in 1...5 { + magicEightBall() +} //: page 1 of 6 | [Next: App Exercise - A Functioning App](@next) diff --git a/Lab - Functions.playground/Pages/2. App Exercise - A Functioning App.xcplaygroundpage/Contents.swift b/Lab - Functions.playground/Pages/2. App Exercise - A Functioning App.xcplaygroundpage/Contents.swift index 17808ef..39708f3 100644 --- a/Lab - Functions.playground/Pages/2. App Exercise - A Functioning App.xcplaygroundpage/Contents.swift +++ b/Lab - Functions.playground/Pages/2. App Exercise - A Functioning App.xcplaygroundpage/Contents.swift @@ -9,11 +9,33 @@ */ var steps = 0 +func incrementSteps() { + steps += 1 + print(steps) +} +for _ in 1...5 { + incrementSteps() +} /*: Similarly, if you want to regularly provide progress updates to your user, you can put your control flow statements that check on progress into a function. Write a function called `progressUpdate` after the declaration of `goal` below. The function should print "You're off to a good start." if `steps` is less than 10% of `goal`, "You're almost halfway there!" if `steps` is less than half of `goal`, "You're over halfway there!" if `steps` is less than 90% of `goal`, "You're almost there!" if `steps` is less than `goal`, and "You beat your goal!" otherwise. Call the function and observe the printout. Remember, you can convert numbers using the appropriate Int or Double initializer. */ let goal = 10000 +func progressUpdate() { + if steps < Int(Double(goal) * 0.1) { + print("You're off to a good start.") + } else if steps < goal / 2 { + print("You're almost halfway there!") + } else if steps < Int(Double(goal) * 0.9) { + print("You're over halfway there!") + } else if steps < goal { + print("You're almost there!" ) + } else { + print("You beat your goal!") + } +} + +progressUpdate() //: [Previous](@previous) | page 2 of 6 | [Next: Exercise - Parameters and Argument Labels](@next) diff --git a/Lab - Functions.playground/Pages/3. Exercise - Parameters and Argument Labels.xcplaygroundpage/Contents.swift b/Lab - Functions.playground/Pages/3. Exercise - Parameters and Argument Labels.xcplaygroundpage/Contents.swift index 33158a5..0960d06 100644 --- a/Lab - Functions.playground/Pages/3. Exercise - Parameters and Argument Labels.xcplaygroundpage/Contents.swift +++ b/Lab - Functions.playground/Pages/3. Exercise - Parameters and Argument Labels.xcplaygroundpage/Contents.swift @@ -3,16 +3,29 @@ Write a new introduction function called `introduction`. It should take two `String` parameters, `name` and `home`, and one `Int` parameter, `age`. The function should print a brief introduction. I.e. if "Mary," "California," and 32 were passed into the function, it might print "Mary, 32, is from California." Call the function and observe the printout. */ +func introduction(name: String, home: String, age: Int) { + print("\(name), \(age), is from \(home).") +} - +introduction(name: "Mary", home: "California", age: 32) /*: Write a function called `almostAddition` that takes two `Int` arguments. The first argument should not require an argument label. The function should add the two arguments together, subtract 2, then print the result. Call the function and observe the printout. */ +func almostAddition(_ firstNumber: Int, secondNumber: Int) { + let result = firstNumber + secondNumber - 2 + print(result) +} +almostAddition(5, secondNumber: 4) /*: Write a function called `multiply` that takes two `Double` arguments. The function should multiply the two arguments and print the result. The first argument should not require a label, and the second argument should have an external label, "by", that differs from the internal label. Call the function and observe the printout. */ +func multiply(_ multiplier: Double, by multiplicand: Double) { + let result = multiplier * multiplicand + print(result) +} +multiply(3, by: 4) //: [Previous](@previous) | page 3 of 6 | [Next: App Exercise - Progress Updates](@next) diff --git a/Lab - Functions.playground/Pages/4. App Exercise - Progress Updates.xcplaygroundpage/Contents.swift b/Lab - Functions.playground/Pages/4. App Exercise - Progress Updates.xcplaygroundpage/Contents.swift index 29d57f3..9d28bcc 100644 --- a/Lab - Functions.playground/Pages/4. App Exercise - Progress Updates.xcplaygroundpage/Contents.swift +++ b/Lab - Functions.playground/Pages/4. App Exercise - Progress Updates.xcplaygroundpage/Contents.swift @@ -9,11 +9,35 @@ Call the function a number of times, passing in different values of `steps` and `goal`. Observe the printouts and make sure what is printed to the console is what you would expect for the parameters passsed in. */ +func progressUpdate(steps: Int, goal: Int) { + if steps < Int(Double(goal) * 0.1) { + print("You're off to a good start.") + } else if steps < goal / 2 { + print("You're almost halfway there!") + } else if steps < Int(Double(goal) * 0.9) { + print("You're over halfway there!") + } else if steps < goal { + print("You're almost there!" ) + } else { + print("You beat your goal!") + } +} +progressUpdate(steps: 1_000, goal: 20_000) +progressUpdate(steps: 3_000, goal: 20_000) +progressUpdate(steps: 12_000, goal: 20_000) +progressUpdate(steps: 19_000, goal: 20_000) +progressUpdate(steps: 20_000, goal: 20_000) /*: Your fitness tracking app is going to help runners stay on pace to reach their goals. Write a function called pacing that takes four `Double` parameters called `currentDistance`, `totalDistance`, `currentTime`, and `goalTime`. Your function should calculate whether or not the user is on pace to hit or beat `goalTime`. If yes, print "Keep it up!", otherwise print "You've got to push it just a bit harder!" */ - +func pacing(currentDistance: Double, totalDistance: Double, currentTime: Double, goalTime: Double) { + if currentDistance / totalDistance >= currentTime / goalTime { + print("Keep it up!") + } else { + print("You've got to push it just a bit harder!") + } +} //: [Previous](@previous) | page 4 of 6 | [Next: Exercise - Return Values](@next) diff --git a/Lab - Functions.playground/Pages/5. Exercise - Return Values.xcplaygroundpage/Contents.swift b/Lab - Functions.playground/Pages/5. Exercise - Return Values.xcplaygroundpage/Contents.swift index 2cdc442..ab03a67 100644 --- a/Lab - Functions.playground/Pages/5. Exercise - Return Values.xcplaygroundpage/Contents.swift +++ b/Lab - Functions.playground/Pages/5. Exercise - Return Values.xcplaygroundpage/Contents.swift @@ -3,11 +3,19 @@ Write a function called `greeting` that takes a `String` argument called name, and returns a `String` that greets the name that was passed into the function. I.e. if you pass in "Dan" the return value might be "Hi, Dan! How are you?" Use the function and print the result. */ +func greeting(name: String) -> String { + return "Hi, \(name)! How are you?" +} +print(greeting(name: "Dan")) /*: Write a function that takes two `Int` arguments, and returns an `Int`. The function should multiply the two arguments, add 2, then return the result. Use the function and print the result. */ +func almostMultiply(_ multiplier: Int, by multiplicand: Int) -> Int { + return multiplier * multiplicand + 2 +} +print(almostMultiply(4, by: 3)) //: [Previous](@previous) | page 5 of 6 | [Next: App Exercise - Separating Functions](@next) diff --git a/Lab - Functions.playground/Pages/6. App Exercise - Separating Functions.xcplaygroundpage/Contents.swift b/Lab - Functions.playground/Pages/6. App Exercise - Separating Functions.xcplaygroundpage/Contents.swift index 76dc16a..705dccd 100644 --- a/Lab - Functions.playground/Pages/6. App Exercise - Separating Functions.xcplaygroundpage/Contents.swift +++ b/Lab - Functions.playground/Pages/6. App Exercise - Separating Functions.xcplaygroundpage/Contents.swift @@ -7,12 +7,28 @@ As an example, write a function that only does a portion of what your previous `pacing` function did. This function will be called `calculatePace`. It should take three `Double` arguments called `currentDistance`, `totalDistance`, and `currentTime`, and should return a `Double` that will represent the time at which the user will finish the run based on the user's current distance and time. call the function and print the return value. */ +func calculatePace(currentDistance: Double, totalDistance: Double, currentTime: Double) -> Double { + return totalDistance * currentTime / currentDistance +} +let pace = calculatePace(currentDistance: 1000, totalDistance: 2000, currentTime: 600) +print(pace) /*: Now write a function called `pacing` that takes four `Double` arguments called `currentDistance`, `totalDistance`, `currentTime`, and `goalTime`. The function should also return a `String`, which will be the message to show the user. The function should call `calculatePace`, passing in the appropriate values, and capture the return value. The function should then compare the returned value to `goalTime` and if the user is on pace return "Keep it up!", and return "You've got to push it just a bit harder!" otherwise. Call the function and print the return value. */ - +func pacing(currentDistance: Double, totalDistance: Double, currentTime: Double, goalTime: Double) -> String { + let pace = calculatePace(currentDistance: currentDistance, totalDistance: totalDistance, currentTime: currentTime) + + if pace <= goalTime { + return "Keep it up!" + } else { + return "You've got to push it just a bit harder!" + } +} + +let message = pacing(currentDistance: 1000, totalDistance: 2000, currentTime: 600, goalTime: 1000) +print(message) /*: diff --git a/Lab - Guard.playground/Pages/1. Exercise - Guard Statements.xcplaygroundpage/Contents.swift b/Lab - Guard.playground/Pages/1. Exercise - Guard Statements.xcplaygroundpage/Contents.swift index f851c0a..8d32ac1 100644 --- a/Lab - Guard.playground/Pages/1. Exercise - Guard Statements.xcplaygroundpage/Contents.swift +++ b/Lab - Guard.playground/Pages/1. Exercise - Guard Statements.xcplaygroundpage/Contents.swift @@ -4,13 +4,28 @@ import UIKit Imagine you want to write a function to calculate the area of a rectangle. However, if you pass a negative number into the function, you don't want it to calculate a negative area. Create a function called `calculateArea` that takes two `Double` parameters, `x` and `y`, and returns an optional `Double`. Write a guard statement at the beginning of the function that verifies each of the parameters is greater than zero and returns `nil` if not. When the guard has succeeded, calculate the area by multiplying `x` and `y` together, then return the area. Call the function once with positive numbers and once with at least one negative number. */ +func calculateArea(x: Double, y: Double) -> Double? { + guard x > 0, y > 0 else { return nil } + + return x * y +} +calculateArea(x: 4, y: 6) +calculateArea(x: -6, y: 4) /*: Create a function called `add` that takes two optional integers as parameters and returns an optional integer. You should use one `guard` statement to unwrap both optional parameters, returning `nil` in the `guard` body if one or both of the parameters doesn't have a value. If both parameters can successfully be unwrapped, return their sum. Call the function once with non-`nil` numbers and once with at least one parameter being `nil`. */ +func add(a: Int?, b: Int?) -> Int? { + guard let a = a, let b = b else { return nil } + + return a + b +} + +add(a: 2, b: 4) +add(a: nil, b: 2) /*: When working with UIKit objects, you will occasionally need to unwrap optionals to handle user input. For example, the text fields initialized below have `text` properties that are of type `String?`. @@ -30,10 +45,18 @@ firstNameTextField.text = "Jonathan" lastNameTextField.text = "Sanders" ageTextField.text = "28" - +func createUser() -> User? { + guard let firstName = firstNameTextField.text, let lastName = lastNameTextField.text, let age = ageTextField.text else { return nil } + + return User(firstName: firstName, lastName: lastName, age: age) +} /*: Call the function you made above and capture the return value. Unwrap the `User` with standard optional binding and print a statement using each of its properties. */ +let user = createUser() +if let user = user { + print("firstName: \(user.firstName), lastName: \(user.lastName), age: \(user.age)") +} //: page 1 of 2 | [Next: App Exercise - Guard](@next) diff --git a/Lab - Guard.playground/Pages/2. App Exercise - Guard.xcplaygroundpage/Contents.swift b/Lab - Guard.playground/Pages/2. App Exercise - Guard.xcplaygroundpage/Contents.swift index 4fea0bf..3a3cf06 100644 --- a/Lab - Guard.playground/Pages/2. App Exercise - Guard.xcplaygroundpage/Contents.swift +++ b/Lab - Guard.playground/Pages/2. App Exercise - Guard.xcplaygroundpage/Contents.swift @@ -10,7 +10,17 @@ import UIKit Write a failable initializer that takes parameters for your start and end times, and then checks to see if they are greater than 10 seconds apart using a guard statement. If they are, your initializer should fail. Otherwise, the initializer should set the properties accordingly. */ - +struct Workout { + let startTime: Double + let endTime: Double + + init?(startTime: Double, endTime: Double) { + guard endTime - startTime > 10 else { return nil } + + self.startTime = startTime + self.endTime = endTime + } +} /*: Imagine a screen where a user inputs a meal that they've eaten. If the user taps a "save" button without adding any food, you might want to prompt the user that they haven't actually added anything. @@ -26,13 +36,23 @@ let foodTextField = UITextField() let caloriesTextField = UITextField() foodTextField.text = "Banana" -caloriesTextField.text = "23" - +caloriesTextField.text = "23e" +func logFood() -> Food? { + guard let name = foodTextField.text, let caloriesText = caloriesTextField.text, let calories = Int(caloriesText) else { return nil } + + return Food(name: name, calories: calories) +} /*: Call the function you made above and capture the return value. Unwrap the `Food` object with standard optional binding and print a statement about the food using each of its properties. Go back and change the text in `caloriesTextField` to a string that cannot be converted into a number. What happens in that case? */ +let food = logFood() + +if let food = food { + print("name: \(food.name), calories: \(food.calories)") +} +// Nothing happens if the text in caloriesTextField is changed to a string that cannot be converted into a number (in that case logFood method returns nil). /*: diff --git a/Lab - Introduction.playground/Pages/1. Exercise - Use Playgrounds.xcplaygroundpage/Contents.swift b/Lab - Introduction.playground/Pages/1. Exercise - Use Playgrounds.xcplaygroundpage/Contents.swift index cd86d9d..4bd7380 100644 --- a/Lab - Introduction.playground/Pages/1. Exercise - Use Playgrounds.xcplaygroundpage/Contents.swift +++ b/Lab - Introduction.playground/Pages/1. Exercise - Use Playgrounds.xcplaygroundpage/Contents.swift @@ -10,14 +10,15 @@ print("How to use playgrounds to make writing Swift fun and simple") /*: Now print your own phrases to the console. Pick one of your favorite songs. Use your knowledge of the `print` function to display the song title and artist. */ - - +print("Rather Be") +print("Clean Bandit") /*: Use multiple `print` functions to write out some of the lyrics to the song. */ - - - +print("With every step we take, Kyoto to The Bay") +print("Strolling so casually") +print("We're different and the same, get you another name") +print("Switch up the batteries") /*: _Copyright © 2018 Apple Inc._ diff --git a/Lab - Loops.playground/Pages/1. Exercise - For-In Loops.xcplaygroundpage/Contents.swift b/Lab - Loops.playground/Pages/1. Exercise - For-In Loops.xcplaygroundpage/Contents.swift index a019d00..e7b3d49 100644 --- a/Lab - Loops.playground/Pages/1. Exercise - For-In Loops.xcplaygroundpage/Contents.swift +++ b/Lab - Loops.playground/Pages/1. Exercise - For-In Loops.xcplaygroundpage/Contents.swift @@ -3,17 +3,23 @@ Create a for-in loop that loops through values 1 to 100, and prints each of the values. */ - - +for i in 1...100 { + print(i) +} /*: Create a for-in loop that loops through each of the characters in the `alphabet` string below, and prints each of the values alongside the index. */ let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - +for (index, letter) in alphabet.enumerated() { + print("\(index): \(letter)") +} /*: Create a `[String: String]` dictionary, where the keys are names of states and the values are their capitals. Include at least three key/value pairs in your collection, then use a for-in loop to iterate over the pairs and print out the keys and values in a sentence. */ +let capitals = ["Alabama": "Montgomery", "Alaska": "Juneau", "Arizona": "Phoenix"] - +for (state, capital) in capitals { + print("The capital of \(state) is \(capital).") +} //: page 1 of 6 | [Next: App Exercise - Movements](@next) diff --git a/Lab - Loops.playground/Pages/2. App Exercise - Movements.xcplaygroundpage/Contents.swift b/Lab - Loops.playground/Pages/2. App Exercise - Movements.xcplaygroundpage/Contents.swift index 20d0853..0bd91bc 100644 --- a/Lab - Loops.playground/Pages/2. App Exercise - Movements.xcplaygroundpage/Contents.swift +++ b/Lab - Loops.playground/Pages/2. App Exercise - Movements.xcplaygroundpage/Contents.swift @@ -7,11 +7,15 @@ */ let movements: [String] = ["Walking", "Running", "Swimming", "Cycling", "Skiing", "Climbing"] - +for movement in movements { + print(movement) +} /*: Now suppose your app uses a dictionary to keep track of your average heart rate during each of the movements in `movements`. The keys correspond to the movements listed above, and the values correspond to the average heart rate that your fitness tracker has monitored during the given movement. Loop through `movementHeartRates` below, printing statements telling the user his/her average heart rate during each exercise. */ var movementHeartRates: [String: Int] = ["Walking": 85, "Running": 120, "Swimming": 130, "Cycling": 128, "Skiing": 114, "Climbing": 129] - +for (movement, heartRate) in movementHeartRates { + print("Your heart rate while \(movement) is \(heartRate).") +} //: [Previous](@previous) | page 2 of 6 | [Next: Exercise - While Loops](@next) diff --git a/Lab - Loops.playground/Pages/3. Exercise - While Loops.xcplaygroundpage/Contents.swift b/Lab - Loops.playground/Pages/3. Exercise - While Loops.xcplaygroundpage/Contents.swift index e03b910..3dbbee5 100644 --- a/Lab - Loops.playground/Pages/3. Exercise - While Loops.xcplaygroundpage/Contents.swift +++ b/Lab - Loops.playground/Pages/3. Exercise - While Loops.xcplaygroundpage/Contents.swift @@ -4,6 +4,10 @@ import Foundation Create a while loop that simulates rolling a 6-sided dice repeatedly until a 1 is rolled. After each roll, print the value. (Hint: use `Int.random(in: 1...6)` to generate a random number between 1 and 6). */ +var rolledValue = 0 - +while rolledValue != 1 { + rolledValue = Int.random(in: 1...6) + print(rolledValue) +} //: [Previous](@previous) | page 3 of 6 | [Next: App Exercise - While Loops](@next) diff --git a/Lab - Loops.playground/Pages/4. App Exercise - Running Cadence.xcplaygroundpage/Contents.swift b/Lab - Loops.playground/Pages/4. App Exercise - Running Cadence.xcplaygroundpage/Contents.swift index 120197b..802db65 100644 --- a/Lab - Loops.playground/Pages/4. App Exercise - Running Cadence.xcplaygroundpage/Contents.swift +++ b/Lab - Loops.playground/Pages/4. App Exercise - Running Cadence.xcplaygroundpage/Contents.swift @@ -11,11 +11,19 @@ import Foundation let cadence: Double = 180 var testSteps = 0 - +while testSteps < 10 { + print("Take a step") + testSteps += 1 + Thread.sleep(forTimeInterval: 60/cadence) +} /*: Recreate the above cadence example using a repeat-while loop. */ testSteps = 0 - +repeat { + print("Take a step") + testSteps += 1 + Thread.sleep(forTimeInterval: 60/cadence) +} while testSteps < 10 //: [Previous](@previous) | page 4 of 6 | [Next: Exercise - Control Transfer Statements](@next) diff --git a/Lab - Loops.playground/Pages/5. Exercise - Control Transfer Statements.xcplaygroundpage/Contents.swift b/Lab - Loops.playground/Pages/5. Exercise - Control Transfer Statements.xcplaygroundpage/Contents.swift index 2ece88a..c3664f7 100644 --- a/Lab - Loops.playground/Pages/5. Exercise - Control Transfer Statements.xcplaygroundpage/Contents.swift +++ b/Lab - Loops.playground/Pages/5. Exercise - Control Transfer Statements.xcplaygroundpage/Contents.swift @@ -5,10 +5,27 @@ */ let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - +for (index, character) in alphabet.enumerated() { + if index.isMultiple(of: 2) { + continue + } else { + print(character) + } +} /*: Create a `[String: String]` dictionary where the keys are names of states and the values are their capitals. Include at least three key/value pairs in your collection, with one of them being your home state. Now loop through this dictionary again, printing out the keys and values in a sentence, but add an if statement that will check if the current iteration is your home state. If it is, print("I found my home!") and break out of the loop. */ +let capitalsByState = ["Germany": "Berlin", "Poland": "Warsaw", "Czech Republic": "Prague", "Lithuania": "Vilnus"] + +for (state, capital) in capitalsByState { + print("The capital of \(state) is \(capital).") + + if state == "Poland" { + print("I found my home!") + break + } +} +//: [Previous](@previous) | page 5 of 6 | [Next: App Exercise - Finding Movements](@next) //: [Previous](@previous) | page 5 of 6 | [Next: App Exercise - Finding Movements](@next) diff --git a/Lab - Loops.playground/Pages/6. App Exercise - Finding Movements.xcplaygroundpage/Contents.swift b/Lab - Loops.playground/Pages/6. App Exercise - Finding Movements.xcplaygroundpage/Contents.swift index 1649e6d..51d1a2a 100644 --- a/Lab - Loops.playground/Pages/6. App Exercise - Finding Movements.xcplaygroundpage/Contents.swift +++ b/Lab - Loops.playground/Pages/6. App Exercise - Finding Movements.xcplaygroundpage/Contents.swift @@ -12,7 +12,13 @@ let lowHR = 110 let highHR = 125 var movementHeartRates: [String: Int] = ["Walking": 85, "Running": 120, "Swimming": 130, "Cycling": 128, "Skiing": 114, "Climbing": 129] - +for (movement, heartRate) in movementHeartRates { + if heartRate < lowHR || heartRate > highHR { + continue + } else { + print("You could go \(movement)") + } +} /*: _Copyright © 2018 Apple Inc._ diff --git a/Lab - Operators.playground/Pages/1. Exercise - Basic Arithmetic.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/1. Exercise - Basic Arithmetic.xcplaygroundpage/Contents.swift index 8c68750..67e6648 100644 --- a/Lab - Operators.playground/Pages/1. Exercise - Basic Arithmetic.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/1. Exercise - Basic Arithmetic.xcplaygroundpage/Contents.swift @@ -3,28 +3,34 @@ You decide to build a shed and want to know beforehand the area of your yard that it will take up. Create two constants, `width` and `height`, with values of 10 and 20, respectively. Create an `area` constant that is the result of multiplying the two previous constants together, and print out the result. */ - - +let width = 10 +let height = 20 +let area = width * height +print(area) /*: You decide that you'll divide your shed into two rooms. You want to know if dividing it equally will leave enough room for some of your larger storage items. Create a `roomArea` constant that is the result of dividing `area` in half. Print out the result. */ - +let roomArea = area / 2 /*: Create a `perimeter` constant whose value equals `width` plus `width` plus `height` plus `height`, then print out the result. */ - - +let perimeter = width + width + height + height +print(perimeter) /*: Print what you would expect the result of integer division of 10 divided by 3 to be. Create a constant, `integerDivisionResult` that is the result of 10 divided by 3, and print the value. */ - - +print(3) +let integerDivisionResult = 10/3 +print(integerDivisionResult) /*: Now create two constants, `double10` and `double3`, set to 10 and 3, and declare their types as `Double` values. Declare a final constant `divisionResult` equal to the result of `double10` divided by `double3`. Print the value of `divisionResult`. How does this differ from the value when using integer division? */ - - +let double10: Double = 10 +let double3: Double = 3 +let divisionResult = double10 / double3 +print(divisionResult) +// The later result includes the decimal part /*: Given the value pi (3.1415927), create a `radius` constant with a value of 5.0, then calculate the diameter and circumference of the circle using the following equations, and print the results: @@ -33,16 +39,22 @@ *circumference = 2 * pi * radius.* */ let pi = 3.1415927 - - +let radius = 5.0 +let diameter = 2 * radius +let circumference = 2 * pi * radius +print(diameter) +print(circumference) /*: Create an integer constant. Using the remainder operator, set its value to the remainder of 12 divided by 5. */ - +let remainder = 12 % 5 /*: Create two integer constants, `even` and `odd` and set them to any even integer and any odd integer, respectively. For each, print the remainder of dividing the value by 2. Looking at the results, how do you think you could use the remainder operator to determine if an integer is even or odd? */ - - +let even = 12 +let odd = 9 +print(even % 2) +print(odd % 2) +// If the reminder is 0, then the value is even, odd otherwise //: page 1 of 8 | [Next: App Exercise - Fitness Calculations](@next) diff --git a/Lab - Operators.playground/Pages/2. App Exercise - Fitness Calculations.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/2. App Exercise - Fitness Calculations.xcplaygroundpage/Contents.swift index 7384367..9824686 100644 --- a/Lab - Operators.playground/Pages/2. App Exercise - Fitness Calculations.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/2. App Exercise - Fitness Calculations.xcplaygroundpage/Contents.swift @@ -5,16 +5,28 @@ Your fitness tracker keeps track of users' heart rate, but you might also want to display their average heart rate over the last hour. Create three constants, `heartRate1`, `heartRate2`, and `heartRate3`. Give each constant a different value between 60 and 100. Create a constant `addedHR` equal to the sum of all three heart rates. Now create a constant called `averageHR` that equals `addedHR` divided by 3 to get the average. Print the result. */ - - +let heartRate1 = 60 +let heartRate2 = 70 +let heartRate3 = 61 +let addedHR = heartRate1 + heartRate2 + heartRate3 +let averageHR = addedHR / 3 +print(averageHR) /*: Now create three more constants, `heartRate1D`, `heartRate2D`, and `heartRate3D`, equal to the same values as `heartRate1`, `heartRate2`, and `heartRate3`. These new constants should be of type `Double`. Create a constant `addedHRD` equal to the sum of all three heart rates. Create a constant called `averageHRD` that equals the `addedHRD` divided by 3 to get the average of your new heart rate constants. Print the result. Does this differ from your previous average? Why or why not? */ - +let heartRate1D: Double = 60 +let heartRate2D: Double = 70 +let heartRate3D: Double = 64 +let addedHRD = heartRate1D + heartRate2D + heartRate3D +let averageHRD = addedHRD / 3 +print(averageHRD) +// They differs: averageHRD includes the decimal part, averageHR is the integer value /*: Imagine that partway through the day a user has taken 3,467 steps out of the 10,000 step goal. Create constants `steps` and `goal`. Both will need to be of type `Double` so that you can perform accurate calculations. `steps` should be assigned the value 3,467, and `goal` should be assigned 10,000. Create a constant `percentOfGoal` that equals an expression that evaluates to the percent of the goal that has been achieved so far. */ - +let steps: Double = 3_467 +let goal: Double = 10_000 +let percentOfGoal = steps / goal //: [Previous](@previous) | page 2 of 8 | [Next: Exercise - Compound Assignment](@next) diff --git a/Lab - Operators.playground/Pages/3. Exercise - Compound Assignment.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/3. Exercise - Compound Assignment.xcplaygroundpage/Contents.swift index b0c97b5..43d93ad 100644 --- a/Lab - Operators.playground/Pages/3. Exercise - Compound Assignment.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/3. Exercise - Compound Assignment.xcplaygroundpage/Contents.swift @@ -3,8 +3,12 @@ Declare a variable whose value begins at 10. Using addition, update the value to 15 using the compound assignment operator. Using multiplication, update the value to 30 using compound assignment. Print out the variable's value after each assignment. */ - - +var value = 10 +print(value) +value += 5 +print(value) +value *= 2 +print(value) /*: Create a variable called `piggyBank` that begins at 0. You will use this to keep track of money you earn and spend. For each point below, use the right compound assignment operator to update the balance in your piggy bank. @@ -16,9 +20,16 @@ Print the balance of your piggy bank after each step. */ - - - - - +var piggyBank = 0 +print(piggyBank) +piggyBank += 10 +print(piggyBank) +piggyBank += 20 +print(piggyBank) +piggyBank /= 2 +print(piggyBank) +piggyBank *= 3 +print(piggyBank) +piggyBank -= 3 +print(piggyBank) //: [Previous](@previous) | page 3 of 8 | [Next: App Exercise - Counting](@next) diff --git a/Lab - Operators.playground/Pages/4. App Exercise - Counting.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/4. App Exercise - Counting.xcplaygroundpage/Contents.swift index 881654a..22202ab 100644 --- a/Lab - Operators.playground/Pages/4. App Exercise - Counting.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/4. App Exercise - Counting.xcplaygroundpage/Contents.swift @@ -5,13 +5,14 @@ The most basic feature of your fitness tracking app is counting steps. Create a variable `steps` and set it equal to 0. Then increment its value by 1 to simulate a user taking a step. */ - - +var steps = 0 +steps += 1 /*: In addition to tracking steps, your fitness tracking app tracks distance traveled. Create a variable `distance` of type `Double` and set it equal to 50. This will represent the user having traveled 50 feet. You decide, however, to display the distance in meters. 1 meter is approximately equal to 3 feet. Use a compound assignment operator to convert `distance` to meters. Print the result. */ - - +var distance: Double = 50 +distance /= 3 +print(distance) //: [Previous](@previous) | page 4 of 8 | [Next: Exercise - Order of Operations](@next) diff --git a/Lab - Operators.playground/Pages/5. Exercise - Order of Operations.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/5. Exercise - Order of Operations.xcplaygroundpage/Contents.swift index e8378a0..be9326b 100644 --- a/Lab - Operators.playground/Pages/5. Exercise - Order of Operations.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/5. Exercise - Order of Operations.xcplaygroundpage/Contents.swift @@ -3,21 +3,21 @@ Print out what you think 10 + 2 * 5 evaluates to. Then print out the actual expression (i.e. `print(10 + 2 * 5)`) */ - - +print(20) +print(10 + 2 * 5) /*: In a separate `print` statement, add in the necessary parentheses so that addition takes place before multiplication. */ - +print((10 + 2) * 5) /*: Print out what you think 4 * 9 - 6 / 2 evaluates to. Then print out the actual expression. */ - - +print(33) +print(4 * 9 - 6 / 2) /*: In a separate `print` statement, add in the necessary parentheses so that the subtraction is prioritized over the multiplication and division. */ - +print(4 * (9 - 6) / 2) //: [Previous](@previous) | page 5 of 8 | [Next: App Exercise - Complex Fitness Calculations](@next) diff --git a/Lab - Operators.playground/Pages/6. App Exercise - Complex Fitness Calculations.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/6. App Exercise - Complex Fitness Calculations.xcplaygroundpage/Contents.swift index 1f2189c..ab0dae0 100644 --- a/Lab - Operators.playground/Pages/6. App Exercise - Complex Fitness Calculations.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/6. App Exercise - Complex Fitness Calculations.xcplaygroundpage/Contents.swift @@ -5,13 +5,15 @@ If you completed the Fitness Calculations exercise, you calculated an average heart rate to display to the user. However, using proper order of operations you can do this in fewer steps. Create three separate heart rate constants, all of type `Double`, with values between 60 and 100. Then create a constant equal to the average heart rate. If you use correct order of operations you can do the heart calculation in one line. */ - - +let heartRate1D: Double = 60 +let heartRate2D: Double = 70 +let heartRate3D: Double = 64 +let averageHRD = (heartRate1D + heartRate2D + heartRate3D) / 3 /*: One feature you might want to give users is to display their current body temperature. Create a constant `tempInFahrenheit` equal to 98.6. You may want to also show the temperature in celsius. You can convert fahrenheit to celsius by taking `tempInFahrenheit` and subtracting 32, then multiplying the result by (5.0/9.0). Create a constant `tempInCelsius` that calculates in one line the temperature in celsius. */ - - +let tempInFahrenheit = 98.6 +let tempInCelsius = (tempInFahrenheit - 32) * (5.0 / 9.0) //: [Previous](@previous) | page 6 of 8 | [Next: Exercise - Numeric Type Conversion](@next) diff --git a/Lab - Operators.playground/Pages/7. Exercise - Numeric Type Conversion.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/7. Exercise - Numeric Type Conversion.xcplaygroundpage/Contents.swift index 93698b8..94098b1 100644 --- a/Lab - Operators.playground/Pages/7. Exercise - Numeric Type Conversion.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/7. Exercise - Numeric Type Conversion.xcplaygroundpage/Contents.swift @@ -3,16 +3,18 @@ Create an integer constant `x` with a value of 10, and a double constant `y` with a value of 3.2. Create a constant `multipliedAsIntegers` equal to `x` times `y`. Does this compile? If not, fix it by converting your `Double` to an `Int` in the mathematical expression. Print the result. */ - - +let x = 10 +var y = 3.2 +let multipliedAsIntegers = x * Int(y) +print(multipliedAsIntegers) /*: Create a constant `multipliedAsDoubles` equal to `x` times `y`, but this time convert the `Int` to a `Double` in the expression. Print the result. */ - - +let multipliedAsDoubles = Double(x) * y +print(multipliedAsDoubles) /*: Are the values of `multipliedAsIntegers` and `multipliedAsDoubles` different? Print a statement to the console explaining why. */ - +print("In the first scenario we are rounding y to the closest integer value, so we are losing its decimal part") //: [Previous](@previous) | page 7 of 8 | [Next: App Exercise - Converting Types](@next) diff --git a/Lab - Operators.playground/Pages/8. App Exercise - Fitness Conversions.xcplaygroundpage/Contents.swift b/Lab - Operators.playground/Pages/8. App Exercise - Fitness Conversions.xcplaygroundpage/Contents.swift index 5de2f53..e9673f4 100644 --- a/Lab - Operators.playground/Pages/8. App Exercise - Fitness Conversions.xcplaygroundpage/Contents.swift +++ b/Lab - Operators.playground/Pages/8. App Exercise - Fitness Conversions.xcplaygroundpage/Contents.swift @@ -7,8 +7,9 @@ Now create a constant `percentOfGoal` of type `Double` that equals the percent of the goal that has been reached so far. You'll need to convert your constants of type `Int` to be of type `Double` in your calculation. */ - - +let steps = 3_000 +let goal = 10_000 +let percentOfGoal = Double(steps) / Double(goal) /*: _Copyright © 2018 Apple Inc._ diff --git a/Lab - Operators.playground/contents.xcplayground b/Lab - Operators.playground/contents.xcplayground index 5b9299e..5f72985 100644 --- a/Lab - Operators.playground/contents.xcplayground +++ b/Lab - Operators.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + diff --git a/Lab - Optionals.playground/Pages/1. Exercise - Optionals.xcplaygroundpage/Contents.swift b/Lab - Optionals.playground/Pages/1. Exercise - Optionals.xcplaygroundpage/Contents.swift index 6a8462d..9eab4a4 100644 --- a/Lab - Optionals.playground/Pages/1. Exercise - Optionals.xcplaygroundpage/Contents.swift +++ b/Lab - Optionals.playground/Pages/1. Exercise - Optionals.xcplaygroundpage/Contents.swift @@ -7,23 +7,27 @@ Declare a constant `userInputAge` of type `String` and assign it "34e" to simulate a typo while typing age. Then declare a constant `userAge` of type `Int` and set its value using the `Int` initializer that takes an instance of `String` as input. Pass in `userInputAge` as the argument for the initializer. What error do you get? */ - +let userInputAge: String = "34" +let userAge: Int? = Int(userInputAge) +print(userAge) /*: Go back and change the type of `userAge` to `Int?`, and print the value of `userAge`. Why is `userAge`'s value `nil`? Provide your answer in a comment or print statement below. */ - +// userAge's value is nil because "34e" does not represent an integer value, thus Int initialization fails. /*: Now go back and fix the typo on the value of `userInputAge`. Is there anything about the value printed that seems off? Print `userAge` again, but this time unwrap `userAge` using the force unwrap operator. */ - +// The integer value has been printed as "Optional(34)". Let's unwrap it to get just the integer value. +print(userAge!) /*: Now use optional binding to unwrap `userAge`. If `userAge` has a value, print it to the console. */ - - +if let userAge = userAge { + print(userAge) +} //: page 1 of 6 | [Next: App Exercise - Finding a Heart Rate](@next) diff --git a/Lab - Optionals.playground/Pages/2. App Exercise - Finding a Heart Rate.xcplaygroundpage/Contents.swift b/Lab - Optionals.playground/Pages/2. App Exercise - Finding a Heart Rate.xcplaygroundpage/Contents.swift index 746b8fc..b6e5549 100644 --- a/Lab - Optionals.playground/Pages/2. App Exercise - Finding a Heart Rate.xcplaygroundpage/Contents.swift +++ b/Lab - Optionals.playground/Pages/2. App Exercise - Finding a Heart Rate.xcplaygroundpage/Contents.swift @@ -7,13 +7,14 @@ Declare a variable `heartRate` of type `Int?` and set it to `nil`. Print the value. */ - +var heartRate: Int? = nil +print(heartRate) /*: In this example, if the user fixes the positioning of the heart rate monitor, the app may get a proper heart rate reading. Below, update the value of `heartRate` to 74. Print the value. */ - - +heartRate = 74 +print(heartRate) /*: As you've done in other app exercises, create a variable `hrAverage` of type `Int` and use the values stored below and the value of `heartRate` to calculate an average heart rate. */ @@ -22,6 +23,15 @@ let oldHR2 = 76 let oldHR3 = 79 let oldHR4 = 70 +var hrAverage: Int + +if let heartRate = heartRate { + hrAverage = (heartRate + oldHR1 + oldHR2 + oldHR3 + oldHR4) / 5 +} else { + hrAverage = (oldHR1 + oldHR2 + oldHR3 + oldHR4) / 4 +} + +print(hrAverage) /*: If you didn't unwrap the value of `heartRate`, you've probably noticed that you cannot perform mathematical operations on an optional value. You will first need to unwrap `heartRate`. diff --git a/Lab - Optionals.playground/Pages/3. Exercise - Functions and Optionals.xcplaygroundpage/Contents.swift b/Lab - Optionals.playground/Pages/3. Exercise - Functions and Optionals.xcplaygroundpage/Contents.swift index 798d991..3a911d9 100644 --- a/Lab - Optionals.playground/Pages/3. Exercise - Functions and Optionals.xcplaygroundpage/Contents.swift +++ b/Lab - Optionals.playground/Pages/3. Exercise - Functions and Optionals.xcplaygroundpage/Contents.swift @@ -5,10 +5,30 @@ */ let userInputAge: String = "34e" +func checkAge(userInputAge: String) -> Int? { + let userAge = Int(userInputAge) + + if let userAge = userAge { + if userAge > 18 { + print("Welcome!") + } else { + print("Sorry, but you aren't old enough to use our app.") + } + } else { + print("Sorry, something went wrong. Can you please re-enter your age?") + } + + return userAge +} + +checkAge(userInputAge: userInputAge) +checkAge(userInputAge: "15") + /*: Go back and update your function to return the age as an integer. Will your function always return a value? Make sure your return type accurately reflects this. Call the function and print the return value. */ - +print(checkAge(userInputAge: userInputAge)) +print(checkAge(userInputAge: "15")) /*: Imagine you are creating an app for making purchases. Write a function that will take the name of an item for purchase and will return the cost of that item. In the body of the function, check to see if the item is in stock by accessing it in the dictionary `stock`. If it is, return the price of the item by accessing it in the dictionary `prices`. If the item is out of stock, return `nil`. Call the function and pass in a `String` that exists in the dictionaries below. Print the return value. @@ -16,5 +36,14 @@ let userInputAge: String = "34e" var prices = ["Chips": 2.99, "Donuts": 1.89, "Juice": 3.99, "Apple": 0.50, "Banana": 0.25, "Broccoli": 0.99] var stock = ["Chips": 4, "Donuts": 0, "Juice": 12, "Apple": 6, "Banana": 6, "Broccoli": 3] +func price(of item: String) -> Double? { + if let numberOfItems = stock[item], numberOfItems > 0 { + return prices[item] + } else { + return nil + } +} +let bananaPrice = prices["Banana"] +print(bananaPrice) //: [Previous](@previous) | page 3 of 6 | [Next: App Exercise - Food Functions](@next) diff --git a/Lab - Optionals.playground/Pages/4. App Exercise - Food Functions .xcplaygroundpage/Contents.swift b/Lab - Optionals.playground/Pages/4. App Exercise - Food Functions .xcplaygroundpage/Contents.swift index 98391a4..66096e6 100644 --- a/Lab - Optionals.playground/Pages/4. App Exercise - Food Functions .xcplaygroundpage/Contents.swift +++ b/Lab - Optionals.playground/Pages/4. App Exercise - Food Functions .xcplaygroundpage/Contents.swift @@ -15,12 +15,30 @@ struct Meal { var meals: [String: Meal] = ["Breakfast": Meal(food: ["Bagel", "Orange Juice", "Egg Whites"], calories: 530)] +func food(for meal: String) -> Meal? { + return meals[meal] +} + +let breakfastMeal = food(for: "Breakfast") +print(breakfastMeal) +let lunchMeal = food(for: "Lunch") +print(lunchMeal) /*: iOS comes with a few different APIs for persistence, or saving data. You'll learn more about persistence in another lesson, but for now imagine what an app experience would be like if every time you opened the app all of your data was gone. That would be frustrating, right? Write a function that will check to see if your meal log (a dictionary like that in the previous exercise) is saved to the device. If it is, return the meal log. If it isn't, return an empty dictionary of type `[String: Any]`. The code you should use in this exercise for retrieving something saved to the device is `UserDefaults.standard.dictionary(forKey: "mealLog")`. This code will return an optional `[String: Any]`. If it returns a value, that is your meal log. If it returns `nil`, then no meal log has been saved. Call the function and print the return value. */ +func mealLog() -> [String: Any] { + if let mealLog = UserDefaults.standard.dictionary(forKey: "mealLog") { + return mealLog + } else { + return [:] + } +} + +let log = mealLog() +print(log) //: [Previous](@previous) | page 4 of 6 | [Next: Exercise - Failable Initializers](@next) diff --git a/Lab - Optionals.playground/Pages/5. Exercise - Failable Initializers.xcplaygroundpage/Contents.swift b/Lab - Optionals.playground/Pages/5. Exercise - Failable Initializers.xcplaygroundpage/Contents.swift index 9a056cd..e592fff 100644 --- a/Lab - Optionals.playground/Pages/5. Exercise - Failable Initializers.xcplaygroundpage/Contents.swift +++ b/Lab - Optionals.playground/Pages/5. Exercise - Failable Initializers.xcplaygroundpage/Contents.swift @@ -3,11 +3,40 @@ Create a `Computer` struct with two properties, `ram` and `yearManufactured`, where both parameters are of type `Int`. Create a failable initializer that will only create an instance of `Computer` if `ram` is greater than 0, and if `yearManufactured` is greater than 1970, and less than 2017. */ - +struct Computer { + let ram: Int + let yearManufactured: Int + + init?(ram: Int, yearManufactured: Int) { + if ram > 0, yearManufactured > 1970, yearManufactured < 2017 { + self.ram = ram + self.yearManufactured = yearManufactured + } else { + return nil + } + } +} /*: Create two instances of `Computer?` using the failable initializer. One instance should use values that will have a value within the optional, and the other should result in `nil`. Use if-let syntax to unwrap each of the `Computer?` objects and print the `ram` and `yearManufactured` if the optional contains a value. */ +let computer1 = Computer(ram: 16384, yearManufactured: 2016) +let computer2 = Computer(ram: 0, yearManufactured: 2015) + +if let computer1 = computer1 { + print(""" + Computer 1: + RAM: \(computer1.ram), + Manufactured : \(computer1.yearManufactured)) + """) +} +if let computer2 = computer2 { + print(""" + Computer 2: + RAM: \(computer2.ram), + Manufactured : \(computer2.yearManufactured)) + """) +} //: [Previous](@previous) | page 5 of 6 | [Next: App Exercise - Workout or Nil](@next) diff --git a/Lab - Optionals.playground/Pages/6. App Exercise - Workout or Nil.xcplaygroundpage/Contents.swift b/Lab - Optionals.playground/Pages/6. App Exercise - Workout or Nil.xcplaygroundpage/Contents.swift index ab9f71e..c0b6bd9 100644 --- a/Lab - Optionals.playground/Pages/6. App Exercise - Workout or Nil.xcplaygroundpage/Contents.swift +++ b/Lab - Optionals.playground/Pages/6. App Exercise - Workout or Nil.xcplaygroundpage/Contents.swift @@ -9,12 +9,27 @@ Write a failable initializer that takes parameters for your start and end times, and then checks to see if they are fewer than 10 seconds apart. If they are, your initializer should fail. Otherwise, they should set the properties accordingly. */ - +struct Workout { + let startTime: Double + let endTime: Double + + init?(startTime: Double, endTime: Double) { + if endTime - startTime < 10 { + return nil + } + + self.startTime = startTime + self.endTime = endTime + } +} /*: Try to initialize two instances of a `Workout` object and print each of them. One of them should not be initialized because the start and end times are too close together. The other should successfully initialize a `Workout` object. */ - +let workout1 = Workout(startTime: 28800, endTime: 28805) +let workout2 = Workout(startTime: 28800, endTime: 29000) +print(workout1) +print(workout2) /*: diff --git a/Lab - Scope.playground/Pages/1. Exercise - Scope.xcplaygroundpage/Contents.swift b/Lab - Scope.playground/Pages/1. Exercise - Scope.xcplaygroundpage/Contents.swift index fb002fb..cc759b3 100644 --- a/Lab - Scope.playground/Pages/1. Exercise - Scope.xcplaygroundpage/Contents.swift +++ b/Lab - Scope.playground/Pages/1. Exercise - Scope.xcplaygroundpage/Contents.swift @@ -9,7 +9,7 @@ for _ in 0..<10 { } //print("The value of foo is \(foo)") - +// The scope of variable foo is limited to the body of the loop (local scope), therefore it cannot be accessed from a global scope. /*: Using a comment or print statement, describe why both print statements below compile when similar-looking code did not compile above. In what scope is `x` defined, and in what scope is it modified? In contrast, in what scope is `foo` defined and used? */ @@ -20,16 +20,33 @@ for _ in 0..<10 { } print("The final value of x is \(x)") - +// x is defined in global scope and can be accessed both from inside of the body of the loop and by the last print statement (from a global scope). /*: In the body of the function `greeting` below, use variable shadowing when unwrapping `greeting`. If `greeting` is successfully unwrapped, print a statement that uses the given greeting to greet the given name (i.e. if `greeting` successfully unwraps to have the value "Hi there" and `name` is `Sara`, print "Hi there, Sara."). Otherwise, use "Hello" to print a statement greeting the given name. Call the function twice, once passing in a value for greeting, and once passing in `nil`. */ func greeting(greeting: String?, name: String) { - + if let greeting = greeting { + print("\(greeting), \(name)") + } else { + print("Hello, \(name)") + } } + +greeting(greeting: "Hi there", name: "Sara") +greeting(greeting: nil, name: "Sara") /*: Create a class called `Car`. It should have properties for `make`, `model`, and `year` that are of type `String`, `String`, and `Int`, respectively. Since this is a class, you'll need to write your own memberwise initializer. Use shadowing when naming parameters in your initializer. */ - +class Car { + let make: String + let model: String + let year: Int + + init(make: String, model: String, year: Int) { + self.make = make + self.model = model + self.year = year + } +} //: page 1 of 2 | [Next: App Exercise - Step Competition](@next) diff --git a/Lab - Scope.playground/Pages/2. App Exercise - Step Competition.xcplaygroundpage/Contents.swift b/Lab - Scope.playground/Pages/2. App Exercise - Step Competition.xcplaygroundpage/Contents.swift index a4c5c73..3b30693 100644 --- a/Lab - Scope.playground/Pages/2. App Exercise - Step Competition.xcplaygroundpage/Contents.swift +++ b/Lab - Scope.playground/Pages/2. App Exercise - Step Competition.xcplaygroundpage/Contents.swift @@ -8,6 +8,18 @@ struct User { var name: String var stepsToday: Int + + init(name: String, stepsToday: Int) { + self.name = name + self.stepsToday = stepsToday + } + + init?(name: String?, stepsToday: Int?) { + guard let name = name, let stepsToday = stepsToday else { return nil} + + self.name = name + self.stepsToday = stepsToday + } } let stepMaster = User(name: "StepMaster", stepsToday: 8394) @@ -24,8 +36,8 @@ func getWinner(competitors: [User]) -> User? { var topCompetitor: User? for competitor in competitors { - if let topCompetitor = topCompetitor { - if competitor.stepsToday > topCompetitor.stepsToday { + if let currentTopCompetitor = topCompetitor { + if competitor.stepsToday > currentTopCompetitor.stepsToday { topCompetitor = competitor } } else { @@ -34,6 +46,9 @@ func getWinner(competitors: [User]) -> User? { } return topCompetitor } + +let winner = getWinner(competitors: competitors) +print(winner?.name ?? "") /*: Write a memberwise initializer inside the `User` struct above that uses variable shadowing for naming the parameters of the initializer. */ diff --git a/Lab - Strings.playground/Pages/1. Exercise - String Basics.xcplaygroundpage/Contents.swift b/Lab - Strings.playground/Pages/1. Exercise - String Basics.xcplaygroundpage/Contents.swift index d17ab77..960b879 100644 --- a/Lab - Strings.playground/Pages/1. Exercise - String Basics.xcplaygroundpage/Contents.swift +++ b/Lab - Strings.playground/Pages/1. Exercise - String Basics.xcplaygroundpage/Contents.swift @@ -3,7 +3,7 @@ Create a `name` constant and assign it a string literal representing your name. */ - +let name = "Jolanta" /*: Create a `favoriteQuote` constant and assign it the following string literal: @@ -15,12 +15,19 @@ - callout(Example): If your favorite quote is "The grass is always greener on the other side" the value of `favoriteQuote` should be such that printing `favoriteQuote` results in the following: * `My favorite quote is "The grass is always greener on the other side."` */ - +let favoriteQuote = "My favorite quote is \"There's 106 miles to Chicago, we've got a full tank of gas, half a pack of cigarettes, it's dark out, and we've wearing sunglasses.\"." +print(favoriteQuote) /*: Write an if-else statement that prints "There's nothing here" if `emptyString` is empty, and "It's not as empty as I thought" otherwise. */ let emptyString = "" +if emptyString.isEmpty { + print("There's nothing here") +} else { + print("It's not as empty as I thought") +} +//: page 1 of 5 | [Next: Exercise - Concatenation and Interpolation](@next) //: page 1 of 5 | [Next: Exercise - Concatenation and Interpolation](@next) diff --git a/Lab - Strings.playground/Pages/2. Exercise - Concatenation and Interpolation.xcplaygroundpage/Contents.swift b/Lab - Strings.playground/Pages/2. Exercise - Concatenation and Interpolation.xcplaygroundpage/Contents.swift index 2bbe7f2..3bdf877 100644 --- a/Lab - Strings.playground/Pages/2. Exercise - Concatenation and Interpolation.xcplaygroundpage/Contents.swift +++ b/Lab - Strings.playground/Pages/2. Exercise - Concatenation and Interpolation.xcplaygroundpage/Contents.swift @@ -3,13 +3,18 @@ Create a `city` constant and assign it a string literal representing your home city. Then create a `state` constant and assign it a string literal representing your home state. Finally, create a `home` constant and use string concatenation to assign it a string representing your home city and state (i.e. Portland, Oregon). Print the value of `home`. */ - - +let city = "Wrocław" +let state = "dolnośląskie" +let home = city + ", " + state +print(home) /*: Use the compound assignment operator (`+=`) to add `home` to `introduction` below. Print the value of `introduction`. */ var introduction = "I live in" - +introduction += " " +introduction += home +introduction += "." +print(introduction) /*: Declare a `name` constant and assign it your name as a string literal. Then declare an `age` constant and give it your current age as an `Int`. Then print the following phrase using string interpolation: @@ -18,6 +23,8 @@ var introduction = "I live in" Insert `name` where indicated, and insert a mathematical expression that evaluates to your current age plus one where indicated. */ - +let name = "Jolanta" +let age = 34 +print("My name is \(name) and after my next birthday I will be \(age + 1) years old.") //: [Previous](@previous) | page 2 of 5 | [Next: App Exercise - Notifications](@next) diff --git a/Lab - Strings.playground/Pages/3. App Exercise - Notifications.xcplaygroundpage/Contents.swift b/Lab - Strings.playground/Pages/3. App Exercise - Notifications.xcplaygroundpage/Contents.swift index abb8e54..d8817de 100644 --- a/Lab - Strings.playground/Pages/3. App Exercise - Notifications.xcplaygroundpage/Contents.swift +++ b/Lab - Strings.playground/Pages/3. App Exercise - Notifications.xcplaygroundpage/Contents.swift @@ -7,8 +7,10 @@ Create `firstName` and `lastName` constants and assign them string literals representing a user's first name and last name, respectively. Create a `fullName` constant that uses string concatenation to combine `firstName` and `lastName`. Print the value of `fullName`. */ - - +let firstName = "Jolanta" +let lastName = "Soja" +let fullName = firstName + " " + lastName +print(fullName) /*: Occasionally users of your fitness tracking app will beat previous goals or records. You may want to notify them when this happens for encouragement purposes. Create a new constant `congratulations` and assign it a string literal that uses string interpolation to create the following string: @@ -19,5 +21,6 @@ let previousBest = 14392 let newBest = 15125 - +let congratulations = "Congratulations, \(fullName)! You beat your previous daily high score of \(previousBest) steps by walking \(newBest) steps yesterday!" +print(congratulations) //: [Previous](@previous) | page 3 of 5 | [Next: Exercise - String Equality and Comparison](@next) diff --git a/Lab - Strings.playground/Pages/4. Exercise - String Equality and Comparison.xcplaygroundpage/Contents.swift b/Lab - Strings.playground/Pages/4. Exercise - String Equality and Comparison.xcplaygroundpage/Contents.swift index 3ee86db..6b276e1 100644 --- a/Lab - Strings.playground/Pages/4. Exercise - String Equality and Comparison.xcplaygroundpage/Contents.swift +++ b/Lab - Strings.playground/Pages/4. Exercise - String Equality and Comparison.xcplaygroundpage/Contents.swift @@ -3,7 +3,14 @@ Create two constants, `nameInCaps` and `name`. Assign `nameInCaps` your name as a string literal with proper capitalization. Assign `name` your name as a string literal in all lowercase. Write an if-else statement that checks to see if `nameInCaps` and `name` are the same. If they are, print "The two strings are equal", otherwise print "The two strings are not equal." */ +let nameInCaps = "JOLANTA" +let name = "jolanta" +if nameInCaps == name { + print("The two strings are equal.") +} else { + print("The two strings are not equal.") +} /*: Write a new if-else statement that also checks to see if `nameInCaps` and `name` are the same. However, this time use the `lowercased()` method on each constant to compare the lowercase version of the strings. If they are equal, print the following statement using string interpolations: @@ -14,14 +21,19 @@ - " and are not the same." */ - - +if nameInCaps.lowercased() == name.lowercased() { + print("\(nameInCaps.lowercased()) and \(name.lowercased()) are the same.") +} else { + print("\(nameInCaps.lowercased()) and \(name.lowercased()) are not the same.") +} /*: Imagine you are looking through a list of names to find any that end in "Jr." Write an if statement below that will check if `junior` has the suffix "Jr.". If it does, print "We found a second generation name!" */ let junior = "Cal Ripken Jr." - +if junior.hasSuffix("Jr.") { + print("We found a second generation name!") +} /*: Suppose you are trying to find a document on your computer that contains Hamlet's famous soliloquy written by Shakespeare. You write a simple app that will check every document to see if it contains the phrase "to be, or not to be". You decide to do part of this with the `contains(_:)` method. Write an if statement below that will check if `textToSearchThrough` contains `textToSearchFor`. If it does, print "I found it!" Be sure to make this functionality case insensitive. */ @@ -29,10 +41,12 @@ import Foundation let textToSearchThrough = "To be, or not to be--that is the question" let textToSearchFor = "to be, or not to be" - +if textToSearchThrough.lowercased().contains(textToSearchFor.lowercased()) { + print("I found it!") +} /*: Print to the console the number of characters in your name by using the `count` property on `name`. */ - +print(name.count) //: [Previous](@previous) | page 4 of 5 | [Next: App Exercise - Password Entry and User Search](@next) diff --git a/Lab - Strings.playground/Pages/5. App Exercise - Password Entry and User Search.xcplaygroundpage/Contents.swift b/Lab - Strings.playground/Pages/5. App Exercise - Password Entry and User Search.xcplaygroundpage/Contents.swift index e396836..1ecd204 100644 --- a/Lab - Strings.playground/Pages/5. App Exercise - Password Entry and User Search.xcplaygroundpage/Contents.swift +++ b/Lab - Strings.playground/Pages/5. App Exercise - Password Entry and User Search.xcplaygroundpage/Contents.swift @@ -10,7 +10,11 @@ let storedPassword = "a8H1LuK91" let enteredUserName = "thefittest11" let enteredPassword: String = "a8H1Luk9" - +if enteredUserName.lowercased() == storedUserName.lowercased() && enteredPassword == storedPassword { + print("You are now logged in!") +} else { + print("Please check your user name and password and try again.") +} /*: Now that users can log in, they need to be able to search through a list of users to find their friends. This might normally be done by having the user enter a name, and then looping through all user names to see if a user name contains the search term entered. You'll learn about loops later, so for now you'll just work through one cycle of that. Imagine you are searching for a friend whose user name is StepChallenger. You enter "step" into a search bar and the app begins to search. When the app comes to the user name "stepchallenger," it checks to see if "StepChallenger" contains "step." @@ -20,7 +24,11 @@ import Foundation let userName = "StepChallenger" let searchName = "step" - +if userName.lowercased().contains(searchName.lowercased()) { + print("There is a match!") +} else { + print("No results.") +} /*: _Copyright © 2018 Apple Inc._ diff --git a/Lab - Structures.playground/Pages/1. Exercise - Structs, Instances, and Default Values.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/1. Exercise - Structs, Instances, and Default Values.xcplaygroundpage/Contents.swift index 61fd1f3..97f3216 100644 --- a/Lab - Structures.playground/Pages/1. Exercise - Structs, Instances, and Default Values.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/1. Exercise - Structs, Instances, and Default Values.xcplaygroundpage/Contents.swift @@ -3,26 +3,47 @@ Imagine you are creating an app that will monitor location. Create a `GPS` struct with two variable properties, `latitude` and `longitude`, both with default values of 0.0. */ +struct GPS { + var latitude = 0.0 + var longitude = 0.0 +} /*: Create a variable instance of `GPS` called `somePlace`. It should be initialized without supplying any arguments. Print out the latitude and longitude of `somePlace`, which should be 0.0 for both. */ - +var somePlace = GPS() +print("latitude: \(somePlace.latitude), longitude: \(somePlace.longitude)") /*: Change `somePlace`'s latitude to 51.514004, and the longitude to 0.125226, then print the updated values. */ - +somePlace.latitude = 51.514004 +somePlace.longitude = 0.125226 +print("latitude: \(somePlace.latitude), longitude: \(somePlace.longitude)") /*: Now imagine you are making a social app for sharing your favorite books. Create a `Book` struct with four variable properties: `title`, `author`, `pages`, and `price`. The default values for both `title` and `author` should be an empty string. `pages` should default to 0, and `price` should default to 0.0. */ +struct Book { + var title = "" + var author = "" + var pages = 0 + var price = 0.0 +} /*: Create a variable instance of `Book` called `favoriteBook` without supplying any arguments. Print out the title of `favoriteBook`. Does it currently reflect the title of your favorite book? Probably not. Change all four properties of `favoriteBook` to reflect your favorite book. Then, using the properties of `favoriteBook`, print out facts about the book. */ +var favoriteBook = Book() +print(favoriteBook.title) + +favoriteBook.title = "Winnie-The-Pooh" +favoriteBook.author = "A. A. Milne" +favoriteBook.pages = 176 +favoriteBook.price = 46.49 +print("title: \(favoriteBook.title), author: \(favoriteBook.author), pages: \(favoriteBook.pages), price: \(favoriteBook.price)") //: page 1 of 10 | [Next: App Exercise - Workout Tracking](@next) diff --git a/Lab - Structures.playground/Pages/10. App Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/10. App Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift index 159bdcc..b28cd19 100644 --- a/Lab - Structures.playground/Pages/10. App Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/10. App Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift @@ -13,11 +13,23 @@ struct RunningWorkout { var distance: Double var time: Double var elevation: Double + + static func mileTimeFor(distance: Double, time: Double) -> Double { + let distanceInMiles = distance / 1600 + return time / distanceInMiles + } + + static var meterInFeet = 3.28084 + static var mileInMeters = 1600.0 } + +let mileTime = RunningWorkout.mileTimeFor(distance: 4000, time: 20) +print("Avarage mile time: \(mileTime)") /*: It may be helpful to have a few type properties on `RunningWorkout` representing unit conversions (i.e. meters to mile, feet to meters, etc.). Go back and add a type property for `meterInFeet` and assign it 3.28084. Then add a type property for `mileInMeters` and assign it 1600.0. Print both of these values below. */ - +print("meterInFeet: \(RunningWorkout.meterInFeet)") +print("mileInMeters: \(RunningWorkout.mileInMeters)") /*: diff --git a/Lab - Structures.playground/Pages/2. App Exercise - Workout Tracking.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/2. App Exercise - Workout Tracking.xcplaygroundpage/Contents.swift index 87c64af..f2f2ee9 100644 --- a/Lab - Structures.playground/Pages/2. App Exercise - Workout Tracking.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/2. App Exercise - Workout Tracking.xcplaygroundpage/Contents.swift @@ -7,16 +7,25 @@ Create a `RunningWorkout` struct. It should have variables properties for `distance`, `time`, and `elevation`. All three properties should have default values of 0.0. */ +struct RunningWorkout { + var distance = 0.0 + var time = 0.0 + var elevation = 0.0 +} /*: Create a variable instance of `RunningWorkout` called `firstRun` without supplying any arguments. Print out all three properties of `firstRun`. This is a good example of when using default values is appropriate, seeing as all running workouts start with a distance, time, and elevation change of 0. */ - +var firstRun = RunningWorkout() +print("distance: \(firstRun.distance), time: \(firstRun.time), elevation: \(firstRun.elevation)") /*: Now imagine that throughout the course of the run, you go a distance of 2,396 meters in 15.3 minutes, and gain 94 meters of elevation. Update the values of `firstRun`'s properties accordingly. Print a statement about your run using the values of each property. */ - +firstRun.distance = 2396 +firstRun.time = 15.3 +firstRun.elevation = 94 +print("distance: \(firstRun.distance), time: \(firstRun.time), elevation: \(firstRun.elevation)") //: [Previous](@previous) | page 2 of 10 | [Next: Exercise - Memberwise and Custom Initializers](@next) diff --git a/Lab - Structures.playground/Pages/3. Exercise - Memberwise and Custom Initializers.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/3. Exercise - Memberwise and Custom Initializers.xcplaygroundpage/Contents.swift index 6afc9c6..09b5809 100644 --- a/Lab - Structures.playground/Pages/3. Exercise - Memberwise and Custom Initializers.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/3. Exercise - Memberwise and Custom Initializers.xcplaygroundpage/Contents.swift @@ -3,18 +3,29 @@ If you completed the exercise Structs, Instances, and Default Values, you created a `GPS` struct with default values for properties of `latitude` and `longitude`. Create your `GPS` struct again, but this time do not provide default values. Both properties should be of type `Double`. */ - +struct GPS { + var latitude: Double + var longitude: Double +} /*: Now create a constant instance of `GPS` called `somePlace`, and use the memberwise initializer to set `latitude` to 51.514004, and `longitude` to 0.125226. Print the values of `somePlace`'s properties. */ - +let somePlace = GPS(latitude: 51.5140004, longitude: 0.125226) +print("latitude: \(somePlace.latitude), longitude: \(somePlace.longitude)") /*: In Structs, Instance, and Default Values, you also created a `Book` struct with properties `title`, `author`, `pages`, and `price`. Create this struct again without default values. Give each property the appropriate type. Declare your `favoriteBook` instance and pass in the values of your favorite book using the memberwise initializer. Print a statement about your favorite book using `favoriteBook`'s properties. */ +struct Book { + let title: String + let author: String + let pages: Int + let price: Double +} - +let book = Book(title: "Winnie-The-Pooh", author: "A. A. Milne", pages: 176, price: 46.49) +print("My favorite book is \(book.title) by \(book.author)") /*: Make a `Height` struct with two variable properties, `heightInInches` and `heightInCentimeters`. Both should be of type `Double`. @@ -22,16 +33,33 @@ - Example: If you use the initializer for inches to pass in a height of 65, the initializer should set `heightInInches` to 65 and `heightInCentimeters` to 165.1. */ - +struct Height { + var heightInInches: Double + var heightInCentimeters: Double + + init(heightInInches: Double) { + self.heightInInches = heightInInches + self.heightInCentimeters = heightInInches * 2.54 + } + + init(heightInCentimeters: Double) { + self.heightInCentimeters = heightInCentimeters + self.heightInInches = heightInCentimeters / 2.54 + } +} /*: Now create a variable instance of `Height` called `someonesHeight`. Use the initializer for inches to set the height to 65. Print out the property for height in centimeters and verify that it is equal to 165.1. */ - +var someonesHeight = Height(heightInInches: 65) +print(someonesHeight.heightInCentimeters) /*: Now create a variable instance of `Height` called `myHeight` and initialize it with your own height. Verify that both `heightInInches` and `heightInCentimeters` are accurate. */ +var myHeight = Height(heightInCentimeters: 168) +print(myHeight.heightInInches) +print(myHeight.heightInCentimeters) //: [Previous](@previous) | page 3 of 10 | [Next: App Exercise - Users and Distance](@next) diff --git a/Lab - Structures.playground/Pages/4. App Exercise - Users and Distance.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/4. App Exercise - Users and Distance.xcplaygroundpage/Contents.swift index 751d413..ec98a7c 100644 --- a/Lab - Structures.playground/Pages/4. App Exercise - Users and Distance.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/4. App Exercise - Users and Distance.xcplaygroundpage/Contents.swift @@ -5,11 +5,19 @@ For most apps you'll need to have a data structure to hold information about a user. Create a `User` struct that has properties for basic information about a user. At a minimum, it should have properties to represent a user's name, age, height, weight, and activity level. You could do this by having `name` be a `String`, `age` be an `Int`, `height` and `weight` be of type `Double`, and `activityLevel` be an `Int` that will represent a scoring 1-10 of how active they are. Implement this now. */ - +struct User { + let name: String + var age: Int + var height: Double + var weight: Double + var activityLevel: Int +} /*: Create a variable instance of `User` and call it your name. Use the memberwise initializer to pass in information about yourself. Then print out a description of your `User` instance using the instance's properties. */ +var user = User(name: "Jolanta", age: 32, height: 168, weight: 54, activityLevel: 6) +print("The user's name is \(user.name), \(user.age) years old.") /*: @@ -17,16 +25,32 @@ - Example: If you use the initializer for meters and pass in a distance of 1600, the initializer should set `meters` to 1600 and `feet` to 5249.344. */ - +struct Distance { + let meters: Double + let feet: Double + + init(meters: Double) { + self.meters = meters + self.feet = meters * 3.28084 + } + + init(feet: Double) { + self.feet = feet + self.meters = feet / 3.28084 + } +} /*: Now create an instance of `Distance` called `mile`. Use the initializer for meters to set the distance to 1600. Print out the property for feet and verify that it is equal to 5249.344. */ - +let mile = Distance(meters: 1600) +print(mile.feet) /*: Now create another instance of `Distance` and give it some other distance. Ensure that both properties are set correctly. */ - +let km = Distance(meters: 1000) +print(km.meters) +print(km.feet) //: [Previous](@previous) | page 4 of 10 | [Next: Exercise - Methods](@next) diff --git a/Lab - Structures.playground/Pages/5. Exercise - Methods.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/5. Exercise - Methods.xcplaygroundpage/Contents.swift index d90b425..a71267f 100644 --- a/Lab - Structures.playground/Pages/5. Exercise - Methods.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/5. Exercise - Methods.xcplaygroundpage/Contents.swift @@ -8,7 +8,14 @@ struct Book { var author: String var pages: Int var price: Double + + func description() { + print("\"\(title)\" by \(author) (\(pages) p., PLN \(price))") + } } + +let favoriteBook = Book(title: "Winnie-The-Pooh", author: "A. A. Milne", pages: 176, price: 46.49) +favoriteBook.description() /*: A `Post` struct has been created for you below, representing a generic social media post. Add a mutating method on `Post` called `like` that will increment `likes` by one. Then create an instance of `Post` and call `like()` on it. Print out the `likes` property before and after calling the method to see whether or not the value was incremented. */ @@ -16,5 +23,14 @@ struct Post { var message: String var likes: Int var numberOfComments: Int + + mutating func like() { + likes += 1 + } } + +var post = Post(message: "Hello, world!", likes: 100, numberOfComments: 20) +print("Likes before: \(post.likes)") +post.like() +print("Likes after: \(post.likes)") //: [Previous](@previous) | page 5 of 10 | [Next: App Exercise - Workout Functions](@next) diff --git a/Lab - Structures.playground/Pages/6. App Exercise - Workout Functions.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/6. App Exercise - Workout Functions.xcplaygroundpage/Contents.swift index 774deca..c2bf959 100644 --- a/Lab - Structures.playground/Pages/6. App Exercise - Workout Functions.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/6. App Exercise - Workout Functions.xcplaygroundpage/Contents.swift @@ -9,12 +9,28 @@ struct RunningWorkout { var distance: Double var time: Double var elevation: Double + + func postWorkoutStats() { + print("distance: \(distance), time: \(time), elevation: \(elevation)") + } } + +let workout = RunningWorkout(distance: 4000, time: 20, elevation: 200) +workout.postWorkoutStats() /*: A `Steps` struct has been created for you below, representing the day's step-tracking data. It has the goal number of steps for the day and the number of steps taken so far. Create a method on `Steps` called `takeStep` that increments the value of `steps` by one. Then create an instance of `Steps` and call `takeStep()`. Print the value of the instance's `steps` property before and after the method call. */ struct Steps { var steps: Int var goal: Int + + mutating func takeStep() { + steps += 1 + } } + +var steps = Steps(steps: 100, goal: 1000) +print("Steps before: \(steps.steps)") +steps.takeStep() +print("Steps after: \(steps.steps)") //: [Previous](@previous) | page 6 of 10 | [Next: Exercise - Computed Properties and Property Observers](@next) diff --git a/Lab - Structures.playground/Pages/7. Exercise - Computed Properties and Property Observers.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/7. Exercise - Computed Properties and Property Observers.xcplaygroundpage/Contents.swift index cb8e9f0..d64de98 100644 --- a/Lab - Structures.playground/Pages/7. Exercise - Computed Properties and Property Observers.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/7. Exercise - Computed Properties and Property Observers.xcplaygroundpage/Contents.swift @@ -6,16 +6,39 @@ struct Rectangle { var width: Int var height: Int + + var area: Int { + return width * height + } } + +let rect = Rectangle(width: 100, height: 20) +print(rect.area) /*: In the `Height` struct below, height is represented in both inches and centimeters. However, if `heightInInches` is changed, `heightInCentimeters` should also adjust to match it. Add a `didSet` to each property that will check if the other property is what it should be, and if not, sets the proper value. If you set the value of the other property even though it already has the right value, you will end up with an infinite loop of each property setting the other. Create an instance of `Height` and then change one of its properties. Print out the other property to ensure that it was adjusted accordingly. */ struct Height { - var heightInInches: Double + var heightInInches: Double { + didSet { + let heightInCentimeters = heightInInches * 2.54 + + if self.heightInCentimeters != heightInCentimeters { + self.heightInCentimeters = heightInCentimeters + } + } + } - var heightInCentimeters: Double + var heightInCentimeters: Double { + didSet { + let heightInInches = heightInCentimeters / 2.54 + + if self.heightInInches != heightInInches { + self.heightInInches = heightInInches + } + } + } init(heightInInches: Double) { self.heightInInches = heightInInches @@ -27,4 +50,10 @@ struct Height { self.heightInInches = heightInCentimeters/2.54 } } + +var height = Height(heightInCentimeters: 100) +height.heightInCentimeters = 200 +print("Height in inches: \(height.heightInInches)") +//: [Previous](@previous) | page 7 of 10 | [Next: App Exercise - Mile Times and Congratulations](@next) + //: [Previous](@previous) | page 7 of 10 | [Next: App Exercise - Mile Times and Congratulations](@next) diff --git a/Lab - Structures.playground/Pages/8. App Exercise - Mile Times and Congratulations.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/8. App Exercise - Mile Times and Congratulations.xcplaygroundpage/Contents.swift index c53c59b..803c00f 100644 --- a/Lab - Structures.playground/Pages/8. App Exercise - Mile Times and Congratulations.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/8. App Exercise - Mile Times and Congratulations.xcplaygroundpage/Contents.swift @@ -11,18 +11,36 @@ struct RunningWorkout { var distance: Double var time: Double var elevation: Double + + var averageMileTime: Double { + let distanceInMiles = distance / 1600 + return time / distanceInMiles + } } + +let workout = RunningWorkout(distance: 4000, time: 20, elevation: 500) +print("Average mile time: \(workout.averageMileTime)") /*: In other app exercises, you've provided encouraging messages to the user based on how many steps they've completed. A great place to check whether or not you should display something to the user is in a property observer. In the `Steps` struct below, add a `willSet` to the `steps` property that will check if the new value is equal to `goal`, and if it is, prints a congratulatory message. Create an instance of `Steps` where `steps` is 9999 and `goal` is 10000, then call `takeStep()` and see if your message is printed to the console. */ struct Steps { - var steps: Int + var steps: Int { + willSet { + if newValue == goal { + print("Congratulations!!!") + } + } + } + var goal: Int mutating func takeStep() { steps += 1 } } + +var steps = Steps(steps: 9999, goal: 10000) +steps.takeStep() //: [Previous](@previous) | page 8 of 10 | [Next: Exercise - Type Properties and Methods](@next) diff --git a/Lab - Structures.playground/Pages/9. Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift b/Lab - Structures.playground/Pages/9. Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift index b4c4457..8604edf 100644 --- a/Lab - Structures.playground/Pages/9. Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/9. Exercise - Type Properties and Methods.xcplaygroundpage/Contents.swift @@ -7,12 +7,21 @@ struct User { var userName: String var email: String var age: Int + + static var currentUser: User = User(userName: "Jolanta", email: "soja@k7.eu", age: 34) + + static func logIn(user: User) { + currentUser = user + print("\(user.userName) has logged in.") + } } + +print("The current user is \(User.currentUser.userName) <\(User.currentUser.email)>, \(User.currentUser.age).") /*: There are other properties and actions associated with a `User` struct that might be good candidates for a type property or method. One might be a method for logging in. Go back and create a type method called `logIn(user:)` where `user` is of type `User`. In the body of the method, assign the passed in user to the `currentUser` property, and print out a statement using the user's userName saying that the user has logged in. Below, call the `logIn(user:)` method and pass in a different `User` instance than what you assigned to currentUser above. Observe the printout in the console. */ - - +let anotherUser = User(userName: "John", email: "john@example.com", age: 20) +User.logIn(user: anotherUser) //: [Previous](@previous) | page 9 of 10 | [Next: App Exercise - Type Properties and Methods](@next) diff --git a/Lab - Type Casting.playground/Pages/1. Exercise - Type Casting and Inspection.xcplaygroundpage/Contents.swift b/Lab - Type Casting.playground/Pages/1. Exercise - Type Casting and Inspection.xcplaygroundpage/Contents.swift index 31ebae6..89dc2f4 100644 --- a/Lab - Type Casting.playground/Pages/1. Exercise - Type Casting and Inspection.xcplaygroundpage/Contents.swift +++ b/Lab - Type Casting.playground/Pages/1. Exercise - Type Casting and Inspection.xcplaygroundpage/Contents.swift @@ -3,26 +3,67 @@ Create a collection of type [Any], including a few doubles, integers, strings, and booleans within the collection. Print the contents of the collection. */ - +let collection: [Any] = ["test", 4.5, 3, 5.6, "test2", false, true] +print(collection) /*: Loop through the collection. For each integer, print "The integer has a value of ", followed by the integer value. Repeat the steps for doubles, strings and booleans. */ - +for item in collection { + if let integerItem = item as? Int { + print("The integer has a value of \(integerItem)") + } else if let doubleValue = item as? Double { + print("The double has a value of \(doubleValue)") + } else if let stringValue = item as? String { + print("The string has a value of \(stringValue)") + } else if let boolValue = item as? Bool { + print("The boool has a value of \(boolValue)") + } +} /*: Create a [String : Any] dictionary, where the values are a mixture of doubles, integers, strings, and booleans. Print the key/value pairs within the collection */ - - +let dictionary: [String: Any] = ["a": 4.5, "b": 6, "c": "test", "d": false, "e": 7.7] +print(dictionary) /*: Create a variable `total` of type `Double` set to 0. Then loop through the dictionary, and add the value of each integer and double to your variable's value. For each string value, add 1 to the total. For each boolean, add 2 to the total if the boolean is `true`, or subtract 3 if it's `false`. Print the value of `total`. */ +var total: Double = 0 + +for value in dictionary.values { + if let integerItem = value as? Int { + total += Double(integerItem) + } else if let doubleValue = value as? Double { + total += doubleValue + } else if value is String { + total += 1 + } else if let boolValue = value as? Bool { + if boolValue { + total += 2 + } else { + total -= 3 + } + } +} +print(total) /*: Create a variable `total2` of type `Double` set to 0. Loop through the collection again, adding up all the integers and doubles. For each string that you come across during the loop, attempt to convert the string into a number, and add that value to the total. Ignore booleans. Print the total. */ +var total2: Double = 0 + +for value in dictionary.values { + if let integerItem = value as? Int { + total2 += Double(integerItem) + } else if let doubleValue = value as? Double { + total2 += doubleValue + } else if let stringValue = value as? String, let doubleValue = Double(stringValue) { + total2 += doubleValue + } +} +print(total2) //: page 1 of 2 | [Next: App Exercise - Workout Types](@next) diff --git a/Lab - Type Casting.playground/Pages/2. App Exercise - Workout Types.xcplaygroundpage/Contents.swift b/Lab - Type Casting.playground/Pages/2. App Exercise - Workout Types.xcplaygroundpage/Contents.swift index ae7131a..2b5bf04 100644 --- a/Lab - Type Casting.playground/Pages/2. App Exercise - Workout Types.xcplaygroundpage/Contents.swift +++ b/Lab - Type Casting.playground/Pages/2. App Exercise - Workout Types.xcplaygroundpage/Contents.swift @@ -46,10 +46,23 @@ var workouts: [Workout] = [ Write simple functions called `describeRun(runningWorkout:)` and `describeSwim(swimmingWorkout:)` that take a `Run` object and a `Swim` object, respectively. Neither should return values. Each function should print a description of the workout, including the run's cadence or the swim's stroke. Time is represented in seconds, distance is represented in meters, and cadence is represented in steps per minute. */ +func describeRun(runningWorkout: Run) { + print("Run of cadence \(runningWorkout.cadence), \(runningWorkout.time)s \(runningWorkout.distance)m") +} +func describeSwim(swimmingWorkout: Swim) { + print("Swim of stroke \(swimmingWorkout.stroke), \(swimmingWorkout.time)s \(swimmingWorkout.distance)m") +} /*: Now loop through each workout in `workouts` and, using type casting, call either `describeRun(runningWorkout:)` or `describeSwim(swimmingWorkout:)` on each. Observe what is printed to the console. */ +for workout in workouts { + if let run = workout as? Run { + describeRun(runningWorkout: run) + } else if let swim = workout as? Swim { + describeSwim(swimmingWorkout: swim) + } +} /*: