<repo_name>Combatd/introProgrammingSwift5<file_sep>/section3/optionals.playground/Contents.swift
import UIKit

// Optionals let developers specify which data could be nil
// and which data is guaranteed to not be nil

//struct Person {
//    let firstName: String
//    let middleName: String?
//    let lastName: String
//
//    func printFullName() {
//        // if nil value, empty string
//        let middle = middleName ?? ""
//        // if middleName == nil {
//        //  middle = ""
//        // }
//        print("\(firstName) \(middle) \(lastName)")
//    }
//}
//
//var person1 = Person(firstName: "Jenna", middleName: nil, lastName: "Smith")
//var person2 = Person(firstName: "Bob", middleName: "Leroy", lastName: "Jenkins")
//
//person1.printFullName()
//person2.printFullName()

class Person {
    let firstName: String
    let middleName: String?
    let lastName: String
    let spouse: Person?
    
    // initializer
    init(firstName: String, middleName: String?, lastName: String, spouse: Person?) {
        self.firstName = firstName
        self.middleName = middleName
        self.lastName = lastName
        self.spouse = spouse
    }
    
    func printFullName() {
        // if nil value, empty string
        let middle = middleName ?? ""
        // if middleName == nil {
        //  middle = ""
        // }
        print("\(firstName) \(middle) \(lastName)")
    }
}

let person1 = Person(firstName: "Kimbo", middleName: "Joe", lastName: "Slice", spouse: nil)

// optional chaining, calling a function on something that could be optional
// if the spouse is not nil, print the Person's spouse name
// else print that they don't have a spouse

if let spouseName = person1.spouse?.printFullName() {
    print(spouseName)
} else {
    print("\(person1.firstName) does not have a spouse.")
}

print(person1.spouse?.printFullName() ?? print("\(person1.firstName) does not have a spouse."))

// unwrapping an optional value, can be useful, but can get runtime errors
// try not to use these
// print(person1.spouse!.getFullName())

// If you have an optional (Question Mark ?), make sure to check if it is nil.
// Always use optional chaining
// Never force unwrap optionals, or you will get runtime crashes

@IBOutlet weak var someButton: UIButton! // implicitly unwrapped ooptional
// url examplewebsite.com

let myWebsite = URL(string: "examplewebsite.com")
<file_sep>/section4/mvcifyme/mvcifyme/Model/AppleProduct.swift
//
//  AppleProduct.swift
//  mvcifyme
//
//  Created by <NAME> on 10/11/20.
//

import Foundation

class AppleProduct {
    // private variables are only accessible & set inside the same class
    // public private can access anywhere but only set in the class
    public private(set) var name: String
    public private(set) var color: String
    public private(set) var price: Double
    
    init(name: String, color: String, price: Double) {
        self.name = name
        self.color = color
        self.price = price
    }
}
<file_sep>/section4/objectsandclasses.playground/Contents.swift
import UIKit

// What is a Class?
// The most popular paradigm - Object Oriented Programming
// With a Class, you can create a blueprint and create copies of it
// You could have a Car Class and instantiate multiple objects with the Car properties and functions

class Vehicle {
    var tires = 4
    var headlights = 2
    var horsepower = 468
    var model = ""
    
    
    func drive() {
        // accelerate the vehicle
    }
    
    func brake() {
        
    }
    
}

// instantiate a Vehicle instance
let bmw = Vehicle()
bmw.model = "328i"

let ford = Vehicle()
ford.model = "F150"
ford.brake()

// Objects are passed by reference, not by value
func someFunction(vehicle: Vehicle) {
    vehicle.model = "Cheese"
}

print(ford.model)
someFunction(vehicle: ford)
print(ford.model) // You can't copy an object, but you can copy the values in memory
// The constant model property was passed by reference

var someonesAge = 20

func passByValue(age: Int) {
    let newAge = age // makes a copy of the value and stores in a new memory location
}

passByValue(age: someonesAge)

// View Component
//class NewVC: UIViewController {
//    override func viewDidLoad() {
//
//    }
//}
<file_sep>/section2/boolsandcomparisons.playground/Contents.swift
import UIKit

