Challenge Solution: Stock Portfolio

JSStockHolding.h

[code]@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) int numberShares;
@property (nonatomic) float currentSharePrice;
@property (nonatomic, copy) NSString *companyName;
@property (nonatomic, copy) NSString *tickerLabel;

  • (float)costDollars; // purchaseSharePrice * numberShares
  • (float)valueDollars; // currentSharePrice * numberShares[/code]

JSStockHolding.m

[code]- (float)costDollars
{
return self.purchaseSharePrice * self.numberShares;
}

  • (float)valueDollars
    {
    return self.currentSharePrice * self.numberShares;
    }

  • (NSString *)description
    {
    NSString *descriptionMethod = [NSString stringWithFormat:@“You paid %.2f for %d shares in %@ (%@), valued at %.2f”, self.costDollars, self.numberShares, self.companyName, self.tickerLabel, self.valueDollars];
    return descriptionMethod;
    }[/code]

JSForeignStockHolding.h

JSForeignStockHolding.m

[code]- (float)costDollars
{
return self.purchaseSharePrice * self.numberShares * self.conversionRate;
}

  • (float)valueDollars
    {
    return self.currentSharePrice * self.numberShares * self.conversionRate;
    }

  • (NSString *)description
    {
    NSString *descriptionMethod = [NSString stringWithFormat:@“You paid %.2f for %d shares in %@ (%@), valued at %.2f (CR:%.2f)”, self.costDollars, self.numberShares, self.companyName, self.tickerLabel, self.valueDollars, self.conversionRate];
    return descriptionMethod;
    }[/code]

JSPortfolio.h

[code]{
NSMutableArray *_stocks;
}

@property (nonatomic, copy) NSArray *stocks;

  • (void)addStock:(JSStockHolding *)stock;
  • (void)addForeignStock:(JSForeignStockHolding *)foreignStock;
  • (float)portfolioValue;
  • (float)totalCost;[/code]

JSPortfolio.m

[code]- (void)setPortfolio:(NSArray *)portfolio
{
_stocks = [portfolio mutableCopy];
}

  • (NSArray *)stocks
    {
    return [_stocks mutableCopy];
    }

  • (void)addStock:(JSStockHolding *)stock
    {
    if (!_stocks) {
    _stocks = [[NSMutableArray alloc] init];
    }
    [_stocks addObject:stock];
    }

  • (void)addForeignStock:(JSForeignStockHolding *)foreignStock
    {
    if (!_stocks) {
    _stocks = [[NSMutableArray alloc] init];
    }
    [_stocks addObject:foreignStock];
    }

  • (float)portfolioValue
    {
    float sum = 0;
    for (JSStockHolding *stock in _stocks) {
    sum += [stock valueDollars];
    }
    return sum;
    }

  • (float)totalCost
    {
    float sum = 0;
    for (JSStockHolding *stock in _stocks) {
    sum += [stock costDollars];
    }
    return sum;
    }

  • (NSString *)description
    {
    NSString *descriptionMethod = [NSString stringWithFormat:@"%@\nYour portfolio cost %.2f and is valued at %.2f", self.stocks, self.totalCost, self.portfolioValue];
    return descriptionMethod;
    }[/code]

Main.m

[code]JSPortfolio *financialPortfolio = [[JSPortfolio alloc] init];

// Generate names for stocks and ticker labels
NSArray *names = @[@“Apple”, @“Volvo”, @“Microsoft”, @“Netflix”];
NSArray *tickerLabels = @[@“ABC”, @“DEF”, @“GHI”, @“JKL”];

for (int i = 0; i < [names count]; i++) {
JSStockHolding *newStock = [[JSStockHolding alloc] init];

NSString *stockName = [names objectAtIndex:i];
newStock.companyName = stockName;
newStock.purchaseSharePrice = 2.30 + i * (arc4random() % 3);
newStock.currentSharePrice = 4.50 + i * (arc4random() % 2);
newStock.numberShares = 15 + i * (arc4random() % 4);
newStock.tickerLabel = [tickerLabels objectAtIndex:i];

[financialPortfolio addStock];

}

