amuso
Jr. Member
Posts: 68
Hope to make a living coding...


« on: February 12, 2009, 12:34:49 PM » 

Trying to modify the print method... I am having problems not changing the fraction itself.
This code (Fraction.m) works, but changes the fraction:
(void) print: (BOOL) simplify // call method using [aFraction print: FALSE]; or [aFraction print: TRUE]; { if ( simplify ) { // We called the method with a TRUE statement [self reduce]; NSLog (@"%g  WAS reduced.", numerator, denominator); } else { NSLog (@"%i/%i  NOT reduced.", numerator, denominator); } }
This was verified by first calling the method with a TRUE statement, then a FALSE. Both returned a reduced fraction since the method reduce obviously reduces the fraction during the first run... (from the main code):
resultFraction = [aFraction add: bFraction]; [resultFraction print: FALSE]; [resultFraction print: TRUE];
(If I swap the last two lines I see that the fraction is modified since the output then is two reduced fractions).
Then I tried to alter the code to create a new fraction which would be modified if the Simplify statement was TRUE... However I cannot get it to work properly... Here is what I got:
(void) print: (BOOL) simplify { if ( simplify ) { Fraction *result = [[Fraction alloc] init]; [result setTo: numerator over: denominator]; [result reduce];
NSLog (@"%i/%i  WAS reduced.", numerator, denominator); [result release]; } else { NSLog (@"%i/%i  NOT reduced.", numerator, denominator); } }
The output though doesnt reduce the fraction...
20090212 20:32:34.256 FractionTest[7985:10b] 1/4  NOT reduced. 20090212 20:32:34.258 FractionTest[7985:10b] + 20090212 20:32:34.259 FractionTest[7985:10b] 1/2  NOT reduced. 20090212 20:32:34.259 FractionTest[7985:10b] = 20090212 20:32:34.260 FractionTest[7985:10b] 6/8  NOT reduced. 20090212 20:32:34.261 FractionTest[7985:10b] 6/8  WAS reduced.
My first code would, but of course did so by modifying the actual fraction...
20090212 20:19:39.978 FractionTest[7846:10b] 6/8  NOT reduced. 20090212 20:19:39.978 FractionTest[7846:10b] 3/4  WAS reduced.


« Last Edit: February 12, 2009, 12:36:55 PM by amuso »

Logged

MacBook MB063 4GB OS X 10.7.3 (Xcode 4.3) iMac MA876 3GB OS X 10.7.3 iPhone 4S 16GB 5.0.1 / iPad 2 16GB 5.0.1 Need translations to Norwegian? Happy to help.



skochan


« Reply #1 on: February 12, 2009, 12:40:58 PM » 

Your approach in the second case is correct. Note that you're reducing result but your NSLog statements are displaying the numerator and denominator of the receiver, not of result.
Cheers
Steve



Logged




amuso
Jr. Member
Posts: 68
Hope to make a living coding...


« Reply #2 on: February 12, 2009, 01:09:49 PM » 

Ah, of course... I see that now. Is this a valid way to fetch those values ?
NSLog (@"%i/%i  WAS reduced.", result.numerator, result.denominator);
Anyways, now the program does actually work as intended:
20090212 21:05:45.843 FractionTest[8503:10b] 7/4  NOT reduced. 20090212 21:05:45.845 FractionTest[8503:10b] = 1 3/4  NOT REDUCED 20090212 21:05:45.845 FractionTest[8503:10b] + 20090212 21:05:45.845 FractionTest[8503:10b] 1/2  NOT reduced. 20090212 21:05:45.847 FractionTest[8503:10b] = 20090212 21:05:45.848 FractionTest[8503:10b] 9/4  WAS reduced. 20090212 21:05:45.848 FractionTest[8503:10b] = 2 2/8  WAS REDUCED 20090212 21:05:45.848 FractionTest[8503:10b] 18/8  NOT reduced. 20090212 21:05:45.851 FractionTest[8503:10b] = 2 2/8  NOT REDUCED
(I moved on while waiting for a tip, and applied the necessary code from exercise 7.5 which is why it says 7/4 is 1 3/4 etc).
I have a habit of adding a bunch of comment output to see if the desired code is run which is why all the extra (WAS or NOT reduced) is output.



Logged

MacBook MB063 4GB OS X 10.7.3 (Xcode 4.3) iMac MA876 3GB OS X 10.7.3 iPhone 4S 16GB 5.0.1 / iPad 2 16GB 5.0.1 Need translations to Norwegian? Happy to help.



skochan


« Reply #3 on: February 12, 2009, 01:11:05 PM » 

