Amazon.com Widgets Exercise 21.4
Welcome, Guest. Please login or register.
Did you miss your activation email?
October 21, 2014, 09:47:04 PM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Programming in Objective-C, 4th edition
| |-+ Exercises
| | |-+ Chapter 21
| | | |-+ Exercise 21.4
Pages: [1] Go Down
Print
Author Topic: Exercise 21.4 (Read 1153 times)
tknp
Newbie
*
Posts: 23






on: February 06, 2012, 04:59:14 PM

All my changes from the previous exercise were made in the ViewController.h and .m file

The changes were:
- created a secondary display to show the running accumulator
- created second string to print to secondary display
- modified the processOp section
- added pastFirstOperand = 0; to viewDidLoad, clickClear and clickEquals sections

What it looks like:
and

I'll post all the source files to get it running.

ViewController.h
Code: (Objective-C)
#import <UIKit/UIKit.h>
#import "Calculator.h"

@interface ViewController : UIViewController

@property (strong, nonatomic) IBOutlet UILabel *display;
@property (strong, nonatomic) IBOutlet UILabel *displaySecond;

-(void) processDigit: (int) digit;
-(void) processOp: (char) theOp;
-(void) storeFracPart;

// Numeric keys

-(IBAction) clickDigit: (UIButton *) sender;

// Arithmetic Operation keys

-(IBAction) clickPlus;
-(IBAction) clickMinus;
-(IBAction) clickMultiply;
-(IBAction) clickDivide;

// Misc. Keys

-(IBAction) clickOver;
-(IBAction) clickEquals;
-(IBAction) clickClear;
-(IBAction) clickConvert;

@end

ViewController.m
Code: (Objective-C)
#import "ViewController.h"

@implementation ViewController
{
    char                op;
    int                 currentNumber;
    int                 pastFirstOperand;
    BOOL                firstOperand, isNumerator, isNegative, isWriting;
    Calculator          *myCalculator;
    NSMutableString     *displayString, *displayStringSecond;
}

@synthesize display, displaySecond;

- (void)viewDidLoad
{
    firstOperand = YES;
    isNumerator = YES;
    isNegative = NO;
    isWriting = NO;
    pastFirstOperand = 0;
    displayString = [NSMutableString stringWithCapacity: 40];
    displayStringSecond = [NSMutableString stringWithCapacity: 40];
    myCalculator = [[Calculator alloc] init ];
}

-(void) processDigit: (int) digit
{
    // Since we are processing a digit, set isWriting to YES
    if(!isWriting)
        isWriting = YES;
   
    if (isNegative)
        currentNumber = currentNumber * 10 - digit;
    else
        currentNumber = currentNumber * 10 + digit;
   
    [displayString appendString: [NSString stringWithFormat: @"%i", digit]];
    display.text = displayString;
}

-(IBAction) clickDigit: (UIButton *) sender
{
    int digit = sender.tag;
   
    [self processDigit: digit];
}

-(void) processOp: (char) theOp
{
    NSString *opStr;
   
    if (theOp == '-' && isWriting == NO) {   // checks for negative sign before first digit of entered num
        isNegative = YES;
        [displayString appendString: @"-"];
        display.text = displayString;
       
        return;
    }
   
    [self storeFracPart];
   
    if (pastFirstOperand) {
        [myCalculator performOperation: op];
       
        // Display running total in secondary display
        [displayStringSecond setString: @" = "];
        [displayStringSecond appendString: [myCalculator.accumulator convertToString]];
        displaySecond.text = displayStringSecond;
       
        // Take the value of the accumulator after a calculation and place it in operand1
        myCalculator.operand1.numerator = myCalculator.accumulator.numerator;
        myCalculator.operand1.denominator = myCalculator.accumulator.denominator;
    }
   
   
    // Check to make sure we are trying to do an operation and not just an initial negative number
    if (!pastFirstOperand)
        ++pastFirstOperand; // at this point, an operand has been pressed
   
    op = theOp;
   
    switch (theOp) {
        case '+':
            opStr = @" + ";
            break;
        case '-':
            opStr = @" - ";
            break;
        case '*':
            opStr = @" ";
            break;
        case '/':
            opStr = @" ";
            break;
    }
   
    firstOperand = NO;
    isNumerator = YES;
    isNegative = NO;
    isWriting = NO;
   
    [displayString appendString: opStr];
    display.text = displayString;
}

-(void) storeFracPart
{
    if (firstOperand) {
        if (isNumerator) {
            myCalculator.operand1.numerator = currentNumber;
            myCalculator.operand1.denominator = 1;  // e.g. 3 * 4/5
        }
        else
            myCalculator.operand1.denominator = currentNumber;
    }
    else if (isNumerator) {
        myCalculator.operand2.numerator = currentNumber;
        myCalculator.operand2.denominator = 1;  // e.g. 3/2 * 4
    }
    else {
        myCalculator.operand2.denominator = currentNumber;
        firstOperand = YES;
    }

    currentNumber = 0;
}

-(IBAction) clickOver
{
    [self storeFracPart];
    isNumerator = NO;
    isNegative = NO;
    [displayString appendString: @"/"];
    display.text = displayString;
}

// Arithmetic Operation keys

-(IBAction) clickPlus
{
    [self processOp: '+'];
}

-(IBAction) clickMinus
{
    [self processOp: '-'];
}

-(IBAction) clickMultiply
{
    [self processOp: '*'];
}

-(IBAction) clickDivide
{
    [self processOp: '/'];
}

// Misc. Keys

