A gold challenge solution


#1

I would say that this isn’t perfect, but it gets the job done.

New class header file:

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

@interface BNRContainer : BNRItem

//Need an array and a string for a name.
@property (nonatomic, copy) NSString *containerName;
@property (nonatomic, strong) NSMutableArray *containerArray;

//We need an init method to get the array in the container instantiated from Main.
-(id)initContainerWithName:(NSString *)name;

//When you want to determine the container value.
-(float)containerValue:(BNRContainer *)container;

//A method so that you can put items in the container array from Main.
-(void)putAnItemInArray: (id)item;

@end

The new class’ implementation file:

#import "BNRContainer.h"
@implementation BNRContainer
@synthesize containerArray;
@synthesize containerName;

//This is an init method.  The goal here is to instantiate the container and instantiate the array in the container. 
-(id)initContainerWithName:(NSString *)name
{
    self = [super init];
    
    if(self) {
        [self setContainerName:name];
        containerArray = [[NSMutableArray alloc] init];
    }
    return self;
}

/* When you want to determine the container value, this method should iterate over the array items, 
 find out if each is a container or an individual item, and them treat each item accordingly. */

-(float)containerValue:(BNRContainer *)container
{
    //Set this container's value to zero.
    float containerValue = 0;
    for (int i = 0; i < [containerArray count]; i++) {
        if ([[containerArray objectAtIndex:i] isKindOfClass:[BNRContainer class]]) {
            //We have a container instead of a single item.  
            
            NSLog(@"There is a container within this container's array named:  %@.", [[containerArray objectAtIndex:i] containerName]);

            //Send the contained container back through the method.
           float containedContainerValue = [[containerArray objectAtIndex:i] containerValue:[containerArray objectAtIndex:i]];
            
            //Log out the value of the container once the method returns.
            NSLog(@"The contained container has a total value of $%.2f.", containedContainerValue);
            
            //Add the contained container value to the total container value.
            containerValue = containerValue + containedContainerValue;
               
            //If you do not have a container at index "i," then you have a single BNRItem.
     } else {
            //Add value to containerValue.
            NSLog(@"The container array contains an item %@, which has a value of $%d.", [[containerArray objectAtIndex:i] itemName], [[containerArray objectAtIndex:i] valueInDollars]);
            containerValue = containerValue + [[containerArray objectAtIndex:i] valueInDollars];
        }
    }
    return containerValue; 
}

-(void)putAnItemInArray:(id)item
{
    //Just a simple method to be called to poke something into a container's array.
    [containerArray addObject:item];
}

@end

The Main file:

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

@autoreleasepool {
    
    /* When I initialize the container, we also need to initialize the 
     other items that are in the array.  Therefore, you have to use an initializer.*/
    
    BNRContainer *myContainer = [[BNRContainer alloc] initContainerWithName:@"My Container"];
    BNRContainer *myAppleStuff = [[BNRContainer alloc] initContainerWithName:@"My Apple Stuff"];
    
  
    BNRItem *ktm = [[BNRItem alloc] init];
    [ktm setItemName:@"KTM"];
    [ktm setValueInDollars:6000];
    
    BNRItem *canon = [[BNRItem alloc] init];
    [canon setItemName:@"Canon 60D"];
    [canon setValueInDollars:1500];
    
    BNRItem *flyrod = [[BNRItem alloc] init];
    [flyrod setItemName:@"Temple Fork Outfitters Fly Rod"];
    [flyrod setValueInDollars:100];
    
    BNRItem *iPhone = [[BNRItem alloc] init];
    [iPhone setItemName:@"iPhone 4S"];
    [iPhone setValueInDollars:200];
    
    BNRItem *iPad = [[BNRItem alloc] init];
    [iPad setItemName:@"iPad 2 16G"];
    [iPad setValueInDollars:300];
    
    BNRItem *iPod = [[BNRItem alloc] init];
    [iPod setItemName:@"Brad's iPod"];
    [iPod setValueInDollars:100];
    
    //Put Apple stuff in the myAppleStuff's array.
    [myAppleStuff putAnItemInArray:iPod];
    [myAppleStuff putAnItemInArray:iPad];
    [myAppleStuff putAnItemInArray:iPhone];
    
    //Put everything, including myAppleStuff into the myContainer array.
    [myContainer putAnItemInArray:ktm];
    [myContainer putAnItemInArray:canon];
    [myContainer putAnItemInArray:flyrod];
    [myContainer putAnItemInArray:myAppleStuff];
    
    float myContainerValue = [myContainer containerValue:myContainer];
    NSLog(@"The value of myContainer is $%.2f.", myContainerValue);
    
}
return 0;

}[/code]

