My go at challenge


#1

My main() for challenge, other than memory related issues (I haven’t got that far) are there any problems? Don’t get me wrong it seems to work but you always wonder “is this the way?”.

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

@autoreleasepool {
    
    StockHolding * stockOne = [[StockHolding alloc]init];
    StockHolding * stockTwo = [[StockHolding alloc]init];
    StockHolding * stockThree = [[StockHolding alloc]init];
    
    [stockOne setNumberOfShares:5];
    [stockOne setCurrentSharePrice:23.5];
    [stockOne setPurchaseSharePrice:5.8];
    
    [stockTwo setNumberOfShares:100];
    [stockTwo setCurrentSharePrice:5.7];
    [stockTwo setPurchaseSharePrice:1.7];
    
    [stockThree setNumberOfShares:78];
    [stockThree setCurrentSharePrice:100.77];
    [stockThree setPurchaseSharePrice:3.5];
    
    
    NSMutableArray * stocks = [[NSMutableArray alloc] init];
    
    [stocks addObject];
    [stocks addObject];
    [stocks addObject:stockThree];
    
  for(StockHolding *n in stocks)
  {
      
      NSLog(@"Stock :Number of shares = %i Purchase price = %.2f Current price = %.2f",[n numberOfShares]
            ,[n purchaseSharePrice],[n currentSharePrice]);
      
      NSLog(@"The cost in dollars is %.2f",[n costInDollars]);
      NSLog(@"The value in dollars is %.2f",[n valueInDollars]);
      
   }
    
    
    
    
            
}
return 0;

}
[/code]


#2

Well, I did pretty much the same, so I say excellent solution :laughing:


#3

Do your values print twice? My solution wasn’t working correctly, so I came here to see others. When I entered your solution, mine printed twice. Once I removed this part though, then it printed correctly once.

// [stocks addObject:stock1]; // [stocks addObject:stock2]; // [stocks addObject:stock3];

Also, I used a different print method as suggested in the other thread.

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

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

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// Create stock pointers
StockHolding *stock1 = [[StockHolding alloc] init];
StockHolding *stock2 = [[StockHolding alloc] init];
StockHolding *stock3 = [[StockHolding alloc] init];

// Create an empty array
NSMutableArray *stocks = [NSMutableArray arrayWithObjects:stock1, stock2, stock3, nil];

// Add values to the array
[stock1 setNumberOfShares:40];
[stock1 setPurchaseSharePrice:2.30];
[stock1 setCurrentSharePrice:4.50];

[stock2 setPurchaseSharePrice:12.19];
[stock2 setCurrentSharePrice:10.56];
[stock2 setNumberOfShares:90];

[stock3 setPurchaseSharePrice:45.10];
[stock3 setCurrentSharePrice:49.51];
[stock3 setNumberOfShares:210];

// [stocks addObject:stock1];
// [stocks addObject:stock2];
// [stocks addObject:stock3];

// Print values in the array
NSLog(@"array = %@", stocks);

[pool drain];
return 0;

}
[/code]

StockHolding.m

[code]#import “StockHolding.h”

@implementation StockHolding

@synthesize purchaseSharePrice, currentSharePrice, numberOfShares;

  • (float)costInDollars
    {
    return purchaseSharePrice * numberOfShares;
    }

  • (float)valueInDollars
    {
    return currentSharePrice * numberOfShares;
    }

  • (NSString *)description
    {
    return [NSString stringWithFormat:@“Stock: cost %.2f and is now worth %.2f”, [self costInDollars], [self valueInDollars]];
    }

@end
[/code]

my print out:
2011-11-06 14:43:14.734 Stocks[5671:707] array = (
“Stock: cost $92.00 and is now worth $180.00”,
“Stock: cost $1097.10 and is now worth $950.40”,
“Stock: cost $9471.00 and is now worth $10397.10”
)


#4

I see why you’d get two print outs in there with the [stock addObject:stock1]; etc. calls. Your call for the NSMutableArray is actually adding three pointers when you declare it. When you call [stocks addObject:stock1] through three you’re adding 3 more pointers to the NSMutableArray. The thing is there are two pointers to the same object for each stock in your NSMutableArray. Confirm it with a NSLog of [stocks count]… Your fix works by commenting them out, because you’re already adding them to the NSMutableArray when you create it (in other words it’s not empty when you created it, there were three pointers already]. Let me know if this helps understand it. (Myrhillion)


#5

I pretty much came to the same place as everyone else on this one. I think I’m going to implement a description method though and maybe a new init method for my stock class.

