Challenge 24.02-03 from Russia


#1
**BNRStockHolding.h**

#import <Foundation/Foundation.h>

@interface BNRStockHolding : NSObject

@property (nonatomic) NSString *nameOfCompany;
@property (nonatomic) float purchasedSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;
@property (nonatomic) NSString *ticker;

- (float)costInDollars;  // purchaseSharePrice * numberOfShares
- (float)valueInDollars;    // currentSharePrice * numberfShares

@end

**BNRStockHolding.m**

#import "BNRStockHolding.h"

@implementation BNRStockHolding

- (float)costInDollars
{
    float p = [self purchasedSharePrice];
    int n = [self numberOfShares];
    return p * n;
}

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

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

@end


**BNRForeignStockHolding.h**

#import "BNRStockHolding.h"

@interface BNRForeignStockHolding : BNRStockHolding

//  To multiply purchasePrice and currentPrice in local price by to get a price in US dollars
@property (nonatomic) float conversionRate;

@end

**BNRForeignStockHolding.m**

#import "BNRForeignStockHolding.h"

@implementation BNRForeignStockHolding


- (float)valueInDollars
{
    float c = [self currentSharePrice]  * self.conversionRate;
    int n = [self numberOfShares];
    return c * n;
}

- (float)costInDollars
{
    float p = [self purchasedSharePrice] * self.conversionRate;
    int n = [self numberOfShares];
    return p * n;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"You paid %.2f.Conv rate %.2f for %d shares in %@ (%@), valued at %.2f", self.costInDollars, self.conversionRate, self.numberOfShares, self.nameOfCompany, self.ticker, self.valueInDollars];
}

@end


**BNRPortfolio.h**

#import "BNRStockHolding.h"

@interface BNRPortfolio : BNRStockHolding

- (float)totalValue;
- (float)totalCost;
- (void)addHoldings:(BNRStockHolding *)h;
- (void)addForeignHoldings:(BNRStockHolding *)hF;
- (NSArray *)getTopThreeValuableHoldings;
- (NSArray *)getSortedBySymbol;

@end

**BNRPortfolio.m**

#import "BNRPortfolio.h"

// A class extension
@interface BNRPortfolio ()
{
    NSMutableArray *_holdings;
}

@property (nonatomic, copy) NSArray *holdings;

@end

@implementation BNRPortfolio

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

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

- (void)addHoldings:(BNRStockHolding *)h
{
    // Is holdings nil?
    if (!_holdings) {
        
        // Create the array
        _holdings = [[NSMutableArray alloc] init];
    }
    [_holdings addObject:h];
}

- (void)addForeignHoldings:(BNRStockHolding *)hF
{
    // Is holdings nil?
    if (!_holdings) {
        
        // Create the array
        _holdings = [[NSMutableArray alloc] init];
    }
    [_holdings addObject:hF];
}

- (float)totalValue
{
    // Sum up total value of the StockHoldings
    float sum = 0;
    for (BNRStockHolding *h in _holdings) {
        sum += [h valueInDollars];
    }
    return sum;
}

- (float)totalCost
{
    // Sum up total cost of the StockHoldings
    float sum = 0;
    for (BNRStockHolding *h in _holdings) {
        sum += [h costInDollars];
    }
    return sum;
}

- (NSArray *)getTopThreeValuableHoldings
{
    // Get descending sorting in order to get the most valuable holdings at start.
    NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"valueInDollars" ascending:NO];
    // Sorting _holdings using created above descriptor
    NSArray *sortedArray = [_holdings sortedArrayUsingDescriptors:@[descriptor]];
    // Create range of three elements
    NSRange range = NSMakeRange(0, 3);
    // Get top three valuable holdings
    NSIndexSet *topThreeValuableHoldings = [NSIndexSet indexSetWithIndexesInRange:range];
    return [sortedArray objectsAtIndexes:topThreeValuableHoldings];
}

- (NSArray *)getSortedBySymbol
{
    // Create descriptor for sorting by ticker property
    NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"ticker" ascending:YES];
    // Apply descriptor for sorting array of share holders (_holdings)
    NSArray *sortedByTicker = [_holdings sortedArrayUsingDescriptors: @[descriptor]];
    return sortedByTicker;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"<Total value is %.2f and total cost is %.2f>",
            self.totalValue, self.totalCost];
}

@end


**main.m**

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

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        // Create an empty mutable array
        BNRPortfolio *holdings = [[BNRPortfolio alloc] init];
        
        // Generate names for stocks and ticker labels
        NSArray *names = @[@"Aeroflot", @"Alrosa", @"Gazprom"];
        NSArray *ticker = @[@"ARF", @"ALR", @"GZP"];
        
        for (int i = 0; i < [names count]; i++) {
            BNRStockHolding *newStock = [[BNRStockHolding alloc] init];
            
            NSString *stockName = [names objectAtIndex:i];
            newStock.nameOfCompany = [stockName uppercaseString];
            newStock.purchasedSharePrice = 2.30 + i * (arc4random() % 3);
            newStock.currentSharePrice = 4.50 + i * (arc4random() % 2);
            newStock.numberOfShares = 15 + i * (arc4random() % 4);
            NSString *lTicker = [ticker objectAtIndex:i];
            newStock.ticker = [lTicker uppercaseString];
            
            [holdings addHoldings:newStock];
            NSLog(@"%@", newStock);
            
        }
        
        // Generate names for foreign stocks and ticker labels
        NSArray *fNames = @[@"Aeroflot-Foreign", @"Alrosa-Foreign", @"Gazprom-Foreign"];
        NSArray *fTickers = @[@"AERO-F", @"ALROSA-F", @"Gazprom-F"];
        
        for (int i = 0; i < [fNames count]; i++) {
            BNRForeignStockHolding *foreignStock = [[BNRForeignStockHolding alloc] init];
            
            NSString *foreignStockName = [fNames objectAtIndex:i];
            foreignStock.nameOfCompany = [foreignStockName uppercaseString];
            foreignStock.purchasedSharePrice = 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);
            NSString *ticker = [fTickers objectAtIndex:i];
            foreignStock.ticker = [ticker uppercaseString];
            
            [holdings addForeignHoldings:foreignStock];
            NSLog(@"%@", foreignStock);
        }

        NSLog(@"%@", holdings);
        NSLog(@"Top three most valueable: \n%@", [holdings getTopThreeValuableHoldings]);
        NSLog(@"All of stock holdings sorted alphabetically by ticker (symbol): \n %@", [holdings getSortedBySymbol]);
    }
    return 0;
}