The output:

2012-05-26 09:19:03.528 RandomPossessions[8378:503] The container array contains an item KTM, which has a value of $6000.
2012-05-26 09:19:03.530 RandomPossessions[8378:503] The container array contains an item Canon 60D, which has a value of $1500.
2012-05-26 09:19:03.531 RandomPossessions[8378:503] The container array contains an item Temple Fork Outfitters Fly Rod, which has a value of $100.
2012-05-26 09:19:03.532 RandomPossessions[8378:503] There is a container within this container’s array named: My Apple Stuff.
2012-05-26 09:19:03.532 RandomPossessions[8378:503] The container array contains an item Brad’s iPod, which has a value of $100.
2012-05-26 09:19:03.533 RandomPossessions[8378:503] The container array contains an item iPad 2 16G, which has a value of $300.
2012-05-26 09:19:03.533 RandomPossessions[8378:503] The container array contains an item iPhone 4S, which has a value of $200.
2012-05-26 09:19:03.534 RandomPossessions[8378:503] The contained container has a total value of $600.00.
2012-05-26 09:19:03.534 RandomPossessions[8378:503] The value of myContainer is $8200.00.


#2

Hey Orangecicle

You forgot the description method, and you unnecessarily used a BNRContainer * reference to create the containerValue method.

Here’s my solution to this problem, using the ‘old-fashioned’ way of creating the instance variables and their accessors…

BNRContainer.h

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

@interface BNRContainer : BNRItem
{
    NSMutableArray * containerItems;
    NSString * containerName;
    int containerValue;
}

-(void)setContainerItems:(NSMutableArray *) bItems;
-(NSMutableArray *) containerItems;

-(void)setContainerName:(NSString *) contName;
-(NSString *) containerName;

-(void)setContainerValue:(int)someValue;
-(int)containerValue;

-(void)addSomethingToContainer:(id) newItem;

-(id)initWithContainerName:(NSString *) name;

@end[/code]

[b]BNRContainer.m[/b]
[code]#import "BNRContainer.h"

@implementation BNRContainer

-(id)initWithContainerName:(NSString *) name {
    self = [super init];
    if (self) {
        [self setContainerName:name]; 
        // equivalent of the above in dot-notation is "self.containerName = name"
        [self setContainerItems:[[NSMutableArray alloc] init]];
    }
    return self;
}

-(void)setContainerItems:(NSMutableArray *) items{
    containerItems = items;
}

-(NSMutableArray *) containerItems{
    return containerItems;
}

-(void)setContainerName:(NSString *) contName{
    containerName = contName;
}

-(NSString *) containerName{
    return containerName;
}

-(void)setContainerValue:(int)someValue{
    containerValue = someValue;
}

-(int)containerValue {
    int value =0;
    // Use fast enumeration to go through all the items
    for (id item in containerItems) {
        // Note that I use "isMemberOfClass:" selector here, since "isKindOfClass"
        // for BNRItem would be true for the BNRContainer as well, since it's a subclass
        if ([item isMemberOfClass:[BNRItem class]]){
            value += [item valueInDollars];
        } else if ([item isMemberOfClass:[BNRContainer class]]) {
            // Deal with containers-within-containers etc
            value += [item containerValue];
        }
    }
    return value;
}

