Stanford CS193P Initial Calculator Code

So I completed the Calculator Code from Stanford CS193P Lecture 2, and got my Calculator to work correctly, only to accidentally delete it from my computer. I then had to re-write the whole code. I also found the RPN Calculator to be a little confusing, and had a hard time getting to work properly at times.

I am therefore posting the initial code for it here. And I’ll post the add-ons as I go through CS193P Assignment 1.

So here is the code…

CalculatorViewController.h

#import <UIKit/UIKit.h>

@interface CalculatorViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *display;

@end

CalculatorViewController.m

#import "CalculatorViewController.h"
#import "CalculatorBrain.h"

@interface CalculatorViewController()
@property (nonatomic) BOOL userIsInTheMiddleOfEnteringANumber;
@property (nonatomic, strong) CalculatorBrain *brain;
@end

@implementation CalculatorViewController

@synthesize display = _display;
@synthesize userIsInTheMiddleOfEnteringANumber = _userIsInTheMiddleOfEnteringANumber;
@synthesize brain = _brain;

- (CalculatorBrain *) brain
{
    if(!_brain) _brain = [[CalculatorBrain alloc] init];
    return _brain;
}

- (IBAction)digitPressed:(UIButton *)sender 
{
    NSString *digit = [sender currentTitle];
    if(self.userIsInTheMiddleOfEnteringANumber) {
     self.display.text = [self.display.text stringByAppendingString:digit];   
    }
    else {
        self.display.text = digit;
        self.userIsInTheMiddleOfEnteringANumber = YES;
    }
    
        
}

- (IBAction)enterPressed 
{
    [self.brain pushOperand:[self.display.text doubleValue]];
    self.userIsInTheMiddleOfEnteringANumber = NO;
}

- (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;
}


@end

CalculatorBrain.h

#import <Foundation/Foundation.h>

@interface CalculatorBrain : NSObject

- (void)pushOperand:(double)operand;
- (double)performOperation:(NSString *)operation;

@end

CalculatorBrain.m

#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;
    }
    
    [self pushOperand:result];
    
    return result;
}


@end

Enjoy the article? Join over 17,500+ Swift developers and enthusiasts who get my weekly updates.

  • Purple

    I copy&pasted to my calculator project

    It runs but when I click enter button, app crashes. is it correct code?

  • Purple

    I revised and it works great…. never mind thanks a lot. It was problem of storyboard

    • Glad to hear it’s working!

    • Mxims

      Hey Purple,

      I am also getting my code crashed when press the enter button.. How did you fix yours?

    • hey purple, what was wrong with the storyboard?
      i have the same problem (looks like alot of people do).

      • Hey Mxims & Juliussky,
        – On your storyboard, DELETE the existing “Enter”.
        – Then drag a NEW “Round Rect Button”
        – Double Click button and name it as “Enter”
        – Hold down “Control” button on your keyboard, select new “Enter” button and drag to your CalcutorViewController.m file.
        – Enter name “enterPressed”, change Argument to “None”
        – Then Connect [PS: Compiler will prompt you, “Duplicate action names” ]
        – DELETE old/existing action, “enterPressed”, then copy&paste code (below) in your new enterPressed action:
        ————————————————————————-
        [self.brain pushOperand:[self.display.text doubleValue]];
        self.userIsInTheMiddleOfEnteringANumber = NO;
        ————————————————————————-
        – Then Run your code again.

  • Luke

    Hello, thanks for the code.

    I have a doubt, can you answer why the pop operand method has no interface declared?
    Every method public or not needs an interface. How it is working without it?

    • Hey Luke,

      Unfortunately, I can’t answer your question. I had a very hard time understanding this class, so I moved on to Ruby since then…

      Best of luck,
      Natasha

  • Thanks so much for posting this. I had gone through the walkthrough and everything was working, but when I started on the first assignment, I broke something and it crashed every time and I couldn’t figure it out. You saved me from having to work through the whole walkthrough again so that I could do the future assignments. I’m definitely taking advantage of the Xcode source control features now. Seriously, you saved me so much time. Thanks again.

  • It is not declared in the interface because it is not called from any external class, but it’s just used inside the class itself. So other classes don’t need to “know” it exists. However declaring methods in protocols are just used to avoid compiler warnings, you can still avoid that warning by calling [brain performSelector: @selector(popOperand)], and however it would work even with a normal call, except that it gives that annoying warning.