Challenge Solution - What am I doing wrong?


#1

Hi,

This by far has been the most confusing chapter/challenge of all. So after several attempts, I’ve finally managed to get it to work but looking at my output, I feel as if I’m doing something wrong and the code/process isn’t very efficient at all.

It seems as if the value of the Portfolio is being calculated all at once and not when a stock is added to it. I realize that I’m adding the objects to the Portfolio before the for loop but when I try to add the objects to the Portfolio in the for loop and run the program, it succeeds in building it and runs it but I can’t see any output.

Would love for someone to explain what is it that I could do better and make my code better and how to have it so the portfolio value is calculated only once the stock is added to it.

Thanks!

StockHoldings.h

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

@interface StockHoldings : NSObject

// Set the instance variables

{
NSString *stockName;
float purchaseSharePrice;
float currentSharePrice;
int numberOfShares;
}

//Use the instance variables using these methods
@property NSString *stockName;
@property float purchaseSharePrice;
@property float currentSharePrice;
@property int numberOfShares;

//These methods calculate the cost and the value of the stocks

  • (float) costInDollars;
  • (float) valueInDollars;

@end
[/code]

StockHoldings.m

[code]#import “StockHoldings.h”

@implementation StockHoldings

// Set the setter methods
@synthesize stockName;
@synthesize purchaseSharePrice;
@synthesize currentSharePrice;
@synthesize numberOfShares;

  • (float) costInDollars
    {
    float p = [self purchaseSharePrice];
    return [self numberOfShares] * p;

}

  • (float) valueInDollars
    {
    float c = [self currentSharePrice];
    return [self numberOfShares] * c;
    }

@end[/code]

Portfolio.h

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

@interface Portfolio : NSObject

//Create the array

{
NSMutableArray *stocksInThePortfolio;
}

@property NSMutableArray *stocksInThePortfolio;

  • (void) addStocksInThePortfolioObject:(StockHoldings *)a;

  • (float) valueOfThePortfolio;

@end
[/code]

Portfolio.m

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

@implementation Portfolio

@synthesize stocksInThePortfolio;

  • (void) addStocksInThePortfolioObject:(StockHoldings *)a
    {
    // Is Portfolio Nil?
    if (!stocksInThePortfolio) {

      //Create the Array
      stocksInThePortfolio = [[NSMutableArray alloc] init];
              
          }  
              
              //Else add the object in the array
              [stocksInThePortfolio addObject:a];
    

}

  • (float) valueOfThePortfolio
    {
    float sum = 0;
    for (StockHoldings *a in stocksInThePortfolio) {
    sum += [a valueInDollars];

      // Checking to how the values are being calculated
      NSLog(@"The value is %.2f", sum);
    

    }
    return sum;
    }

@end
[/code]

Main.m

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

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

@autoreleasepool {
    
    StockHoldings *google = [[StockHoldings alloc] init];
    StockHoldings *apple = [[StockHoldings alloc] init];
    StockHoldings *facebook = [[StockHoldings alloc] init];
    
    //Build an array for the portfolio
    Portfolio *portfolioStocks = [[Portfolio alloc] init];
    
    //Assign values to the stocks
    [google setStockName:@"Google"];
    [google setPurchaseSharePrice:5.00];
    [google setCurrentSharePrice:10.00];
    [google setNumberOfShares:1000];
    
    
    [apple setStockName:@"Apple"];
    [apple setPurchaseSharePrice:20.00];
    [apple setCurrentSharePrice:200.00];
    [apple setNumberOfShares:1000];
    
    
    [facebook setStockName:@"Facebook"];
    [facebook setPurchaseSharePrice:50.00];
    [facebook setCurrentSharePrice:10.00];
    [facebook setNumberOfShares:200.00];

    
    [portfolioStocks addStocksInThePortfolioObject:google];
    [portfolioStocks addStocksInThePortfolioObject:apple];
    [portfolioStocks addStocksInThePortfolioObject];
    
    
    // Go through the array and print out the value of the portfolio
    
    for ( StockHoldings *s in portfolioStocks.stocksInThePortfolio ) {
        
        
        NSLog(@"%@ has a value of %.2f", s.stockName, s.valueInDollars);

        
        NSLog(@"The value of the portfolio is %.2f", portfolioStocks.valueOfThePortfolio);
    }
    
    
}
return 0;

}
[/code]

Output