-(void)addSomethingToContainer:(id) newItem {
    if ([newItem isMemberOfClass:[BNRContainer class]]) {
        NSLog(@"Object added to '%@' is a container, '%@'", containerName, [newItem containerName]);
    } else {
        NSLog(@"Object added to '%@': %@", containerName, newItem);
    }
    [[self containerItems] addObject:newItem];
}

-(NSString *) description{
    NSString * descriptionString = @"";
    NSString * itemString = @"";
    descriptionString = [descriptionString stringByAppendingFormat:@"There are %d items in '%@', with a total value of $%d:\n", 
                         [containerItems count], containerName, containerValue];

    for (id item in containerItems) {        
        if ([item isMemberOfClass:[BNRItem class]]) {
            itemString = [item description];
            descriptionString = [descriptionString stringByAppendingFormat:@"%@\n", itemString];
        } else if ([item isMemberOfClass:[BNRContainer class]]) {
            descriptionString = [descriptionString stringByAppendingString:@"\tAnd then in the inner container\n"];
            descriptionString = [descriptionString stringByAppendingString:[item description]];            
        }
    }
    return descriptionString;
}

@end

And then main.m, with four containers, the last 2 having containers-within containers.

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

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

@autoreleasepool {
    
    // create a mutable array object
    NSMutableArray * items = [[NSMutableArray alloc] init];

    BNRItem *p = [[BNRItem alloc] initWithItemName:@"Red Sofa"
                                    valueInDollars:123
                                      serialNumber:@"A1B2C3"];
    [items addObject:p];
    //NSLog(@"%@", p);
    
    for (int i = 0; i<2; i++) {
        p = [BNRItem randomItem];
        [items addObject:p];
    }
  
    int i=0;
    for (BNRItem *item in items) {
        NSLog(@"%d: %@", i, item); 
        i++;
    }
    
    //NSLog(@"%@", [items objectAtIndex:11]);
    // destry the array
    items = nil;
    
    BNRContainer * boxOfBits = [[BNRContainer alloc] initWithContainerName:@"Just a box of bits"];
    for (int i = 0; i<5; i++) {
        [boxOfBits addSomethingToContainer:[BNRItem randomItem]];
    }
    NSLog(@"%@", boxOfBits);
    
    BNRContainer * boxOfPieces = [[BNRContainer alloc] initWithContainerName:@"Just a box of pieces"];
    for (int i = 0; i<2; i++) {
        [boxOfPieces addSomethingToContainer:[BNRItem randomItem]];
    }
    NSLog(@"%@", boxOfPieces);

    BNRContainer * newBoxOfBits = [[BNRContainer alloc] initWithContainerName:@"A new box of stuff"];
    for (int i = 0; i < 6; i++) {
        [newBoxOfBits addSomethingToContainer:[BNRItem randomItem]];           
    }
    [newBoxOfBits addSomethingToContainer:boxOfPieces];
    NSLog(@"%@", newBoxOfBits);

    BNRContainer * newestBoxOfBits = [[BNRContainer alloc] initWithContainerName:@"The newest box of things"];
    for (int i = 0; i < 6; i++) {
        [newestBoxOfBits addSomethingToContainer:[BNRItem randomItem]];           
    }
    [newestBoxOfBits addSomethingToContainer:boxOfPieces];
    [newestBoxOfBits addSomethingToContainer:newBoxOfBits];
    NSLog(@"%@", newestBoxOfBits);

}
return 0;

}
[/code]

This results in the following (final) sort of output for the last container, which had a container inside and another container within that.

