Amazon.com Widgets Chapter 9 Exercise 4
Welcome, Guest. Please login or register.
Did you miss your activation email?
May 24, 2013, 07:37:42 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 9
| | | |-+  Chapter 9 Exercise 4
Poll
Question: Was this helpful?
Yes
No
Somewhat
I'm even more confused

Pages: [1]   Go Down
Print
Author Topic: Chapter 9 Exercise 4  (Read 979 times)
clouded
Full Member
***
Posts: 123






« on: May 23, 2012, 11:38:40 AM »

I think this is what the exercise is looking for:

Code: (Objective-C)
// Chapter 9 Exercise 4
// Based on the discussions about argument and return types in this chapter,
// modify both add: methods in the Fraction and Complex classes to take and
// return id objects. Then write a program that incorporates the following
// code sequence:
//    result = [dataValue1 add: dataValue2];
//    [result print];
// Here, result, dataValue1, and dataValue2 are id objects. Make sure you set
// dataValue1 and dataValue2 appropriately in your program.
//
// Note:
// You’ll have to change the name of the methods to something other than add:.
// That’s because the system’s NSObjectController class also has an add:
// method. As noted in the “Arguments and Return Types with Dynamic Typing”
// section, if multiple methods of the same name exist in different classes
// and the type of the receiver isn’t known at compile time, the compiler will
// perform a consistency check to make sure the arguments and return types are
// consistent among the similarly named methods.

//  main.m

#import <Foundation/Foundation.h>
#import "Fraction.h"
#import "Complex.h"

int main (int argc, char * argv[])
{
    @autoreleasepool {
        id dataValue1;
        id dataValue2;
        id result;
        
        Complex *c1 = [[Complex alloc] init];
        Complex *c2 = [[Complex alloc] init];
        Complex *tc = [[Complex alloc] init];
        
        Fraction *f1 = [[Fraction alloc] init];
        Fraction *f2 = [[Fraction alloc] init];
        Fraction *tf = [[Fraction alloc] init];
        
        [c1 setReal: 10.0 andImaginary: 2.5];
        [c2 setReal: 1.0 andImaginary: 20.5];
        
        [f1 setTo: 2 over: 5];
        [f2 setTo: 1 over: 5];
        
        // set to Complex
        
        dataValue1 = c1;
        dataValue2 = c2;
        result = tc;
        [dataValue1 print];
        [dataValue2 print];
        result = [dataValue1 addN: dataValue2];
        [result print];
        
        // set to Fractions
        
        dataValue1 = f1;
        dataValue2 = f2;
        result = tf;
        [dataValue1 print];
        [dataValue2 print];
        result = [dataValue1 addN: dataValue2];
        [result print];
        
    }
    return 0;
}
Code: (Objective-C)
//  Fraction.h

#import <Foundation/Foundation.h>

@interface Fraction : NSObject
@property int numerator, denominator;

-(void) print;
-(double) convertToNum;
-(void) setTo: (int) n over: (int) d;
-(Fraction *) add: (Fraction *) f;
-(Fraction *) subtract: (Fraction *) f;
-(Fraction *) multiply: (Fraction *) f;
-(Fraction *) divide: (Fraction *) f;
-(void) negate;
-(void) reduce;
-(Fraction *) addN: (Fraction *) f;
@end
Code: (Objective-C)
// Fraction.m

#import "Fraction.h"

@implementation Fraction
@synthesize numerator, denominator;

-(void) print
{
    Fraction *result = [[Fraction alloc] init];
    result.numerator = numerator;
    result.denominator = denominator;
    
    if (numerator/denominator >= 1 || numerator/denominator <= -1) {
        if (result.numerator % result.denominator == 0) {
            NSLog(@"%i", result.numerator / result.denominator);
        } else if (result.numerator <= 0) {
            NSLog(@"%i %i/%i", result.numerator / result.denominator, -(result.numerator % result.denominator) , result.denominator);
        } else {
            NSLog(@"%i %i/%i", result.numerator / result.denominator, result.numerator % result.denominator , result.denominator);
        }
    }
        [result reduce];
        NSLog (@"%i/%i", result.numerator, result.denominator);
}
-(double) convertToNum
{
    if (denominator != 0)
        return (double) numerator / denominator;
    else
        return NAN;
}
-(void) setTo: (int) n over: (int) d
{
    numerator = n;
    denominator = d;
    if (d < 0) {
        [self negate];
    }
}
-(void) negate
{
    denominator *= -1;
    numerator *= -1;
}
-(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;
    while (v != 0) {
        temp = u % v;
        u = v;
        v = temp;
    }
    numerator /= u;
    denominator /= u;
    if (denominator < 0) {
        [self negate];
    }
}
-(Fraction *) addN: (Fraction *) f
{
    Fraction *result = [[Fraction alloc] init];
    result.numerator = numerator * f.denominator + denominator * f.numerator;
    result.denominator = denominator * f.denominator;
    
    [result reduce];
    return result;
}
@end
Code: (Objective-C)
//  Complex.h

