This one had me going for a while. Kept irritating me because no matter what I did it would only return the memory address instead of the stock name or value!!! lol I let the project sit for 2 days, went back a few chapters to go over it all and make sure I didn’t make any mistakes and saw the “descriptors and %@” section to realize I was returning the default NSObject descriptor! After about 4 days of research on the code that I wrote in 3 different ways, all of which would have worked, it was a single line in the BNRStockHoldings class lol, but at least I will remember this from now on. See the following for my project:
note, I didn’t create BNRForeignStockHoldings. I felt it wasn’t really needed so I created conversionRate in BNREmployee, and added an if statement to determine if it needed to be converted. Basically, if conversionRate is empty, calculate valueInDollar/costInDollars, else if it is not empty (IE contains a value), add the exchange rate to the equation.
Main.m
[code]//
// main.m
// Stocks
//
// Created by Matthew Raby on 8/18/14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//
#import <Foundation/Foundation.h>
#import “BNRPortfolio.h”
#import “BNRPortfolio.h”
int main(int argc, const char * argv[])
{
@autoreleasepool {
// Create BNRPortfolio object to store all the stocks
BNRPortfolio *portfolio = [[BNRPortfolio alloc] init];
// create BNRStockHolding instances, assign values, and add to portfolio
BNRStockHolding *pike = [[BNRStockHolding alloc] init];
BNRStockHolding *starrett = [[BNRStockHolding alloc] init];
BNRStockHolding *facebook = [[BNRStockHolding alloc] init];
BNRStockHolding *chinaTech = [[BNRStockHolding alloc] init];
BNRStockHolding *indiaComp = [[BNRStockHolding alloc] init];
BNRStockHolding *poorCountry = [[BNRStockHolding alloc] init];
pike.purchaseSharePrice = 8.30;
pike.currentSharePrice = 11.82;
pike.numberOfShares = 50;
pike.stockName = @"PIKE";
[portfolio addToPortfolio:pike];
starrett.purchaseSharePrice = 8.6;
starrett.currentSharePrice = 15.54;
starrett.numberOfShares = 200;
starrett.stockName = @"SCX";
[portfolio addToPortfolio];
facebook.purchaseSharePrice = 60;
facebook.currentSharePrice = 73.63;
facebook.numberOfShares = 100;
facebook.stockName = @"FB";
[portfolio addToPortfolio];
chinaTech.purchaseSharePrice = 800;
chinaTech.currentSharePrice = 1000;
chinaTech.numberOfShares = 50;
chinaTech.stockName = @"CTECH";
chinaTech.conversionRate = 0.0689;
[portfolio addToPortfolio:chinaTech];
indiaComp.purchaseSharePrice = 15677.8;
indiaComp.currentSharePrice = 22568.7;
indiaComp.numberOfShares = 10;
indiaComp.stockName = @"ICOMP";
indiaComp.conversionRate = 0.00327;
[portfolio addToPortfolio:indiaComp];
poorCountry.purchaseSharePrice = 200.8;
poorCountry.currentSharePrice = 2283.2;
poorCountry.numberOfShares = 30;
poorCountry.stockName = @"PCNTR";
poorCountry.conversionRate = 0.000843;
[portfolio addToPortfolio:poorCountry];
// Iterate through the array and print the stocks
for (BNRStockHolding *i in portfolio.holdings) {
// declare local variables
float purchasedAt = i.costInDollars;
float currentValue = i.valueInDollars;
float netValue = i.netValueInDollars;
NSString *name = i.stockName;
NSLog(@"\nStock: %@\nPrice Purchased: %.2f\nCurrent Value: %.2f\nProfit: %.2f\n", name, purchasedAt, currentValue, netValue);
}
// Print the holdings in alphabetical order
NSLog(@"Holdings sorted by symbol: %@", [portfolio stockSortedABC]);
// print the top 3 valued holdings
NSLog(@"Top 3 most valuable holdings: %@", [portfolio topThreeHoldings]);
// cleanup holdings
portfolio = nil;
/* Commenting out previous challenge code not needed for this challenge, to keep for future reference
NSLog(@"The total value of all stocks is %.2f", [portfolio totalValue]);
NSLog(@"The value of portfolio[3] is %.2f", chinaTech.valueInDollars);
//remove chinaTech
[portfolio removeFromPortfolio:3];
// should be the total value minus chinaTech
NSLog(@"The total after removing portfolio[3] is %@", portfolio);
*/
}
return 0;
}
[/code]
BNRStockHoldings.h
[code]//
// BNRStockHolding.h
// Stocks
//
// Created by Matthew Raby on 8/18/14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//
#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;
@property (nonatomic) float conversionRate;
// Declare the instance methods
- (float)costInDollars; // purchaseSharePrice * numberOfShares
- (float)valueInDollars; // currentSharePrice * numberOfShares
- (float)netValueInDollars; // valueInDollars - costInDollars
@end[/code]
BNRStockHoldings.m
[code]//
// BNRStockHolding.m
// Stocks
//
// Created by Matthew Raby on 8/18/14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//
#import “BNRStockHolding.h”
@implementation BNRStockHolding
// create method to calculate cost to purchase stock, include conversion if non-US currency
-
(float)costInDollars {
if (!_conversionRate) {float cost = self.purchaseSharePrice;
return cost * self.numberOfShares;} else {
float cost = self.purchaseSharePrice; float num = self.numberOfShares; return cost * num * self.conversionRate;
}
}
// create method to calculate the current value of the stock, include conversion if non-US currency
-
(float)valueInDollars {
if(!_conversionRate){float val = self.currentSharePrice; return val * self.numberOfShares;
}else{
float val = self.currentSharePrice; float num = self.numberOfShares; return val * num * self.conversionRate;
}
}
// calculate the profit
-
(float)netValueInDollars {
return self.valueInDollars - self.costInDollars;
} -
(void)addSelfToArray:(NSMutableArray *)array
{
[array addObject:self];
}
// The default description method of NSObject returns the memory location when using %@ in NSLog
// Overwrite the description method to return a more specific message, for this project the stock name
- (NSString *)description
{
return [NSString stringWithFormat:@"<BNRStockHoldings: %@, valued at %.2f>", self.stockName, self.valueInDollars];
}
@end[/code]
BNRPortfolio.h
[code]//
// BNRPortfolio.h
// Stocks
//
// Created by Matthew Raby on 8/18/14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//
#import <Foundation/Foundation.h>
#import “BNRStockHolding.h”
@interface BNRPortfolio : NSObject
@property (nonatomic, copy) NSArray *holdings;
- (void)addToPortfolio:(BNRStockHolding *)a;
- (void)removeFromPortfolio:(unsigned int)i;
- (float)totalValue;
- (NSArray *)topThreeHoldings;
- (NSArray *)stockSortedABC;
@end
[/code]
BNRPortfolio.m
[code]//
// BNRPortfolio.m
// Stocks
//
// Created by Matthew Raby on 8/18/14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//
#import “BNRPortfolio.h”
@interface BNRPortfolio ()
{
NSMutableArray *_holdings;
}
@end
@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];
}
-(void)removeFromPortfolio: (unsigned int)i
{
[_holdings removeObjectAtIndex:i];
} -
(NSArray *)topThreeHoldings
{
NSSortDescriptor *sortValue = [NSSortDescriptor sortDescriptorWithKey:@“valueInDollars” ascending:NO];
NSMutableArray *sortVID= [[NSMutableArray alloc] init];
sortVID = _holdings;
[sortVID sortUsingDescriptors:@[sortValue]];//noticed someone use the NSMakeRange to do this instead of calling each individually, I liked it better
return [sortVID subarrayWithRange:NSMakeRange(0, 2)];
//return @[sortVID[0], sortVID[1], sortVID[2]];
} -
(NSArray *)stockSortedABC
{
NSSortDescriptor *sortABC = [NSSortDescriptor sortDescriptorWithKey:@“stockName” ascending:YES];
NSMutableArray *sortedArray = [[NSMutableArray alloc] init];
sortedArray = _holdings;
[sortedArray sortUsingDescriptors:@[sortABC]];return sortedArray;
} -
(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[/code]