-(IBAction) clickEquals
{
    if ( firstOperand == NO ) {
        [self storeFracPart];
       
        if (!myCalculator.operand1.denominator || !myCalculator.operand2.denominator) { // Checks for division by zero
            [myCalculator clear];   // Clears calc to avoid a valid result from the previous calculation messing up Convert button
            [displayString setString: @"Error"];
            display.text = displayString;
        }
        else {
            [myCalculator performOperation: op];
           
            [displayString appendString: @" = "];
            [displayString appendString: [myCalculator.accumulator convertToString]];
            display.text = displayString;
        }
       
        // Clear the secondary display
        [displayStringSecond setString: @""];
        displaySecond.text = displayStringSecond;
       
        currentNumber = 0;
        isNumerator = YES;
        isNegative = NO;
        isWriting = NO;
        pastFirstOperand = 0;
        firstOperand = YES;
        [displayString setString: @""];
    }
}

-(IBAction) clickClear
{
    isNumerator = YES;
    isNegative = NO;
    isWriting = NO;
    pastFirstOperand = 0;
    firstOperand = YES;
    currentNumber = 0;
    [myCalculator clear];
   
    [displayString setString: @""];
    display.text = displayString;
   
    // Clear the secondary display
    [displayStringSecond setString: @""];
    displaySecond.text = displayStringSecond;
}

-(IBAction) clickConvert
{
    display.text = [NSString stringWithFormat: @"%f", [myCalculator.accumulator convertToNum]];
}

@end

Fraction.h
Code: (Objective-C)
#import <UIKit/UIKit.h>

@interface Fraction : NSObject

@property int numerator, denominator;

-(void)         print;
-(void)         setTo: (int) n over: (int) d;
-(Fraction *)   add: (Fraction *) f;
-(Fraction *)   subtract: (Fraction *) f;
-(Fraction *)   multiply: (Fraction *) f;
-(Fraction *)   divide: (Fraction *) f;
-(void)         reduce;
-(double)       convertToNum;
-(NSString *)   convertToString;

@end

Fraction.m
Code: (Objective-C)
#import "Fraction.h"

@implementation Fraction

@synthesize numerator, denominator;

-(void) setTo: (int) n over: (int) d
{
    numerator = n;
    denominator = d;
}

-(void) print
{
    NSLog(@"%i/%i", numerator, denominator);
}

-(double) convertToNum
{
    if (denominator != 0)
        return (double) numerator / denominator;
    else
        return NAN;
}

-(NSString *) convertToString
{
    if (numerator == denominator)
        if (numerator == 0)
            return @"0";
    else
        return @"1";
    else if (denominator == 1)
        return [NSString stringWithFormat: @"%i", numerator];
    else
        return [NSString stringWithFormat: @"%i/%i", numerator, denominator];
}

// add a Fraction to the receiver

-(Fraction *) add: (Fraction *) f
{
    Fraction *result = [[Fraction alloc] init];
   
    result.numerator = numerator * f.denominator + denominator * f.numerator;
    result.denominator = denominator * f.denominator;
   
    [result reduce];
    return result;
}

-(Fraction *) subtract: (Fraction *) f
{
    Fraction *result = [[Fraction alloc] init];
   
    result.numerator = numerator * f.denominator - denominator * f.numerator;
    result.denominator = denominator * f.denominator;
   
    [result reduce];
    return result;
}

-(Fraction *) multiply: (Fraction *) f
{
    Fraction *result = [[Fraction alloc] init];
   
    result.numerator = numerator * f.numerator;
    result.denominator = denominator * f.denominator;
   
    [result reduce];
    return result;
}

-(Fraction *) divide: (Fraction *) f
{
    Fraction *result = [[Fraction alloc] init];
   
    result.numerator = numerator * f.denominator;
    result.denominator = denominator * f.numerator;
   
    [result reduce];
    return result;
}

-(void) reduce
{
    int u = numerator;
    int v = denominator;
    int temp;
   
    if (u == 0)
        return;
    else if (u<v)
        u = -u;
   
    while (v != 0) {
        temp = u % v;
        u = v;
        v = temp;
    }
   
    numerator /= u;
    denominator /= u;
}

@end

Calculator.h
Code: (Objective-C)
#import <UIKit/UIKit.h>
#import "Fraction.h"

@interface Calculator : NSObject

@property (strong, nonatomic) Fraction *operand1, *operand2, *accumulator;

-(Fraction *) performOperation: (char) op;
-(void) clear;

@end

Calculator.m
Code: (Objective-C)
#import "Calculator.h"

@implementation Calculator

@synthesize operand1, operand2, accumulator;

-(id) init
{
    self = [super init];
   
    if (self) {
        operand1 = [[Fraction alloc] init];
        operand2 = [[Fraction alloc] init];
        accumulator = [[Fraction alloc] init];
    }
   
    return self;
}

-(void) clear
{
    accumulator.numerator = 0;
    accumulator.denominator = 0;
}

-(Fraction *) performOperation: (char) op
{
    Fraction *result;
   
    switch (op) {
            case '+':
                result = [operand1 add: operand2];
                break;
            case '-':
                result = [operand1 subtract: operand2];
                break;
            case '*':
                result = [operand1 multiply: operand2];
                break;
            case '/':
                result = [operand1 divide: operand2];
                break;
    }
   
    accumulator.numerator = result.numerator;
    accumulator.denominator = result.denominator;
   
    return accumulator;
}

@end
Logged
Pages: [1] Go Up
Print
Jump to:



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.