// Bool is the explicit type, Boolean is for type casting
var amITheBestTeacherEver: Bool = true

amITheBestTeacherEver = false

// Booleans are more commonly used for comparisons or doing based on conditions

if true == false || true == true {
    print("WTFish")
}

var hasDataFinishedDownloading: Bool = false
// ... loading spinner

if !hasDataFinishedDownloading {
    print("Loading data...")
}

hasDataFinishedDownloading = true
// Load the UI and other app features
// State Control!

if 1 == 2 {
    print("Should not see this")
}

// Equal to: ==
// Not equal to: !=
// Greater than: >
// Greater than or equal to: >=
// Less than or equal to: <=
// Less than: <

var bankBalance = 400
var itemToBuy = 100

if bankBalance >= itemToBuy {
    print("purchased item")
}

if itemToBuy > bankBalance {
    print("You need more money!")
}

if itemToBuy == bankBalance {
    print("Hey buddy, your balance is now 0")
}

var bookTitle1 = "<NAME> and the Moppet of Mire"
var bookTitle2 = "<NAME> the Moppet of Mire"

if bookTitle1 != bookTitle2 {
    print("Need to fix spelling before printing")
} else if bookTitle2.count > 10 {
    print("find a new title for the book")
} else {
    print("Book looks great, send to printer")
}
<file_sep>/section4/mvcifyme/mvcifyme/View/CustomPrettyView.swift
//
//  CustomPrettyView.swift
//  mvcifyme
//
//  Created by <NAME> on 10/11/20.
//

import UIKit

class CustomPrettyView: UIView {
    override func awakeFromNib() {
        layer.cornerRadius = 20
        layer.shadowColor = #colorLiteral(red: 0.2549019754, green: 0.2745098174, blue: 0.3019607961, alpha: 1) // color literal
        layer.shadowRadius = 10
        layer.shadowOpacity = 0.75
        backgroundColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
        layer.borderColor = #colorLiteral(red: 0.2549019754, green: 0.2745098174, blue: 0.3019607961, alpha: 1)
        layer.borderWidth = 5
    }
}
<file_sep>/section1/strings.playground/Contents.swift
import UIKit

var str = "Hello, playground" // Declaration: Type inference

var message: String = "This is a String" // Declaration: Explicit Type

var age: String = "20" // There might be a case where you can store an age where you don't plan on doing mathematical operations with it
// Swift is a statically-typed language - type safe

var fullName = "<NAME>"
var aMessage: String = "Hey There!"

let firstName = "Jenna"
let lastName = "Smith"

fullName = firstName + " " + lastName // string concatenation
print(fullName)

var newMessage: String = "Hi, my name is \(firstName) and I am \(age) years old"
print(newMessage) // string interpolation

newMessage.append(". I like scary clowns.")
print(newMessage)
<file_sep>/section1/variables.playground/Contents.swift
import UIKit

// Lets talk about a Person!
// What are some attributes of a person?
var name = "Bob" // String
var age = 51 // Integer
var weight = 212.15 // Double
var isOrganDonor = false // Boolean

print(weight)
// var is mutable - they can change!
weight = 200.10
print(weight)
// Variables are stored in the RAM on your computer, memory space

// Define constant using let keyword
let eyeColor = "Blue"
<file_sep>/section2/loopstime.playground/Contents.swift
import UIKit

// These should be in an array!
var employee1Salary = 45000.0
var employee2Salary = 100000.0
var employee3Salary = 54000.0
var employee4Salary = 20000.0

// something seems wrong here....DRY Don't Repeat Yourself
//employee1Salary = employee1Salary + (employee1Salary * 0.10)
//employee2Salary = employee2Salary + (employee2Salary * 0.10)
//employee3Salary = employee3Salary + (employee3Salary * 0.10)
//employee4Salary = employee4Salary + (employee4Salary * 0.10)

var salaries = Array<Double>()
salaries.append(employee1Salary)
salaries.append(employee2Salary)
salaries.append(employee3Salary)
salaries.append(employee4Salary)

