Stanford CS193P Assignment 1 Calculator Solution
I got to be honest, this Stanford CS193P RPN Calculator Assignment is not exciting me one bit. I am working through it to understand the basics, and I’ve completed it without the Extra Credit. I’m also not sure about part 6, since my calculator says “inf” if I divide by 0 already, so I’m not sure what else I need to do.
Anyways, here is my solution to at least the “meat” of this assignment:
CalculatorViewController.h
// // CalculatorViewController.h // Calculator // // Created by Natalia Murashev on 12/4/11. // Copyright (c) 2011 Holler. All rights reserved. // #import <UIKit/UIKit.h> @interface CalculatorViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *display; @property (weak, nonatomic) IBOutlet UILabel *history; @end
CalculatorViewController.m
// // CalculatorViewController.m // Calculator // // Created by Natalia Murashev on 12/4/11. // Copyright (c) 2011 Holler. All rights reserved. // #import "CalculatorViewController.h" #import "CalculatorBrain.h" @interface CalculatorViewController() @property (nonatomic) BOOL userIsInTheMiddleOfEnteringANumber; @property (nonatomic, strong) CalculatorBrain *brain; @property (nonatomic, strong) NSMutableArray *periodPressed; @end @implementation CalculatorViewController @synthesize display = _display; @synthesize history = _history; @synthesize userIsInTheMiddleOfEnteringANumber = _userIsInTheMiddleOfEnteringANumber; @synthesize brain = _brain; @synthesize periodPressed = _periodPressed; - (CalculatorBrain *) brain { if(!_brain) _brain = [[CalculatorBrain alloc] init]; return _brain; } - (NSMutableArray *) periodPressed { if(_periodPressed == nil)_periodPressed = [[NSMutableArray alloc] init]; return _periodPressed; } - (IBAction)digitPressed:(UIButton *)sender { NSString *digit = [sender currentTitle]; if(self.userIsInTheMiddleOfEnteringANumber) { //when the period is entered, it is stored in the periodPressed array. //if the user entered more than 1 period, it does not get added to the outlets if([digit isEqualToString:@"."]) { [self.periodPressed addObject:digit]; if([self.periodPressed count] == 1) { //adds the digit to the main calculator display self.display.text = [self.display.text stringByAppendingString:digit]; //adds the digit to the history display self.history.text = [self.history.text stringByAppendingString:digit]; } //when the user clicks on a digit (not a period), it is added to the outlets } else { self.display.text = [self.display.text stringByAppendingString:digit]; self.history.text = [self.history.text stringByAppendingString:digit]; } } //when the user is not in the middle of entering a number... else { //when a period is added first, it is added to the period pressed array if([digit isEqualToString:@"."]) { [self.periodPressed addObject:digit]; } //adds the initial digit to the main calculator display self.display.text = digit; //adds the digit to the history display if(self.history.text == nil) { self.history.text = digit; } else { self.history.text = [self.history.text stringByAppendingString:digit]; } self.userIsInTheMiddleOfEnteringANumber = YES; } } - (IBAction)enterPressed { [self.brain pushOperand:[self.display.text doubleValue]]; self.userIsInTheMiddleOfEnteringANumber = NO; [self.periodPressed removeAllObjects]; self.history.text = [self.history.text stringByAppendingString:@" "]; } - (IBAction)operationPressed:(UIButton *)sender { if(self.userIsInTheMiddleOfEnteringANumber) [self enterPressed]; double result = [self.brain performOperation:sender.currentTitle]; NSString *resultString = [NSString stringWithFormat:@"%g", result]; self.display.text = resultString; self.history.text = [self.history.text stringByAppendingString:sender.currentTitle]; self.history.text = [self.history.text stringByAppendingString:@" "]; } - (IBAction)clearPressed:(UIButton *)sender { self.userIsInTheMiddleOfEnteringANumber = NO; self.display.text = nil; self.history.text = nil; [self.periodPressed removeAllObjects]; self.brain = nil; } - (void)viewDidUnload { [self setHistory:nil]; [super viewDidUnload]; } @end
CalculatorBrain.h
// // CalculatorBrain.h // Calculator // // Created by Natalia Murashev on 12/4/11. // Copyright (c) 2011 Holler. All rights reserved. // #import <Foundation/Foundation.h> @interface CalculatorBrain : NSObject - (void)pushOperand:(double)operand; - (double)performOperation:(NSString *)operation; @end
CalculatorBrain.m
// // CalculatorBrain.m // Calculator // // Created by Natalia Murashev on 12/4/11. // Copyright (c) 2011 Holler. All rights reserved. // #import "CalculatorBrain.h" @interface CalculatorBrain() @property (nonatomic, strong) NSMutableArray *operandStack; @end @implementation CalculatorBrain @synthesize operandStack = _operandStack; - (NSMutableArray *)operandStack { if(_operandStack == nil) _operandStack = [[NSMutableArray alloc] init]; return _operandStack; } - (void)pushOperand:(double)operand { [self.operandStack addObject:[NSNumber numberWithDouble:operand]]; } - (double) popOperand { NSNumber *operandObject = [self.operandStack lastObject]; if(operandObject != nil) [self.operandStack removeLastObject]; return [operandObject doubleValue]; } - (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 ([operation isEqualToString:@"-"]) { double subtrahend = [self popOperand]; result = [self popOperand] - subtrahend; } else if ([operation isEqualToString:@"/"]) { double divisor = [self popOperand]; result = [self popOperand] / divisor; } else if([operation isEqualToString:@"sin"]) { result = sin([self popOperand]); } else if([operation isEqualToString:@"cos"]) { result = cos([self popOperand]); } else if([operation isEqualToString:@"sqrt"]) { result = sqrt([self popOperand]); } else if([operation isEqualToString:@"π"]) { result = M_PI; } else if([operation isEqualToString:@"log"]) { result = log([self popOperand]); } [self pushOperand:result]; return result; } @end