2012-06-07 00:36:06.050 RandomPossessions[26051:403] There are 8 items in 'The newest box of things', with a total value of $0: Red Computer (8J8T0): Worth $94, recorded on 2012-06-06 14:36:06 +0000 Royal Car (5E2Z1): Worth $42, recorded on 2012-06-06 14:36:06 +0000 Round Corgi (1K1G7): Worth $71, recorded on 2012-06-06 14:36:06 +0000 Royal Calculator (9X6C8): Worth $40, recorded on 2012-06-06 14:36:06 +0000 Round Cream (3H0R6): Worth $54, recorded on 2012-06-06 14:36:06 +0000 Round Calculator (0A4S4): Worth $13, recorded on 2012-06-06 14:36:06 +0000 And then in the inner container There are 2 items in 'Just a box of pieces', with a total value of $0: Red Calculator (3A6T4): Worth $30, recorded on 2012-06-06 14:36:05 +0000 Ryan's Computer (8S3I1): Worth $77, recorded on 2012-06-06 14:36:05 +0000 And then in the inner container There are 7 items in 'A new box of stuff', with a total value of $0: Rigid Computer (4F6F9): Worth $65, recorded on 2012-06-06 14:36:05 +0000 Round Corgi (1P5F4): Worth $29, recorded on 2012-06-06 14:36:06 +0000 Round Car (3R2Q6): Worth $88, recorded on 2012-06-06 14:36:06 +0000 Royal Cream (4X7P8): Worth $38, recorded on 2012-06-06 14:36:06 +0000 Ryan's Calculator (7E4L1): Worth $77, recorded on 2012-06-06 14:36:06 +0000 Ryan's Cream (8K9Y2): Worth $35, recorded on 2012-06-06 14:36:06 +0000 And then in the inner container There are 2 items in 'Just a box of pieces', with a total value of $0: Red Calculator (3A6T4): Worth $30, recorded on 2012-06-06 14:36:05 +0000 Ryan's Computer (8S3I1): Worth $77, recorded on 2012-06-06 14:36:05 +0000

The “8” items here are six BNRItems, then one container, and then the other container, so the description lays out the 6 items, then the items in the first container, and then the items in the second container which has seven items, the last of them being yet another container.

(confused? play with this and see how it works for you :slight_smile: )

Edit Darn it! I can see now that I’ve got my value of the container displayed as $0 in that final ‘results’ post, whereas just before I posted my solution here (and yes, edited my code to make it look better…) it had been calculating the total properly. So time to fix that up now.


#3

huh? now this I don’t get. In the above post, I’ve got a solution to the Gold Challenge for this chapter, except that it doesn’t calculate the containerValue properly. I put some NSLog’s into the containerValue method, and found that it wasn’t even being called by description method.

So, I changed one line in the description, from

descriptionString = [descriptionString stringByAppendingFormat:@"There are %d items in '%@', with a total value of $%d:\n", [containerItems count], containerName, containerValue];
to

descriptionString = [descriptionString stringByAppendingFormat:@"There are %d items in '%@', with a total value of $%d:\n", [containerItems count], containerName, [self containerValue]];
and now I get the proper results, e.g.