#import <Foundation/Foundation.h>

@interface Complex: NSObject
@property double real, imaginary;
-(void) print;
-(void) setReal: (double) a andImaginary: (double) b;
-(Complex *) add: (Complex *) f;
-(Complex *) addN: (Complex *) f;
@end
Code: (Objective-C)
//  Complex.m

#import "Complex.h"

@implementation Complex
@synthesize real, imaginary;
-(void) print
{
    NSLog (@" %g + %gi ", real, imaginary);
}
-(void) setReal: (double) a andImaginary: (double) b
{
    real = a;
    imaginary = b;
}
-(Complex *) add: (Complex *) f
{
    Complex *result = [[Complex alloc] init];
    result.real = real + f.real;
    result.imaginary = imaginary + f.imaginary;
    return result;
}
-(Complex *) addN: (Complex *) f
{
    Complex *result = [[Complex alloc] init];
    result.real = real + f.real;
    result.imaginary = imaginary + f.imaginary;
    return result;
}
@end

Output:

10 + 2.5i
1 + 20.5i
11 + 23i
2/5
1/5
3/5
« Last Edit: May 23, 2012, 11:46:24 AM by clouded » Logged
clouded
Full Member
***
Posts: 123






« Reply #1 on: May 24, 2012, 11:42:20 AM »