// This is still a lot of manual work. DRY Don't Repeat Yourself
//salaries[0] = salaries[0] + (salaries[0] * 0.10)

// Why don't we create a while loop?
var idx = 0
repeat {
    salaries[idx] = salaries[idx] + (salaries[idx] * 0.10)
    idx += 1
} while (idx < salaries.count) // Remember, last array index is length - 1

// ... is inclusive of the final index!
for x in 1...5 {
    print("Value of x: \(x)")
}

// ..< is exclusive of the final index!
for x in 1..<5 {
    print("Value of x: \(x)")
}

// Let us do the same thing in a for in loop with a range!
for i in 0..<salaries.count {
    salaries[i] = salaries[i] + (salaries[i] * 0.10)
}

// foreach enumerable
for salary in salaries {
    print("Salary: \(salary)")
}
<file_sep>/README.md
# Introduction to Programming in Swift 5
This is an Introduction to Programming in Swift 5 for building simple programs with the Swift programming language and preparing to learn iOS mobile development.


## Learning Goals
*	An Introduction to Swift 5 programming concepts
*	Installing the necessary tools - XCode
*	Working with data such as Integers and Strings
*	Creating reusable code with functions
*	Working with data constructs such as arrays and dictionaries
*	Object-oriented programming (Classes, Composition, Inheritance, etc)
*	Model View Controller (MVC) Software Architecture
<file_sep>/section4/polymorphism.playground/Contents.swift
import UIKit

// What is Polymorphism?
// Dictionary says it is the condition of occuring in several different forms

// Stack Overflow has an interesting answer to this:
/*
  Polymorphism allows the expression of some sort of contract
  with potentially many types implementing that contract
  whether through class inheritance or not in different ways each according to their own purpose.
  Code using that contract should not have to care about which implementation is involved,
  only that the contract will be obeyed.
 */

// At some point, those abstracted, not yet defined methods will have to be implemented!

class Shape {
    var area: Double?
    
    func calculateArea(valA: Double, valB: Double)  {
        
    }
}

class Triangle: Shape {
    
    override func calculateArea(valA: Double, valB: Double) {
        area = (valA * valB) / 2
    }
}

class Rectangle: Shape {
    
    override func calculateArea(valA: Double, valB: Double) {
        area = valA * valB
    }
}
<file_sep>/section3/uptownfunctions.playground/Contents.swift
import UIKit

// Shape 1
var length = 5
var width = 10

var area = length * width

// Shape 2
var length2 = 6
var width2 = 12

var area2 = length2 * width2

// We are starting to violate DRY - Don't Repeat Yourself

func calculateArea(length: Int, width: Int) -> Int {
//    let area = length * width
//    return area // returns Int area
    return length * width // single line return for simple operations
}

let shape1 = calculateArea(length: 5, width: 4)
let shape2 = calculateArea(length: 6, width: 2)
let shape3 = calculateArea(length: 4, width: 4)

var bankAccountBalance = 500.00 // double
var alienStomperShoes = 350.00 // double

func purchaseItem(currentBalance: Double, itemPrice: Double) -> Double {
    if itemPrice <= currentBalance {
        print("Purchased item for: $\(itemPrice)")
        return currentBalance - itemPrice
    } else {
        print("You need more money to purchase the item")
        return currentBalance
    }
}

func mutatingPurchaseItem(currentBalance: inout Double, itemPrice: Double) {
    if itemPrice <= currentBalance {
        currentBalance = currentBalance - itemPrice
        print("Purchased item for: $\(itemPrice)")
    } else {
        print("You need more money to purchase the item")
    }
}

bankAccountBalance = purchaseItem(currentBalance: bankAccountBalance, itemPrice: alienStomperShoes)

var retroLunchBox = 40.00

bankAccountBalance = purchaseItem(currentBalance: bankAccountBalance, itemPrice: retroLunchBox)
<file_sep>/section3/09-dictionaries.playground/Contents.swift
import UIKit

/*:
 ### Code Example
 */

var namesOfIntegers = [Int: String]()

namesOfIntegers[3] = "three"
namesOfIntegers[4] = "four"
namesOfIntegers = [:]

var ageDictionary = ["John": 33, "Samantha": 14]

