Amazon.com Widgets 11.3
Welcome, Guest. Please login or register.
Did you miss your activation email?
December 18, 2014, 10:19:27 AM
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
|-+ Old Stuff
| |-+ Answers to Exercises
| | |-+ Chapter 11
| | | |-+ 11.3
Pages: [1] Go Down
Print
Author Topic: 11.3 (Read 2445 times)
sir
Full Member
***
Posts: 118


Email




on: March 20, 2009, 12:13:10 AM

/*
Extend the Fraction class by adding methods that conform to the
informal protocol NSComparisonMethods, as listed earlier in this chapter.
Implement the first six methods from that protocol

(isEqualTo:, isLessThanOrEqualTo:, isLessThan:, isGreaterThanOrEqualTo:,
isGreaterThan:, isNotEqualTo:)

and test them.
*/

//the "informal protocal" category....
#import "Fraction.h"

@interface Fraction (NSComparisonMethods)
-(BOOL) isEqualTo: (id) object;
-(BOOL) isLessThanOrEqualTo: (id) object;
-(BOOL) isLessThan: (id) object;
-(BOOL) isGreaterThanOrEqualTo: (id) object;
-(BOOL) isGreaterThan: (id) object;
-(BOOL) isNotEqualTo: (id) object;
@end

@implementation Fraction (NSComparisonMethods)
-(BOOL) isEqualTo: (id) object {
   double f1 = (double) numerator / denominator;
   double f2 = (double) [object numerator] / [object denominator];
   
   if (f1 == f2)
      return YES;
   else
      return NO;
}

-(BOOL) isLessThanOrEqualTo: (id) object {
   double f1 = (double) numerator / denominator;
   double f2 = (double) [object numerator] / [object denominator];
   if (f1 <= f2)
      return YES;
   else
      return NO;
}

-(BOOL) isLessThan: (id) object {
   double f1 = (double) numerator / denominator;
   double f2 = (double) [object numerator] / [object denominator];
   
   if (f1 < f2)
      return YES;
   else
      return NO;
}

-(BOOL) isGreaterThanOrEqualTo: (id) object {
   double f1 = (double) numerator / denominator;
   double f2 = (double) [object numerator] / [object denominator];
   
   if (f1 >= f2)
      return YES;
   else
      return NO;
}

-(BOOL) isGreaterThan: (id) object {
   double f1 = (double) numerator / denominator;
   double f2 = (double) [object numerator] / [object denominator];
   
   if (f1 > f2)
      return YES;
   else
      return NO;
}

-(BOOL) isNotEqualTo: (id) object {
   double f1 = (double) numerator / denominator;
   double f2 = (double) [object numerator] / [object denominator];
   
   if (f1 != f2)
      return YES;
   else
      return NO;
}
@end

//---------------------------MAIN-------------------------------

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    id f1 = [[Fraction alloc] init];
   id f2 = [[Fraction alloc] init];
   
   [f1 setTo: 5 over: 8];
   [f2 setTo: 10 over: 16];

    if ([f1 isEqualTo: f2])
      NSLog(@"f1 is equal to f2");
   else
      NSLog(@"f1 is not equal to f2");
      
   [f1 setTo: 5 over: 8];
   [f2 setTo: 2 over: 16];

    if ([f1 isLessThanOrEqualTo: f2])
      NSLog(@"f1 is less than or equal to f2");
   else
      NSLog(@"f1 is not less than or equal to f2");
   
   [f1 setTo: 5 over: 8];
   [f2 setTo: 10 over: 12];

    if ([f1 isLessThan: f2])
      NSLog(@"f1 is less than f2");
   else
      NSLog(@"f1 is not less than f2");
   
   [f1 setTo: 50 over: 100];
   [f2 setTo: 22 over: 44];

    if ([f1 isGreaterThanOrEqualTo: f2])
      NSLog(@"f1 is greater than or equal to f2");
   else
      NSLog(@"f1 is not greater than or equal to f2");
      
   [f1 release];
   [f2 release];
    [pool drain];
    return 0;
}

