1. Jay Yu
  2. CS193P Assignment 1

Commits

Jay Yu  committed da50ce9

work in progress: assignment 2 descriptionOfProgram

  • Participants
  • Parent commits c8a2a3a
  • Branches default

Comments (0)

Files changed (4)

File Calculator.xcodeproj/project.xcworkspace/xcuserdata/jay.xcuserdatad/UserInterfaceState.xcuserstate

  • Ignore whitespace
Binary file modified.

File Calculator/CalculatorBrain.h

View file
  • Ignore whitespace
 - (double)performOperation:(NSString *)operation;
 - (void)clearStates;
 
+@property (readonly) id program;
+
++ (double)runProgram:(id)program;
++ (NSString *)descriptionOfProgram:(id)program;
+
 @end

File Calculator/CalculatorBrain.m

View file
  • Ignore whitespace
 #import "math.h"
 
 @interface  CalculatorBrain()
-@property (nonatomic, strong) NSMutableArray *operandStack;
+@property (nonatomic, strong) NSMutableArray *programStack;
 @end
 
 @implementation CalculatorBrain
 
-@synthesize operandStack = _operandStack;
+@synthesize programStack = _programStack;
 
-- (NSMutableArray *)operandStack
+- (NSMutableArray *)programStack
 {
-    if (!_operandStack) {
-        _operandStack = [[NSMutableArray alloc] init];
+    if (!_programStack) {
+        _programStack = [[NSMutableArray alloc] init];
     }
-    return _operandStack;
+    return _programStack;
 }
 
 - (void)pushOperand:(double)operand
 {
     NSNumber *operandObject = [NSNumber numberWithDouble:operand];
-    [self.operandStack addObject:operandObject];
-}
-
-- (double)popOperand
-{
-    NSNumber *operandObject = [self.operandStack lastObject];
-    if (operandObject) {
-        [self.operandStack removeLastObject];
-    }
-    return [operandObject doubleValue];
+    [self.programStack addObject:operandObject];
 }
 
 - (double)performOperation:(NSString *)operation
 {
-    double result = 0;
-    
-    if ([operation isEqualToString:@"+"]) {
-        result = [self popOperand] + [self popOperand];
-    } else if ([@"*" isEqualToString:operation]) {
-        result = [self popOperand] * [self popOperand];
-    } else if ([@"-" isEqualToString:operation]) {
-        double subtrahend = [self popOperand];
-        result = [self popOperand] - subtrahend;
-    } else if ([@"/" isEqualToString:operation]) {
-        double divisor = [self popOperand];
-        if (divisor) {
-            result = [self popOperand] / divisor;            
-        }
-    } else if ([@"sin" isEqualToString:operation]) {
-        result = sin([self popOperand]);
-    } else if ([@"cos" isEqualToString:operation]) {
-        result = cos([self popOperand]);
-    } else if ([@"sqrt" isEqualToString:operation]) {
-        result = sqrt([self popOperand]);
-    } else if ([@"π" isEqualToString:operation]) {
-        result = M_PI;
-    } else if ([@"+/-" isEqualToString:operation]) {
-        result = [self popOperand] * -1;
-    }
-
-    [self pushOperand:result];
-    
-    return result;
+    [self.programStack addObject:operation];
+    return [CalculatorBrain runProgram:self.program];
 }
 
 - (void)clearStates
 {
-    [self.operandStack removeAllObjects];
+    [self.programStack removeAllObjects];
+}
+
+- (id)program
+{
+    return [self.programStack copy];
+}
+
++ (double)runProgram:(id)program
+{
+    NSMutableArray *stack;
+    if ([program isKindOfClass:[NSArray class]]) {
+        stack = [program mutableCopy];
+    }
+    return [self popOperandOffStack:stack];
+}
+
++ (NSString *)descriptionOfProgram:(id)program
+{
+    NSMutableArray *stack;
+    if ([program isKindOfClass:[NSArray class]]) {
+        stack = [program mutableCopy];
+    }
+    return [self programStringOffStack:stack];
+
+}
+
++ (NSString *)programStringOffStack:(NSMutableArray *)stack
+{
+    NSString *result = nil;
+    id topOfStack = [stack lastObject];
+    if (topOfStack) {
+        [stack removeLastObject];
+    }
+
+    if ([topOfStack isKindOfClass:[NSNumber class]]) {
+        result = [NSString stringWithFormat:@"%g", [topOfStack doubleValue]];
+
+    } else if ([topOfStack isKindOfClass:[NSString class]]) {
+        NSString *operation = topOfStack;
+        if ([operation isEqualToString:@"+"]) {
+            result = [NSString stringWithFormat:@"(%g + %g)", [self programStringOffStack:stack], [self programStringOffStack:stack]];
+        } else if ([@"*" isEqualToString:operation]) {
+            result = [NSString stringWithFormat:@"(%g * %g)", [self programStringOffStack:stack], [self programStringOffStack:stack]];
+        } else if ([@"-" isEqualToString:operation]) {
+            double subtrahend = [self programStringOffStack:stack];
+            result = [self popOperandOffStack:stack] - subtrahend;
+        } else if ([@"/" isEqualToString:operation]) {
+            double divisor = [self popOperandOffStack:stack];
+            if (divisor) {
+                result = [self popOperandOffStack:stack] / divisor;
+            }
+        } else if ([@"sin" isEqualToString:operation]) {
+            result = sin([self popOperandOffStack:stack]);
+        } else if ([@"cos" isEqualToString:operation]) {
+            result = cos([self popOperandOffStack:stack]);
+        } else if ([@"sqrt" isEqualToString:operation]) {
+            double operand = [self popOperandOffStack:stack];
+            if (operand < 0) {
+                result = 0;
+            } else {
+                result = sqrt(operand);
+            }
+        } else if ([@"π" isEqualToString:operation]) {
+            result = M_PI;
+        } else if ([@"+/-" isEqualToString:operation]) {
+            result = [self popOperandOffStack:stack];
+            if (result != 0) {
+                result = result * -1;
+            }
+        }
+    }
+    return result;
+
+}
+
++ (double)popOperandOffStack:(NSMutableArray *)stack
+{
+    double result = 0;
+    id topOfStack = [stack lastObject];
+    if (topOfStack) {
+        [stack removeLastObject];
+    }
+
+    if ([topOfStack isKindOfClass:[NSNumber class]]) {
+        result = [topOfStack doubleValue];
+    } else if ([topOfStack isKindOfClass:[NSString class]]) {
+        NSString *operation = topOfStack;
+        if ([operation isEqualToString:@"+"]) {
+            result = [self popOperandOffStack:stack] + [self popOperandOffStack:stack];
+        } else if ([@"*" isEqualToString:operation]) {
+            result = [self popOperandOffStack:stack] * [self popOperandOffStack:stack];
+        } else if ([@"-" isEqualToString:operation]) {
+            double subtrahend = [self popOperandOffStack:stack];
+            result = [self popOperandOffStack:stack] - subtrahend;
+        } else if ([@"/" isEqualToString:operation]) {
+            double divisor = [self popOperandOffStack:stack];
+            if (divisor) {
+                result = [self popOperandOffStack:stack] / divisor;
+            }
+        } else if ([@"sin" isEqualToString:operation]) {
+            result = sin([self popOperandOffStack:stack]);
+        } else if ([@"cos" isEqualToString:operation]) {
+            result = cos([self popOperandOffStack:stack]);
+        } else if ([@"sqrt" isEqualToString:operation]) {
+            double operand = [self popOperandOffStack:stack];
+            if (operand < 0) {
+                result = 0;
+            } else {
+                result = sqrt(operand);
+            }
+        } else if ([@"π" isEqualToString:operation]) {
+            result = M_PI;
+        } else if ([@"+/-" isEqualToString:operation]) {
+            result = [self popOperandOffStack:stack];
+            if (result != 0) {
+                result = result * -1;
+            }
+        }
+    }
+    return result;
 }
 
 @end

File Calculator/CalculatorViewController.m

View file
  • Ignore whitespace
     if (! self.history.text) {
         self.history.text = @"";
     } else {
-        self.history.text = [self.history.text stringByAppendingString:@" "];        
+        self.history.text = [self.history.text stringByAppendingString:@" "];
     }
 
     if ([aString isEqualToString:@"="]) {
     if (length >= limit) {
         self.history.text = [self.history.text substringFromIndex:length - limit];
     }
-    
+
 }
 
 - (IBAction)digitPressed:(UIButton *)sender
 {
     NSString *digit = [sender currentTitle];
     if ([digit isEqualToString:@"."]) {
-        if (! self.userIsInTheMiddleOfEnteringANumber) {
+        // handle special case for decimal point
+        if (self.userIsInTheMiddleOfEnteringANumber) {
+            NSRange range = [self.display.text rangeOfString:@"."];
+            if (range.location == NSNotFound) {
+                self.display.text = [self.display.text stringByAppendingString:digit];
+            }
+        } else {
             // shortcut for user: start entering an operand with "." will
             // automatically enter "0."
             self.display.text = @"0.";
             self.userIsInTheMiddleOfEnteringANumber = YES;
-            return;
         }
-
-        NSRange range = [self.display.text rangeOfString:@"."];
-        if (range.location == NSNotFound) {
+    } else {
+        if (self.userIsInTheMiddleOfEnteringANumber) {
             self.display.text = [self.display.text stringByAppendingString:digit];
         } else {
-            return;
-        }
-    }
-
-    if (self.userIsInTheMiddleOfEnteringANumber) {
-        self.display.text = [self.display.text stringByAppendingString:digit];            
-    } else {
-        self.display.text = digit;
-        if (! [digit isEqualToString:@"0"]) {
-            self.userIsInTheMiddleOfEnteringANumber = YES;
+            self.display.text = digit;
+            if (! [digit isEqualToString:@"0"]) {
+                self.userIsInTheMiddleOfEnteringANumber = YES;
+            }
         }
     }
 }
     double result = [self.brain performOperation:operation];
     [self appendHistory:operation];
     self.display.text = [NSString stringWithFormat:@"%g", result];
-    
+
     [self appendHistory:@"="];
 }
 
 
 - (IBAction)invertSignPressed
 {
+    double result = 0;
     if (self.userIsInTheMiddleOfEnteringANumber) {
-        double result = [self.display.text doubleValue] * -1;
+        // modify in-place the number currently in the display.
+        result = [self.display.text doubleValue];
+        if (result != 0) {
+            result = result * -1;
+        }
         self.display.text = [NSString stringWithFormat:@"%g", result];
     } else {
         // implement +/- as an operation
-        // FIXME: reduce duplicate code in here and operationPressed
-        if (self.userIsInTheMiddleOfEnteringANumber) {
-            [self enterPressed];
-        }
-        NSString *operation = @"+/-";
-        double result = [self.brain performOperation:operation];
-        self.display.text = [NSString stringWithFormat:@"%g", result];        
+        [self.brain performOperation:@"+/-"];
     }
 }