Yep, looks good!
Cheers,
Steve



Logged




rock
Newbie
Posts: 10


« Reply #4 on: April 11, 2009, 11:20:01 AM » 

I am having an issue with understanding the statement "Modify the print method from your Fraction class so that it takes an optional BOOL argument..." from this exercise. The solution given here is not actually an optional argument, is it (i.e. you must supply YES or NO)? How do you create a method that has truly optional arguments, and does that actually apply to this exercise, or was the intention to simply have a BOOL that is always populated (which is not how the exercise reads at all, btw)? Related to that, how do you create an argument that is prepopulated with a default, as in: function(a,b=null) so that "a" is required, but if "b" is not supplied, the default is null? Is that something that even makes sense in ObjectiveC? Thanks.



Logged




skochan


« Reply #5 on: April 11, 2009, 11:44:44 AM » 

That is a typo. It really should say to modify it to take an additional argument, not an optional one!
Cheers,
Steve Kochan



Logged




dysan819
Newbie
Posts: 1


« Reply #6 on: April 12, 2009, 03:40:51 PM » 

That helps, because I don't think that technique was explained yet. Could you write a second version of the method:  (void) simplify { // do work here }  (void) print { // do work here }  (void) print: (BOOL) simplify { if (simplify) { [self simplify]; } [self print]; }
and the program will run the correct version? [aFraction print]; [aFraction print: TRUE];



Logged




skochan


« Reply #7 on: April 12, 2009, 05:16:57 PM » 

That works but, of course, print and print: are two different methods, not one that takes an optional argument!
Cheers,
Steve



Logged




scutter7282
Newbie
Posts: 18


« Reply #8 on: June 02, 2009, 02:38:38 PM » 