Logged
adamgonzalez1984
Jr. Member
**
Posts: 89






Reply #1 on: April 30, 2009, 03:12:55 PM

Hey I was just wondering if you ever made sure that this program conformed to the informal protocol NSComparisonMethods.  I was just wondering if I did the check right.

Fraction.h
Quote
#import <Foundation/Foundation.h>

@interface Fraction : NSObject
{
    int numerator;
    int denominator;
}

@property int numerator, denominator;

-(void)      setTo: (int) n over: (int) d;
-(void)      reduce;
-(double)    convertToNum;
-(void)      print;



- (BOOL)isEqualTo:(Fraction *)f;

- (BOOL)isLessThanOrEqualTo:(Fraction *) f;

- (BOOL)isLessThan:(Fraction *)f;

- (BOOL)isGreaterThanOrEqualTo:(Fraction *)f;

- (BOOL)isGreaterThan:(Fraction *)f;

- (BOOL)isNotEqualTo:(Fraction *)f;

@end




Fraction.m
Quote

#import "Fraction.h"

@implementation Fraction

@synthesize numerator, denominator;

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

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

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

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


- (BOOL)isEqualTo:(Fraction *)f{
   double result1, result2;
   
   result1 = (double) f.numerator/f.denominator;
   result2 = (double) numerator/denominator;
   
   NSLog(@"%i/%i", f.numerator, f.denominator);
   NSLog(@"%i/%i", numerator, denominator);
   NSLog(@"%g , %g", result1, result2);
   
   if (result1 == result2)
      return YES;
   else
      return NO;
   
}

- (BOOL)isLessThanOrEqualTo:(Fraction *) f{
   return NO;
}

- (BOOL)isLessThan:(Fraction *)f{
   return NO;
}


- (BOOL)isGreaterThanOrEqualTo:(Fraction *)f{
   return NO;
}


- (BOOL)isGreaterThan:(Fraction *)f{
   return NO;
}


- (BOOL)isNotEqualTo:(Fraction *)f{
   return NO;
}


@end




Main.m
Quote
#import "Fraction.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   Fraction *aFraction = [[Fraction alloc] init];
   Fraction *bFraction = [[Fraction alloc] init];
   
   [aFraction setTo: 1 over:3];
   [bFraction setTo: 1 over:4];
   
   if ([Fraction respondsToSelector: @selector (isEqualTo:)] == YES)
      NSLog(@"It does respond to isEqualTo: method");
   else
      NSLog(@"it does not respond to isEqualTo: method");

   if ([aFraction isEqualTo:bFraction] == YES)
      NSLog(@"They are equal");
      else
         NSLog(@"They are not equal");
   
   
   
    [pool drain];
    return 0;
}

I haven't defined the other 5 methods yet.  I just wanted to make sure That I was going down the right path with isEqualTo:



Logged
jclermont
Jr. Member
**
Posts: 55


Email




Reply #2 on: July 12, 2009, 02:11:34 PM

My approach involved using less repeated code. For example, instead of calling converToNum in every comparison, I establish that logic in only the three key comparison. The others are just a combination of the existing ones. I also realized that instead of an if block where you return YES or NO, you can just as easily return the result of the comparison. Thoughts?