2012-06-07 08:40:14.280 RandomPossessions[26608:403] There are 8 items in 'The newest box of things', with a total value of $860: Red Computer (8J8T0): Worth $94, recorded on 2012-06-06 22:40:14 +0000 Royal Car (5E2Z1): Worth $42, recorded on 2012-06-06 22:40:14 +0000 Round Corgi (1K1G7): Worth $71, recorded on 2012-06-06 22:40:14 +0000 Royal Calculator (9X6C8): Worth $40, recorded on 2012-06-06 22:40:14 +0000 Round Cream (3H0R6): Worth $54, recorded on 2012-06-06 22:40:14 +0000 Round Calculator (0A4S4): Worth $13, recorded on 2012-06-06 22:40:14 +0000 And then in the inner container There are 2 items in 'Just a box of pieces', with a total value of $107: Red Calculator (3A6T4): Worth $30, recorded on 2012-06-06 22:40:14 +0000 Ryan's Computer (8S3I1): Worth $77, recorded on 2012-06-06 22:40:14 +0000 And then in the inner container There are 7 items in 'A new box of stuff', with a total value of $439: Rigid Computer (4F6F9): Worth $65, recorded on 2012-06-06 22:40:14 +0000 Round Corgi (1P5F4): Worth $29, recorded on 2012-06-06 22:40:14 +0000 Round Car (3R2Q6): Worth $88, recorded on 2012-06-06 22:40:14 +0000 Royal Cream (4X7P8): Worth $38, recorded on 2012-06-06 22:40:14 +0000 Ryan's Calculator (7E4L1): Worth $77, recorded on 2012-06-06 22:40:14 +0000 Ryan's Cream (8K9Y2): Worth $35, recorded on 2012-06-06 22:40:14 +0000 And then in the inner container There are 2 items in 'Just a box of pieces', with a total value of $107: Red Calculator (3A6T4): Worth $30, recorded on 2012-06-06 22:40:14 +0000 Ryan's Computer (8S3I1): Worth $77, recorded on 2012-06-06 22:40:14 +0000
So I don’t get this, what’s going on here? In that line from description, the call to the containerName method didn’t require the [self containerName] treatment, since I believe that it is just shorthand for self.containerName. But for containerValue it did.

Maybe until I understand what’s going on here (which means maybe always? :slight_smile: ) I’ll just go with the self.methodName syntax.


#4

Why so much code?

Guys, think objectoriented!

My BNRContainer.h

#import "BNRItem.h"

@interface BNRContainer : BNRItem
{
    NSMutableArray *items;
}

- (void)addObject:(BNRItem *)itemToAdd;

@end

My BRNContainer.m

#import "BNRContainer.h"

@implementation BNRContainer

- (id)initWithItemName:(NSString *)name valueInEuro:(int)value serialNumber:(NSString *)sNumer
{
    
    //call the super
    self = [super initWithItemName:name valueInEuro:value serialNumber:sNumer];
    
    //fill in instance variables
    
    if (self)
    {
        items = [[NSMutableArray alloc] init];
    }
    
    //return dich selber
    return self;
}

- (int)valueInEuro
{
    int nSumvalueInEuro;
    
    nSumvalueInEuro = valueInEuro;
    
    for (BNRItem *item in items) {
        nSumvalueInEuro = nSumvalueInEuro + [item valueInEuro];
    }
    return nSumvalueInEuro;
}

- (NSString *)description
{
    NSString *descriptionString = [[NSString alloc] initWithFormat:@"%@ (%@): Wert %d€, aufgenommen am %@",
                                   itemName,
                                   serialNumber,
                                   [self valueInEuro],
                                   dateCreated];
    
    descriptionString = [descriptionString stringByAppendingString:@"\n"];
    
    for (BNRItem *item in items) {
        descriptionString = [descriptionString stringByAppendingString:@"  -->"];
        descriptionString = [descriptionString stringByAppendingString:[item description]];
        descriptionString = [descriptionString stringByAppendingString:@"\n"];
    }
    return descriptionString;
}

- (void)addObject:(BNRItem *)itemToAdd
{
    [items addObject:itemToAdd];
}

@end

#5

Sorcuring, does your code deal with containers-within-containers?


#6

Yes, sure he did. Because we have no strong types in objective-C.

Not nice code, but good enough for working test:

//Create a mutabel array
        
        NSMutableArray *items = [[NSMutableArray alloc] init];
        
        for (int i = 0; i < 10; i++) {
            BNRItem *pi = [BNRItem randomItem];
            [items addObject:pi];
        }
        
        //for (int i = 0; i < 10; i++) {
        //    NSLog(@"%@", [items objectAtIndex:i]);
        //}
        
        for (BNRItem *item in items) {
            NSLog(@"%@", item);
        }
        
        
        
        BNRItem *p = [[BNRItem alloc] init];
        
        NSLog(@"%@",p);
        
        [p setItemName:@"Rotes Sofa"];
        [p setSerialNumber:@"0815"];
        [p setValueInEuro:100];
        
        NSLog(@"%@ %@ %@ %d", [p itemName], [p dateCreated], [p serialNumber], [p valueInEuro]);
        
        NSLog(@"%@",p);
        
        
        BNRContainer *c = [[BNRContainer alloc] initWithItemName:@"Rucksack" serialNumber:@"123456"];
        
        NSLog(@"%@",c);
        
        [c addObject:p];
        
        NSLog(@"%@",c);
        
        BNRContainer *d = [[BNRContainer alloc] initWithItemName:@"Schachtel"];
        
         [c addObject:d];
        
        for (BNRItem *item in items) {
            [d addObject:item];
        }
        
        NSLog(@"%@",c);
        
        items = nil;