// Generate names for foreign stocks and ticker labels
NSArray *fNames = @[@“Izuzu”, @“Toyota”, @“Toshiba”, @“Fujitsu”];
NSArray *fTickers = @[@“MNO”, @“PQR”, @“STU”, @“VWX”];

for (int i = 0; i < [fNames count]; i++) {
JSForeignStockHolding *foreignStock = [[JSForeignStockHolding alloc] init];

NSString *foreignStockName = [fNames objectAtIndex:i];
foreignStock.companyName = foreignStockName;
foreignStock.purchaseSharePrice = 3.15 + i * (arc4random() % 3);
foreignStock.currentSharePrice = 5.15 + i * (arc4random() % 2);
foreignStock.numberShares = 10 + i * (arc4random() % 4);
foreignStock.conversionRate = 0.50 + (0.15 * i);
foreignStock.tickerLabel = [fTickers objectAtIndex:i];

[financialPortfolio addForeignStock:foreignStock];

}

NSLog(@"%@", financialPortfolio);[/code]

Output

[quote](
“You paid $34.50 for 15 shares in Apple (ABC), valued at $67.50”,
“You paid $59.40 for 18 shares in Volvo (DEF), valued at $99.00”,
“You paid $107.10 for 17 shares in Microsoft (GHI), valued at $110.50”,
“You paid $95.40 for 18 shares in Netflix (JKL), valued at $135.00”,
“You paid $15.75 for 10 shares in Izuzu (MNO), valued at $25.75 (CR:0.50)”,
“You paid $26.97 for 10 shares in Toyota (PQR), valued at $39.97 (CR:0.65)”,
“You paid $65.92 for 16 shares in Toshiba (STU), valued at $91.52 (CR:0.80)”,
“You paid $111.01 for 19 shares in Fujitsu (VWX), valued at $92.96 (CR:0.95)”
)
Your portfolio cost $516.05 and is valued at $662.20[/quote]

I tried your code and I got the following error in BNRPortfolio.m:

This error came up on two lines.

The first time the error came up was on the following line:

[_stocks addObject:stock];

The second time the error came up was on the following line:

[_stocks addObject:foreignStock];

The program won’t run as a result.

Below is all of my code for your reference, but I have pretty much copied it exactly from your post:

main.m:

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

int main(int argc, const char * argv[]) {
    @autoreleasepool
    
    {
        BNRPortfolio *financialPortfolio = [[BNRPortfolio alloc] init];
        
        // Generate names for stocks and ticker symbols
        NSArray *names = @[@"Apple", @"Volvo", @"Microsoft", @"Netflix"];
        NSArray *tickerLabels = @[@"ABC", @"DEF", @"GHI", @"JKL"];
        
        for (int i = 0; i < [names count]; i++) {
            BNRStockHolding *newStock = [[BNRStockHolding alloc] init];
            NSString *stockName = [names objectAtIndex:i];
            newStock.companyName = stockName;
            newStock.purchaseSharePrice = 2.30 + i * (arc4random() % 3);
            newStock.currentSharePrice = 4.50 + i * (arc4random() % 2);
            newStock.numberOfShares = 15 + i * (arc4random() % 4);
            newStock.tickerLabel = [tickerLabels objectAtIndex:i];
            
            [financialPortfolio addStock];
        }
        
        // Generate names for foreign stocks and ticker labels
        
        NSArray *fNames = @[@"Izuzu", @"Toyota", @"Toshiba", @"Fujitsu"];
        NSArray *fTickers = @[@"MNO", @"PQR", @"STU", @"VWX"];
        
        for (int i = 0; i < [fNames count]; i++) {
            BNRForeignStockHolding *foreignStock = [[BNRForeignStockHolding alloc] init];
            
            NSString *foreignStockName = [fNames objectAtIndex:i];
            foreignStock.companyName = foreignStockName;
            foreignStock.purchaseSharePrice = 3.15 + i * (arc4random() % 3);
            foreignStock.currentSharePrice = 5.15 + i * (arc4random() % 2);
            foreignStock.numberOfShares = 10 + i * (arc4random() % 4);
            foreignStock.conversionRate = 0.50 + (0.15 * i);
            foreignStock.tickerLabel = [fTickers objectAtIndex:i];
            
            [financialPortfolio addForeignStock:foreignStock];
        }
        
        NSLog(@"%@", financialPortfolio);
    }
    return 0;
}