Code: (Objective-C)
@interface Fraction (NSComparisonMethods)
- (BOOL)isEqualTo:(id)object;
- (BOOL)isLessThanOrEqualTo:(id)object;
- (BOOL)isLessThan:(id)object;
- (BOOL)isGreaterThanOrEqualTo:(id)object;
- (BOOL)isGreaterThan:(id)object;
- (BOOL)isNotEqualTo:(id)object;
@end
@implementation Fraction (NSComparisonMethods)
- (BOOL)isEqualTo:(id)object
{
double f1 = [self convertToNum];
double f2 = [object convertToNum];
return (f1 == f2);
}
- (BOOL)isLessThanOrEqualTo:(id)object
{
return ([self isLessThan: object] || [self isEqualTo: object]);
}
- (BOOL)isLessThan:(id)object
{
double f1 = [self convertToNum];
double f2 = [object convertToNum];
return (f1 < f2);
}
- (BOOL)isGreaterThanOrEqualTo:(id)object
{
return ([self isGreaterThan: object] || [self isEqualTo: object]);
}
- (BOOL)isGreaterThan:(id)object
{
double f1 = [self convertToNum];
double f2 = [object convertToNum];
return (f1 > f2);
}
- (BOOL)isNotEqualTo:(id)object
{
return ![self isEqualTo: object];
}
@end
Logged
purplebox
Newbie
*
Posts: 12



WWW




Reply #3 on: September 01, 2009, 03:12:41 AM

I think code should be easy to read. That is much more important than that your code is efficient or doesn't need as many keystrokes on the keyboard.

Yes, it will most likely be (somewhat) more verbose, but it will be at least very easy to read. I'm told that 90 % of the code is re-purposed and only 10 % is written from scratch. This means that in most cases other people than you will read your code, and you should make it easy for them to understand what you've written.

Here's how I wrote this piece of the exercise code:

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

@interface Fraction (NSComparisonMethods)
- (BOOL)isEqualTo:(id)object;
- (BOOL)isLessThanOrEqualTo:(id)object;
- (BOOL)isLessThan:(id)object;
- (BOOL)isGreaterThanOrEqualTo:(id)object;
- (BOOL)isGreaterThan:(id)object;
- (BOOL)isNotEqualTo:(id)object;
@end

@implementation Fraction (NSComparisonMethods)
- (BOOL)isEqualTo:(id)object
{
BOOL result = [self convertToNum] == [object convertToNum];
return result;
}

- (BOOL)isLessThanOrEqualTo:(id)object
{
BOOL result = [self convertToNum] <= [object convertToNum];
return result;
}

- (BOOL)isLessThan:(id)object
{
BOOL result = [self convertToNum] < [object convertToNum];
return result;
}

- (BOOL)isGreaterThanOrEqualTo:(id)object
{
BOOL result = [self convertToNum] >= [object convertToNum];
return result;
}

- (BOOL)isGreaterThan:(id)object
{
BOOL result = [self convertToNum] > [object convertToNum];
return result;
}

- (BOOL)isNotEqualTo:(id)object
{
BOOL result = [self convertToNum] != [object convertToNum];
return result;
}
@end

As you can see, there is a structure to this code. A BOOL is given a logical value, and that BOOL is returned to the sender. Of course, many other solutions are possible. My point is, that it is dead easy to read.
Logged
mdziedzic
Newbie
*
Posts: 41



WWW




Reply #4 on: November 11, 2009, 01:10:49 PM

A little less verbose but just as easy to read...

Code: (Objective-C)
@implementation Fraction (NSComparisonMethods)

-(BOOL) isEqualTo: (id) object
{
return [self convertToNum] == [object convertToNum];
}


-(BOOL) isLessThanOrEqualTo: (id) object
{
return [self convertToNum] <= [object convertToNum];
}


-(BOOL) isLessThan: (id) object
{
return [self convertToNum] < [object convertToNum];
}


-(BOOL) isGreaterThanOrEqualTo: (id) object
{
return [self convertToNum] >= [object convertToNum];
}


-(BOOL) isGreaterThan: (id) object
{
return [self convertToNum] > [object convertToNum];
}


-(BOOL) isNotEqualTo: (id) object
{
return [self convertToNum] != [object convertToNum];
}

@end
Logged
Jyrbian
Newbie
*
Posts: 22






Reply #5 on: January 30, 2010, 01:32:10 PM

I have written several of the methods for exercise 11.3 and have confirmed that they are working. I wanted to compare what I am doing with what has been displayed here.

