From 1927dac42210f7cbc5ec0411242874c68cd2b687 Mon Sep 17 00:00:00 2001 From: Milosz Staszewski Date: Fri, 6 Aug 2021 11:50:10 +0200 Subject: [PATCH] All labs completed. No questions there. --- .../Contents.swift | 58 +++++++---- .../Contents.swift | 51 ++++++---- .../Contents.swift | 48 +++++++--- .../Contents.swift | 43 ++++++--- .../contents.xcplayground | 2 +- .../Contents.swift | 48 ++++------ .../Contents.swift | 43 +++++---- .../Contents.swift | 50 +++++----- .../Contents.swift | 46 ++++----- .../contents.xcplayground | 2 +- .../Contents.swift | 8 +- .../Contents.swift | 18 ++-- .../Contents.swift | 16 ++-- .../Contents.swift | 12 +-- .../Contents.swift | 20 ++-- .../Contents.swift | 15 +-- .../Contents.swift | 16 ++-- .../Contents.swift | 30 +++--- .../Contents.swift | 33 ++++--- .../Contents.swift | 12 +-- .../Contents.swift | 26 +++-- .../contents.xcplayground | 2 +- .../Contents.swift | 72 ++++++-------- .../Contents.swift | 30 ++++-- .../Contents.swift | 22 ++++- .../Contents.swift | 27 ++++-- .../Contents.swift | 14 ++- .../Contents.swift | 13 --- .../Contents.swift | 34 +++++-- .../Contents.swift | 14 +-- .../Contents.swift | 16 ++-- .../contents.xcplayground | 4 +- .../Contents.swift | 83 ++++++++++------ .../Contents.swift | 95 +++++++++++++++---- .../contents.xcplayground | 2 +- .../Contents.swift | 31 ++++-- .../Contents.swift | 30 ++++-- .../Contents.swift | 24 +++-- .../Contents.swift | 31 +++++- .../Contents.swift | 16 +++- .../Contents.swift | 32 ++++--- .../contents.xcplayground | 2 +- .../Contents.swift | 44 ++++++--- .../Contents.swift | 40 +++++--- Lab - Guard.playground/contents.xcplayground | 2 +- .../Contents.swift | 15 ++- .../contents.xcplayground | 2 +- .../Contents.swift | 25 +++-- .../Contents.swift | 16 ++-- .../Contents.swift | 13 ++- .../Contents.swift | 21 ++-- .../Contents.swift | 23 +++-- .../Contents.swift | 17 ++-- Lab - Loops.playground/contents.xcplayground | 2 +- Lab - Operators.playground/Contents.swift | 18 ++-- .../Contents.swift | 69 +++++++------- .../Contents.swift | 33 ++++--- .../Contents.swift | 39 +++++--- .../Contents.swift | 15 +-- .../Contents.swift | 26 +++-- .../Contents.swift | 18 ++-- .../Contents.swift | 22 ++--- .../Contents.swift | 13 +-- .../contents.xcplayground | 2 +- .../Contents.swift | 56 +++++++---- .../Contents.swift | 42 ++++---- .../Contents.swift | 46 ++++++--- .../Contents.swift | 22 ++++- .../Contents.swift | 40 ++++++-- .../Contents.swift | 34 ++++--- .../contents.xcplayground | 2 +- .../Contents.swift | 46 ++++++--- .../Contents.swift | 35 ++++--- Lab - Scope.playground/contents.xcplayground | 2 +- .../Contents.swift | 25 +++-- .../Contents.swift | 30 +++--- .../Contents.swift | 20 ++-- .../Contents.swift | 43 +++++---- .../Contents.swift | 22 +++-- .../contents.xcplayground | 2 +- .../Contents.swift | 54 ++++++----- .../Contents.swift | 26 +++-- .../Contents.swift | 25 +++-- .../Contents.swift | 67 ++++++++----- .../Contents.swift | 56 +++++++---- .../Contents.swift | 27 +++++- .../Contents.swift | 28 ++++-- .../Contents.swift | 40 +++++++- .../Contents.swift | 25 ++++- .../Contents.swift | 22 ++++- .../contents.xcplayground | 2 +- .../Contents.swift | 73 ++++++++++---- .../Contents.swift | 38 +++++--- .../contents.xcplayground | 2 +- 94 files changed, 1684 insertions(+), 934 deletions(-) delete mode 100644 Lab - Control Flow.playground/Pages/6. Switch Statements.xcplaygroundpage/Contents.swift 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..9b4b189 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 @@ -1,25 +1,47 @@ /*: - ## Exercise - Define a Base Class - - - Note: The exercises below are based on a game where a spaceship avoids obstacles in space. The ship is positioned at the bottom of a coordinate system and can only move left and right while obstacles "fall" from top to bottom. Throughout the exercises, you'll create classes to represent different types of spaceships that can be used in the game. - - 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. - */ - - -/*: - Create a `let` constant called `falcon` and assign it to an instance of `Spaceship`. After initialization, set `name` to "Falcon". - */ +## Exercise - Define a Base Class + - Note: The exercises below are based on a game where a spaceship avoids obstacles in space. The ship is positioned at the bottom of a coordinate system and can only move left and right while obstacles "fall" from top to bottom. Throughout the exercises, you'll create classes to represent different types of spaceships that can be used in the game. -/*: - 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. + 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() +print(falcon.position) +falcon.moveLeft() +print(falcon.position) +falcon.moveRight() +print(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(falcon.health) /*: - 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`. +page 1 of 4 | [Next: Exercise - Create a Subclass](@next) */ - - -//: 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..a937e38 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 @@ -1,6 +1,6 @@ /*: - ## Exercise - Create a Subclass - +## Exercise - Create a Subclass + - Note: The exercises below are based on a game where a spaceship avoids obstacles in space. The ship is positioned at the bottom of a coordinate system and can only move left and right while obstacles "fall" from top to bottom. Throughout the exercises, you'll create classes to represent different types of spaceships that can be used in the game. The base class `Spaceship` has been provided for you below. */ class Spaceship { @@ -23,24 +23,37 @@ 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. - */ - - -/*: - 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. - */ - - -/*: - 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. - */ +//: 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 remainingPower = 5 + + func fire() { + if remainingPower > 0 { + remainingPower -= 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.remainingPower = 10 +destroyer.name = "Destroyer" +print(destroyer.position) +destroyer.moveRight() +print(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. +//print(falcon.weapon) +print("falcon was an instance of class Spaceship which doesn't have a weapon property. Besides that falcon is outside the scope of this file. ;)") +//: 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. +for _ in 1...13 { + print("Destroyer's fire power: \(destroyer.remainingPower)") + destroyer.fire() +} /*: - 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. +[Previous](@previous) | page 2 of 4 | [Next: Exercise - Override Methods and Properties](@next) */ - - -//: [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..a610e40 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 @@ -1,8 +1,8 @@ /*: - ## Exercise - Override Methods and Properties - +## Exercise - Override Methods and Properties + - Note: The exercises below are based on a game where a spaceship avoids obstacles in space. The ship is positioned at the bottom of a coordinate system and can only move left and right while obstacles "fall" from top to bottom. Throughout the exercises, you'll create classes to represent different types of spaceships that can be used in the game. The base class `Spaceship` and one subclass `Fighter` have been provided for you below. -*/ + */ class Spaceship { var name: String = "" var health = 100 @@ -36,19 +36,39 @@ 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`. - */ - +//: 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 -/*: - 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`. - */ + override func wasHit() { + if shieldStrength > 0 { + shieldStrength -= 5 + } else { + super.wasHit() + } + } +} +let defender = ShieldedShip() +defender.name = "Defender" +defender.weapon = "Cannon" -/*: - 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`. - */ +print(defender.position) +defender.moveRight() +print(defender.position) + +print(defender.remainingFirePower) +defender.fire() +print(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`. +print("defender's shield: \(defender.shieldStrength) and health: \(defender.health)") +for _ in 1...10 { + defender.wasHit() + print("defender's shield: \(defender.shieldStrength) and 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`. -//: [Previous](@previous) | page 3 of 4 | [Next: Exercise - Class Memberwise Initializers and References](@next) +/*: +[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..eceb05b 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 @@ -1,5 +1,5 @@ /*: - ## Exercise - Class Memberwise Initializers and References +## Exercise - Class Memberwise Initializers and References - Note: The exercises below are based on a game where a spaceship avoids obstacles in space. The ship is positioned at the bottom of a coordinate system and can only move left and right while obstacles "fall" from top to bottom. The base class `Spaceship` and subclasses `Fighter` and `ShieldedShip` have been provided for you below. You will use these to complete the exercises. */ @@ -8,6 +8,12 @@ class Spaceship { 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, remainingPower: Int) { + self.weapon = weapon + self.remainingFirePower = remainingPower + super.init(name: name, health: health, position: position) + } + func fire() { if remainingFirePower > 0 { remainingFirePower -= 1 @@ -40,6 +52,11 @@ class Fighter: Spaceship { class ShieldedShip: Fighter { var shieldStrength: Int + init(name: String, health: Int, position: Int, weapon: String, remainingPower: Int, shieldStrength: Int) { + self.shieldStrength = shieldStrength + super.init(name: name, health: health, position: position, weapon: weapon, remainingPower: remainingPower) + } + override func wasHit() { if shieldStrength > 0 { shieldStrength -= 5 @@ -49,39 +66,41 @@ class ShieldedShip: Fighter { } } /*: - Note that each class above has an error by the class declaration that says "Class has no initializers." Unlike structs, classes do not come with memberwise initializers because the standard memberwise initializers don't always play nicely with inheritance. You can get rid of the error by providing default values for everything, but it is common and better practice to simply write your own initializer. Go to the declaration of `Spaceship` and add an initializer that takes in an argument for each property on `Spaceship` and sets the properties accordingly. + Note that each class above has an error by the class declaration that says "Class has no initializers." Unlike structs, classes do not come with memberwise initializers because the standard memberwise initializers don't always play nicely with inheritance. You can get rid of the error by providing default values for everything, but it is common, and better practice, to simply write your own initializer. Go to the declaration of `Spaceship` and add an initializer that takes in an argument for each property on `Spaceship` and sets the properties accordingly. 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: 100, position: 0, weapon: "Laser", remainingPower: 10) /*: 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: 100, position: 0, weapon: "Cannon", remainingPower: 10, shieldStrength: 25) +//: 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 +print("falcon's position: \(falcon.position), sameShip's position: \(sameShip.position)") +sameShip.moveLeft() +print("falcon's position: \(falcon.position), sameShip's position: \(sameShip.position)") +print("With structs, each time we are creating separate copies (instances) of them. When it comes to classes we are just using memory pointers to the same instances in memory.") /*: - 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. - */ - - -/*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 4 of 4 */ -//: [Previous](@previous) | page 4 of 4 diff --git a/Lab - Classes.playground/contents.xcplayground b/Lab - Classes.playground/contents.xcplayground index 0989436..8c0e7a8 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..be5977f 100644 --- a/Lab - Collections.playground/Pages/1. Exercise - Arrays.xcplaygroundpage/Contents.swift +++ b/Lab - Collections.playground/Pages/1. Exercise - Arrays.xcplaygroundpage/Contents.swift @@ -1,33 +1,27 @@ /*: - ## Exercise - Arrays +## Exercise - Arrays 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. */ - - -/*: - 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. - */ - - -/*: - 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. - */ - - +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 += ["Daga", "Jola", "Krzysztof", "Adrian"] +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) + +//: Somebody had a conflict and decided to transfer 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(registrationList) +print(deletedItem) /*: - Use the `insert(_:at:)` method to add `Charlie` into the array as the second element. Print the contents of the collection. +page 1 of 4 | [Next: App Exercise - Activity Challenge](@next) */ - - -/*: - 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. - */ - - -/*: - 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`. - */ - - -//: 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..d55c595 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Activity Challenge +## App Exercise - Activity Challenge >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,26 +7,27 @@ 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. */ - - -/*: - 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. - */ - +let walkingChallenges = ["Walk 3 miles a day", "Walk 5 miles a day", "Walk every day of the week"] +let runningChallenges = ["Run 5 times a week", "Run at least 5 kms a day", "Run 10 kms 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`. +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 committedChallneges = ["Excercising every day", "Riding a bike every day", "Dancing every day"] + +//: 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 committedChallneges.isEmpty { + print("Please (for your own good! 😉 commit to a challenge!") +} else if committedChallneges.count == 1 { + print("The challenge you have chosen is \(committedChallneges[0])") +} else { + print("You have chosen multiple challenges.") +} /*: - All of the challenges will reset at the end of the month. Use the `removeAll` to remove everything from `challenges`. Print `challenges`. +[Previous](@previous) | page 2 of 4 | [Next: Exercise - Dictionaries](@next) */ - - -/*: - 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. - */ - - -/*: - 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." - */ - - -//: [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..cb9cb05 100644 --- a/Lab - Collections.playground/Pages/3. Exercise - Dictionaries.xcplaygroundpage/Contents.swift +++ b/Lab - Collections.playground/Pages/3. Exercise - Dictionaries.xcplaygroundpage/Contents.swift @@ -1,35 +1,35 @@ /*: - ## Exercise - Dictionaries +## Exercise - Dictionaries 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. */ - - -/*: - Using subscripting syntax to add April to the collection with a value of 30. Print the dictionary. - */ - - -/*: - It's a leap year! Update the number of days in February to 29 using the `updateValue(_:, forKey:)` method. Print the dictionary. - */ - - -/*: - 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. - */ - - -/*: - 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. - */ +var daysPerMonth = ["January": 31, "February": 28, "March": 31] +print(daysPerMonth) +//: Using subscripting syntax to add April to the collection with a value of 30. Print the dictionary. +daysPerMonth["April"] = 30 +print(daysPerMonth) +//: It's a leap year! Update the number of days in February to 29 using the `updateValue(_:, forKey:)` method. Print the dictionary. +daysPerMonth.updateValue(29, forKey: "February") +print(daysPerMonth) +//: 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 numberOfDays = daysPerMonth["January"] { + print("January has \(numberOfDays) 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. +//These were missing. Copied them from my own archives and previous course version. let shapesArray = ["Circle", "Square", "Triangle"] let colorsArray = ["Red", "Green", "Blue"] +let myDictionary = ["Shapes": shapesArray, "Colors": colorsArray] +print(myDictionary) +//: 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 colorsArray = myDictionary["Colors"] { + if let lastColor = colorsArray.last { + print(lastColor) + } +} /*: - 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. +[Previous](@previous) | page 3 of 4 | [Next: App Exercise - Pacing](@next) */ - - -//: [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..8dc289d 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Pacing +## App Exercise - Pacing >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,36 +7,32 @@ 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. */ - - -/*: - Add a new key/value pair to the dictionary. The key should be "Sprint" and the value should be 4.0. Print the dictionary. - */ - - -/*: - 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. - */ - +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." +let chosenOption = "Medium" +if let myPace = paces[chosenOption] { + print("Okay! I'll keep you at a \(myPace) minute mile 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. - */ - - -/*: - 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." - */ - - -/*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 4 of 4 */ -//: [Previous](@previous) | page 4 of 4 diff --git a/Lab - Collections.playground/contents.xcplayground b/Lab - Collections.playground/contents.xcplayground index 607c8cd..3d61d81 100644 --- a/Lab - Collections.playground/contents.xcplayground +++ b/Lab - Collections.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + diff --git a/Lab - Constants and Variables.playground/Contents.swift b/Lab - Constants and Variables.playground/Contents.swift index d86a552..76061fc 100644 --- a/Lab - Constants and Variables.playground/Contents.swift +++ b/Lab - Constants and Variables.playground/Contents.swift @@ -30,21 +30,21 @@ /*: - Create a double variable with a value of 1.1. Update it to 2.2, 3.3, and 4.4. Print out the value after each assignment (again by referencing the variable you created). + Create a double variable with a value of 1.1. Update it to 2.2, 3.3, and 4.4, printing out the value after each assignment (again by referencing the variable you created). */ /*: - Create a Boolean variable and set it to `true`. Print the variable, then assign it a value of `false`, and print it again. + Create a boolean variable and set it to `true`. Print the variable, then assign it a value of `false`, and print it again. */ /*: - Create two variables: one with a value of 0, the other with a value of 0.0. Try to assign the second variable to the first, and you'll receive an error. Add the necessary type annotation to allow the second variable to be assigned to the first. + Create two variables, one with a value of 0, the other with a value of 0.0. Try to assign the second variable to the first, and you will receive an error. Add the necessary type annotation that will allow the second variable to be assigned to the first. */ /*: - Create a variable integer with a value of 1,000,000,000. Format it using commas, so it's easier to read. + Create a variable integer with a value of 1,000,000,000, ensuring that you format it so it is more readable (i.e. it's hard to read 1000000000, so make it easier to read). */ 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..9509405 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 @@ -1,18 +1,16 @@ /*: - ## Exercise - Constants +## Exercise - Constants 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 = 50 +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. +//friends -= 10 +//: 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 modify constant. Well... It's the reason why we call it coinstants 😉") /*: - 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. +page 1 of 10 | [Next: App Exercise - Step Goal](@next) */ - - -/*: - 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. - */ - - -//: 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..982a849 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 @@ -1,25 +1,23 @@ /*: - ## App Exercise - Percent Completed +## App Exercise - Percent Completed >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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 /*: - 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. - */ - - -/*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 10 of 10 */ -//: [Previous](@previous) | page 10 of 10 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..d59cb85 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 @@ -1,15 +1,15 @@ /*: - ## App Exercise - Step Goal +## App Exercise - Step Goal >These exercises reinforce Swift concepts in the context of a fitness tracking app. Your fitness tracking app needs to know goal number of steps per day. Create a constant `goalSteps` and set it to 10000. */ +let goalSteps = 10_000 - +//: 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) /*: - 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. +[Previous](@previous) | page 2 of 10 | [Next: Exercise - Variables](@next) */ - - -//: [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..0b2d955 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 @@ -1,18 +1,16 @@ /*: - ## Exercise - Variables +## Exercise - Variables 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 = 19 +print("I have completed \(schooling) years of school.") +//: 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 difference between variables and constants comes down to the fact one can change the former during runtime and can't the latter.") /*: - Now imagine you just completed an additional year of school, and update the `schooling` variable accordingly. Print `schooling` to the console. +[Previous](@previous) | page 3 of 10 | [Next: App Exercise - Step Count](@next) */ - - -/*: - 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. - */ - - -//: [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..6b175ef 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 @@ -1,15 +1,16 @@ /*: - ## App Exercise - Step Count +## App Exercise - Step Count >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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.") /*: - 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." +[Previous](@previous) | page 4 of 10 | [Next: Exercise - Constant or Variable?](@next) */ - - -//: [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..67b1cb8 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 @@ -1,5 +1,5 @@ /*: - ## Exercise - Constant or Variable? +## Exercise - Constant or Variable? Imagine you're creating a simple photo sharing app. You want to keep track of the following metrics for each post: - Number of likes: the number of likes that a photo has received @@ -10,9 +10,11 @@ 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. */ - - - - - -//: [Previous](@previous) | page 5 of 10 | [Next: App Exercise - Fitness Tracker: Constant or Variable?](@next) +var numberOfLikes = 7 +var numberOfComments = 2 +let yearCreated = 2011 //It probably won't change during the lifetime of a single code execution +let monthCreated = 6 +let dayCreated = 11 +/*: +[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..43c6f03 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 @@ -1,22 +1,28 @@ /*: - ## App Exercise - Fitness Tracker: Constant or Variable? +## App Exercise - Fitness Tracker: Constant or Variable? >These exercises reinforce Swift concepts in the context of a fitness tracking app. There are all sorts of things that a fitness tracking app needs to keep track of in order to display the right information to the user. Similar to the last exercise, declare either a constant or a variable for each of the following items, and assign each a sensible value. Be sure to use proper naming conventions. - - Name: The user's name - - Age: The user's age - - Number of steps taken today: The number of steps that a user has taken today - - 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 +- Name: The user's name +- Age: The user's age +- Number of steps taken today: The number of steps that a user has taken today +- 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 = "Henryk" +print("It probably won't change during the lifetime of aingle code execution.") +let age = 17 +print("It probably won't change during the lifetime of aingle code execution.") +var stepsTakenToday = 800 +print("This will definitely be changing during our code execution.") +let stepsGoal = 1000 +print("It probably won't change during the lifetime of aingle code execution.") +var avgHeartRate = 80 +print("This will definitely be changing during our code execution.") /*: 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. + +[Previous](@previous) | page 6 of 10 | [Next: Exercise - Types and Type Safety](@next) */ -//: [Previous](@previous) | page 6 of 10 | [Next: Exercise - Types and Type Safety](@next) 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..6834379 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 @@ -1,23 +1,22 @@ /*: - ## Exercise - Types and Type Safety +## Exercise - Types and Type Safety 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: Double +var secondDecimal: Double +//: 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 trueOrFale = true +//firstDecimal = trueOrFale +print("Swift provides type safety meaning that it checks for proper data type storage in each of variables. It allows developer to omit errors and the compiler to provide proper optimizations.") +//: 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 testString = "This is our demonstartional string." +//firstDecimal = testString +print("Similarly to the situation above, type safety provided by Swift won't allow for this type of assignment.") +//: 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. +var wholeNumber = 7 +//firstDecimal = wholeNumber +print("The compiler will notice that there is a type mismatch – even tough it whould be possible to store integer inside a value opf type Double, the language will enforce type safety attitude.") /*: - 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. +[Previous](@previous) | page 7 of 10 | [Next: App Exercise - Tracking Different Types](@next) */ - - -/*: - 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. - */ - - -/*: - 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. - */ - - -//: [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..8db3e2a 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 @@ -1,15 +1,15 @@ /*: - ## App Exercise - Tracking Different Types +## App Exercise - Tracking Different Types >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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: Bool - +//: 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. +var stepsTakenToday = 8_000 +let stepsGoal = 1_000_000 /*: - 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. +[Previous](@previous) | page 8 of 10 | [Next: Exercise - Type Inference and Required Values](@next) */ - - -//: [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..9ed98f3 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 @@ -1,23 +1,19 @@ /*: - ## Exercise - Type Inference and Required Values +## Exercise - Type Inference and Required Values 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 +//print(name) +//: Now assign a value to `name`, and print it to the console. +name = "Stefan" +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 /*: - Now assign a value to `name`, and print it to the console. +[Previous](@previous) | page 9 of 10 | [Next: App Exercise - Percent Completed](@next) */ - - -/*: - Declare a variable called `distanceTraveled` and set it to 0. Do not give it an explicit type. - */ - - -/*: - 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. - */ - - -//: [Previous](@previous) | page 9 of 10 | [Next: App Exercise - Percent Completed](@next) diff --git a/Lab - Constants and Variables.playground/contents.xcplayground b/Lab - Constants and Variables.playground/contents.xcplayground index e869a18..7d81894 100644 --- a/Lab - Constants and Variables.playground/contents.xcplayground +++ b/Lab - Constants and Variables.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..ec2ced9 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 @@ -1,5 +1,5 @@ /*: - ## Exercise - Logical Operators +## Exercise - Logical Operators For each of the logical expressions below, print out what you think the resulting value will be (`true` or `false`). Then print out the actual expression to see if you were right. An example has been provided below. @@ -10,46 +10,32 @@ 1. `9 == 9` */ - - -/*: - 2. `9 != 9` - */ - - -/*: - 3. `47 > 90` - */ - - -/*: - 4. `47 < 90` - */ - - -/*: - 5. `4 <= 4` - */ - - -/*: - 6. `4 >= 5` - */ - - -/*: - 7. `(47 > 90) && (47 < 90)` - */ - - -/*: - 8. `(47 > 90) || (47 < 90)` - */ - - -/*: - 9. `!true` +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(false) +print((47 > 90) || (47 < 90)) +//: 9. `!true` +print(false) +print(!true) +/*: +page 1 of 9 | [Next: Exercise - If and If-Else Statements](@next) */ - - -//: 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..ab9a714 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 @@ -1,21 +1,31 @@ /*: - ## Exercise - If and If-Else Statements +## Exercise - If and If-Else Statements Imagine you're creating a machine that will count your money for you and tell you how wealthy you are based on how much money you have. A variable `dollars` has been given to you with a value of 0. Write an if statement that prints "Sorry, kid. You're broke!" if `dollars` has a value of 0. Observe what is printed to the console. */ var dollars = 0 - -/*: - `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. - */ +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!") +} /*: - `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. +[Previous](@previous) | page 2 of 9 | [Next: App Exercise - Fitness Decisions](@next) */ -dollars = 105 - - -//: [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..9b0f45c 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 @@ -1,15 +1,27 @@ /*: - ## App Exercise - Fitness Decisions +## App Exercise - Fitness Decisions >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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`. */ +let steps = 7_777 +let stepGoal = 10_000 +if steps < (stepGoal / 2) { + print("You're almost halfway there!") +} else if steps > (stepGoal / 2) { + 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 if steps > (stepGoal / 2) { + 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`. +[Previous](@previous) | page 3 of 9 | [Next: Exercise - Boolean Practice](@next) */ - - -//: [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..33fe47f 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 @@ -1,25 +1,32 @@ /*: - ## Exercise - Boolean Practice +## Exercise - Boolean Practice Imagine you're going to dinner with friends and are struggling to decide where to go. Two of you have very strong opinions and have clearly laid out your requirements for dinner as follows: - - You want to eat somewhere that has either fish or pizza - - Your friend wants to eat somewhere with vegan options. +- You want to eat somewhere that has either fish or pizza +- Your friend wants to eat somewhere with vegan options. Another friend brings up a restaurant she thinks will fit both of your criteria. This restaurant's attributes are represented by a few constants below. Write an if-else statement that will print "Let's go!" if the restaurant's attributes match the group's dietary requirements, and otherwise will print "Sorry, we'll have to think of somewhere else." */ - + let hasFish = true let hasPizza = false let hasVegan = true - -/*: - 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. - */ +if (hasFish || hasPizza) && hasVegan { + print("Let's go!") +} else { + print("Sorry, we'll have to think of something 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. let temp = 82 let isRaining = true let isSunny = true +let isNiceWeather = !isRaining || (temp >= 82 && isSunny) - -//: [Previous](@previous) | page 4 of 9 | [Next: App Exercise - Target Heart Rate](@next) +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..85417e7 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Target Heart Rate +## App Exercise - Target Heart Rate >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -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 -//: [Previous](@previous) | page 5 of 9 | [Next: Exercise - Switch Statements](@next) +if isInTarget { + print("You're right on track!") +} else if isBelowTarget { + print("You're doing great, but try to push it 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 deleted file mode 100644 index ed3e397..0000000 --- a/Lab - Control Flow.playground/Pages/6. Switch Statements.xcplaygroundpage/Contents.swift +++ /dev/null @@ -1,13 +0,0 @@ -/*: - ## Exercise - Switch Statements - - 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. - */ - - -/*: - Write a new `switch` statement that prints "Medal winner" if `leaguePosition` is within the range of 1-3. Otherwise, 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..980518d 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Heart Rate Zones +## App Exercise - Heart Rate Zones >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,15 +7,31 @@ Write a switch statement that will print different statements based on what range `currentHR` falls into. Below is a list of ranges and the associated statements - - 100-120: "You are in the Very Light zone. Activity in this zone helps with recovery." - - 121-140: "You are in the Light zone. Activity in this zone helps improve basice endurance and fat burning." - - 141-160: "You are in the Moderate zone. Activity in this zone helps improve aerobic fitness." - - 161-180: "You are in the Hard zone. Activity in this zone increases maximum performance capacity for shorter sessions." - - 181-200: "You are in the Maximum zone. Activity in this zone helps fit athletes develop speed." +- 100-120: "You are in the Very Light zone. Activity in this zone helps with recovery." +- 121-140: "You are in the Light zone. Activity in this zone helps improve basice endurance and fat burning." +- 141-160: "You are in the Moderate zone. Activity in this zone helps improve aerobic fitness." +- 161-180: "You are in the Hard zone. Activity in this zone increases maximum performance capacity for shorter sessions." +- 181-200: "You are in the Maximum zone. Activity in this zone helps fit athletes develop speed." If `currentHR` is above the listed zones, print some kind of warning asking the user to slow down. */ let currentHR = 128 - - -//: [Previous](@previous) | page 7 of 9 | [Next: Exercise - Ternary Operator](@next) +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 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("Mate, SLOW DOWN _NOW_ or you may hurt yourself!") +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..06a02c6 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 @@ -1,16 +1,18 @@ /*: - ## Exercise - Ternary Operator +## Exercise - Ternary Operator Refactor the code below so that `largest` is declared and assigned to in one line using the ternary operator. */ let number1 = 14 let number2 = 25 -var largest: Int -if number1 > number2 { +var largest: Int = number1 > number2 ? number1 : number2 + +/*if number1 > number2 { largest = number1 } else { largest = number2 -} - -//: [Previous](@previous) | page 8 of 9 | [Next: App Exercise - Ternary Messages](@next) +} */ +/*: +[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..5ea97b7 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Ternary Messages +## App Exercise - Ternary Messages >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -8,21 +8,21 @@ let stepGoal = 10000 let steps = 3948 -if steps < stepGoal / 2 { +steps > (stepGoal / 2) ? print("Almost halfway!") : print("Over halfway!") + +/* if steps < stepGoal / 2 { print("Almost halfway!") } else { print("Over halfway!") -} - - +} */ /*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 9 of 9 */ -//: [Previous](@previous) | page 9 of 9 diff --git a/Lab - Control Flow.playground/contents.xcplayground b/Lab - Control Flow.playground/contents.xcplayground index 4996c93..ca593d3 100644 --- a/Lab - Control Flow.playground/contents.xcplayground +++ b/Lab - Control Flow.playground/contents.xcplayground @@ -1,12 +1,12 @@ - + - + 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..f1b6419 100644 --- a/Lab - Enumerations.playground/Pages/1. Exercise - Enumerations.xcplaygroundpage/Contents.swift +++ b/Lab - Enumerations.playground/Pages/1. Exercise - Enumerations.xcplaygroundpage/Contents.swift @@ -1,33 +1,62 @@ /*: - ## Exercise - Enumerations +## Exercise - Enumerations Define a `Suit` enum with four possible cases: `clubs`, `spades`, `diamonds`, and `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. - */ - - -/*: - 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. - */ - - +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 may need to wait a bit longer for your destiny.") + case .diamonds: + print("A real treasure is about to be finally found!\nFingers crossed!") + case .hearts: + print("Don't be afraid to welcome someone new.") + } +} + +getFortune(cardSuit: .clubs) +getFortune(cardSuit: .spades) +getFortune(cardSuit: .diamonds) +getFortune(cardSuit: .hearts) +//: 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 { + let suit: Suit + let value: Int +} */ + +//: 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. +struct Card { + enum Value { + case ace + case two, three, four, five, six, seven, eight, nine, ten + case jack, queen, king + } + + let suit: Suit + let value: Value +} + +let firstCard = Card(suit: .hearts, value: .seven) +let secondCard = Card(suit: .spades, value: .ace) +print("The first card is: \(firstCard.value) of \(firstCard.suit)") +print("The second card is: \(secondCard.value) of \(secondCard.suit)") /*: - 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. +page 1 of 2 | [Next: App Exercise - Swimming Workouts](@next) */ - - -/*: - Create a `Card` struct below. It should have two properties, one for `suit` of type `Suit` and another for `value` of type `Int`. - */ - - -/*: - 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. - */ - - -//: 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..17ad7e7 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 @@ -1,35 +1,94 @@ /*: - ## App Exercise - Swimming Workouts +## App Exercise - Swimming Workouts >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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 { + let distance: Double + let time: Double + let stroke: String +} */ +//: 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. +/* struct SwimmingWorkout { + enum Stroke { + case freestyle + case butterfly + case backstroke + case breakstroke + } + + let distance: Double + let time: Double + let stroke: Stroke +} */ +let firstSwimmingWorkout = SwimmingWorkout(distance: 77, time: 600, stroke: .freestyle) +let secondSwimmingWorkout = SwimmingWorkout(distance: 78, time: 580, stroke: .butterfly) +//: 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. +//struct SwimmingWorkout { +// enum Stroke { +// case freestyle +// case butterfly +// case backstroke +// case breakstroke +// } +// +// let distance: Double +// let time: Double +// let stroke: Stroke +// +// static var freestyleWorkouts: [SwimmingWorkout] = [] +// static var butterflyWorkouts: [SwimmingWorkout] = [] +// static var backstrokeWorkouts: [SwimmingWorkout] = [] +// static var breakstrokeWorkouts: [SwimmingWorkout] = [] +//} -/*: - 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. - */ - - -/*: - 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. - */ - - -/*: - 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. - */ - +//: 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. +struct SwimmingWorkout { + enum Stroke { + case freestyle + case butterfly + case backstroke + case breakstroke + } + + let distance: Double + let time: Double + let stroke: Stroke + + static var freestyleWorkouts: [SwimmingWorkout] = [] + static var butterflyWorkouts: [SwimmingWorkout] = [] + static var backstrokeWorkouts: [SwimmingWorkout] = [] + static var breakstrokeWorkouts: [SwimmingWorkout] = [] + + func save() { + switch stroke { + case .freestyle: + SwimmingWorkout.freestyleWorkouts.append(self) + case .butterfly: + SwimmingWorkout.butterflyWorkouts.append(self) + case .backstroke: + SwimmingWorkout.butterflyWorkouts.append(self) + case .breakstroke: + SwimmingWorkout.butterflyWorkouts.append(self) + } + } +} +firstSwimmingWorkout.save() +secondSwimmingWorkout.save() +print(SwimmingWorkout.freestyleWorkouts) +print(SwimmingWorkout.butterflyWorkouts) /*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 2 of 2 */ -//: [Previous](@previous) | page 2 of 2 diff --git a/Lab - Enumerations.playground/contents.xcplayground b/Lab - Enumerations.playground/contents.xcplayground index c5c3cd8..45919b4 100644 --- a/Lab - Enumerations.playground/contents.xcplayground +++ b/Lab - Enumerations.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..7e3d507 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 @@ -1,13 +1,32 @@ /*: - ## Exercise - Create Functions - +## Exercise - Create Functions + 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 Miłosz Staszewski and I'm an avid Mac user.") +} +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. +import Foundation +let randomNum = Int.random(in: 0...4) +switch randomNum { +case 0: + print("Tough luck!") +case 1: + print("Keep up the good work!") +case 2: + print("Hold strong there!") +case 3: + print("Incoming!") +case 4: + print("Make no mistake: moving is living.") +default: + break +} /*: - 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. +page 1 of 6 | [Next: App Exercise - A Functioning App](@next) */ - - -//: 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..0e3b670 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - A Functioning App +## App Exercise - A Functioning App >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -8,12 +8,30 @@ A reoccurring process like this is a perfect candidate for a function. Write a function called `incrementSteps` after the declaration of `steps` below that will increment `steps` by one and then print its value. Call the function multiple times and observe the printouts. */ var steps = 0 +func incrementSteps() { + steps += 1 + print(steps) +} +for _ in 1...7 { + 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. +let goal = 10000 +func progressUpdate () { + if (steps < Int(Double(goal) * 0.1)) { + print("You're off to a good start.") + } else if (steps < Int(Double(goal) * 0.5)) { + print("You're almost halfway there!") + } else if (steps < Int(Double(goal) * 0.9)) { + print("You're over halfway there!") + } else { + print("You beat your goal!") + } +} + +progressUpdate() /*: - 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. +[Previous](@previous) | page 2 of 6 | [Next: Exercise - Parameters and Argument Labels](@next) */ -let goal = 10000 - - -//: [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..ee6ee47 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 @@ -1,18 +1,26 @@ /*: - ## Exercise - Parameters and Argument Labels +## Exercise - Parameters and Argument Labels 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(_ firstArg: Int, secondArg: Int) { + print(firstArg + secondArg - 2) +} -/*: - 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. - */ +almostAddition(4, secondArg: 5) +//: 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(_ firstArg: Double, by secondArg: Double) { + print(firstArg * secondArg) +} +multiply(7, by: 8) /*: - 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. +[Previous](@previous) | page 3 of 6 | [Next: App Exercise - Progress Updates](@next) */ - - -//: [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..e10567d 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Progress Updates +## App Exercise - Progress Updates >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -9,11 +9,32 @@ 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 < Int(Double(goal) * 0.5)) { + print("You're almost halfway there!") + } else if (steps < Int(Double(goal) * 0.9)) { + print("You're over halfway there!") + } else { + print("You beat your goal!") + } +} +progressUpdate(steps: 101, goal: 1000) +progressUpdate(steps: 100, goal: 1000) +progressUpdate(steps: 99, goal: 1000) +progressUpdate(steps: 999, goal: 1000) +progressUpdate(steps: 500, goal: 1000) +//: 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 / currentTime >= totalDistance / goalTime) { + print("Keep it up!") + } else { + print("You've got to push it just a bit harder!") + } +} /*: - 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!" +[Previous](@previous) | page 4 of 6 | [Next: Exercise - Return Values](@next) */ - - -//: [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..6bedd6f 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 @@ -1,13 +1,19 @@ /*: - ## Exercise - Return Values +## Exercise - Return Values 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 almostMultiplication(_ firstArg: Int, _ secondArg: Int) -> Int { + return (firstArg * secondArg + 2) +} +print(almostMultiplication(2, 3)) /*: - 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. +[Previous](@previous) | page 5 of 6 | [Next: App Exercise - Separating Functions](@next) */ - - -//: [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..7e219fa 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Separating Functions +## App Exercise - Separating Functions >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,21 +7,31 @@ 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 estTime = calculatePace(currentDistance: 350, totalDistance: 1000, currentTime: 120) +//: 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 estTime = calculatePace(currentDistance: currentDistance, totalDistance: totalDistance, currentTime: currentTime) + if estTime <= goalTime { + return "Keep it up!" + } else { + return "You've got to push it just a bit harder!" + } +} + +print(pacing(currentDistance: 350, totalDistance: 1000, currentTime: 120, goalTime: 350)) +print(pacing(currentDistance: 350, totalDistance: 1000, currentTime: 120, goalTime: 340)) /*: - 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. - */ - - -/*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 6 of 6 */ -//: [Previous](@previous) | page 6 of 6 diff --git a/Lab - Functions.playground/contents.xcplayground b/Lab - Functions.playground/contents.xcplayground index 788a8fc..0b5fc77 100644 --- a/Lab - Functions.playground/contents.xcplayground +++ b/Lab - Functions.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..b7498f8 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 @@ -1,19 +1,25 @@ import UIKit /*: - ## Exercise - Guard Statements +## Exercise - Guard Statements 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. -*/ - - -/*: - 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 calculateArea (x: Double, y: Double) -> Double? { + guard x > 0 && y > 0 else { return nil } + return x * y +} +calculateArea(x: 7, y: 7) +calculateArea(x: -4, y: 6) +//: 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(x: Int?, y: Int?) -> Int? { + guard let xValue = x, let yValue = y else { return nil } + return xValue + yValue +} +add(x: 5, y: 2) +add(x: nil, y: 8) /*: - 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?`. - + 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?`. + Write a function below the given code called `createUser` that takes no parameters and returns an optional `User` object. Write a guard statement at the beginning of the function that unwraps the values of each text field's `text` property, and returns `nil` if not all values are successfully unwrapped. After the guard statement, use the unwrapped values to create and return and instance of `User`. */ struct User { @@ -30,10 +36,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. +if let testUser = createUser() { + print(""" + First name: \(testUser.firstName) + Last name: \(testUser.lastName) + Age: \(testUser.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. +page 1 of 2 | [Next: App Exercise - Guard](@next) */ - - -//: 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..67f90df 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 @@ -1,6 +1,6 @@ import UIKit /*: - ## App Exercise - Guard +## App Exercise - Guard >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -10,8 +10,16 @@ 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,22 +34,32 @@ let foodTextField = UITextField() let caloriesTextField = UITextField() foodTextField.text = "Banana" -caloriesTextField.text = "23" +caloriesTextField.text = "23d" +func logFood() -> Food? { + guard let foodText = foodTextField.text, let caloriesText = caloriesTextField.text, let caloriesAmount = Int(caloriesText) else { return nil } + return Food(name: foodText, calories: caloriesAmount) +} +//: 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? +if let myFood = logFood() { + print(""" + Name: \(myFood.name) + Calories: \(myFood.calories) + """) +} else { + print("An error accessing log food occured.") +} -/*: - 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? - */ - +/* If the text representing number of calories cannot be converted into an Int, the guard statement of the logFood() function returns nil and therefore prevents the Food instance creation. */ /*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 2 of 2 */ -//: [Previous](@previous) | page 2 of 2 diff --git a/Lab - Guard.playground/contents.xcplayground b/Lab - Guard.playground/contents.xcplayground index 5771366..3be2195 100644 --- a/Lab - Guard.playground/contents.xcplayground +++ b/Lab - Guard.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..16383e9 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,17 +10,24 @@ 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("The Waterboys - \"Good News\"") +print("Leon Bridges - \"Smooth Sailin'\"") /*: Use multiple `print` functions to write out some of the lyrics to the song. */ - +print("We can fight our desires, ooh") +print("But when we start making fires") +print("We get ever so hot, ooh") +print("Whether we like it or not") +print("They say we can love who we trust, ooh") +print("But what is love without lust?") +print("Two hearts with accurate devotions, ooh") +print("What are feelings without emotions?") /*: - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ diff --git a/Lab - Introduction.playground/contents.xcplayground b/Lab - Introduction.playground/contents.xcplayground index 5ed2911..55cd9e3 100644 --- a/Lab - Introduction.playground/contents.xcplayground +++ b/Lab - Introduction.playground/contents.xcplayground @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file 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..b8c6e7f 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 @@ -1,19 +1,24 @@ /*: - ## Exercise - For-In Loops +## Exercise - For-In Loops 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" -/*: - 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, character) in alphabet.enumerated() { + print("\(index): \(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, then use a for-in loop to iterate over the pairs and print out the keys and values in a sentence. +var countriesAndCapitals = ["Poland": "Warsaw", "United Kingdom": "London", "United States": "Washington", "Canada": "Ottawa", "Germany": "Berlin", "Spain": "Madrid", "France": "Paris"] +for (country, capital) in countriesAndCapitals { + print("The capital city of \(country) is: \(capital).") +} /*: - 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. +page 1 of 6 | [Next: App Exercise - Movements](@next) */ - - -//: 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..8a331b0 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Movements +## App Exercise - Movements >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,11 +7,15 @@ */ let movements: [String] = ["Walking", "Running", "Swimming", "Cycling", "Skiing", "Climbing"] +for movement in movements { + print("This app can track \(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("When \(movement) your heart rate was: \(heartRate)") +} /*: - 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. +[Previous](@previous) | page 2 of 6 | [Next: Exercise - While Loops](@next) */ -var movementHeartRates: [String: Int] = ["Walking": 85, "Running": 120, "Swimming": 130, "Cycling": 128, "Skiing": 114, "Climbing": 129] - - -//: [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..280b7b1 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 @@ -1,9 +1,14 @@ import Foundation /*: - ## Exercise - While Loops +## Exercise - While Loops 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). */ - - -//: [Previous](@previous) | page 3 of 6 | [Next: App Exercise - While Loops](@next) +var theDice = 0 +while theDice != 1 { + theDice = Int.random(in: 1...6) + print("In this roll the value on the dice says: \(theDice)") +} +/*: +[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..ef72025 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 @@ -1,6 +1,6 @@ import Foundation /*: - ## App Exercise - While Loops +## App Exercise - While Loops >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -11,11 +11,20 @@ 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 +testSteps = 0 +repeat { + print("Take a step") + Thread.sleep(forTimeInterval: 60/cadence) + testSteps += 1 +} while testSteps < 10 /*: - Recreate the above cadence example using a repeat-while loop. +[Previous](@previous) | page 4 of 6 | [Next: Exercise - Control Transfer Statements](@next) */ -testSteps = 0 - - -//: [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..9e9b7d4 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 @@ -1,14 +1,25 @@ /*: - ## Exercise - Control Transfer Statements +## Exercise - Control Transfer Statements Create a for-in loop that will loop through `alphabet`. Inside the loop, print every other letter by continuing to the next iteration if you are on a letter you do not wish to print. (Hint: You can use the `isMultiple(of:)` method on `Int` to only print even indexed characters). */ let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - +for (index, letter) in alphabet.enumerated() { + if index % 2 == 1 { + continue + } + print("\(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, 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. +var countriesAndCapitals = ["Poland": "Warsaw", "United Kingdom": "London", "United States": "Washington", "Canada": "Ottawa", "Germany": "Berlin", "Spain": "Madrid", "France": "Paris"] +for (country, capital) in countriesAndCapitals { + print("I'm in \(capital), the capital of \(country).") + if (country == "Poland") { + print("I found my home!") + break + } +} /*: - 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. +[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..6ea18d5 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Finding Movements +## App Exercise - Finding Movements >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,20 +7,25 @@ You decide you want your app's users to be able to put in a heart rate range they would like to hit, and then you want the app to suggest movements where historically the user has reached that heart rate range. The dictionary `movementHeartRates` below contains keys corresponding to the movements that the app has tracked, and values corresponding to the average heart rate of the user that your fitness tracker has monitored historically during the given movement. Loop through `movementHeartRates` below and if the heart rate doesn't fall between `lowHR` and `highHR`, continue to the next movement and heart rate. Otherwise, print "You could go ". -*/ + */ let lowHR = 110 let highHR = 125 var movementHeartRates: [String: Int] = ["Walking": 85, "Running": 120, "Swimming": 130, "Cycling": 128, "Skiing": 114, "Climbing": 129] - +for (movement, avgHR) in movementHeartRates { + if !(lowHR < avgHR && avgHR < highHR) { + continue + } + print("You could go \(movement)") +} /*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 6 of 6 */ -//: [Previous](@previous) | page 6 of 6 diff --git a/Lab - Loops.playground/contents.xcplayground b/Lab - Loops.playground/contents.xcplayground index c5bdbb1..d14783f 100644 --- a/Lab - Loops.playground/contents.xcplayground +++ b/Lab - Loops.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + diff --git a/Lab - Operators.playground/Contents.swift b/Lab - Operators.playground/Contents.swift index 73f34bf..749929c 100644 --- a/Lab - Operators.playground/Contents.swift +++ b/Lab - Operators.playground/Contents.swift @@ -1,7 +1,7 @@ /*: **Lab - Operators** - Create two constants, `width` and `height`, with values of 100 and 250, respectively. Create an `area` constant that's the result of multiplying the `width` and `height` constants together. Print out the result. + Create two constants, `width` and `height`, with values of 100 and 250, respectively. Create an `area` constant that is the result of multiplying the two previous constants together, and print out the result. */ // Basic arithmetic // Compound assignment @@ -9,12 +9,12 @@ // Modulo // Numeric Type Conversion /*: - Create a `perimeter` constant whose value equals `width` plus `width` plus `height` plus `height`. Print out the result. + Create a `perimeter` constant whose value equals `width` plus `width` plus `height` plus `height`, then print out the result. */ /*: - Print out what you think 10 + 2 * 5 evaluates to. Then print out the actual expression (i.e., `print(10 + 2 * 5)`) + Print out what you think 10 + 2 * 5 evaluates to. Then print out the actual expression (i.e. `print(10 + 2 * 5)`) */ @@ -24,17 +24,17 @@ /*: - Create a constant, `divisionResult`, that's the result of 10 divided by 3. Print the constant's value. + Create a constant, `divisionResult` that is the result of 10 divided by 3, and print the value. */ /*: - Create a constant, `moreAccurateResult`, that's also the result of 10 divided by 3, but includes the repeating decimal. Print this value. + Create a constant, `moreAccurateResult`, that is also the result of 10 divided by 3, but includes the repeating decimal. Print this value. */ /*: - Given the value pi (3.1415927), create a `radius` constant with a value of 5.0. Use the following equations to calculate the diameter and circumference of a circle, and print the results: + 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: *diameter = 2 * radius* @@ -43,16 +43,16 @@ /*: - Declare a variable whose value begins at 10. Using addition and the compound assignment operator, update the value to 15. Using multiplication and compound assignment, update the value to 30. Print out the variable's value after each assignment. + 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. */ /*: - Create an integer constant with a value of 10, and a double constant with a value of 3.2. Cast the `Double` to an `Int`, then multiply it by the integer constant. Print out the resulting value. + Create an integer constant with a value of 10, and a double constant with a value of 3.2. Cast the `Double` to an `Int`, then multiply it by the integer constant and print out the value. */ /*: - Create an integer constant. Using the modulus operator, set its value to the remainder of 12 divided by 5. + Create an integer constant. It's value should be equal to the remainder of 12 divided by 5. Do this using the modulus operator. */ 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..d9b3925 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 @@ -1,30 +1,28 @@ /*: - ## Exercise - Basic Arithmetic +## Exercise - Basic Arithmetic 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. */ - - -/*: - 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. - */ - - -/*: - Create a `perimeter` constant whose value equals `width` plus `width` plus `height` plus `height`, then print out the result. - */ - - -/*: - 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. - */ - - -/*: - 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 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 +print(roomArea) +//: 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("In human-math terms I would naturally expect to get 10.333(3) as the result of the aforementioned operation.") +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) +print("Now we operate on Doubles so the required precision is there.") /*: 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: @@ -32,17 +30,20 @@ *circumference = 2 * pi * radius.* */ -let pi = 3.1415927 - - -/*: - Create an integer constant. Using the remainder operator, set its value to the remainder of 12 divided by 5. - */ - +let pi = 3.1415927 +let radius = 5.0 +let diameter = 2 * radius +let circumference = 2 * pi * radius +print("The diameter equals \(diameter) and the circumfenerce \(circumference)./") +//: Create an integer constant. Using the modulus operator, set its value to the remainder of 12 divided by 5. +let integerConstant: Int = 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: Int = 8 +let odd: Int = 7 +print("Remainder of dividing the even value by 2: \(even % 2).") +print("Remainder of dividing the odd value by 2: \(odd % 2).") +print("Well... As one can see, whenever we examine an odd number the modulo operator returns 1.") /*: - 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? +page 1 of 8 | [Next: App Exercise - Fitness Calculations](@next) */ - - -//: 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..f585723 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 @@ -1,20 +1,29 @@ /*: - ## App Exercise - Fitness Calculations +## App Exercise - Fitness Calculations >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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 = 77 +let heartRate2 = 67 +let heartRate3 = 87 +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 = 77 +let heartRate2D: Double = 67 +let heartRate3D: Double = 87 +let addedHRD = heartRate1D + heartRate2D + heartRate3D +let averageHRD = addedHRD / 3 +print(averageHRD) +print("Now we are operating with floating numbers-capable type, so our calculations aren't rounded down to the nearest whole number.") +//: 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 = 3467 +let goal: Double = 10_000 +let percentOfGoal = steps / goal +print(percentOfGoal) /*: - 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? +[Previous](@previous) | page 2 of 8 | [Next: Exercise - Compound Assignment](@next) */ - - -/*: - 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. - */ - - -//: [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..72148eb 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 @@ -1,24 +1,35 @@ /*: - ## Exercise - Compound Assignment +## Exercise - Compound Assignment 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 testVariable = 10 +print(testVariable) +testVariable += 15 +print(testVariable) +testVariable *= 2 +print(testVariable) /*: 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. - - Your neighbor gives you 10 dollars for mowing her lawn - - You earn 20 more dollars throughout the week doing odd jobs - - You spend half your money on dinner and a movie - - You triple what's left in your piggy bank by washing windows - - You spend 3 dollars at a convenience store +- Your neighbor gives you 10 dollars for mowing her lawn +- You earn 20 more dollars throughout the week doing odd jobs +- You spend half your money on dinner and a movie +- You triple what's left in your piggy bank by washing windows +- You spend 3 dollars at a convenience store Print the balance of your piggy bank after each step. */ - - - - - -//: [Previous](@previous) | page 3 of 8 | [Next: App Exercise - Counting](@next) +var 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..c5a5070 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 @@ -1,17 +1,20 @@ /*: - ## App Exercise - Counting +## App Exercise - Counting >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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. */ - - -//: [Previous](@previous) | page 4 of 8 | [Next: Exercise - Order of Operations](@next) +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..bacceb7 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 @@ -1,23 +1,19 @@ /*: - ## Exercise - Order of Operations +## Exercise - Order of Operations 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(24) +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) /*: - In a separate `print` statement, add in the necessary parentheses so that addition takes place before multiplication. +[Previous](@previous) | page 5 of 8 | [Next: App Exercise - Complex Fitness Calculations](@next) */ - - -/*: - Print out what you think 4 * 9 - 6 / 2 evaluates to. Then print out the actual expression. - */ - - -/*: - In a separate `print` statement, add in the necessary parentheses so that the subtraction is prioritized over the multiplication and division. - */ - - -//: [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..a006dc7 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 @@ -1,17 +1,23 @@ /*: - ## App Exercise - Complex Fitness Calculations +## App Exercise - Complex Fitness Calculations >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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 anotherHeartRate1: Double = 87 +let anotherHeartRate2: Double = 72 +let anotherHeartRate3: Double = 87 +let anotherAverageHR = (anotherHeartRate1 + anotherHeartRate2 + anotherHeartRate3) / 3 +print(anotherAverageHR) /*: 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. */ - - -//: [Previous](@previous) | page 6 of 8 | [Next: Exercise - Numeric Type Conversion](@next) +let tempInFahrenheit = 98.6 +let tempInCelsius = (tempInFahrenheit - 32) / (5.0 / 9.0) +print(tempInCelsius) +/*: +[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..66afcff 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 @@ -1,18 +1,18 @@ /*: - ## Exercise - Numeric Type Conversion +## Exercise - Numeric Type Conversion 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: Int = 10 +let y: Double = 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 case (multipliedAsIntegers) we round down the double value making as loose precision and in this way skewing the end result") /*: - Create a constant `multipliedAsDoubles` equal to `x` times `y`, but this time convert the `Int` to a `Double` in the expression. Print the result. +[Previous](@previous) | page 7 of 8 | [Next: App Exercise - Converting Types](@next) */ - - -/*: - Are the values of `multipliedAsIntegers` and `multipliedAsDoubles` different? Print a statement to the console explaining why. - */ - - -//: [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..8c501b2 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Converting Types +## App Exercise - Converting Types >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,16 +7,17 @@ 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: Int = 1_248 +let goal: Int = 10_000 +let percentOfGoal = Double(steps) / Double(goal) /*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 8 of 8 */ -//: [Previous](@previous) | page 8 of 8 diff --git a/Lab - Operators.playground/contents.xcplayground b/Lab - Operators.playground/contents.xcplayground index 5b9299e..26a1adc 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..ceba3c5 100644 --- a/Lab - Optionals.playground/Pages/1. Exercise - Optionals.xcplaygroundpage/Contents.swift +++ b/Lab - Optionals.playground/Pages/1. Exercise - Optionals.xcplaygroundpage/Contents.swift @@ -1,29 +1,49 @@ /*: - ## Exercise - Optionals - - >Throughout the exercises in this playground, you will be printing optional values. The Swift compiler will display a warning: "Expression implicitly coerced from `Int?` to Any". For the purposes of these exercises, you can ignore this warning. +## Exercise - Optionals - Imagine you have an app that asks the user to enter his/her age using the keyboard. When your app allows a user to input text, what is captured for you is given as a `String`. However, you want to store this information as an `Int`. Is it possible for the user to make a mistake and for the input to not match the type you want to store? - - 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? -*/ + >Throughout the exercises in this playground, you will be printing optional values. The Swift compiler will display a warning: "Expression implicitly coerced from `Int?` to Any". For the purposes of these exercises, you can ignore this warning. + Imagine you have an app that asks the user to enter his/her age using the keyboard. When your app allows a user to input text, what is captured for you is given as a `String`. However, you want to store this information as an `Int`. Is it possible for the user to make a mistake and for the input to not match the type you want to store? -/*: - 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. + 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 = "34" +let userAge: Int? = Int(userInputAge) +print(userAge) + +// error message: +//Playground execution failed: +// +//error: 1. Exercise - Optionals.xcplaygroundpage:11:20: error: value of optional type 'Int?' must be unwrapped to a value of type 'Int' +//let userAge: Int = Int(userInputAge) +// ^ +// +//1. Exercise - Optionals.xcplaygroundpage:11:20: note: coalesce using '??' to provide a default when the optional value contains 'nil' +//let userAge: Int = Int(userInputAge) +// ^ +// ?? <#default value#> +// +//1. Exercise - Optionals.xcplaygroundpage:11:20: note: force-unwrap using '!' to abort execution if the optional value contains 'nil' +//let userAge: Int = Int(userInputAge) +// ^ +// ! +//: 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. +print(""" +userAge's value is nil, because the string \"34e\" could not be converted to a proper integer and the class' failable initializer returns nil in this type of scenario. +""") /*: 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. */ - - +print(""" + The value has beed printed as 'Optional(34)'. After force unwrapping it – it prints as the regular Int. + """) +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) +} /*: - Now use optional binding to unwrap `userAge`. If `userAge` has a value, print it to the console. +page 1 of 6 | [Next: App Exercise - Finding a Heart Rate](@next) */ - - -//: 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..ed7613d 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 @@ -1,32 +1,38 @@ /*: - ## App Exercise - Finding a Heart Rate - +## App Exercise - Finding a Heart Rate + >These exercises reinforce Swift concepts in the context of a fitness tracking app. - - Many APIs that give you information gathered by the hardware return optionals. For example, an API for working with a heart rate monitor may give you `nil` if the heart rate monitor is adjusted poorly and cannot properly read the user's heart rate. - - Declare a variable `heartRate` of type `Int?` and set it to `nil`. Print the value. - */ + Many APIs that give you information gathered by the hardware return optionals. For example, an API for working with a heart rate monitor may give you `nil` if the heart rate monitor is adjusted poorly and cannot properly read the user's heart rate. -/*: - 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. + 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. - */ +//: 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. let oldHR1 = 80 let oldHR2 = 76 -let oldHR3 = 79 +let oldHR3 = 79 let oldHR4 = 70 +//var hrAverage = (oldHR1 + oldHR2 + oldHR3 + oldHR4 + heartRate) / 5 + +var averageHR: Int +if let unwrappedHR = heartRate { + averageHR = (oldHR1 + oldHR2 + oldHR3 + oldHR4 + unwrappedHR) / 5 +} else { + averageHR = (oldHR1 + oldHR2 + oldHR3 + oldHR4) / 4 +} +print("The average heart rate is: \(averageHR)") /*: 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`. - - Safely unwrap the value of `heartRate` using optional binding. If it has a value, calculate the average heart rate using that value and the older heart rates stored above. If it doesn't have a value, calculate the average heart rate using only the older heart rates. In each case, print the value of `hrAverage`. - */ + Safely unwrap the value of `heartRate` using optional binding. If it has a value, calculate the average heart rate using that value and the older heart rates stored above. If it doesn't have a value, calculate the average heart rate using only the older heart rates. In each case, print the value of `hrAverage`. + -//: [Previous](@previous) | page 2 of 6 | [Next: Exercise - Functions and Optionals](@next) +[Previous](@previous) | page 2 of 6 | [Next: Exercise - Functions and Optionals](@next) + */ 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..1ba4030 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 @@ -1,20 +1,44 @@ /*: - ## Exercise - Functions and Optionals - +## Exercise - Functions and Optionals + If an app asks for a user's age, it may be because the app requires a user to be over a certain age to use some of the services it provides. Write a function called `checkAge` that takes one parameter of type `String`. The function should try to convert this parameter into an `Int` value and then check if the user is over 18 years old. If he/she is old enough, print "Welcome!", otherwise print "Sorry, but you aren't old enough to use our app." If the `String` parameter cannot be converted into an `Int` value, print "Sorry, something went wrong. Can you please re-enter your age?" Call the function and pass in `userInputAge` below as the single parameter. Then call the function and pass in a string that can be converted to an integer. */ let userInputAge: String = "34e" -/*: - 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. - */ - - -/*: - 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. - */ +func checkAge(givenAge: String) -> Int? { + if let unwrappedAge = Int(givenAge) { + if unwrappedAge >= 18 { + print("Welcome!") + } else { + print("Sorry, but you aren't old enough to use our app.") + } + return unwrappedAge + } else { + print("Sorry, something went wrong. Can you please re-enter your age?") + return nil + } +} +checkAge(givenAge: userInputAge) +checkAge(givenAge: "34") +checkAge(givenAge: "17") +//: 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(givenAge: userInputAge)) +print(checkAge(givenAge: "7")) +print(checkAge(givenAge: "77")) +//: Imagine you are creating an app for making purchases. Write a function that will take in the name of an item for purchase as a `String` and will return the cost of that item as an optional `Double`. 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. 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 itemStock = stock[item], itemStock > 0 { + return prices[item] + } else { + return nil + } +} -//: [Previous](@previous) | page 3 of 6 | [Next: App Exercise - Food Functions](@next) +let applePrice = price(of: "Apple") +print(applePrice) +/*: +[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..3ff4161 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 @@ -1,6 +1,6 @@ import Foundation /*: - ## App Exercise - Food Functions +## App Exercise - Food Functions >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -15,12 +15,30 @@ struct Meal { var meals: [String: Meal] = ["Breakfast": Meal(food: ["Bagel", "Orange Juice", "Egg Whites"], calories: 530)] +func ate(for meal: String) -> Meal? { + return meals[meal] +} +let myBreakfast = ate(for: "Breakfast") +print(myBreakfast) +let myDinner = ate(for: "Dinner") +print(myDinner) /*: 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 savedMeal () -> [String: Any] { + if let meal = UserDefaults.standard.dictionary(forKey: "mealLog") { + return meal + } else { + return [:] + } +} +let mySavedMeal = savedMeal() +print(mySavedMeal) -//: [Previous](@previous) | page 4 of 6 | [Next: Exercise - Failable Initializers](@next) +/*: +[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..e0fbc28 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 @@ -1,13 +1,39 @@ /*: - ## Exercise - Failable Initializers - - 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. +## Exercise - Failable Initializers + + 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 2020. */ +struct Computer { + var ram: Int + var 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. - */ +//: 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. +var myComputer = Computer(ram: 16, yearManufactured: 2016) +var otherComputer = Computer(ram: 32, yearManufactured: 2017) +if let unwrappedComputer = myComputer { + print("RAM: \(unwrappedComputer.ram) GB, year manufactured: \(unwrappedComputer.yearManufactured)") +} else { + print("Such a computer could not exist in our universe!") +} -//: [Previous](@previous) | page 5 of 6 | [Next: App Exercise - Workout or Nil](@next) +if let unwrappedComputer = otherComputer { + print("RAM: \(unwrappedComputer.ram) GB, year manufactured: \(unwrappedComputer.yearManufactured)") +} else { + print("Such a computer could not exist in our universe!") +} + +/*: +[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..f053287 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Workout or Nil +## App Exercise - Workout or Nil >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -9,21 +9,33 @@ 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 { + self.startTime = startTime + self.endTime = endTime + } else { + return nil + } + } +} + +//: Try to initialize two instances of a `Workout` object. Unwrap each of them and print its properties. 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 myWorkout1 = Workout(startTime: 28_800, endTime: 28_810) +let myWorkout2 = Workout(startTime: 28_800, endTime: 29_810) +print(myWorkout1) +print(myWorkout2) /*: - 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. - */ - - -/*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 6 of 6 */ -//: [Previous](@previous) | page 6 of 6 diff --git a/Lab - Optionals.playground/contents.xcplayground b/Lab - Optionals.playground/contents.xcplayground index a5a53bd..5a83c5c 100644 --- a/Lab - Optionals.playground/contents.xcplayground +++ b/Lab - Optionals.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..89747d9 100644 --- a/Lab - Scope.playground/Pages/1. Exercise - Scope.xcplaygroundpage/Contents.swift +++ b/Lab - Scope.playground/Pages/1. Exercise - Scope.xcplaygroundpage/Contents.swift @@ -1,18 +1,18 @@ /*: - ## Exercise - Scope +## Exercise - Scope Using a comment or print statement, describe why the code below will generate a compiler error if you uncomment line 10. -*/ + */ for _ in 0..<10 { let foo = 55 print("The value of foo is \(foo)") } //print("The value of foo is \(foo)") - -/*: - 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? - */ +print(""" +The 'foo' variable (and its value) is available only for the for loop scope. Every attempt to use it outside of it in the above example will result in an error. +""") +//: 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? var x = 10 for _ in 0..<10 { x += 1 @@ -20,16 +20,36 @@ for _ in 0..<10 { } print("The final value of x is \(x)") +print(""" +Here the x variable has been defined in the global scope. Therefore it is available for use both in the global scope and inside a for loop. -/*: - 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`. - */ +The foo variable, however, is defined and can only be used inside the for loop. +""") +//: 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) { + var statement = "" + if let greeting = greeting { + statement = greeting + } else { + statement = "Hello" + } + statement += ", \(name)" + print(statement) +} +greeting(greeting: "Czołem", name: "Kornel") +greeting(greeting: nil, name: "Kacper") +//: 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 { + var make: String + var model: String + var year: Int + init(make: String, model: String, year: Int) { + self.make = make + self.model = model + self.year = year + } } /*: - 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. +page 1 of 2 | [Next: App Exercise - Step Competition](@next) */ - - -//: 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..8a3c328 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Step Competition +## App Exercise - Step Competition >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -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?) { + if let name = name, let stepsToday = stepsToday { + self.name = name + self.stepsToday = stepsToday + } else { + return nil + } + } } 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 checkCompetitor = topCompetitor { + if competitor.stepsToday > checkCompetitor.stepsToday { topCompetitor = competitor } } else { @@ -34,24 +46,23 @@ func getWinner(competitors: [User]) -> User? { } return topCompetitor } -/*: - Write a memberwise initializer inside the `User` struct above that uses variable shadowing for naming the parameters of the initializer. - */ +let mostActiveUser = getWinner(competitors: competitors) +print (mostActiveUser) +//: Write a memberwise initializer inside the `User` struct above that uses variable shadowing for naming the parameters of the initializer. -/*: - Now write a failable initializer inside the `User` struct above that takes parameters `name` and `stepsToday` as an optional `String` and `Int`, respectively. The initializer should return `nil` if either of the parameters are `nil`. Use variable shadowing when unwrapping the two parameters. - */ +//: Now write a failable initializer inside the `User` struct above that takes parameters `name` and `stepsToday` as an optional `String` and `Int`, respectively. The initializer should return `nil` if either of the parameters are `nil`. Use variable shadowing when unwrapping the two parameters. -/*: - _Copyright © 2018 Apple Inc._ +/*: + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 2 of 2 */ -//: [Previous](@previous) | page 2 of 2 diff --git a/Lab - Scope.playground/contents.xcplayground b/Lab - Scope.playground/contents.xcplayground index f1e5b35..90e72e1 100644 --- a/Lab - Scope.playground/contents.xcplayground +++ b/Lab - Scope.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..9ce88fa 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 @@ -1,26 +1,31 @@ /*: - ## Exercise - String Basics +## Exercise - String Basics Create a `name` constant and assign it a string literal representing your name. */ - +let name = "Miłosz" /*: Create a `favoriteQuote` constant and assign it the following string literal: - - "My favorite quote is ." +- "My favorite quote is ." Write in your own favorite quote where indicated, and be sure to include escaped quotation marks. When finished, print the value of `favoriteQuote`. - - 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."` + - 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 \"We're 106 miles to Chicago. We've got a full tank of gas, half a pack of cigarettes, it's dark and we're wearing sunglasses... Hit it!\"" +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") +} /*: - 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. +page 1 of 5 | [Next: Exercise - Concatenation and Interpolation](@next) */ -let emptyString = "" - - -//: 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..4bb82d7 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 @@ -1,23 +1,27 @@ /*: - ## Exercise - Concatenation and Interpolation +## Exercise - Concatenation and Interpolation 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`. */ - - -/*: - Use the compound assignment operator (`+=`) to add `home` to `introduction` below. Print the value of `introduction`. - */ -var introduction = "I live in" - - +let city = "Cracow" +let state = "Lesser Poland" +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 += 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: - - "My name is and after my next birthday I will be years old." +- "My name is and after my next birthday I will be years old." Insert `name` where indicated, and insert a mathematical expression that evaluates to your current age plus one where indicated. */ - - -//: [Previous](@previous) | page 2 of 5 | [Next: App Exercise - Notifications](@next) +let name = "Milosz" +let age = 36 +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..0a190e1 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 @@ -1,23 +1,27 @@ /*: - ## App Exercise - Notifications +## App Exercise - Notifications - >These exercises reinforce Swift concepts in the context of a fitness tracking app. +>These exercises reinforce Swift concepts in the context of a fitness tracking app. In your app, you may want to search for other users. This would be easier with first and last names stored separately. This is not an uncommon practice. 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 = "John" +let lastName = "Appleseed" +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: - - "Congratulations, ! You beat your previous daily high score of steps by walking steps yesterday!" +- "Congratulations, ! You beat your previous daily high score of steps by walking steps yesterday!" Insert `fullName`, `previousBest` and `newBest` where indicated. Print the value of `congratulations`. */ let previousBest = 14392 let newBest = 15125 - - -//: [Previous](@previous) | page 3 of 5 | [Next: Exercise - String Equality and Comparison](@next) +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..b174031 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 @@ -1,38 +1,47 @@ /*: - ## Exercise - String Equality and Comparison +## Exercise - String Equality and Comparison 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 = "Miłosz" +let name = "miłosz" +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: - - " and are the same." +- " and are the same." If they are not equal, print the following statement using string interpolation: - - " and are not the same." +- " 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!" - */ +//: 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." - - -/*: - 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. - */ +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. 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) /*: - Print to the console the number of characters in your name by using the `count` property on `name`. +[Previous](@previous) | page 4 of 5 | [Next: App Exercise - Password Entry and User Search](@next) */ - - -//: [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..c84c4c2 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 @@ -1,7 +1,7 @@ /*: - ## App Exercise - Password Entry and User Search +## App Exercise - Password Entry and User Search - >These exercises reinforce Swift concepts in the context of a fitness tracking app. +>These exercises reinforce Swift concepts in the context of a fitness tracking app. You think it might be fun to incorporate some friendly competition into your fitness tracking app. Users will be able to compete with friends in small fitness challenges. However, to do this users will need a password-protected account. Write an if-else statement below that will check that the entered user name and password match the stored user name and password. While the password should be case sensitive, users should be able to log in even if their entered user name has the wrong capitalization. If the user name and password match, print "You are now logged in!" Otherwise, print "Please check your user name and password and try again." */ @@ -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 name ands 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,15 +24,19 @@ import Foundation let userName = "StepChallenger" let searchName = "step" - +if (userName.lowercased().contains(searchName.lowercased())) { + print(userName) +} else { + print("") +} /*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 5 of 5 */ -//: [Previous](@previous) | page 5 of 5 diff --git a/Lab - Strings.playground/contents.xcplayground b/Lab - Strings.playground/contents.xcplayground index a563208..96eab9c 100644 --- a/Lab - Strings.playground/contents.xcplayground +++ b/Lab - Strings.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..16211c9 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 @@ -1,28 +1,38 @@ /*: - ## Exercise - Structs, Instances, and Default Values +## Exercise - Structs, Instances, and Default Values 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. */ - - -/*: - 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. - */ - - -/*: - Change `somePlace`'s latitude to 51.514004, and the longitude to 0.125226, then print the updated values. - */ - - -/*: - 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 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 = "Up in the Air" +favoriteBook.author = "Walter Kim" +favoriteBook.pages = 320 +favoriteBook.price = 15.80 + +print("My favorite book details:\ntitle: \(favoriteBook.title), author: \(favoriteBook.author), pages: \(favoriteBook.pages), price: \(favoriteBook.price)") /*: - 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. +page 1 of 10 | [Next: App Exercise - Workout Tracking](@next) */ - - -//: 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..7110d12 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Type Properties and Methods +## App Exercise - Type Properties and Methods >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -13,20 +13,32 @@ struct RunningWorkout { var distance: Double var time: Double var elevation: Double + + static var meterInFeet = 3.28084 + static var mileInMeters = 1600.0 + + static func mileTimeFor(distance: Double, time: Double) -> Double { + return time / (distance / 1600) + } } -/*: - 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. - */ +let myMileTime = RunningWorkout.mileTimeFor(distance: 10_000, time: 20) +print(myMileTime) -/*: +print("Meters in feet: \(RunningWorkout.meterInFeet)") +print("Miles in meter: \(RunningWorkout.mileInMeters)") - _Copyright © 2018 Apple Inc._ +//: 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. + + +/*: + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 10 of 10 */ -//: [Previous](@previous) | page 10 of 10 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..9059c80 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Workout Tracking +## App Exercise - Workout Tracking >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -7,16 +7,21 @@ 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 = 2_396 +firstRun.time = 15.3 +firstRun.elevation = 94 +print("distance: \(firstRun.distance), time: \(firstRun.time), elevation: \(firstRun.elevation)") /*: - 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. +[Previous](@previous) | page 2 of 10 | [Next: Exercise - Memberwise and Custom Initializers](@next) */ - - -/*: - 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. - */ - - -//: [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..6dc899b 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 @@ -1,37 +1,54 @@ /*: - ## Exercise - Memberwise and Custom Initializers +## Exercise - Memberwise and Custom Initializers 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`. */ - - -/*: - 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. - */ - - -/*: - 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 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.514004, 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 { + var title: String + var author: String + var pages: Int + var price: Double +} + +let favoriteBook = Book(title: "Up in the Air", author: "Walter Kim", pages: 320, price: 15.80) + +print("My favorite book details:\ntitle: \(favoriteBook.title), author: \(favoriteBook.author), pages: \(favoriteBook.pages), price: \(favoriteBook.price)") /*: Make a `Height` struct with two variable properties, `heightInInches` and `heightInCentimeters`. Both should be of type `Double`. Create two custom initializers. One initializer will take a `Double` argument that represents height in inches. The other initializer will take a `Double` argument that represents height in centimeters. Each initializer should take the passed in value and use it to set the property that corresponds to the unit of measurement passed in. It should then set the other property by calculating the right value from the passed in value. Hint: *1 inch = 2.54 centimeters*. - - - 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. - */ - -/*: - 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. + - 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.heightInInches = heightInCentimeters / 2.54 + self.heightInCentimeters = heightInCentimeters + } +} + +//: 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: 185) +print(myHeight.heightInInches) /*: - Now create a variable instance of `Height` called `myHeight` and initialize it with your own height. Verify that both `heightInInches` and `heightInCentimeters` are accurate. +[Previous](@previous) | page 3 of 10 | [Next: App Exercise - Users and Distance](@next) */ - - -//: [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..247e7c9 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 @@ -1,32 +1,50 @@ /*: - ## App Exercise - Users and Distance +## App Exercise - Users and Distance >These exercises reinforce Swift concepts in the context of a fitness tracking app. 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. */ - - -/*: - 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. - */ - +struct User { + let name: String + var age: Int + let 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 milosz = User(name: "Miłosz", age: 36, height: 186, weight: 79, activityLevel: 7) +print("\(milosz.name) is \(milosz.age), having height of \(milosz.height) centimeters, weight of \(milosz.weight) kilos and activity level of \(milosz.activityLevel).") /*: In previous app exercises, you've worked with distance in the fitness tracking app example as a simple number. However, distance can be represented using a variety of units of measurement. Create a `Distance` struct that will represent distance in various units of measurement. At a minimum, it should have a `meters` property and a `feet` property. Create a custom initializer corresponding to each property (i.e. if you only have the two properties for meters and feet you will then have two initializers) that will take in a distance in one unit of measurement and assign the correct value to both units of measurements. Hint: *1 meter = 3.28084 feet*. - - - 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. - */ - -/*: - 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. + - 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: 777) +print(km.meters) +print(km.feet) /*: - Now create another instance of `Distance` and give it some other distance. Ensure that both properties are set correctly. +[Previous](@previous) | page 4 of 10 | [Next: Exercise - Methods](@next) */ - - -//: [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..c0062e4 100644 --- a/Lab - Structures.playground/Pages/5. Exercise - Methods.xcplaygroundpage/Contents.swift +++ b/Lab - Structures.playground/Pages/5. Exercise - Methods.xcplaygroundpage/Contents.swift @@ -1,5 +1,5 @@ /*: - ## Exercise - Methods +## Exercise - Methods A `Book` struct has been created for you below. Add an instance method on `Book` called `description` that will print out facts about the book. Then create an instance of `Book` and call this method on that instance. */ @@ -8,13 +8,30 @@ struct Book { var author: String var pages: Int var price: Double + + func description() { + print("title: \(title), author: \(author), pages: \(pages), price: \(price)") + } } -/*: - 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. - */ + +let myBook = Book(title: "Up in the Air", author: "Walter Kim", pages: 320, price: 15.80) +myBook.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. struct Post { var message: String var likes: Int var numberOfComments: Int + + mutating func like() { + likes += 1 + } } -//: [Previous](@previous) | page 5 of 10 | [Next: App Exercise - Workout Functions](@next) + +var post = Post(message: "Always look on the Bright Side of Life!", likes: 7, numberOfComments: 77) + +print(post.likes) +post.like() +print(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..7276e09 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Workout Functions +## App Exercise - Workout Functions >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -9,12 +9,28 @@ struct RunningWorkout { var distance: Double var time: Double var elevation: Double + + func postWorkoutStats() { + print("distance: \(distance), time: \(time), elevation: \(elevation)") + } } -/*: - 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 { + +let myWorkout = RunningWorkout(distance: 7000, time: 45, elevation: 89) +myWorkout.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 + } } -//: [Previous](@previous) | page 6 of 10 | [Next: Exercise - Computed Properties and Property Observers](@next) + +var mySteps = Steps(steps: 700, goal: 7000) +print(mySteps.steps) +mySteps.takeStep() +print(mySteps.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..266d6ca 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 @@ -1,21 +1,44 @@ /*: - ## Exercise - Computed Properties and Property Observers +## Exercise - Computed Properties and Property Observers The `Rectangle` struct below has two properties, one for width and one for height. Add a computed property that computes the area of the rectangle (i.e. width * height). Create an instance of `Rectangle` and print the `area` property. */ struct Rectangle { var width: Int var height: Int + + var area: Int { + return width * height + } } + +let myRect = Rectangle(width: 7, height: 17) +print (myRect.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,13 @@ struct Height { self.heightInInches = heightInCentimeters/2.54 } } -//: [Previous](@previous) | page 7 of 10 | [Next: App Exercise - Mile Times and Congratulations](@next) + +var myHeight = Height(heightInCentimeters: 185) +print(myHeight.heightInInches) +myHeight.heightInInches = 100 +print(myHeight.heightInInches) +print(myHeight.heightInCentimeters) + +/*: +[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..66c73f4 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Mile Times and Congratulations +## App Exercise - Mile Times and Congratulations >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -11,18 +11,37 @@ struct RunningWorkout { var distance: Double var time: Double var elevation: Double + + var averageMiletime: Double { + let distanceInMiles = distance / 1600 + return time / distanceInMiles + } } + +let myRunningWorkout = RunningWorkout(distance: 700, time: 6, elevation: 89) +print(myRunningWorkout.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("You made it! Congratulations! The goal has been reached!") + } + } + } var goal: Int mutating func takeStep() { steps += 1 } } -//: [Previous](@previous) | page 8 of 10 | [Next: Exercise - Type Properties and Methods](@next) + +var mySteps = Steps(steps: 9_999, goal: 10_000) +mySteps.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..57f1bef 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 @@ -1,18 +1,32 @@ /*: - ## Exercise - Type Properties and Methods +## Exercise - Type Properties and Methods Imagine you have an app that requires the user to log in. You may have a `User` struct similar to that shown below. However, in addition to keeping track of specific user information, you might want to have a way of knowing who the current logged in user is. Create a `currentUser` type property on the `User` struct below and assign it to a `user` object representing you. Now you can access the current user through the `User` struct. Print out the properties of `currentUser`. */ struct User { + var userName: String var email: String var age: Int + + static var currentUser: User = User(userName: "Milosz", email: "milosz@k7.eu", age: 36) + + static func logIn(user: User) { + currentUser = user + print("\(currentUser.userName) has logged in.") + } } + +print("current user: \(User.currentUser.userName), email: \(User.currentUser.email), age: \(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. */ - - -//: [Previous](@previous) | page 9 of 10 | [Next: App Exercise - Type Properties and Methods](@next) +let myUser = User(userName: "Krzysztof", email: "krzysztof@k7.eu", age: 26) +User.logIn(user: myUser) +/*: +[Previous](@previous) | page 9 of 10 | [Next: App Exercise - Type Properties and Methods](@next) + */ diff --git a/Lab - Structures.playground/contents.xcplayground b/Lab - Structures.playground/contents.xcplayground index 9708b7e..8aa97c3 100644 --- a/Lab - Structures.playground/contents.xcplayground +++ b/Lab - Structures.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + 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..3f10d4f 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 @@ -1,28 +1,69 @@ /*: - ## Exercise - Type Casting and Inspection - +## Exercise - Type Casting and Inspection + Create a collection of type [Any], including a few doubles, integers, strings, and booleans within the collection. Print the contents of the collection. */ +var myArray: [Any] = [7, 8, 9, 77.7, 12.34, 19.39, "Amiga", "Mac", "Linux", true, true, false, false] +print(myArray) -/*: - 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 someItem in myArray { + print(someItem) +} +//: 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 someItem in myArray { + if let intValue = someItem as? Int { + print("The integer has a value of \(intValue)") + } else if let doubleValue = someItem as? Double { + print("The double has a value of \(doubleValue)") + } else if let stringValue = someItem as? String { + print("The string has a value of: \"\(stringValue)\"") + } else if let boolValue = someItem as? Bool { + print("The boolean 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 myDictionary: [String: Any] = ["first": 7, "second": 8, "third": 9, "fourth": 77.7, "fifth": 12.34, "sixth": 19.39, "seventh": "Amiga", "eighth": "Mac", "ninth": "Linux", "tenth": true, "eleventh": true, "twelfth": false, "thirteenth": false] +for (key, value) in myDictionary { + print("\(key): \(value)") +} +//: 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 -/*: - 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 - */ - +for (_, value) in myDictionary { + if let intValue = value as? Int { + total += Double(intValue) + } else if let doubleValue = value as? Double { + total += doubleValue + } else if let stringValue = value as? String { + total += 1 + } else if let boolValue = value as? Bool { + if boolValue { + total += 2 + } else { + total -= 3 + } + } +} -/*: - 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`. - */ +print("total: \(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 myDictionary { + if let intValue = value as? Int { + total2 += Double(intValue) + } else if let doubleValue = value as? Double { + total2 += doubleValue + } else if let stringValue = value as? String { + if let doubleValue = Double(stringValue) { + total2 += doubleValue + } + } +} +print("Total2: \(total2)") /*: - 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. +page 1 of 2 | [Next: App Exercise - Workout Types](@next) */ - - -//: 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..86b0aa2 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 @@ -1,5 +1,5 @@ /*: - ## App Exercise - Workout Types +## App Exercise - Workout Types >These exercises reinforce Swift concepts in the context of a fitness tracking app. @@ -42,24 +42,38 @@ var workouts: [Workout] = [ Swim(stroke: "Freestyle", time: 523.6, distance: 500), Run(cadence: 90, time: 358.9, distance: 1600) ] -/*: - 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. - */ - - -/*: - 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. - */ +//: 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(""" + Cadence: \(runningWorkout.cadence) steps/minute + Time: \(runningWorkout.time) seconds + Distance: \(runningWorkout.distance) meters + + """) +} +func describeSwim(swimmingWorkout: Swim) { + print(""" + Stroke: \(swimmingWorkout.stroke) + Time: \(swimmingWorkout.time) seconds + Distance: \(swimmingWorkout.distance) meters + + """) +} +//: 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) } + if let swim = workout as? Swim { describeSwim(swimmingWorkout: swim) } +} /*: - - _Copyright © 2018 Apple Inc._ + _Copyright © 2021 Apple Inc._ _Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:_ _The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software._ _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +[Previous](@previous) | page 2 of 2 */ -//: [Previous](@previous) | page 2 of 2 diff --git a/Lab - Type Casting.playground/contents.xcplayground b/Lab - Type Casting.playground/contents.xcplayground index aaf2548..f163994 100644 --- a/Lab - Type Casting.playground/contents.xcplayground +++ b/Lab - Type Casting.playground/contents.xcplayground @@ -1,5 +1,5 @@ - +