cs193p – Project #2 Assignment #2 Task #9

By NJR ZA (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0) or GFDL (http://www.gnu.org/copyleft/fdl.html)], via Wikimedia Commons

Please note, this blog entry is from a previous course. You might want to check out the current one.

Add two new buttons to your Calculator’s keypad: →M and M. These 2 buttons will set and get (respectively) a variable in the CalculatorBrain called M.

  1. →M sets the value of the variable M in the brain to the current value of the display (if any)
  2. →M should not perform an automatic ↲ (though it should reset “user is in the middle of typing a number”)
  3. Touching M should push an M variable (not the value of M) onto the CalculatorBrain
  4. Touching either button should show the evaluation of the brain (i.e. the result of evaluate()) in the display
  5. →M and M are Controller mechanics, not Model mechanics (though they both use the Model mechanic of variables).
  6. This is not a very great “memory” button on our Calculator, but it’s good for testing whether our variable function implemented above is working properly. Examples …
    7 M + √ ⇒ description is √(7+M), display is blank because M is not set
    9 →M ⇒ display now shows 4 (the square root of 16), description is still √(7+M)
    14 + ⇒ display now shows 18, description is now √(7+M)+14

Rename the two remaining blank buttons in storyboard and link them to actions in the view controller:

cs193p - Project #2 Assignment #2 Task #9 - Memory Buttons
cs193p – Project #2 Assignment #2 Task #9 – Memory Buttons


To keep the actions generic extract the last character from the button title (“M”), and if there is a valid value store it in the variable values of the calculator brain. Evaluate the brain and finally reset “user is in the middle of typing a number”.

    @IBAction func storeVariable(sender: UIButton) {
        if let variable = last(sender.currentTitle!) {
            if displayValue != nil {
                brain.variableValues["\(variable)"] = displayValue
                if let result = brain.evaluate() {
                    displayValue = result
                } else {
                    displayValue = nil
                }
            }
        }
        userIsInTheMiddleOfTypingANumber = false
    }

Before pushing the variable, check if the “user is in the middle of typing a number” and push that number if necessary – note this is an implicit requirement provided by the examples of item f above.

Then push the variable – like above we get the variable name from the button title – and set its result:

    @IBAction func pushVariable(sender: UIButton) {
        if userIsInTheMiddleOfTypingANumber {
            enter()
        }
        if let result = brain.pushOperand(sender.currentTitle!) {
            displayValue = result
        } else {
            displayValue = nil
        }
    }

Two additional minor changes remain. Before we displayed “0” if nothing has happened yet, or a result does not compute. Change that to to display a space character, once in viewDidLoad and once in the setter of the display value:

display.text = " "

The complete code for the task #9 is available on GitHub.

FacebooktwitterredditpinterestlinkedintumblrmailFacebooktwitterredditpinterestlinkedintumblrmail

5 thoughts on “cs193p – Project #2 Assignment #2 Task #9”

  1. Can I just set function storeVariable as below?
    @IBAction func storeVariable(sender: UIButton) {
    if displayValue != nil {
    brain.variableValues["M"] = displayValue
    if let result = brain.evaluate() {
    displayValue = result
    } else {
    displayValue = nil
    }
    }
    userIsInTheMiddleOfTypingANumber = false
    }

    1. Of course, but then you would have the magic constant “M” in your code … what if you want to change it “A”, or add additional variables “B” and “C” … ?

  2. Since displayValue is an Optional there is no need to unwrap the result from evaluate() before assigning it to displayValue. Just write: displayValue = brain.evaluate()

  3. If you’re using Swift 2.0, you’ll need to replace the above line:
    if let variable = last(sender.currentTitle!) {

    with:
    if let variable = sender.currentTitle!.characters.last {

    or it won’t work.

    @Martin Mandl: Huge thanks for all your help, btw…

Leave a Reply

Your email address will not be published.