One thing that I have noticed that I didn't notice with others who have posted is that I am implementing a check on (id) object using isKindofClass to make sure that a fraction has been passed. It may be out of scope of this exercise, but shouldn't this be checked in the method to make sure you are actually working with a fraction?

Edit: Added code below.

Fraction.h has not been changed so I have not included it.

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


@implementation Fraction

@synthesize numerator, denominator;

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

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

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


-(void) reduce
{
int u = numerator;
int v = denominator;
int temp;

while (v !=0) { 
temp = u % v; 
u = v;
v = temp;
}

numerator /= u;
denominator /= u;
}

//Informal protocol NSComparisonMethods

-(BOOL) isEqualTo:(id)object
{
BOOL result;

if([object isKindOfClass: [Fraction class]])
result = [self convertoToNum] == [object convertoToNum];
else
{
NSLog(@"Error: Object is not a Fraction");
result = NO;
}
return result;
}
 
 -(BOOL) isLessThanOrEqualTo:(id)object
{
BOOL result;

if([object isKindOfClass: [Fraction class]])
result = [self convertoToNum] <= [object convertoToNum];
else
{
NSLog(@"Error: Object is not a Fraction");
result = NO;
}
return result;
}

-(BOOL) isLessThan:(id)object
{
BOOL result;

if([object isKindOfClass: [Fraction class]])
result = [self convertoToNum] < [object convertoToNum];
else
{
NSLog(@"Error: Object is not a Fraction");
result = NO;
}
return result;
}

-(BOOL) isGreaterThanOrEqualTo:(id)object
{
{
BOOL result;

if([object isKindOfClass: [Fraction class]])
result = [self convertoToNum] >= [object convertoToNum];
else
{
NSLog(@"Error: Object is not a Fraction");
result = NO;
}
return result;
}
}

-(BOOL) isGreaterThan:(id)object
{
BOOL result;

if([object isKindOfClass: [Fraction class]])
result = [self convertoToNum] > [object convertoToNum];
else
{
NSLog(@"Error: Object is not a Fraction");
result = NO;
}
return result;
}

-(BOOL) isNotEqualTo:(id)object
{
BOOL result;

if([object isKindOfClass: [Fraction class]])
result = [self convertoToNum] != [object convertoToNum];
else
{
NSLog(@"Error: Object is not a Fraction");
result = NO;
}
return result;
}

@end

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

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Fraction *a = [[Fraction alloc] init];
Fraction *b = [[Fraction alloc] init];
//Fraction *result;

[a setTo: 1 over: 3];
[b setTo: 2 over: 6];

[a print]; NSLog(@"   =="); [b print]; NSLog(@"-----");
if ([a isEqualTo: b])
NSLog(@"Yes");
else
NSLog(@"NO");
NSLog(@"\n");


[a print]; NSLog(@"   <="); [b print]; NSLog(@"-----");
if ([a isLessThanOrEqualTo: b])
NSLog(@"Yes");
else
NSLog(@"NO");
NSLog(@"\n");


[a print]; NSLog(@"    <"); [b print]; NSLog(@"-----");
if ([a isLessThan: b])
NSLog(@"Yes");
else
NSLog(@"NO");
NSLog(@"\n");


[a print]; NSLog(@"   >="); [b print]; NSLog(@"-----");
if ([a isGreaterThanOrEqualTo: b])
NSLog(@"Yes");
else
NSLog(@"NO");
NSLog(@"\n");


[a print]; NSLog(@"    >"); [b print]; NSLog(@"-----");
if ([a isGreaterThan: b])
NSLog(@"Yes");
else
NSLog(@"NO");
NSLog(@"\n");


[a print]; NSLog(@"   !="); [b print]; NSLog(@"-----");
if ([a isNotEqualTo: b])
NSLog(@"Yes");
else
NSLog(@"NO");
NSLog(@"\n");

[a release];
[b release];

[pool drain];
return 0;
}





  
Last Edit: January 30, 2010, 11:19:43 PM by Jyrbian 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.