Favorite Challenge so Far!


#1

I really liked this challenge a lot! This book has been great so far, and now I’ve seen the sneakiest code reuse exercise ever made. :astonished:

First I made my new project, then imported my StockHolding class from earlier. Then I made my Portfolio class:

Portfolio.h

[code]#import <Foundation/Foundation.h>
#import “StockHolding.h”

@interface Portfolio : NSObject
{
// We need to have a mutable array
NSMutableArray *portfolio;

}

// Methods to add our stocks
-(void)addStock:(StockHolding *)stock;
-(unsigned int)portfolioValue;
-(unsigned long)numberOfStocks;

@end[/code]

Portfolio.m

[code]#import “Portfolio.h”
#import “StockHolding.h”

@implementation Portfolio

// Methods

// Add stocks to the portfolio
-(void)addStock:(StockHolding *)stock
{
// Do we need to make an array
if (!portfolio) {

    // Make a new portfolio array
    portfolio = [[NSMutableArray alloc] init];

}

// Add the stock
[portfolio addObject:stock];

}

// Get the total portfolio value
-(unsigned int)portfolioValue
{
// Set the total sum to 0
unsigned int sum = 0;

// Fast enumerate the array and add up the values
for (StockHolding *stock in portfolio) {
    sum += [stock valueInDollars];
}

return sum;

}

// How many stocks in our portfolio
-(unsigned long)numberOfStocks
{
return [portfolio count];
}

@end
[/code]

Then I coded up main to do my bidding…

main.m

[code]#import <Foundation/Foundation.h>
#import “StockHolding.h”
#import “Portfolio.h”

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

@autoreleasepool {
    
    // Create our portfolio 
    
    Portfolio *portfolio = [[Portfolio alloc] init];
    
    // Fill the array with 10 random stocks
    for (int i = 0; i < 10; i++) {
        StockHolding *stock = [[StockHolding alloc] initWithPurchasePrice:i * 42 currentPrice:i * 42 + 10 numberOfShares:i + 42];
        
        [portfolio addStock:stock];
    }
    
    // Get the total value of the portfolio
    
    NSLog(@"Portfolio contains %lu stocks. Total value: $%i", [portfolio numberOfStocks], [portfolio portfolioValue]);
    
}

return 0;

}[/code]

And the output is what I expected even if I add up all the values by hand!

This tutorial took a few minutes of thinking to get started on, but made me actually feel like I knew what I was doing!


#2

In Portfolio.h, everything is good if I use:

#import <Foundation/Foundation.h> @class StockHolding;

But if I use:

#import <Foundation/Foundation.h> #import "StockHolding.h"

Then I get an error, “expected a type” on this line:

So that’s a little confusing, because it seems like #importing would be something like a “superset” of declaring a @Class.

@macshome, thanks for your clean code to work from – I had this about 3/4 complete and just couldn’t quite get my head around how to pull it all together.


#3

I suspect there is something in your StockHolding class that isn’t jiving with the code checking that Xcode is doing. When you use #import it pulls the class in and is able to see what it expects.

Using @class is more of a quick promise that you will be providing it, but it doesn’t import until compile time.


#4

@macshome
Was reading through your code and I noticed how you did something clever with your StockHolding class. A “Class Method” that takes multiple arguments. I’m guessing thats why myacavone was unsuccessful. I already finished this challenge but would love to see how you created your StockHolding Class. Could you please post your StockHolding Class code?

the Class Method:


#5

Sure!

StockHolding.h

[code]#import <Foundation/Foundation.h>

@interface StockHolding : NSObject
{
float purchaseSharePrice;
float currentSharePrice;
int numberOfShares;
}

@property float purchaseSharePrice;
@property float currentSharePrice;
@property int numberOfShares;

// Methods
-(float)costInDollars;
-(float)valueInDollars;
-(NSString *)description;
-(id)initWithPurchasePrice:(float)pp currentPrice:(float)cp numberOfShares:(int)ns;

@end[/code]

StockHolding.m

[code]#import “StockHolding.h”

@implementation StockHolding

// Accessors
@synthesize purchaseSharePrice, currentSharePrice, numberOfShares;

// Custom init
-(id)initWithPurchasePrice:(float)pp currentPrice:(float)cp numberOfShares:(int)ns
{
self = [super init];

// Did we get something back?
if (self) {
    [self setPurchaseSharePrice:pp];
    [self setCurrentSharePrice:cp];
    [self setNumberOfShares:ns];
}

return self;

}

// Methods
-(float)costInDollars
{
return purchaseSharePrice * numberOfShares;
}

-(float)valueInDollars
{
return currentSharePrice * numberOfShares;
}

-(NSString *)description
{
return [NSString stringWithFormat:@“Stock cost %.2f and is currently worth %.2f”, [self costInDollars], [self valueInDollars]];
}

@end
[/code]

I hope that helps!


#6

In regards to my weird “expected a type” problem above:

In Portfolio.h I was #importing StockHolding.h, and in StockHolding.h I was #importing Portfolio.h. Commenting out the #import in StockHolding.h fixed it - runs the same as doing an @class in Portfolio.h.

Thanks to macintux for pinging me to ask if I’d solved it yet - I hadn’t, but it got me to open the project and in ten seconds it was obvious.

Yet another example of how taking a few days off can make the solution to a problems obvious.