I am following the Stanford iOS 8 lectures and I believe I have successfully added the "Clear" functionality to the application, but I don't know if I am doing it properly.
Controller
import UIKit
class ViewController: UIViewController
{
@IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTypingANumber = false
var brain = CalculatorBrain()
var displayValue: Double
{
get
{
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set
{
display.text = "\(newValue)"
userIsInTheMiddleOfTypingANumber = false
}
}
@IBAction func appendDigit(sender: UIButton)
{
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber
{
display.text = display.text! + digit
}
else
{
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}
}
@IBAction func enter()
{
userIsInTheMiddleOfTypingANumber = false
if let result = brain.pushOperand(displayValue){ displayValue = result }
else {displayValue = 0}
}
@IBAction func operate(sender: UIButton)
{
if userIsInTheMiddleOfTypingANumber{ enter() }
if let operation = sender.currentTitle
{
if let result = brain.performOperation(operation) {displayValue = result}
else {displayValue = 0}
}
}
// Linked to the "C" button in the Storyboard
@IBAction func clear()
{
userIsInTheMiddleOfTypingANumber = false
brain.clear()
displayValue = 0
}
Model
import Foundation
class CalculatorBrain
{
private enum Op: Printable
{
case Operand(Double)
case UnaryOperation(String, Double -> Double)
case BinaryOperation(String, (Double, Double) -> Double)
var description: String
{
get
{
switch self
{
case .Operand(let operand): return "\(operand)"
case .UnaryOperation(let symbol, _): return symbol
case .BinaryOperation(let symbol, _): return symbol
}
}
}
}
private var opStack = [Op]()
private var knownOps = [String: Op]()
init()
{
knownOps["×"] = Op.BinaryOperation("×", *)
knownOps["÷"] = Op.BinaryOperation("÷") { $1 / $0 }
knownOps["+"] = Op.BinaryOperation("+", +)
knownOps["−"] = Op.BinaryOperation("−") { $1 - $0 }
knownOps["√"] = Op.UnaryOperation("√", sqrt)
}
private func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op])
{
if !ops.isEmpty {
var remainingOps = ops
let op = remainingOps.removeLast()
switch op {
case .Operand(let operand):
return (operand, remainingOps)
case .UnaryOperation(_, let operation):
let operandEvaluation = evaluate(remainingOps)
if let operand = operandEvaluation.result
{
return (operation(operand), operandEvaluation.remainingOps)
}
case .BinaryOperation(_, let operation):
let op1Evaluation = evaluate(remainingOps)
if let operand1 = op1Evaluation.result
{
let op2Evaluation = evaluate(op1Evaluation.remainingOps)
if let operand2 = op2Evaluation.result
{
return (operation(operand1, operand2), op2Evaluation.remainingOps)
}
}
}
}
return (nil, ops)
}
func evaluate() -> Double?
{
let (result, remainder) = evaluate(opStack)
println("\(opStack) = \(result) with \(remainder) left over")
return result
}
func pushOperand(operand: Double) -> Double?
{
opStack.append(Op.Operand(operand))
return evaluate()
}
func performOperation(symbol: String) -> Double?
{
if let operation = knownOps[symbol] { opStack.append(operation) }
return evaluate()
}
func clear()
{
opStack = [Op]()
evaluate()
}
}
And my log output is:
[8.0] = Optional(8.0) with [] left over [8.0, 9.0] = Optional(9.0) with [8.0] left over [8.0, 9.0, ×] = Optional(72.0) with [] left over [8.0, 9.0, ×, 2.0] = Optional(2.0) with [8.0, 9.0, ×] left over [8.0, 9.0, ×, 2.0, −] = Optional(70.0) with [] left over [8.0, 9.0, ×, 2.0, −, 5.0] = Optional(5.0) with [8.0, 9.0, ×, 2.0, −] left over [8.0, 9.0, ×, 2.0, −, 5.0, ÷] = Optional(14.0) with [] left over [] = nil with [] left over
I am pretty sure the last line in the log output is correct. Basically I was just hoping someone with more iOS/MVC experience could tell me whether or not I implemented the clear
functionality correctly. If I didn't, how might I go about fixing my code?
clear
functions in the Model and the Controller. Everything else was provided in the lecture demo from Stanford. \$\endgroup\$