var airports: [String: String] = ["YYZ": "Toronto Pearson", "LAX": "Los Angeles International"]

print("The airports dictionary has: \(airports.count) items")

if airports.isEmpty {
    print("The airports dictionary is empty!")
}

airports["LHR"] = "London"
airports["LHR"] = "London Heathrow"
airports["DEV"] = "Coder International"

airports["DEV"] = nil

for (airportCode, airportName) in airports {
    print("\(airportCode): \(airportName)")
}

for key in airports.keys {
    print("Key: \(key)")
}

for val in airports.values {
    print("Value: \(val)")
}

/*:
 ### Exercise
 
 Consider a real-world dictionary that you might read on your desk.
 
 1.  Create an animal dictionary where the key is the name of the animal and the value should be a string which represents the definition of the animal
 2.  Add ten animals to this dictionary
 3.  Iterate through the dictionary and print the keys and values in this format: `"Animal: X -- Description: Y"` where X is the name of the animal and Y is the description of the animal
 4.  Clear out the entire dictionary and then instead use this dictionary to store United States state abbrieviations and full names (ie CA : California)
 5. Store ten state names and abbreviations in this dictionary and then print them in this format: `Y: X` where Y is the name of the state and where X is the abbreviation
 6. Set the first state you chose to `nil`
 7. Iterate through the array and print each key and value and see what happened to that state you set to nil
 */

var animals: [String: String] = ["Human": "Homo Sapien Sapiens, a primate species that created civilization. Only known intelligent species in the Milky Way Galaxy as of now."]
animals["Dog"] = "Best Friends!"
animals["Cat"] = "Guardians of the Computer Keyboard"
animals["Cockatiel"] = "Sometimes confused with parakeets"
animals["Guinea Pig"] = "Cute Little Rodent"

for (animal, animalDescription) in animals {
    print("Animal: \(animal) -- Description: \(animalDescription)")
}

animals = [:] // clearing things out!

animals["USA"] = "United States" // this ain't no state! and it isn't an animal!
animals["CA"] = "California"

for (abbreviation, fullName) in animals {
    print("\(fullName) : \(abbreviation)")
}

animals["USA"] = nil // getting removed now

for (abbreviation, fullName) in animals {
    print("\(fullName) : \(abbreviation)")
} // the USA is gone
<file_sep>/section3/fizzbuzz.playground/Contents.swift
func fizzBuzz(){
    let end = 100
    for integer in 1...end {
        if integer % 3 == 0 && integer % 5 == 0 {
            print("FizzBuzz")
        } else if integer % 3 == 0 {
            print("Fizz")
        } else if integer % 5 == 0 {
            print("Buzz")
        } else {
            print(integer)
        }
    }
}

//fizzBuzz()

var amount = 0

for x in 0..<10 {
    if x % 2 == 0 {
        amount += 3
    }
}
print(amount)

let planets = ["Jupiter", "Mars", "Venus", "Earth"]
print(planets.last!)

//let result = true == false && false != true
//
//let firstName = "Amy"
//let lastName = "Smith"
//let age = 25
//
//let profile = "\(firstName)\(lastName)\(age)"
//let average = Int(10.3 + 4.0) / 2

//var sum = 0
//for i in 0...20 {
//    sum += 1
//}
//print(sum)

var nicknames = ["jax" : "James"]
nicknames["spike"] = "Tom"
nicknames["jax"] = "Billy"

//let result = nicknames["jax"]!

//var result = 0.0

//func calcPerimeter(sides: [Double], perimeter: Double) {
//    var perm = perimeter
//    for x in 0..<sides.count {
//        perm += sides[x]
//    }
//    print(perm)
//}
//
//calcPerimeter(sides:[5.0,2.0,3.1], perimeter: result)

var randomstuff = false
if (randomstuff) { print(true) }

enum Device: Int {
    case iPhone
    case Android
    case MacBook
    case Windows
}

var chosen: Device = .MacBook
let result = chosen.rawValue

var fullName = "empty"
var firstName: String?
var lastName: String?

firstName = "Jan"

