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

Enhance your application to show the user error conditions like divide by zero, square root of a negative number, and insufficient operands. One way to do this (and to get more experience with using id) might be to have runProgram:usingVariableValues: in CalculatorBrain return an id (instead of a double) which is an NSNumber with the result or an NSString with the description of an error if it encounters one. Then update your Controller to use introspection on the return value and display the appropriate thing to the end-user.

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

Add an Undo button to your calculator. Hitting Undo when the user is in the middle of typing should take back the last digit or decimal point pressed until doing so would clear the display entirely at which point it should show the result of running the brain’s current program in the display (and now the user is clearly not in the middle of typing, so take care of that). Hitting Undo when the user is not in the middle of typing should remove the top item from the program stack in the brain and update the user- interface.

This task can be implemented with 1 method in your Controller (of about 5-6 lines of code, assuming you’ve factored out the updating of your user-interface into a single method somewhere) and 1 method (with 1 line of code) in your Model. If it’s taking much more than that, you might want to reconsider your approach.

The first part of this task has already been implemented in the previous assignment. So we have to adjust the backSpace method to achieve the rest. To receive the result of the last program when the last entry is cleared we just add

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

Update the user-interface of your Calculator to test all of the above.

a. Your UI should already have a UILabel which shows what has been sent to the brain. Change it to now always show the latest description of the program currently in the CalculatorBrain using your descriptionOfProgram:method. It should show the description without substituting variable values (obviously, since descriptionOfProgram: does not take a variable value dictionary as an argument).
b. Add a few variable buttons (e.g, x, y, foo). These are buttons that push a variable into the CalculatorBrain.
c. Change your calculator to update its display (as needed) by calling your new runProgram:usingVariableValues: method. The variable values dictionary it passes to this method should be a property in your Controller (let’s call it “testVariableValues”).
d. Add a UILabel to your UI whose contents are determined by iterating through all the variablesUsedInProgram: and displaying each with its current value from testVariableValues. Example display: “x = 5 y = 4.8 foo = 0”.
e. Add a few different “test” buttons which set testVariableValues to some preset testing values. One of them should set testVariableValues to nil. Don’t forget to update the rest of your UI when you change testVariableValues by pressing one of these test buttons. Make sure that your preset values are good edge-cases for testing (we are intentionally not telling you what to use since part of good programming is figuring out how to thoroughly test your application).

To solve #a just remove all occurrences of code where you have manipulated the history label from CalculatorViewControler.m and replace it by

As you can see, you will have to use parentheses in your output to correctly display the program. For example, 3 E 5 + 6 * is not 3 + 5 * 6, it is (3 + 5) * 6. Try to keep extraneous parentheses to a minimum though (see Hints).

It might be that there are multiple things on the stack. If so, separate them by commas in the output with the top of the stack first, for example 3 E 5 E would display as “5, 3”. 3 E 5 + 6 E 7 * 9 sqrt would be “sqrt(9), 6 * 7, 3 + 5”.

Analog to the runProgram method we first have to check if we actually have a valid program. We use call descriptionOfTopOfStack which will work through the stack like popOperandOffStack already does. If after that there is something still on the stack we call descriptionOfProgram for the rest. To beautify the result we call stripUnneccessaryParenthesis.Continue reading “Assignment #2 Task #2”

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

The second assignment is a further extension of the calculator built in the previous assignment.

Add the capability to your CalculatorBrain to accept variables as operands (in addition to still accepting doubles as operands). You will need new public API in your CalculatorBrain to support this.

A variable will be specified as an NSString object. To simplify your implementation, you can ignore attempts to push a variable whose name is the same as an operation (e.g. you can ignore an attempt to push a variable named “sqrt”).

The values of the variables will only be supplied when the “program” is “run.” You must add a new version of the runProgram: class method with the following signature …

The keys in the passed variableValues dictionary are NSString objects corresponding to the names of variables used in the passed program, and the values in the dictionary are NSNumber objects specifying the value of the corresponding variable (for this assignment we will supply “test” values, see Required Task #3).

If there are variables in the specified program for which there are no values in the specified NSDictionary, use a value of 0 for those variables when you run the program. This should be the case if someone calls the original runProgram: method (the one shown in the demo in class).
In addition, create another class method to get all the names of the variables used in a given program (returned as an NSSet of NSString objects) …

+ (NSSet *)variablesUsedInProgram:(id)program;

If the program has no variables return nil from this method (not an empty set).

We will start by implementing the new runProgram method. If we have an actual program meaning array we loop through the program and replace variables by its values and finally run the cleaned up program:Continue reading “Assignment #2 Task #1”