Here’s my first crack at the code.

StockHoldings.h

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

@interface StockHoldings : NSObject
{
float purchaseSharePrice;
float currentSharePrice;
int numberOfShares;
}

@property float purchaseSharePrice;
@property float currentSharePrice;
@property int numberOfShares;

// Methods
-(float)costInDollars;
-(float)valueInDollars;

@end[/code]

StockHoldings.m

[code]#import “StockHoldings.h”

@implementation StockHoldings

// Accessors
@synthesize purchaseSharePrice, currentSharePrice, numberOfShares;

// Methods
-(float)costInDollars
{
return purchaseSharePrice * numberOfShares;
}

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

@end[/code]

main.m

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

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

@autoreleasepool {
    
    // Create a mutable array
    NSMutableArray *portfolio = [NSMutableArray array];
    
    // Create our StockHoldings objects
    StockHoldings *BNR = [[StockHoldings alloc] init];
    StockHoldings *apple = [[StockHoldings alloc] init];
    StockHoldings *google = [[StockHoldings alloc] init];
    
    // Populate the instance variables in each stock
    [BNR setPurchaseSharePrice:10.0];
    [BNR setCurrentSharePrice:123.45];
    [BNR setNumberOfShares:1321];
    
    [apple setPurchaseSharePrice:13.43];
    [apple setCurrentSharePrice:395.28];
    [apple setNumberOfShares:4200];
    
    [google setPurchaseSharePrice:321.34];
    [google setCurrentSharePrice:600.95];
    [google setNumberOfShares:42];
    
    // Put the shares in the array
    [portfolio addObject:BNR];
    [portfolio addObject:apple];
    [portfolio addObject:google];
    
    // iterate the array and print the valueInDollars of each object
    for (StockHoldings *sh in portfolio) {
        NSLog(@"Stock cost $%.2f and is currently worth $%.2f", [sh costInDollars], [sh valueInDollars]);
    }
    
}
return 0;

}[/code]


#6

Thank you Myrhillion. Your explanation does make sense.


#7

For the sake of completeness, here is a solution that uses NSArray instead of NSMutableArray.

StockHolding *stock1 = [[StockHolding alloc] init];
[stock1 setPurchaseSharePrice:10.0];
[stock1 setCurrentSharePrice:20.0];
[stock1 setNumberOfShares:5];

StockHolding *stock2 = [[StockHolding alloc] init];
[stock2 setPurchaseSharePrice:20.0];
[stock2 setCurrentSharePrice:20.0];
[stock2 setNumberOfShares:10];

StockHolding *stock3 = [[StockHolding alloc] init];
[stock3 setPurchaseSharePrice:40.0];
[stock3 setCurrentSharePrice:50.00];
[stock3 setNumberOfShares:10];

NSArray *stocks = [NSArray arrayWithObjects:stock1, stock2, stock3, nil];

for (StockHolding *stock in stocks) {
    NSLog(@"Stock cost %.2f, current value %.2f", [stock costInDollars], [stock valueInDollars]);
}

Output:
Stock cost 50.00, current value 100.00
Stock cost 200.00, current value 200.00
Stock cost 400.00, current value 500.00


#8

Ok, after peeking at the forum from time to time, I wanted to contribute, too.
As the challenge was calling to iterate through the array for the output, I wanted to go with a for loop.

#import <Foundation/Foundation.h>
#import “StockHolding.h”

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

//Create instances of StockHolding
StockHolding *sH0 = [[StockHolding alloc]init];
StockHolding *sH1 = [[StockHolding alloc]init];
StockHolding *sH2 = [[StockHolding alloc]init];
    
//Give the instance variables values
[sH0 setPurchaseSharePrice:2.3];
[sH0 setCurrentSharePrice:4.5];
[sH0 setNumberOfShares:40];

[sH1 setPurchaseSharePrice:12.19];
[sH1 setCurrentSharePrice:10.56];
[sH1 setNumberOfShares:90];

[sH2 setPurchaseSharePrice:45.1];
[sH2 setCurrentSharePrice:49.51];
[sH2 setNumberOfShares:210];

//Create an empty mutable array
NSMutableArray *stocksArray = [NSMutableArray array];

//Add the instances of StockHolding into the array
[stocksArray addObject:sH0];
[stocksArray addObject:sH1];
[stocksArray addObject:sH2];

//Iterate through the array for output
int i;
for (i=0; i<[stocksArray count]; i++) {
    NSLog(@"cost %.2f, value %.2f", [[stocksArray objectAtIndex:i] costInDollars], [[stocksArray objectAtIndex:i] valueInDollars]);
}