This question is about 7.2 but on the topic of memory release (related to the big 7.5/7.6 discussion which I've read): I'm wondering where in my code does it indicate that the object "result" that I created in the print method is released? In the console, it looks fine. If I add to main.m "[result release];" before or after releasing aFraction, it says it can't release something already released. Comparing to 7.5, it seems to me that I was supposed to release both of them in order to not have memory leak. #import <Foundation/Foundation.h>
@interface Fraction: NSObject { int numerator; int denominator; }
@property int numerator, denominator;
(void) print: (BOOL) simplify; (void) setTo: (int) n over: (int) d; (void) reduce; @end
@implementation Fraction
@synthesize numerator, denominator;
(void) print: (BOOL) simplify { if (denominator == 1) NSLog(@"%i", numerator); else if (numerator == 0) NSLog(@"0"); else if (simplify) { Fraction *result = [[Fraction alloc] init]; [result setTo: numerator over: denominator]; [result reduce]; NSLog(@"%i/%i", result.numerator, result.denominator); // release result in main } else NSLog(@"%i/%i", numerator, denominator); } (void) setTo: (int) n over: (int) d { numerator = n; denominator = d; } (void) reduce { int u = numerator; int v = denominator; int temp; while (v != 0) { temp = u % v; u = v; v = temp; } numerator /= u; denominator /= u; } @end
int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *aFraction = [[Fraction alloc] init]; Fraction *result; [aFraction setTo: 6 over: 8];
result = aFraction; [result print: YES]; [aFraction print: NO];
[aFraction release]; [pool drain]; return 0; }
/* Console Output: [Session started at 20090602 17:37:24 0400.] 20090602 17:37:24.725 Fraction[10495:10b] 3/4 20090602 17:37:24.727 Fraction[10495:10b] 6/8
The Debugger has exited with status 0. */



Logged




skochan


« Reply #9 on: June 02, 2009, 02:51:05 PM » 

You don't need to use the temporary Fraction result that you create inside your add: method after you've reduced and printed its value. That is, its value is not returned to (or needed by) the caller (main) and so you can release it in your print method when you're done using it.
Cheers,
Steve



Logged




nhohmann


« Reply #10 on: July 02, 2009, 05:06:39 AM » 

(void) print: (BOOL) simplify { if ( simplify ) { Fraction *result = [[Fraction alloc] init]; [result setTo: numerator over: denominator]; [result reduce];
NSLog (@"%i/%i  WAS reduced.", numerator, denominator); [result release]; } else { NSLog (@"%i/%i  NOT reduced.", numerator, denominator); } }
I realize this was posted months ago, but I'm confused. What does your FractionTest.m look like? Specifically, what expression or "test" is determining whether or not the Boolean variable "simplify" (as shown above) is TRUE or FALSE? It seems like the test that would determine if the fraction needs to be reduced would be the reduce loop itself (found in the reduce method), so why bother? Calling the reduce method works the same whether a fraction needs to be reduced or not. So why waste the time and code? (Especially if they're one and the same.) I must be missing something. Am I? (I hope so.) Please help. Thanks, Neil



Logged




skochan


« Reply #11 on: July 02, 2009, 06:39:39 AM » 

Neil, The purpose of this exercise was to add a print: method that takes a BOOL argument to indicate if you want to have to fraction reduced before printing. That's not the same as specifying whether the fraction can be reduced. So, for example, give the fraction 6/8 is stored in myFract, this call: [myFract print: YES];
should produce 3/4 as the output, whereas [myFract print: NO];
should display 6/8, since the NO means not to reduce the fraction. Cheers, Steve Kochan



Logged




nhohmann


« Reply #12 on: July 03, 2009, 02:45:33 AM » 

Thanks Steve  I think I was reading too much into the exercise. That said, here are snippets of my code and output. Everything seems to work (after a good 30 minutes of banging around). Let me know if anything seems amiss. Here is the console output, which includes the reduced and nonreduced result (to show that the original fraction was not permanently changed): [ [Session started at 20090703 11:12:33 +0200.] 20090703 11:12:33.082 FractionTest[1182:10b] 2/4 20090703 11:12:33.092 FractionTest[1182:10b] + 20090703 11:12:33.095 FractionTest[1182:10b] 1/4 20090703 11:12:33.097 FractionTest[1182:10b] = 20090703 11:12:33.099 FractionTest[1182:10b] 3/4 20090703 11:12:33.102 FractionTest[1182:10b] Previously the fraction had been 12/16.
The Debugger has exited with status 0.
Here is part of the FractionTest.m file that calls the print method with the added Boolean variable, reduceFrac: // Print results [aFraction print: NO]; NSLog (@"+"); [bFraction print: NO]; NSLog (@"="); resultFraction = [aFraction add: bFraction]; [resultFraction print: YES];
And here is the print method in the Fraction.m file: (void) print: (BOOL) reduceFrac { if (denominator == 1) NSLog (@"%i", numerator); else if (reduceFrac) { Fraction *reduceFraction = [[Fraction alloc] init]; [reduceFraction setTo: numerator over: denominator]; [reduceFraction reduce]; NSLog(@"%i/%i", reduceFraction.numerator, reduceFraction.denominator); NSLog (@"Previously the fraction had been %i/%i.", numerator, denominator); [reduceFraction release]; } else NSLog (@"%i/%i", numerator, denominator); }


« Last Edit: July 04, 2009, 07:13:57 AM by nhohmann »

Logged




TheWildJacko
Newbie
Posts: 2


« Reply #13 on: August 27, 2009, 11:59:38 PM » 

Thanks for posting these answers. This exercise confused me a bit but now I get it. Also, once I understood out how to do this exercise, I found that if the fraction you are trying to reduce is something like 9/3, the print method will reduce it to 3/1, not 3 (because it will only check for 1 in the denominator once, before it reduces the fraction). So you can add an extra else if statement checking whether numerator % denominator == 0, and then printing a whole number if the if statement is true.  (void) print: (BOOL) toReduce { if (denominator == 1) NSLog(@"%i", numerator); else if (numerator == 0) NSLog(@"0"); else if (numerator % denominator == 0) NSLog(@"%i", numerator / denominator); else if (denominator == 0) NSLog(@"Undefined: denominator = 0"); else if (toReduce) { Fraction *result = [[Fraction alloc] init]; [result setTo: numerator over: denominator]; [result reduce]; if (result.denominator == 1) NSLog(@"%i", result.numerator); else NSLog(@"%i/%i", result.numerator, result.denominator); [result release]; } else NSLog(@"%i/%i", numerator, denominator); }


« Last Edit: August 28, 2009, 01:00:31 AM by TheWildJacko »

Logged




jocko757
Newbie
Posts: 12


« Reply #14 on: February 28, 2010, 08:49:44 AM » 

Hi guys, I have ZERO programming experience and am way behind all of you. This exercise took me two days and I'm still confused about one thing...
Can anyone explain to me where you declare the Boolean variable? I declared it in the main like this:
BOOL toReduce;
In the interface section, I declared the print method like this:
(void) print: (BOOL) toReduce;
Then I called on the print method like this...
[aFraction print: NO]
[resultFraction print: YES]
When I run the program, I get the correct result, but I get a caution...
unused variable "toReduce"
If I comment out //BOOL toReduce; everything works. So my question is, how does the program know that the boolean variable "toReduce" is in fact a boolean variable? From the declaration in the interface section?
Any clarification would be appreciated. Thanks, Jack



Logged




