Challenge 1

I am new to all of this and this is a hard chapter for me so please can you guys give me some pointers.

BNRPortfolio.h

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

@interface BNRPortfolio : NSObject
{
    NSMutableArray *_holdings;
}

@property (nonatomic, copy) NSArray *holdings;
- (void)addHolding:(BNRStockHolding *)stock;
- (float)totalValue;
@end

BNRPortfolio.m

#import "BNRPortfolio.h"
#import "BNRStockHolding.h"

@implementation BNRPortfolio 

// Accessors for holdings properties
- (void)setHoldings:(NSArray *)holdings
{
    _holdings = [holdings mutableCopy];
}

- (NSArray *)holdings
{
    return [_holdings copy];
}

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

- (float)totalValue
{
    float totalValue = 0.0;
    for (BNRStockHolding *stock in _holdings) {
        totalValue = totalValue + [stock valueInDollars];
    }
    return totalValue;
}

- (NSString *)description
{
    for(BNRStockHolding *stock in self.holdings)
    {
        NSLog(@"%@", stock);
    }
    return [NSString stringWithFormat: @"The value of your portfolio is $%.2f.", self.totalValue];
}

@end

BNRStockHolding.h

#import <Foundation/Foundation.h>

@interface BNRStockHolding : NSObject

@property (nonatomic) NSString *symbol;
@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;
- (float)costInDollars;
- (float)valueInDollars;

@end

BNRStockHolding.m

#import "BNRStockHolding.h"

@implementation BNRStockHolding

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

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

- (NSString *)description
{
    return [NSString stringWithFormat: @"<Ticker: %@, Value: $%.2f>", self.symbol, self.valueInDollars];
}

@end

BNRForeignStockHolding.h

#import "BNRStockHolding.h"

@interface BNRForeignStockHolding : BNRStockHolding

@property (nonatomic) float conversionRate;

@end

BNRForeignStockHolding.m

#import "BNRForeignStockHolding.h"

@implementation BNRForeignStockHolding

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

- (float)valueInDollars {
    return super.purchaseSharePrice * self.conversionRate * super.numberOfShares;
}

@end

main.m

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

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

    @autoreleasepool {
        
        // Create BNRStockHoldings
        BNRStockHolding *appl = [[BNRStockHolding alloc] init];
        BNRStockHolding *msft = [[BNRStockHolding alloc] init];
        BNRStockHolding *goog = [[BNRStockHolding alloc] init];
        BNRForeignStockHolding *ssnlf = [[BNRForeignStockHolding alloc] init];
        BNRForeignStockHolding *htc = [[BNRForeignStockHolding alloc] init];
        
        // Set Stock Variables
        appl.purchaseSharePrice = 60.0;
        appl.currentSharePrice = 99.3;
        appl.numberOfShares = 10;
        appl.symbol = @"APPL";
        
        msft.purchaseSharePrice = 30.0;
        msft.currentSharePrice = 33.5;
        msft.numberOfShares = 12;
        msft.symbol = @"MSFT";
        
        goog.purchaseSharePrice = 425.8;
        goog.currentSharePrice = 400.0;
        goog.numberOfShares = 15;
        goog.symbol = @"GOOG";
        
        ssnlf.purchaseSharePrice = 1400.0;
        ssnlf.currentSharePrice = 1394.14;
        ssnlf.conversionRate = .34;
        ssnlf.numberOfShares = 25;
        ssnlf.symbol = @"SSNLF";
        
        htc.purchaseSharePrice = 141.5;
        htc.currentSharePrice = 140.0;
        htc.numberOfShares = 150;
        htc.conversionRate = .80;
        htc.symbol = @"HTC";
        
        // Create Stock Portfolio and add BNRStockHoldings
        BNRPortfolio *stockPortfolio = [[BNRPortfolio alloc] init];
        [stockPortfolio addHolding: appl];
        [stockPortfolio addHolding: msft];
        [stockPortfolio addHolding: goog];
        [stockPortfolio addHolding: ssnlf];
        [stockPortfolio addHolding: htc];
        
        NSLog(@"%@", stockPortfolio);
        
    }
    return 0;
}

Mine has a similar approach to yours. Any feedback would be appreciated it.

BNRPortfolio.h

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

@interface BNRPortfolio : NSObject
{
    NSMutableArray *_holdings;
}

@property (nonatomic, copy) NSArray *holdings;


- (void)addToPortfolio:(BNRStockHolding *)a;
- (float)totalValue;


@end

BNRPortfolio.m

#import "BNRPortfolio.h"

@implementation BNRPortfolio

// setter method for - @property (nonatomic, copy) NSArray *portfolio;
- (void)setHoldings:(NSArray *)a
{
    _holdings = [a mutableCopy];
}

