Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Final Exam" -- updated Calculator. #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 31 additions & 30 deletions Calculator/Controller/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,61 +13,62 @@ class ViewController: UIViewController {
@IBOutlet weak var displayLabel: UILabel!

private var isFinishedTypingNumber: Bool = true
private var calculator = CalculatorLogic()


private var displayValue: Double {
private var displayValue : Double {
get {
guard let number = Double(displayLabel.text!) else {
fatalError("Cannot convert display label text to a Double.")
fatalError("Cannot convert string to Double")
}
return number
}
set {
let isInteger = floor(newValue) == newValue
if isInteger {
displayLabel.text = String(Int(newValue))
} else {
displayLabel.text = String(newValue)
}
}
}

private var calculator = CalculatorLogic()

@IBAction func calcButtonPressed(_ sender: UIButton) {

//What should happen when a non-number button is pressed

isFinishedTypingNumber = true

calculator.setNumber(displayValue)

if let calcMethod = sender.currentTitle {

if let result = calculator.calculate(symbol: calcMethod) {
displayValue = result
}
calculator.inputValue = displayValue
if sender.currentTitle! == "+/-" || sender.currentTitle! == "%" {
calculator.otherOps(operation: sender.currentTitle!)
} else {
calculator.calculate(operation: sender.currentTitle!)
}
displayValue = calculator.totalValue ?? 0

}


@IBAction func numButtonPressed(_ sender: UIButton) {

//What should happen when a number is entered into the keypad

if let numValue = sender.currentTitle {

if let numString = sender.currentTitle {
if isFinishedTypingNumber {
displayLabel.text = numValue
displayLabel.text = numString
isFinishedTypingNumber = false
calculator.percentHasBeenUsed = false
calculator.operatorLastTouched = false
} else {

if numValue == "." {

let isInt = floor(displayValue) == displayValue

if !isInt {
if numString == "." {
if displayLabel.text!.contains(".") {
return
}
}
displayLabel.text = displayLabel.text! + numValue
displayLabel.text = displayLabel.text! + numString
}
}
}


@IBAction func clearPressed(_ sender: UIButton) {
// resets errrerything
calculator.reset()
isFinishedTypingNumber = true
displayLabel.text = "0"
}

}

124 changes: 79 additions & 45 deletions Calculator/Model/CalculatorLogic.swift
Original file line number Diff line number Diff line change
@@ -1,61 +1,95 @@
//
// CalculatorLogic.swift
// Calculator
//
// Created by Angela Yu on 18/09/2019.
// Copyright © 2019 London App Brewery. All rights reserved.
//

import Foundation

struct CalculatorLogic {

private var number: Double?
var totalValue: Double?
private var storedValue: Double?
private var storedOp: String?
private var storedOpForReturn: String?
var inputValue: Double = 0

private var intermediateCalculation: (n1: Double, calcMethod: String)?
var operatorLastTouched: Bool = false
var percentHasBeenUsed: Bool = false

mutating func setNumber(_ number: Double) {
self.number = number
mutating func reset() {
totalValue = nil
storedValue = nil
storedOp = nil
inputValue = 0
operatorLastTouched = false
percentHasBeenUsed = false
}

mutating func calculate(symbol: String) -> Double? {

if let n = number {
switch symbol {
case "+/-":
return n * -1
case "AC":
return 0
case "%":
return n * 0.01
case "=":
return performTwoNumCalculation(n2: n)
default:
intermediateCalculation = (n1: n, calcMethod: symbol)
}
mutating func math(passOp: String, inputOrStoredValue: Double) {
switch passOp {
case "÷":
totalValue = totalValue! / inputOrStoredValue
case "×":
totalValue = totalValue! * inputOrStoredValue
case "-":
totalValue = totalValue! - inputOrStoredValue
case "+":
totalValue = totalValue! + inputOrStoredValue
case "=":
return
default:
return
}
return nil
}

private func performTwoNumCalculation(n2: Double) -> Double? {

if let n1 = intermediateCalculation?.n1,
let operation = intermediateCalculation?.calcMethod {

switch operation {
case "+":
return n1 + n2
case "-":
return n1 - n2
case "×":
return n1 * n2
case "÷":
return n1 / n2
default:
fatalError("The operation passed in does not match any of the cases.")
mutating func calculate(operation: String) {
// when user clicks an operate button the first time
// 12 +
if totalValue == nil {
totalValue = inputValue
storedOp = operation
inputValue = 0
return
}
// following should only go through if the SAME op is pressed twice in a row.
if operatorLastTouched {
if storedOp == operation {
if storedOp == "=" {
math(passOp: storedOpForReturn!, inputOrStoredValue: storedValue!)
} else {
math(passOp: operation, inputOrStoredValue: storedValue!)
}
} else {
return
}
} else {
operatorLastTouched = true
// stores the current input value and operation in case the user
// wants to repeat the Operation.
math(passOp: storedOp!, inputOrStoredValue: inputValue)
if operation == "=" {
storedOpForReturn = storedOp
storedOp = operation
} else {
storedOp = operation
}
storedValue = inputValue
}
return nil

}

mutating func otherOps(operation: String) {
// having this in the same function as the math makes a conflict
// with "operatorLastTouched" so you can't use this
// after you hit an operator.
// (like if you hit divide when you meant to hit percent)
// keeping it separated solves this issue
switch operation {
case "+/-":
totalValue = totalValue! * -1
case "%" :
if percentHasBeenUsed {
return
}
totalValue = inputValue * 0.01
percentHasBeenUsed = true
default:
return
}
}
}
10 changes: 4 additions & 6 deletions Calculator/View/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ey4-0b-agg">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ey4-0b-agg">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
Expand Down Expand Up @@ -49,7 +47,7 @@
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<connections>
<action selector="calcButtonPressed:" destination="ey4-0b-agg" eventType="touchUpInside" id="V8L-uc-4VH"/>
<action selector="clearPressed:" destination="ey4-0b-agg" eventType="touchUpInside" id="Icn-wV-Vcm"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9KY-Qg-57t">
Expand Down