BNRStockHolding.h:

#import <Foundation/Foundation.h>

@interface BNRStockHolding : NSObject

@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;
@property (nonatomic, copy) NSString *companyName;
@property (nonatomic, copy) NSString *tickerLabel;

// BNRStockHolding has methods to read and set its instance variables
- (float)costInDollars; // purchaseSharePrice * numberOfShares
- (float)valueInDollars; // currentSharePrice * numberOfShares

@end

BNRStockHolding.m:

#import "BNRStockHolding.h"

@implementation BNRStockHolding

- (float)costInDollars
{
    return (_purchaseSharePrice * _numberOfShares);
}

- (float)valueInDollars
{
    return (_currentSharePrice * _numberOfShares);
}

- (NSString *)description
{
    NSString *descriptionMethod = [NSString stringWithFormat:@"You paid $%.2f for %d shares in %@ (%@), valued at $%.2f", self.costInDollars, self.numberOfShares, self.companyName, self.tickerLabel, self.valueInDollars];
    return descriptionMethod;
}

@end

BNRForeignStockHolding.h:

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

@interface BNRForeignStockHolding : BNRStockHolding

@property (nonatomic) float conversionRate;

@end

BNRForeignStockHolding.m:

#import "BNRForeignStockHolding.h"

@implementation BNRForeignStockHolding

- (float)costInDollars
{
    return (self.purchaseSharePrice * self.numberOfShares * _conversionRate);
}

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

- (NSString *)description
{
    NSString *descriptionMethod = [NSString stringWithFormat:@"You paid $%.2f for %d shares in %@ (%@), valued at $%.2f (CR:%.2f)", self.costInDollars, self.numberOfShares, self.companyName, self.tickerLabel, self.valueInDollars, self.conversionRate];
    return descriptionMethod;
}

@end

BNRPortfolio.h:

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

@interface BNRPortfolio : NSObject

{
    NSMutableArray *stocks;
}

@property (nonatomic, copy) NSArray *stocks;

- (void)addStock:(BNRStockHolding *)stock;
- (void)addForeignStock:(BNRForeignStockHolding *)foreignStock;
- (float)portfolioValue;
- (float)totalCost;

@end

BNRPortfolio.m:

#import "BNRPortfolio.h"

@implementation BNRPortfolio

- (void)setPortfolio:(NSArray *)portfolio
{
    _stocks = [portfolio mutableCopy];
}

- (NSArray *)stocks
{
    return [_stocks mutableCopy];
}

- (void)addStock:(BNRStockHolding *)stock
{
    if (!_stocks) {
        _stocks = [[NSMutableArray alloc] init];
    }
    [_stocks addObject:stock];
}

- (void)addForeignStock:(BNRForeignStockHolding *)foreignStock
{
    if (!_stocks) {
        _stocks = [[NSMutableArray alloc] init];
    }
    [_stocks addObject:foreignStock];
}

- (float)portfolioValue
{
    float sum = 0;
    for (BNRStockHolding *stock in _stocks) {
        sum += [stock valueInDollars];
    }
    return sum;
}

- (float)totalCost
{
    float sum = 0;
    for (BNRStockHolding *stock in _stocks) {
        sum += [stock costInDollars];
    }
    return sum;
}

- (NSString *)description
{
    NSString *descriptionMethod = [NSString stringWithFormat:@"%@\nYour portfolio cost $%.2f and is valued at $%.2f", self.stocks, self.totalCost, self.portfolioValue];
    return descriptionMethod;
}

@end

Could you please help me figure out where I’ve gone wrong?