2012-06-30 15:34:09.310 PortfolioStocks[566:403] Google has a value of 10000.00 2012-06-30 15:34:09.312 PortfolioStocks[566:403] The value is 10000.00 2012-06-30 15:34:09.314 PortfolioStocks[566:403] The value is 210000.00 2012-06-30 15:34:09.315 PortfolioStocks[566:403] The value is 212000.00 2012-06-30 15:34:09.316 PortfolioStocks[566:403] The value of the portfolio is 212000.00 2012-06-30 15:34:09.317 PortfolioStocks[566:403] Apple has a value of 200000.00 2012-06-30 15:34:09.317 PortfolioStocks[566:403] The value is 10000.00 2012-06-30 15:34:09.318 PortfolioStocks[566:403] The value is 210000.00 2012-06-30 15:34:09.319 PortfolioStocks[566:403] The value is 212000.00 2012-06-30 15:34:09.319 PortfolioStocks[566:403] The value of the portfolio is 212000.00 2012-06-30 15:34:09.320 PortfolioStocks[566:403] Facebook has a value of 2000.00 2012-06-30 15:34:09.321 PortfolioStocks[566:403] The value is 10000.00 2012-06-30 15:34:09.322 PortfolioStocks[566:403] The value is 210000.00 2012-06-30 15:34:09.322 PortfolioStocks[566:403] The value is 212000.00 2012-06-30 15:34:09.323 PortfolioStocks[566:403] The value of the portfolio is 212000.00


#2

First of all, remove the log statement from the valueOfThePortfolio method in Portfolio; printing the running sum there makes the output logs very confusing.

Secondly, to have the portfolio value calculated only once a stock is added to it, add a property to Portfolio and update its value when a new stock is added:

Portfolio.m:

@interface Portfolio ()
@property float currentValueOfThePortfolio;
@end

@implementation Portfolio

@synthesize currentValueOfThePortfolio;
@synthesize stocksInThePortfolio;

- (void)addStocksInThePortfolioObject:(StockHoldings *)a
{
    if (!stocksInThePortfolio) {
        
        //Create the Array
        self.stocksInThePortfolio = [[NSMutableArray alloc] init];
        
    }  
    [self.stocksInThePortfolio addObject:a];
    
    self.currentValueOfThePortfolio += [a valueInDollars];
}

- (float)valueOfThePortfolio
{
    return [self currentValueOfThePortfolio];
}

@end

Thirdly, remove all comments that do not convey useful information:

Finally, flush the output stream buffers just before leaving main ():

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

        for (StockHoldings *s in portfolioStocks.stocksInThePortfolio) {
            NSLog (@"---> %@ has a value of %.2f", s.stockName, s.valueInDollars);
        }
        NSLog (@"The value of the portfolio is %.2f", portfolioStocks.valueOfThePortfolio);
    }
    fflush (NULL);
    return 0;
}

Without this, sometimes not all your logs will make it to the console.


#3

Thanks a lot ibex!! You’re awesome!! :smiley:

I’ve been trying to get over this challenge for a while and seems like I finally understand it.

Thanks again!


#4

[quote=“ibex10”][quote]
Would love for someone to explain what is it that I could do better and make my code better and how to have it so the portfolio value is calculated only once the stock is added to it.
[/quote]
First of all, remove the log statement from the valueOfThePortfolio method in Portfolio; printing the running sum there makes the output logs very confusing.

Secondly, to have the portfolio value calculated only once a stock is added to it, add a property to Portfolio and update its value when a new stock is added:

Portfolio.m:

@interface Portfolio ()
@property float currentValueOfThePortfolio;
@end

@implementation Portfolio

@synthesize currentValueOfThePortfolio;
@synthesize stocksInThePortfolio;

- (void)addStocksInThePortfolioObject:(StockHoldings *)a
{
    if (!stocksInThePortfolio) {
        
        //Create the Array
        self.stocksInThePortfolio = [[NSMutableArray alloc] init];
        
    }  
    [self.stocksInThePortfolio addObject:a];
    
    self.currentValueOfThePortfolio += [a valueInDollars];
}

- (float)valueOfThePortfolio
{
    return [self currentValueOfThePortfolio];
}

@end
[/code][/quote]

It's still calculating the value altogether and not one at a time... Here's the output.

[code]2012-07-01 11:21:58.102 PortfolioFromForums[1256:403]  ----> Google has a value of 10000.00
2012-07-01 11:21:58.104 PortfolioFromForums[1256:403] The value of the portfolio is 212000.00
2012-07-01 11:21:58.105 PortfolioFromForums[1256:403]  ----> Apple has a value of 200000.00
2012-07-01 11:21:58.106 PortfolioFromForums[1256:403] The value of the portfolio is 212000.00
2012-07-01 11:21:58.106 PortfolioFromForums[1256:403]  ----> Facebook has a value of 2000.00
2012-07-01 11:21:58.108 PortfolioFromForums[1256:403] The value of the portfolio is 212000.00