After reading a few pages into the next chapter, i realized i missed the point of the exercise, had to pay close attention to how the variable was accessed (doesn't like '.' dot) here's my revision:

Code: (Objective-C)
// Chapter 9 Exercise 4  
// Based on the discussions about argument and return types in this chapter,  
// modify both add: methods in the Fraction and Complex classes to take and  
// return id objects. Then write a program that incorporates the following  
// code sequence:  
//    result = [dataValue1 add: dataValue2];  
//    [result print];  
// Here, result, dataValue1, and dataValue2 are id objects. Make sure you set  
// dataValue1 and dataValue2 appropriately in your program.  
//  
// Note:  
// You’ll have to change the name of the methods to something other than add:.  
// That’s because the system’s NSObjectController class also has an add:  
// method. As noted in the “Arguments and Return Types with Dynamic Typing”  
// section, if multiple methods of the same name exist in different classes  
// and the type of the receiver isn’t known at compile time, the compiler will  
// perform a consistency check to make sure the arguments and return types are  
// consistent among the similarly named methods.  

//  main.m  

#import <Foundation/Foundation.h>  
#import "Fraction.h"  
#import "Complex.h"  

int main (int argc, char * argv[])  
{  
    @autoreleasepool {  
        id dataValue1;  
        id dataValue2;  
        id result;  
        
        Complex *c1 = [[Complex alloc] init];  
        Complex *c2 = [[Complex alloc] init];  
        
        Fraction *f1 = [[Fraction alloc] init];  
        Fraction *f2 = [[Fraction alloc] init];
        
        [c1 setReal: 10.0 andImaginary: 2.5];  
        [c2 setReal: 1.0 andImaginary: 20.5];  
        
        [f1 setTo: 2 over: 5];  
        [f2 setTo: 1 over: 5];  
        
        // set to Complex  
        
        dataValue1 = c1;  
        dataValue2 = c2;  
        [dataValue1 print];  
        [dataValue2 print];
        
        result = [dataValue1 addN: dataValue2];  
        [result print];  
        
        // set to Fractions  
        
        dataValue1 = f1;  
        dataValue2 = f2;  
        [dataValue1 print];  
        [dataValue2 print];
        
        result = [dataValue1 addN: dataValue2];  
        [result print];  
        
    }  
    return 0;  
}
Code: (Objective-C)
//  Fraction.h

#import <Foundation/Foundation.h>

@interface Fraction : NSObject
@property int numerator, denominator;

-(void) print;
-(double) convertToNum;
-(void) setTo: (int) n over: (int) d;
-(Fraction *) add: (Fraction *) f;
-(Fraction *) subtract: (Fraction *) f;
-(Fraction *) multiply: (Fraction *) f;
-(Fraction *) divide: (Fraction *) f;
-(void) negate;
-(void) reduce;
-(id) addN: (id) f;
@end
Code: (Objective-C)
// Fraction.m

#import "Fraction.h"

@implementation Fraction
@synthesize numerator, denominator;

-(void) print
{
    Fraction *result = [[Fraction alloc] init];
    result.numerator = numerator;
    result.denominator = denominator;
    
    if (numerator/denominator >= 1 || numerator/denominator <= -1) {
        if (result.numerator % result.denominator == 0) {
            NSLog(@"%i", result.numerator / result.denominator);
        } else if (result.numerator <= 0) {
            NSLog(@"%i %i/%i", result.numerator / result.denominator, -(result.numerator % result.denominator) , result.denominator);
        } else {
            NSLog(@"%i %i/%i", result.numerator / result.denominator, result.numerator % result.denominator , result.denominator);
        }
    }
        [result reduce];
        NSLog (@"%i/%i", result.numerator, result.denominator);
}
-(double) convertToNum
{
    if (denominator != 0)
        return (double) numerator / denominator;
    else
        return NAN;
}
-(void) setTo: (int) n over: (int) d
{
    numerator = n;
    denominator = d;
    if (d < 0) {
        [self negate];
    }
}
-(void) negate
{
    denominator *= -1;
    numerator *= -1;
}
-(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;
    while (v != 0) {
        temp = u % v;
        u = v;
        v = temp;
    }
    numerator /= u;
    denominator /= u;
    if (denominator < 0) {
        [self negate];
    }
}
-(id) addN: (id) f
{
    Fraction *result = [[Fraction alloc] init];
    result.numerator = numerator * [f denominator] + denominator * [f numerator];
    result.denominator = denominator * [f denominator];
    
    [result reduce];
    return result;
}
@end
Code: (Objective-C)
//  Complex.h

#import <Foundation/Foundation.h>

@interface Complex: NSObject
@property double real, imaginary;
-(void) print;
-(void) setReal: (double) a andImaginary: (double) b;
-(Complex *) add: (Complex *) f;
-(id) addN: (id) f;
@end
Code: (Objective-C)
//  Complex.m

#import "Complex.h"

@implementation Complex
@synthesize real, imaginary;
-(void) print
{
    NSLog (@" %g + %gi ", real, imaginary);
}
-(void) setReal: (double) a andImaginary: (double) b
{
    real = a;
    imaginary = b;
}
-(Complex *) add: (Complex *) f
{
    Complex *result = [[Complex alloc] init];
    result.real = real + f.real;
    result.imaginary = imaginary + f.imaginary;
    return result;
}
-(id) addN: (id) f
{
    Complex *result = [[Complex alloc] init];
    result.real = real + [f real];
    result.imaginary = imaginary + [f imaginary];
    return result;
}
@end

Output:

10 + 2.5i
1 + 20.5i
11 + 23i
2/5
1/5
3/5
« Last Edit: May 24, 2012, 11:46:19 AM by clouded » Logged
rickyshands
Newbie
*
Posts: 8






« Reply #2 on: May 31, 2012, 06:22:04 PM »

I am very confused by this exercise.  I think I'm missing the lesson entirely, and I don't understand the results of my program.
I have essentially the same code as above, but I have no problems when running the code using the original add: methods in main.m.  My new methods  "-(id) addf: (id) f;" and "-(id) addc: (id) c;" work fine also.  

I'm not even quite sure what I'm asking here:  Was something supposed to happen with the compiler doing a consistency check?  What am I missing here?  



Logged
clouded
Full Member
***
Posts: 123






« Reply #3 on: June 25, 2012, 05:55:54 AM »

I think they're just showing how type id works... it mutates to what you want, according to how you use it.
« Last Edit: June 25, 2012, 05:58:46 AM by clouded » Logged
Gordio
Newbie
*
Posts: 12


Email




« Reply #4 on: July 15, 2012, 11:03:14 PM »

I'm having issues

My line "result = [dataValue 1 add: dataValue2];" has an error because it says add is in different definitions.  I already wrote the code so dataValue1 is a fraction and dataValue2 is a fraction, so why is my compiler having trouble figuring which 'add' (complex or fraction) to use?  The only way my code works is if I have addC and addF so the compiler knows which to use.
« Last Edit: July 15, 2012, 11:07:07 PM by Gordio » Logged
Gordio
Newbie
*
Posts: 12


Email




« Reply #5 on: July 15, 2012, 11:22:35 PM »

Never mind I figured it out.  I missed the note on renaming "add" or it'll conflict with a method of the same name from NSObjectController
Logged
m.savci
Newbie
*
Posts: 12






« Reply #6 on: August 03, 2012, 05:35:15 AM »

This is my version.  Wink

Code: (Objective-C)
//
//  Complex.h

#import <Foundation/Foundation.h>

@interface Complex : NSObject

@property double real, imaginary;

-(void) print;
-(void) setReal:(double)a andImaginary:(double)b;

-(id) addd:(id)f;


Code: (Objective-C)
//  Complex.m

#import "Complex.h"

@implementation Complex

@synthesize real, imaginary;

-(void) print
{
    NSLog(@" %g + %gi -> This is Class Complex's print method!", real, imaginary);
}

-(void) setReal:(double)a andImaginary:(double)b
{
    real = a;
    imaginary = b;
}

-(id) addd:(id)f
{
    Complex *result = [[Complex alloc] init];
    Complex *arg;
   
    arg = f;
   
    result.real = real + arg.real;
    result.imaginary = imaginary + arg.imaginary;
   
    return result;
}

@end

Code: (Objective-C)
//  Fraction.h

#import <Foundation/Foundation.h>

@interface Fraction : NSObject

@property int numerator, denominator;

-(void) print;

-(id) addd: (id)f;

-(void) setTo:(int)n over:(int)d;

-(double) convertToNum;

-(void) reduce;


@end

Code: (Objective-C)
//  Fraction.m

#import "Fraction.h"

@implementation Fraction

@synthesize numerator, denominator;

-(void) print
{
    NSLog(@"%i/%i -> This is Class Fractions's print method!",numerator, denominator);
}

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

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

-(double) convertToNum
{   
    return denominator < 0 ? NAN : (double) numerator / denominator;
}

-(void) reduce
{
    int temp, num, denom;
    num = numerator;
    denom = denominator;
   
    while (denom) {
        temp = num % denom;
        num = denom;
        denom = temp;
    } 
   
    numerator /= num;
    denominator /= num;
   
}

@end

Code: (Objective-C)

//  main.m
//  Chapter9Ex4

#import <Foundation/Foundation.h>
#import "Fraction.h"
#import "XYPoint.h"
#import "Complex.h"

int main (int argc, const char * argv[])
{

    @autoreleasepool {
       
        Complex *c1 = [[Complex alloc] init];
        Complex *c2 = [[Complex alloc] init];
       
        id dataValue1, dataValue2;
       
        dataValue1 = c1;
        dataValue2 = c2;
       
        [dataValue1 setReal:10 andImaginary:5];
        [dataValue2 setReal:5 andImaginary:7];

        [[dataValue1 addd:dataValue2] print];
       
        Fraction *f1 = [[Fraction alloc] init];
        Fraction *f2 = [[Fraction alloc] init];
       
        dataValue1 = f1;
        dataValue2 = f2;
       
        [dataValue1 setTo:5 over:10];
        [dataValue2 setTo:6 over:12];
       
        [[dataValue1 addd:dataValue2] print]; 
       
    }
    return 0;
}

Code: (Objective-C)
// Output:

2012-08-03 14:51:11.283 Chapter9Ex4[2450:4503]  15 + 12i -> This is Class Complex's print method!
2012-08-03 14:51:11.286 Chapter9Ex4[2450:4503] 1/1 -> This is Class Fractions's print method!
Program ended with exit code: 0
Logged
m.savci
Newbie
*
Posts: 12






« Reply #7 on: August 03, 2012, 06:01:15 AM »

I'am putting a second version with a little change. I change my addd functions, but the result is the same.

Code: (Objective-C)
//  Complex.h

#import <Foundation/Foundation.h>

@interface Complex : NSObject

@property double real, imaginary;

-(void) print;
-(void) setReal:(double)a andImaginary:(double)b;

-(id) addd:(id)f;

@end

Code: (Objective-C)
//  Complex.m

#import "Complex.h"

@implementation Complex

@synthesize real, imaginary;

-(void) print
{
    NSLog(@" %g + %gi -> This is Class Complex's print method!", real, imaginary);
}

-(void) setReal:(double)a andImaginary:(double)b
{
    real = a;
    imaginary = b;
}

-(id) addd:(id)f
{
    Complex *result = [[Complex alloc] init];
   
    result.real = real + [f real];
    result.imaginary = imaginary + [f imaginary];
   
    return result;
}

@end

Code: (Objective-C)
//  Fraction.h

#import <Foundation/Foundation.h>

@interface Fraction : NSObject

@property int numerator, denominator;

-(void) print;

-(id) addd: (id)f;

-(void) setTo:(int)n over:(int)d;

-(double) convertToNum;

-(void) reduce;

@end

Code: (Objective-C)
//  Fraction.m

#import "Fraction.h"

@implementation Fraction

@synthesize numerator, denominator;

-(void) print
{
    NSLog(@"%i/%i -> This is Class Fractions's print method!",numerator, denominator);
}

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

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

-(double) convertToNum
{   
    return denominator < 0 ? NAN : (double) numerator / denominator;
}

-(void) reduce
{
    int temp, num, denom;
    num = numerator;
    denom = denominator;
   
    while (denom) {
        temp = num % denom;
        num = denom;
        denom = temp;
    } 
   
    numerator /= num;
    denominator /= num;
   
}
@end

Code: (Objective-C)
//  main.m
//  Chapter9Ex4v2

#import <Foundation/Foundation.h>
#import "Fraction.h"
#import "Complex.h"

int main (int argc, const char * argv[])
{

    @autoreleasepool {
       
        Complex *c1 = [[Complex alloc] init];
        Complex *c2 = [[Complex alloc] init];
       
        id dataValue1, dataValue2;
       
        dataValue1 = c1;
        dataValue2 = c2;
       
        [dataValue1 setReal:10 andImaginary:5];
        [dataValue2 setReal:5 andImaginary:7];
       
        [[dataValue1 addd:dataValue2] print];
       
        Fraction *f1 = [[Fraction alloc] init];
        Fraction *f2 = [[Fraction alloc] init];
       
        dataValue1 = f1;
        dataValue2 = f2;
       
        [dataValue1 setTo:5 over:10];
        [dataValue2 setTo:6 over:12];
       
        [[dataValue1 addd:dataValue2] print]; 
       
    }
    return 0;
}

Code: (Objective-C)
// Output:
2012-08-03 15:53:51.163 Chapter9Ex4v2[2803:4503]  15 + 12i -> This is Class Complex's print method!
2012-08-03 15:53:51.166 Chapter9Ex4v2[2803:4503] 1/1 -> This is Class Fractions's print method!
Program ended with exit code: 0
Logged
mo7ionsickness
Jr. Member
**
Posts: 50






« Reply #8 on: August 19, 2012, 01:03:50 PM »

Code: (Objective-C)
-(id) addThis:(id) f
{
    Complex *result = [[Complex alloc] init];
   
    [result setReal: real + [f real]];
    [result setImaginary: imaginary + [f imaginary]];
   
    return result;
}
Code: (Objective-C)
-(id) addThis:(id)f
{
    Fraction *result = [[Fraction alloc] init];
   
    [result setNumerator: numerator * [f denominator] + denominator * [f numerator]];
    [result setDenominator: denominator * [f denominator]];
    [result reduce];
   
    return result;
}

Code: (Objective-C)
int main(int argc, const char * argv[])
{

    @autoreleasepool {
       
        Fraction *f1 = [[Fraction alloc] init];
        Fraction *f2 = [[Fraction alloc] init];
        Complex *c1 = [[Complex alloc] init];
        Complex *c2 = [[Complex alloc] init];
       
        id result;
        id dataValue1;
        id dataValue2;
       
        [f1 setTo: 1 over: 10];
        [f2 setTo: 2 over: 15];
       
        [c1 setReal: 18.0 andImaginary: 2.5];
        [c2 setReal: -5.0 andImaginary: 3.2];
       
        dataValue1 = f1;
        dataValue2 = f2;
        result = [dataValue1 addThis:dataValue2];
        [result print];
       
        dataValue1 = c1;
        dataValue2 = c2;
        result = [dataValue1 addThis:dataValue2];
        [result print];
       
    }
    return 0;
}

2012-08-19 20:56:25.393 FractionTest[1775:303] 7/30
2012-08-19 20:56:25.395 FractionTest[1775:303] 13.00 + 5.70i
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.