Output:

2012-06-10 16:13:02.451 RandomPossessions[3198:403] Hello, World!
2012-06-10 16:13:02.475 RandomPossessions[3198:403] blaues Auto (8Q2U8): Wert 73€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.477 RandomPossessions[3198:403] grünes Auto (5Y2V3): Wert 40€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.478 RandomPossessions[3198:403] blaues Auto (2F9Z7): Wert 40€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.480 RandomPossessions[3198:403] blaues Bett (8G5V6): Wert 99€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.482 RandomPossessions[3198:403] grünes Auto (3P9B1): Wert 10€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.487 RandomPossessions[3198:403] blaues Regal (6R5C1): Wert 93€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.489 RandomPossessions[3198:403] gelbes Auto (3E4O0): Wert 1€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.490 RandomPossessions[3198:403] gelbes Regal (3A6T4): Wert 30€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.493 RandomPossessions[3198:403] grünes Auto (8S3I1): Wert 77€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.495 RandomPossessions[3198:403] blaues Auto (4F6F9): Wert 65€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.496 RandomPossessions[3198:403] Item (): Wert 0€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.497 RandomPossessions[3198:403] Rotes Sofa 2012-06-10 14:13:02 +0000 0815 100
2012-06-10 16:13:02.499 RandomPossessions[3198:403] Rotes Sofa (0815): Wert 100€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.500 RandomPossessions[3198:403] Rucksack (123456): Wert 0€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.502 RandomPossessions[3198:403] Rucksack (123456): Wert 100€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->Rotes Sofa (0815): Wert 100€, aufgenommen am 2012-06-10 14:13:02 +0000
2012-06-10 16:13:02.517 RandomPossessions[3198:403] Rucksack (123456): Wert 628€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->Rotes Sofa (0815): Wert 100€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->Schachtel (): Wert 528€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->blaues Auto (8Q2U8): Wert 73€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->grünes Auto (5Y2V3): Wert 40€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->blaues Auto (2F9Z7): Wert 40€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->blaues Bett (8G5V6): Wert 99€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->grünes Auto (3P9B1): Wert 10€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->blaues Regal (6R5C1): Wert 93€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->gelbes Auto (3E4O0): Wert 1€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->gelbes Regal (3A6T4): Wert 30€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->grünes Auto (8S3I1): Wert 77€, aufgenommen am 2012-06-10 14:13:02 +0000
  -->blaues Auto (4F6F9): Wert 65€, aufgenommen am 2012-06-10 14:13:02 +0000

“Rucksack” is my first Container, i put an “Rotes Sofa” in it and write the log to the console.

Then i create a second Container “Schachtel” an put a lot of other stuff in it (from the old test of BNRitem, i think you did this practice too).

After this, i put “Schachtel” in to “RuckSack” and start the output again.

(My Stuff is named with German words (e.g. “Schachtel” means box), but i think you can read it also.)

King regards,

Sorcuring


#7

Hi All,
I wanted to post my solution to the Gold Challenge for Chapter 2 involving creating a BNRContainer class.


#import "BNRItem.h"

@interface BNRContainer : BNRItem
{
    NSString *name;
    NSMutableArray *subitems;
}