// getter method for - @property (nonatomic, copy) NSArray *portfolio;
- (NSArray *)holdings
{
    return [_holdings copy];
}

- (void)addToPortfolio:(BNRStockHolding *)a
{
    if (!_holdings) {
        _holdings = [[NSMutableArray alloc] init];
    }
    [_holdings addObject:a];
}

- (float)totalValue
{
    float sum = 0.0;
    for (BNRStockHolding *a in _holdings)
    {
        sum += [a valueInDollars];
            }
    return sum;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"The total value of my portfolio is %.2f", self.totalValue];
}

@end

BNRStockHolding.h

#import <Foundation/Foundation.h>

@interface BNRStockHolding : NSObject

// Declare properties
@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;
@property (nonatomic) NSString *stockName;


// Declare the instance methods
- (float)costInDollars; // purchaseSharePrice * numberOfShares
- (float)valueInDollars; // currentSharePrice * numberOfShares
- (float)profit; // valueInDollars - costInDollars



@end

BNRStockHolding.m

#import "BNRStockHolding.h"

@implementation BNRStockHolding

// implement the instance methods
// costInDollars = purchaseSharePrice * numberOfShares
- (float)costInDollars {
    float i = [self purchaseSharePrice];
    return i * [self numberOfShares];
}

// valueInDollars = currentSharePrice * numberOfShares
- (float)valueInDollars {
    float i = [self currentSharePrice];
    return i * [self numberOfShares];
}

// profit = valueInDollars - costInDollars
- (float)profit {
    float costInDollars = [self costInDollars];
    float valueInDollars = [self valueInDollars];
    return valueInDollars - costInDollars;
}

// addSelfToArray method
- (void)addSelfToArray:(NSMutableArray *)theArray {
    [theArray addObject:self];
}


@end

BNRForeignStockHolding.h

#import "BNRStockHolding.h"

@interface BNRForeignStockHolding : BNRStockHolding

// Declare a property
@property (nonatomic) float conversionRate;


@end

BNRForeignStockHolding.m

#import "BNRForeignStockHolding.h"

@implementation BNRForeignStockHolding

// Override the instance methods to consider conversion rate (costInDollars and valueInDollars)

// costInDollars = (purchaseSharePrice * numberOfShares) * conversionRate
- (float)costInDollars {
    float purchasedPrice = [super costInDollars];
    float conversionRate = [self conversionRate];
    return purchasedPrice * conversionRate;
}

// valueInDollars = (currentSharePrice * numberOfShares) * conversionRate
- (float)valueInDollars {
    float currentValue = [super valueInDollars];
    return currentValue * [self conversionRate];
}


@end

main.m

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

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

    @autoreleasepool {
        
        // Create BNRPortfolio object to hold the stocks.
        BNRPortfolio *myPortfolio = [[BNRPortfolio alloc] init];
        
        // (1) Create instances of BNRStockHolding objects
        // (2) Give values to object's instance variables
        // (3) Add to my portfolio
        
        BNRStockHolding *apple = [[BNRStockHolding alloc] init];
        
        apple.purchaseSharePrice = 2.30;
        apple.currentSharePrice = 500;
        apple.numberOfShares = 1500;
        apple.stockName = @"APPLE";
        [myPortfolio addToPortfolio:apple];
        
        BNRStockHolding *google = [[BNRStockHolding alloc] init];
        
        google.purchaseSharePrice = 15.43;
        google.currentSharePrice = 500;
        google.numberOfShares = 1500;
        google.stockName = @"GOOGL";
        [myPortfolio addToPortfolio:google];
        
        BNRStockHolding *facebook = [[BNRStockHolding alloc] init];

        facebook.purchaseSharePrice = 30.50;
        facebook.currentSharePrice = 800;
        facebook.numberOfShares = 1500;
        facebook.stockName = @"FCBOK";
        [myPortfolio addToPortfolio];
        
        // (1) Create instances of BNRForeignStockHolding objects
        // (2) Give values to object's instance variables
        // (3) Add to my portfolio
        
        BNRForeignStockHolding *kakaoTalk = [[BNRForeignStockHolding alloc] init];
        
        kakaoTalk.purchaseSharePrice = 15000;
        kakaoTalk.currentSharePrice = 30000;
        kakaoTalk.numberOfShares = 400;
        kakaoTalk.stockName = @"KAKAO";
        kakaoTalk.conversionRate = 0.000973;
        [myPortfolio addToPortfolio:kakaoTalk];
        
        BNRForeignStockHolding *daum = [[BNRForeignStockHolding alloc] init];
        
        daum.purchaseSharePrice = 30000;
        daum.currentSharePrice = 50000;
        daum.numberOfShares = 600;
        daum.stockName = @"DAUM";
        daum.conversionRate = 0.000973;
        [myPortfolio addToPortfolio:daum];
        
        BNRForeignStockHolding *naver = [[BNRForeignStockHolding alloc] init];
        
        naver.purchaseSharePrice = 50000;
        naver.currentSharePrice = 70000;
        naver.numberOfShares = 300;
        naver.stockName = @"NAVER";
        naver.conversionRate = 0.000973;
        [myPortfolio addToPortfolio:naver];
        
        // Iterate though arrays and print the values
        
        for (BNRStockHolding *i in myPortfolio.holdings) {
            // declare local variables
            float purchasedAt = [i costInDollars];
            float currentValue = [i valueInDollars];
            float profit = [i profit];
            NSString *name = [i stockName];
            NSLog(@"\nStock: %@\nPurchased Price: %.2f\nCurrent Value: %.2f\nProfit: %.2f\n", name, purchasedAt, currentValue, profit);
        }
        
        // Print the total value of stocks in my portfolio
        
        NSLog(@"\n%@", myPortfolio);

    }
    return 0;
}