[pool drain];
return 0;

}

I tried the for loop before but didn’t get it to work. I’m a complete noob but decided I want to learn something new :wink:

Great book so far and how it’s written reminds me of my studies. Go through new stuff fast, try to do read it again at home to get your brains around it, do your homework to practice and understand even more what you’re doing.
Great.
(Sorry if my code isn’t a different color or scrollable, but I don’t know how to set this up yet.)


#9

To get the code formatting I just click the “Code” button in the editor here before I paste in my snippets.

Generally using fast enumeration with a NSArray is the way to go for performance…

http://www.learn-cocos2d.com/2010/09/array-performance-comparison-carray-ccarray-nsarray-nsmutablearray/


#10

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

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

@autoreleasepool {
    
    //create three instances of StockHolding
    StockHolding *stock1 = [[StockHolding alloc] init];
    StockHolding *stock2 = [[StockHolding alloc] init];
    StockHolding *stock3 = [[StockHolding alloc] init];
    
    //Set instance variables for each
    [stock1 setNumberOfShares:10];
    [stock1 setPurchaseSharePrice:100.00];
    [stock1 setCurrentSharePrice:101.00];
    [stock2 setNumberOfShares:20];
    [stock2 setPurchaseSharePrice:200.00];
    [stock2 setCurrentSharePrice:100.00];
    [stock3 setNumberOfShares:30];
    [stock3 setPurchaseSharePrice:300.00];
    [stock3 setCurrentSharePrice:1000.00];
    

    //Add each object to the array
    NSMutableArray *myStocks = [[NSMutableArray alloc] init];
    [myStocks addObject:stock1];
    [myStocks addObject:stock2];
    [myStocks addObject:stock3];
    
    float totalValue = 0;
    //Iterate through the array and printout data
    for (StockHolding *thisStock in myStocks)
    {
        totalValue = (totalValue + [thisStock valueInDollars]);
       NSLog(@"This stock has %d shares purchased for $%.2f each at a cost of $%.2f", [thisStock numberOfShares], [thisStock purchaseSharePrice], [thisStock costInDollars]);
       NSLog(@"It's current share price is $%.2f and is currently worth $%.2f.", [thisStock currentSharePrice], [thisStock valueInDollars]);
    
    }
    
      NSLog(@"The current value of my holdings is %.2f.", totalValue);
    
    
    
    
}
return 0;

}[/code]

Results:

2011-12-06 10:17:07.630 Stocks[2064:707] This stock has 10 shares purchased for $100.00 each at a cost of $1000.00
2011-12-06 10:17:07.631 Stocks[2064:707] It’s current share price is $101.00 and is currently worth $1010.00.
2011-12-06 10:17:07.631 Stocks[2064:707] This stock has 20 shares purchased for $200.00 each at a cost of $4000.00
2011-12-06 10:17:07.632 Stocks[2064:707] It’s current share price is $100.00 and is currently worth $2000.00.
2011-12-06 10:17:07.632 Stocks[2064:707] This stock has 30 shares purchased for $300.00 each at a cost of $9000.00
2011-12-06 10:17:07.632 Stocks[2064:707] It’s current share price is $1000.00 and is currently worth $30000.00.
2011-12-06 10:17:07.633 Stocks[2064:707] The current value of my holdings is 33010.00.


#11

New person here, I found a solution to the challenge, but I have not found a way to extract the individual instance names? Have only managed to get an address. Am I missing something obvious?


#12

If I understand your question, Geoffry, there are no names assigned to the individual stocks or portfolios in this challenge (other than the variable names themselves, which very rarely have any meaning to users of an application).


#13

@macshome : Awesome! Thanks a bunch!
Interesting how even though NSMutableArray is a subclass of NSArray, NSMutableArray is faster without fast enumeration.


#14

I went the long route and did not use @property to define my methods.

Here is my code:

StockHolding.h

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

@interface StockHolding : NSObject

// instance variables
{
float purchaseSharePrice, currentSharePrice;
int numberOfShares;
}

// accessor methods

  • (float)purchaseSharePrice;

  • (void)setpurchaseSharePrice:(float)x;

  • (float)currentSharePrice;

  • (void)setcurrentSharePrice:(float)y;

  • (int)numberOfShares;

  • (void)setnumberOfShares:(int)a;

  • (float)costInDollars; // purchaseSharePrice * numberOfShares

  • (float)valueInDollars; // currentSharePrice * numberOfShares

