cs193p – Assignment #2 Task #7

cs193p-assignment-2-task-7-winter-2017

Add two new buttons to your Calculator’s UI: →M and M. Don’t sacrifice any of the required operation buttons from Assignment 1 to add these (though you may add yet more operations buttons if you want). These two buttons will set and get (respectively) a variable in the CalculatorBrain called M.
a. →M calls evaluate in your Model with a Dictionary which has a single entry whose key is M and whose value is the current value of the display, and then updates the display to show the result that comes back from evaluate. Until this button (or the clear button) is pressed again, this same Dictionary should be used every time evaluate is called.
b. →M does not perform setOperand.
c. Touching M should setOperand(variable: “M”) in the brain and then show the
result of calling evaluate in the display.
d. →M and M are Controller mechanics, not Model mechanics (though they both use
the Model mechanic of variables).
e. This is not a very great “memory” button on our Calculator, but it can be used for testing whether our variable function implemented in our Model is working properly. Examples …
9 + M = √ ⇒ description is √(9+M), display is 3 because M is not set (thus 0.0).
7 →M ⇒ display now shows 4 (the square root of 16), description is still √(9+M) + 14 = ⇒ display now shows 18, description is now √(9+M)+14

Start by adding the two new buttons:
cs193p-assignment-2-task-7-winter-2017-storyboard

Though this actually a view-controller task, I had a tiny bug in the last task – so change the brain to show the symbol of the variable as description:

    func evaluate(using variables: Dictionary<String,Double>? = nil)
        -> (result: Double?, isPending: Bool, description: String)
    {
                ...
            case .variable(let symbol):
                if let value = variables?[symbol] {
                    accumulator = (value, symbol)
                } else {
                    accumulator = (0, symbol)
                }
            ...
    }

We need something to store the variables:

    private var variables = Dictionary<String,Double>()

Currently show the result of the calculation only from the perform-operation method. Because we will need to do this in different places move that part of the code into a new private method. Don’t forget to use the variables now for the evaluation:

    private func displayResult() {
        let evaluated = brain.evaluate(using: variables)        
        if let result = evaluated.result {
            displayValue = result
        }        
        if "" != evaluated.description {
            descriptionDisplay.text = evaluated.description.beautifyNumbers() + (evaluated.isPending ? "…" : "=")
        } else {
            descriptionDisplay.text = " "
        }
    }

    @IBAction func performOperation(_ sender: UIButton) {
        ...
        displayResult()
    }

Now link the two (or four) new buttons to two new actions. One time we just set the variable value in the view controller, the other time we push it to the calculator brain. Both times we update the display – and tell the controller, that the user is not in the middle of typing any more:

    @IBAction func storeToMemory(_ sender: UIButton) {
        variables["M"] = displayValue
        userIsInTheMiddleOfTyping = false
        displayResult()
     }
    
    @IBAction func callMemory(_ sender: UIButton) {
        brain.setOperand(variable: "M")
        userIsInTheMiddleOfTyping = false
        displayResult()
    }

It is actually task 9 but it makes testing a little bit easier:

    @IBAction func reset(_ sender: UIButton) {
        ...
        variables = Dictionary<String,Double>()
    }

The complete code for the assignment #2 task #7 is available on GitHub.

FacebooktwitterredditpinterestlinkedintumblrmailFacebooktwitterredditpinterestlinkedintumblrmail

Leave a Reply

Your email address will not be published.