if let first = firstName, let last = lastName {
    fullName = "\(first) \(last)"
}
//
//struct Person {
//    var name: String
//    var age: Int
//}
//let john = Person(name: "John", age: 21)
//var steven = john
//steven.name = "Steven"
//print(john.name)

class Person {
    var name: String
    var age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}
let john = Person(name: "John", age: 21)
var steven = john
steven.name = "Steven"
print(john.name)

<file_sep>/section3/dictionaries.playground/Contents.swift
import UIKit

var namesOfIntegers = [Int: String]()
// unique integer keys with string values
namesOfIntegers[3] = "three"
namesOfIntegers[44] = "forty four"

namesOfIntegers = [:] // clear out the dictionary keys and values

// var airports = ["YYZ": "Toronto Pearson", "LAX": "Los Angeles International"]
var airports: [String: String] = ["YYZ": "Toronto Pearson", "LAX": "Los Angeles International"]

print("The airports dictionary has: \(airports.count) items")

if airports.isEmpty {
    print("The airports dictionary is empty!")
}

airports["LHR"] = "London"
airports["LHR"] = "London Heathrow" // overwrites previous value
airports["DEV"] = "Devlife International"

airports["DEV"] = nil // destroy this key value pair with a nil value

// getting a tuple, a data structure that has more than one element in it
// for (key, value) in whatever
for (airportCode, airportName) in airports {
    print("\(airportCode): \(airportName)")
}

for airportCode in airports.keys {
    print("Key: \(airportCode)")
}

for airportName in airports.values {
    print("Value: \(airportName)")
}
<file_sep>/section2/ArrayMiArray.playground/Contents.swift
import UIKit

var employee1Salary = 45000.0
var employee2Salary = 54000.0
var employee3Salary = 100000.0
var employee4Salary = 20000.0

// array of type int
var employeeSalaries: [Double] = [45000.0, 54000.0, 100000.0, 20000.0] // [] brackets {} braces

// var employeeSalaries: Array<Double> = [45000.0, 54000.0, 100000.0, 20000.0]


print(employeeSalaries.count)

employeeSalaries.append(39000.34)

print(employeeSalaries.count)

employeeSalaries.remove(at: 1) // remove second element

print(employeeSalaries.count)

// Create empty array of type string
var students = [String]() // () initializes the array

students.append("Jon")
students.append("Jacob")
students.append("Jose")
students.append("Jingle")
students.append("Heimer")
students.append("Smith")

students.remove(at: 2) // remove Jose, the 3rd element

print(students)
<file_sep>/section1/numbers.playground/Contents.swift
import UIKit

var age = 15 // Integer
var price = 10.99 // Double - Default Type for Decimals

/*
 Multi-line Comment
 */

var aPrice: Float = 10.99

var personAge: Int = 15
var thePrice: Double = 10.99

var length = 10
var width = 5

let area = length * width // Multiplication
print(area)

var health = 100
var poisonDamage = 15

health = health - poisonDamage // subtraction
print(health)

health -= poisonDamage // Subtraction Compound assignment operator
print(health)

var potion = 20
health += potion // Addition Compound assignment operator
health = health + potion // Addition

var students = 30
var treats = 500

let treatsPerStudent = treats / students // Division
print(treatsPerStudent) // => 16 (integer result)

let remainder = treats % students // Remainder operator (modulo)
print(remainder)

var tLength: Double = 10
var tWidth: Double = 5

// Pythagorean Theorem a^2 + b^2 = c^2
let areaTriangle = sqrt(pow(tLength, 2) + pow(tWidth, 2))
print(areaTriangle)

var quantity: Int = 5
var productPrice: Double = 10.99

var cost = Double(quantity) * productPrice // type cast to quantity
print(cost)
<file_sep>/section4/mvcifyme/mvcifyme/mvcifymeApp.swift
//
//  mvcifymeApp.swift
//  mvcifyme
//
//  Created by <NAME> on 10/11/20.
//

import SwiftUI

@main
struct mvcifymeApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
<file_sep>/section1/hello-swift.playground/Contents.swift
import UIKit

var message = "Hello, World!"
print(message)