@end[/code]

StockHolding.m

[code]#import “StockHolding.h”

@implementation StockHolding

  • (float)purchaseSharePrice
    {
    return purchaseSharePrice;
    }

  • (void)setpurchaseSharePrice:(float)x
    {
    purchaseSharePrice = x;
    }

  • (float)currentSharePrice
    {
    return currentSharePrice;
    }

  • (void)setcurrentSharePrice:(float)y
    {
    currentSharePrice = y;
    }

  • (int)numberOfShares
    {
    return numberOfShares;
    }

  • (void)setnumberOfShares:(int)a
    {
    numberOfShares = a;
    }

  • (float)costInDollars
    {
    return purchaseSharePrice * numberOfShares;
    }

  • (float)valueInDollars
    {
    return currentSharePrice * numberOfShares;
    }

@end[/code]

main.m

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

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

@autoreleasepool {
    
    // create instance of StockHolding
    StockHolding *stock1 = [[StockHolding alloc] init];
    StockHolding *stock2 = [[StockHolding alloc] init];
    StockHolding *stock3 = [[StockHolding alloc] init];
    
    
    [stock1 setnumberOfShares:40];
    [stock1 setcurrentSharePrice:4.50];
    [stock1 setpurchaseSharePrice:2.30];
    
    [stock2 setnumberOfShares:90];
    [stock2 setcurrentSharePrice:7.10];
    [stock2 setpurchaseSharePrice:6.20];
    
    [stock3 setnumberOfShares:17];
    [stock3 setcurrentSharePrice:9.10];
    [stock3 setpurchaseSharePrice:21.60];
    
    
    NSMutableArray *stocks = [NSMutableArray array];
    
    [stocks addObject:stock1];
    [stocks addObject:stock2];
    [stocks addObject:stock3];
    
    for (StockHolding *k in stocks)
    {
        NSLog(@"%i %f %f", 
              [k numberOfShares], 
              [k currentSharePrice], 
              [k purchaseSharePrice]);

        NSLog(@"the cost in dollars is $%.2f", [k costInDollars]);
        NSLog(@"the value in dollars is $%.2f", [k valueInDollars]);
    }
}
return 0;

}[/code]


#15

How would you go about printing the names of the stocks in the NSLog? I can’t wrap my head around that one.

Here is my main.m:

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

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

@autoreleasepool {
    
    //Create array for stocks
    NSMutableArray *stocks = [NSMutableArray array];
    
    //Create stocks
    StockHolding *AAPL = [[StockHolding alloc] init];
    StockHolding *FB = [[StockHolding alloc] init];
    StockHolding *GOOG = [[StockHolding alloc] init];
    
    //Add data to array
    [AAPL setNumberOfShares:8];
    [AAPL setPurchaseSharePrice:96.23];
    [AAPL setCurrentSharePrice: 459.86];
    
    [FB setNumberOfShares:5];
    [FB setPurchaseSharePrice:36.78];
    [FB setCurrentSharePrice:108.57];
    
    [GOOG setNumberOfShares:28];
    [GOOG setPurchaseSharePrice:107.28];
    [GOOG setCurrentSharePrice:367.28];
    
    [stocks addObject:FB];
    [stocks addObject:AAPL];
    [stocks addObject:GOOG];
    //End of array
    
    //Print of stocks to console by enumerating over array
    for (StockHolding *sh in stocks) {
        NSLog(@"Stock %@ cost $%.2f and is currently worth $%.2f", [stocks objectAtIndex:0], [sh costInDollars], [sh valueInDollars]);
    }
    
    
}
return 0;

}
[/code]


#16

Your stocks don’t have names. (The variables that hold them have names, but the objects themselves have no names.)

You’ll add names later on.


#17

Ah, alrighty. I think that’s what I was wondering, if there was a way to print the variables as a string in to NSLog. I’ll be patient until later chapters. Thanks Aaron!


#18

Blurred Line, I had the urge the add names for the sake of completeness, so I did the following:

StockHolding.h

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

@interface StockHolding : NSObject
{
float purchaseSharePrice;
float currentSharePrice;
int numberOfShares;
char *stockName;
}
@property float purchaseSharePrice;
@property float currentSharePrice;
@property int numberOfShares;
@property char *stockName;

// purchaseSharePrice * numberOfShares

  • (float)costInDollars;

// currentSharePrice * numberOfShares

  • (float)valueInDollars;

@end[/code]

StockHolding.m

[code]#import “StockHolding.h”

@implementation StockHolding