- (id)initWithSubitems:(NSMutableArray *)sItems andName:(NSString *)sName andSerial:(NSString *) sNumber andValue:(int) cValue;

- (id)initWithSubitems:(NSMutableArray *)sItems andName:(NSString *)sName andSerial:(NSString *) sNumber;

- (id)initWithSubitems:(NSMutableArray *)sItems andName:(NSString *)sName;

- (id)initWithSubitems:(NSMutableArray *)sItems;

- (void)addItem:(BNRItem *)item;
- (NSMutableArray *)subitems;

@end

#import "BNRContainer.h"

@implementation BNRContainer

- (id)initWithSubitems:(NSMutableArray *)sItems andName:(NSString *)sName andSerial:(NSString *) sNumber andValue:(int) cValue
{
    self = [super init];
    if(self) {
        [self setItemName:sName];
        [self setSubitems:sItems];
        [self setSerialNumber:sNumber];
        [self setValueInDollars:cValue];
        dateCreated = [[NSDate alloc] init];
    }
    return self;   
}


- (id)initWithSubitems:(NSMutableArray *)sItems andName:(NSString *)sName andValue:(int) cValue
{
    return [self initWithSubitems:sItems andName:sName andSerial:@"" andValue:0];  
}

- (id)initWithSubitems:(NSMutableArray *)sItems andName:(NSString *)sName
{
    return [self initWithSubitems:sItems andName:sName andSerial:@""];  
}

- (id)initWithSubitems:(NSMutableArray *)sItems
{
    return [self initWithSubitems:sItems andName:@"" andValue:0];

}

- (id) init
{
    NSMutableArray *sItems = [[NSMutableArray alloc] init];
    return [self initWithSubitems:sItems];
}

- (NSString *)description
{   
    int totalValueOfSubitems = 0;
    NSMutableString *itemsString = [[NSMutableString alloc] initWithString:@""];
    
    for (BNRItem *item in subitems) {
        totalValueOfSubitems += [item valueInDollars];
        [itemsString appendString:[item itemName]];
        NSLog(@"Describing %@", item);        
    }
    NSLog(@"itemsString%@", itemsString);
    
    NSString *descriptionString = 
        [[NSString alloc] initWithFormat:@" Name:%@ (Serial:%@): Container Value $%d, Total Value of Subitems $%d, recorded on %@, with items: %@",
         itemName,
         serialNumber,
         valueInDollars,
         totalValueOfSubitems,
         dateCreated,
         itemsString];
    
    return descriptionString;
}

- (void)addItem:(BNRItem *)item
{
    [subitems addObject:item];
}

- (void)setSubitems:(NSMutableArray *)sItems
{
    subitems = sItems;
}

- (NSMutableArray *)subitems
{
    return subitems;
}

@end

#import <Foundation/Foundation.h>

#import "BNRItem.h"
#import "BNRContainer.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {     
        NSMutableArray *items = [[NSMutableArray alloc] init];
        for (int i=0; i < 10; i++) {
            [items addObject:[BNRItem randomItem]];
        }
        
        BNRContainer *container = [[BNRContainer alloc] initWithSubitems:items andName:@"MyContainer" andSerial:@"1234" andValue:600];

        NSLog(@"CONTAINER%@", container);

        BNRContainer *container2 = [[BNRContainer alloc] init];
        [container2 addItem:container];
        NSLog(@"CONTAINER2%@", container2);
        
        container = nil;
        container2 = nil;
        items = nil;
    }
    return 0;
}

It supports containers within containers but the container description doesn’t enumerate deep (ie. when there’s a container withing a container we don’t get the contents of the child container enumerated).

I wanted to see if anyone here could make any suggestions / comments. Good or bad. This is my first class in Objective C, so don’t worry about coming down hard on me – I can take it. :slight_smile:


#8

I do have a question regarding a specific line.

The item argument is expecting a BNRItem, does it supports BNRCointainr as it is a subclass of BNRItem? or do I need to declare item as id?

Thank in advance.