## cs193p – Project #2 Assignment #2 Task #9

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 #8

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

Modify the UILabel you added last week to show your CalculatorBrain’s description instead. It should put an = on the end of it (and be positioned strategically so that the display looks like it’s the result of that =). This = was Extra Credit last week, but it is required this week.

When setting the display value use the calculator-brain description for the history text (adding an equal sign).

```    var displayValue: Double? {
...
set {
...
history.text = brain.description + " ="
}
}
```

## cs193p – Project #2 Assignment #2 Task #7

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

Implement a new read-only (get only, no set) var to CalculatorBrain to describe the contents of the brain as a String …

`var description: String`
1. Unary operations should be shown using “function” notation. For example, the input 10 cos would display in the description as cos(10).
2. Binary operations should be shown using “infix” notation. For example, the input 3↲5 – should display as 3-5. Be sure to get the order correct!
3. All other stack contents (e.g. operands, variables, constants like π, etc.) should be displayed unadorned. For example, 23.5 ⇒ 23.5, π ⇒ π (not 3.1415!), the variable x ⇒ x (not its value!), etc.
4. Any combination of stack elements should be properly displayed. Examples:
10√3+ ⇒ √(10)+3
3↲5+√ ⇒ √(3+5)
3↲5↲4++ ⇒ 3+(5+4) or (for Extra Credit) 3+5+4
3↲5√+√6÷ ⇒ √(3+√(5))÷6
5. If there are any missing operands, substitute a ? for them, e.g. 3↲+ ⇒ ?+3.
6. If there are multiple complete expressions on the stack, separate them by commas: for example, 3↲5+√πcos ⇒ √(3+5),cos(π). The expressions should be in historical order with the oldest at the beginning of the string and the most recently pushed/performed at the end.
7. Your description must properly convey the mathematical expression. For example, 3↲5↲4+* must not output 3*5+4 — it must be 3*(5+4). In other words, you will need to sometimes add parentheses around binary operations. Having said that, try to minimize parentheses as much as you can (as long as the output is mathematically correct). See Extra Credit if you want to really do this well.

## cs193p – Project #2 Assignment #2 Task #6

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

The evaluate() function should use a variable’s value (from the variableValues dictionary) whenever a variable is encountered or return nil if it encounters a variable with no corresponding value.

… which actually means just return the dictionary entry from the variable values:

```    private func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op]) {
...
case .Variable(let symbol):
return (variableValues[symbol], remainingOps)
...
}
```

## cs193p – Project #2 Assignment #2 Task #5

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

Add the capability to your CalculatorBrain to allow the pushing of variables onto its internal stack. Do so by implementing the following API in your CalculatorBrain …

```      func pushOperand(symbol: String) -> Double?
var variableValues: Dictionary<String,Double>
```

These must do exactly what you would imagine they would: the first pushes a “variable” onto your brain’s internal stack (e.g. pushOperand(“x”) would push a variable named x) and the second lets users of the CalculatorBrain set the value for any variable they wish (e.g. brain.variableValues[“x”] = 35.0). pushOperand should return the result of evaluate() after having pushed the variable (just like the other pushOperand does).

Implementing the push method looks just like the existing one, the only difference is that we append a variable instead of an operand:

```    func pushOperand(symbol: String) -> Double? {
opStack.append(Op.Variable(symbol))
return evaluate()
}
```

## cs193p – Project #2 Assignment #2 Task #4

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

The extra credit item from last week to turn displayValue into a Double? (i.e, an Optional rather than a Double) is now required. displayValue should return nil whenever the contents of the display cannot be interpreted as a Double. Setting displayValue to nil should clear the display.

… done that, too. However, hint #1 asks to consider using optional chaining, which we did not up to now.

Assuming there is always a text string, and that we handle the internationalization problem elsewhere, we can reduce the getter of displayValue to a single line using optional chaining:

```return NSNumberFormatter().numberFromString(display.text!)?.doubleValue
```

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