@synthesize purchaseSharePrice, currentSharePrice, numberOfShares, stockName;

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

  • (float)valueInDollars
    {
    return [self currentSharePrice] * [self numberOfShares];
    }[/code]

main.m (abbreviated)

[code]#import <Foundation/Foundation.h>
#import "StockHolding.h"
int main (int argc, const char * argv[])
{

@autoreleasepool {
    
    NSMutableArray *thePortfolio = [NSMutableArray array];
    
    StockHolding *aapl = [[StockHolding alloc] init];
    [aapl setStockName:"AAPL"];
    [aapl setPurchaseSharePrice:100.00];
    [aapl setCurrentSharePrice:502.12];
    [aapl setNumberOfShares:500];
    [thePortfolio addObject:aapl];
    
    for (StockHolding *p in thePortfolio) {
        NSLog(@"I bought %d shares of %s for $%.2f, they're now worth $%.2f", [p numberOfShares], [p stockName], [p costInDollars], [p valueInDollars]);
    }   
}
return 0;

}

[/code]

Output:
I bought 500 shares of AAPL for $50000.00, they’re now worth $251060.00

Not sure if this is the best approach, but I wanted to see if I could get it work one way or another. As get through the later chapters, I see if there’s a better way.


#19

Hi All,

I want to add that the reason some of you are getting the results twice is because you are declaring the arrayWithObjects:

[code]// Create an array with objects
NSMutableArray *stockList = [NSMutableArray arrayWithObjects:stockholding1, stockholding2, stockholding3, nil];

    // Call the stockholding methods
    
    for(StockHolding *n in stockList)
    {
        //Call the methods 
        float cost = [n costInDollars];
        float value = [n valueInDollars];
        NSLog(@"Bought stock for $%.2f, It is now at $%.2f, I have %d shares, They cost me $%.2f, Now they are worth $%.2f",
              [n purchaseSharePrice], [n currentSharePrice], [n numberOfShares], cost, value);
    }

// and also adding objects individually to the same array pointer:
[stockList addObject:stockholding1;
[stockList addObject:stockholding2;
[stockList addObject:stockholding1;
[/code]

It doesn’t matter if the array is mutable or not. If it’s not mutable you cannot modify the contents of the array later.

If you use the adding objects individually, create the array as follows:

// Create an empty array //NSMutableArray *stockList = [NSMutableArray array];


#20

OK, Can someone help me see the error? It seems that whatever I do I keep getting the error “Use of undeclared identifier ‘StockHolding’” and Use of undeclared identifier ‘stock1’ … I tried with different methods but I keep getting the same error. I don’t know where the error is :confused:
Stockholding.h

#import <Foundation/Foundation.h>

@interface StockHolding : NSObject
{
    float purchaseSharePrice;
    float currentSharePrice;
    int numberOfShares;
}
@property float purchaseSharePrice;
@property float currentSharePrice;
@property int numberOfShares;

- (float)costInDollars;     // purchaseSharePrice * numberOfShares

- (float)valueInDollars;    // currentSharePrice * numberOfShares



@end

Stockholding.m

[code]#import “StockHolding.h”

@implementation StockHolding
@synthesize purchaseSharePrice, currentSharePrice, numberOfShares;

  • (float)costInDollars;
    {
    return (purchaseSharePrice * numberOfShares);
    }

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

@end
[/code]

main.m

#import <Foundation/Foundation.h>

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

    @autoreleasepool {
        
        StockHolding *stock1 = [[StockHolding alloc]init];
        StockHolding *stock2 = [[StockHolding alloc]init];
        StockHolding *stock3 = [[StockHolding alloc]init];
        
       
        [stock1 setpurchaseSharePrice:2.30];
        [stock1 setcurrentSharePrice:4.50];
        [stock1 setnumberOfShares:40];
                                  
        [stock2 setpurchaseSharePrice:12.19];
        [stock2 setcurrentSharePrice:10.56];
        [stock2 setnumberOfShares:90];
                                  
        [stock3 setpurchaseSharePrice:45.10];
        [stock3 setcurrentSharePrice:49.51];
        [stock3 setnumberOfShares:210];
        
        NSMutableArray *stocks = [[NSMutableArray alloc] init];
        
        // Create three instancse of StockHolding
        [stocks addObject:stock1];
        [stocks addObject:stock2];
        [stocks addObject:stock3];
                                  
        for (NSMutableArray *stocks in array) {
        NSLog(@"Here are the stocks: %@", stocks);
                
        
        
    }
    return 0;
}