Mine was essentially the same, other than the final for loop printing each holding. Skipped all the class declaration files, but here’s my main.m…
@hahndrew - my final for loop is a bit simpler than yours. I’m already getting a bit lazy in that I’d prefer to use variables that are already defined, instead of defining another variable, copying the value of the instance variable into the new variable, then printing the new variable. I’ve just been printing the value of the instance variable directly within the NSLog.
However, I kept getting an uncaught exception error and I couldn’t figure out why, until I saw your code. Turns out I was trying to send a request for the details of each holding, to the portfolio name itself, not the MutableArray contained within the portfolio. Thanks for helping me figure this out!

Here’s my main.m in case you are interested in the final for loop:

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

@autoreleasepool {

    BNRPortfolio *stockHoldings = [[BNRPortfolio alloc]init];

    BNRStockHolding *csco = [[BNRStockHolding alloc]init];
    [csco setNameOfStock:@"CSCO"];
    [csco setPurchaseSharePrice:22.57];
    [csco setCurrentSharePrice:25.24];
    [csco setNumberOfShares:8000];
    BNRStockHolding *aapl = [[BNRStockHolding alloc]init];
    [aapl setNameOfStock:@"AAPL"];
    [aapl setPurchaseSharePrice:83.45];
    [aapl setCurrentSharePrice:97.89];
    [aapl setNumberOfShares:35];
    BNRStockHolding *bbry = [[BNRStockHolding alloc]init];
    [bbry setNameOfStock:@"BBRY"];
    [bbry setPurchaseSharePrice:12.23];
    [bbry setCurrentSharePrice:7.24];
    [bbry setNumberOfShares:100];
    BNRForeignStockHolding *tsla = [[BNRForeignStockHolding alloc]init];
    [tsla setNameOfStock:@"TSLA"];
    [tsla setPurchaseSharePrice:10.00];
    [tsla setCurrentSharePrice:20.00];
    [tsla setNumberOfShares:100];
    [tsla setConversionRate:1.4];
    BNRForeignStockHolding *nflx = [[BNRForeignStockHolding alloc]init];
    [nflx setNameOfStock:@"NFLX"];
    [nflx setPurchaseSharePrice:193.00];
    [nflx setCurrentSharePrice:487.24];
    [nflx setNumberOfShares:100];
    [nflx setConversionRate:1.4];

    [stockHoldings addStock:csco];
    [stockHoldings addStock:aapl];
    [stockHoldings addStock:bbry];
    [stockHoldings addStock:tsla];
    [stockHoldings addStock:nflx];

    for (BNRStockHolding *stock in stockHoldings.holdings) {
        NSLog(@"\n%@ stocks cost $%.2f, now worth $%.2f. Value changed by $%.2f.", stock.nameOfStock, stock.costInDollars, stock.valueInDollars, stock.totalLossGain);
    }

    NSLog(@"Your portfolio is worth $%.2f", stockHoldings.totalValue);
    
}
return 0;

}
[/code]

EDIT: Oh I forgot. I also edited my BNRStockHolding.m file to override the deallocating method, so that I could see in english which stock was being deallocated. This was more for my own interest as I dont speak memory addresses:

[code]#import “BNRStockHolding.h”

@implementation BNRStockHolding

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

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

  • (float)totalLossGain
    {
    return [self valueInDollars] - [self costInDollars];
    }

  • (void)dealloc
    {
    NSLog(@“Deallocating %@”, self.nameOfStock);
    }

@end
[/code]