# cs193p – Project #2 Assignment #2 Extra Task #1 Please note, this blog entry is from a previous course. You might want to check out the current one.

Make your description have as few parentheses as possible for binary operations.

Add a new computed variable to the Op enum, which returns by the default the maximum integer value and for binary operations the value you set when defining the operation:

[swift]
private enum Op: Printable
{

case BinaryOperation(String, Int, (Double, Double) -> Double)

var precedence: Int {
get {
switch self {
case .BinaryOperation(_, let precedence, _):
return precedence
default:
return Int.max
}
}
}
}
[/swift]

For multiplications and divisions set the value to “2” and for additions and subtractions to “1”:

[swift]
init() {

learnOp(Op.BinaryOperation("×", 2, *))
learnOp(Op.BinaryOperation("÷", 2, { \$1 / \$0 }))
learnOp(Op.BinaryOperation("+", 1, +))
learnOp(Op.BinaryOperation("−", 1, { \$1 – \$0 }))

}
[/swift]

The API of the recursive description method gets an additional return variable holding the precedence of the current operation. For binary operations check if the current precedence is higher than the one from the previous operation. If yes, add brackets. Do the same for unary operations – even it is not required, it looks nicer 😉

[swift]
private func description(ops: [Op]) -> (result: String?, remainingOps: [Op], precedence: Int?) {

case .Operand(let operand):
return (String(format: "%g", operand) , remainingOps, op.precedence)
case .NullaryOperation(let symbol, _):
return (symbol, remainingOps, op.precedence);
case .UnaryOperation(let symbol, _):
let operandEvaluation = description(remainingOps)
if var operand = operandEvaluation.result {
if op.precedence > operandEvaluation.precedence {
operand = "(\(operand))"
}
return ("\(symbol)\(operand)", operandEvaluation.remainingOps, op.precedence)
}
case .BinaryOperation(let symbol, _, _):
let op1Evaluation = description(remainingOps)
if var operand1 = op1Evaluation.result {
if op.precedence > op1Evaluation.precedence {
operand1 = "(\(operand1))"
}
let op2Evaluation = description(op1Evaluation.remainingOps)
if let operand2 = op2Evaluation.result {
if op.precedence > op2Evaluation.precedence {
operand2 = "(\(operand2))"
}
return ("\(operand2) \(symbol) \(operand1)",
op2Evaluation.remainingOps, op.precedence)
}
}
case .Variable(let symbol):
return (symbol, remainingOps, op.precedence)
}
}
return ("?", ops, Int.max)
}
[/swift]

Update: I forgot to check the second operand above, its corrected now …

The description method can ignore the additional return value:

[swift]
var description: String {

(current, ops, _) = description(ops)

}
[/swift]

The evaluation method needs also a tiny adjustment (just tell it to ignore the additional parameter for binary operations) to cope with the adjusted enum:

[swift]
private func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op]) {

case .BinaryOperation(_, _, let operation):

}
[/swift]

The missing brackets break our test cases, therefore we need to test for the “new” expected results:

[swift]
func testDescription() {

XCTAssertEqual(brain.description, "cos10")

XCTAssertEqual(brain.description, "√10 + 3")

XCTAssertEqual(brain.description, "3 + 5 + 4")

XCTAssertEqual(brain.description, "√(3 + √5) ÷ 6")

XCTAssertEqual(brain.description, "√(3 + 5), cosπ")

}
[/swift]

The complete code for extra task #1 is available on GitHub.

## 7 thoughts on “cs193p – Project #2 Assignment #2 Extra Task #1”

1. mamazur says:

Could you please tell me why you chose that
return (String(format: “%g”, operand) , remainingOps, op.precedence)
return (“\(operand)” , remainingOps, op.precedence)

Thank you

2. mamazur says:

Thank you

By the way what if you put
3
enter
6
enter
9
*
+
or
3
enter
6
+
9
*

I don’t know…

Thank you for quick answer and amazing code work

3. abdo says:

Update: I forgot to check the second operand above, its corrected now …

the update is only on the blog, please update github too 😀

4. wb says:

Hi, I think there is an error in the algorithm. If the user types in “1 1 1 + -“, it shows 1-1+1 instead of 1-(1+1).