My Version of Gold Challenge


#1

Hey Everyone,

Here is my version of the gold challenge, all feedback is welcome as I’m learning Objective-C.

BNRContainer.h

#import "BNRItem.h"

@interface BNRContainer : BNRItem
{
    NSString *containerName;
    NSMutableArray *subItems;
}

- (id)initWithContainerName:(NSString *)name subItem:(id)item;
- (id)initWithContainerName:(NSString *)name subItems:(NSMutableArray *)items;
- (id)initWithContainerName:(NSString *)name subItems:(NSMutableArray *)items valueOfContainer:(int)v;

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

- (void)setSubItems:(NSMutableArray *)items;
- (NSMutableArray *)subItems;

- (void)addItem:(id)item;

@end

BNRContainer.m

#import "BNRContainer.h"

@implementation BNRContainer

- (NSString *)description
{
    NSString *descriptionString = [[NSString alloc] initWithFormat:@"Container Name: %@, Sub Items: %@, Total Container Value: %d", containerName, subItems, valueInDollars];
    
    return descriptionString;
}

- (id)initWithContainerName:(NSString *)name subItem:(id)item
{
    NSMutableArray *items = [[NSMutableArray alloc] initWithObjects:item, nil];
    
    int value = [item valueInDollars];
    
    return [self initWithContainerName:name subItems:items valueOfContainer:value];
}

- (id)initWithContainerName:(NSString *)name subItems:(NSMutableArray *)items
{
    int sumOfItems = 0;
    for (int i = 0; i < [items count]; i++) {
        sumOfItems += [[items objectAtIndex:i] valueInDollars];
    }
    
    return [self initWithContainerName:name subItems:items valueOfContainer:sumOfItems];
}

- (id)initWithContainerName:(NSString *)name subItems:(NSMutableArray *)items valueOfContainer:(int)v
{
    self = [super init];
    
    if (self) {
        [self setContainerName:name];
        [self setSubItems:items];
        [self setValueInDollars:v];
    }
    
    return self;
}

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

- (void)setSubItems:(NSMutableArray *)items
{
    subItems = [[NSMutableArray alloc] initWithArray:items];
}
- (NSMutableArray *)subItems
{
    return subItems;
}

- (void)addItem:(id)item
{
    [subItems addObject:item];
    int value = [self valueInDollars] + [item valueInDollars];
    [self setValueInDollars:value];
}



@end

main.m

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

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

    @autoreleasepool {
        //Stuff In My Room
        BNRItem *blueFuton = [[BNRItem alloc] initWithItemName:@"Blue Futon" valueInDollars:100 serialNumber:@"A1B2C"];
        
        BNRItem *silverMac = [[BNRItem alloc] initWithItemName:@"Silver MacBook Pro" valueInDollars:1500 serialNumber:@"L337"];
        
        BNRContainer *stuffInMyRoom = [[BNRContainer alloc] initWithContainerName:@"Stuff In My Room" subItem:blueFuton];
        
        [stuffInMyRoom addItem:silverMac];
        
        //Stuff In My Living Room
        BNRItem *bigTv = [[BNRItem alloc] initWithItemName:@"Big TV" valueInDollars:2000 serialNumber:@"Q1W2E"];
        
        BNRItem *whiteCouch = [[BNRItem alloc] initWithItemName:@"White Comfy Couch" valueInDollars:5000 serialNumber:@"A1S2D"];
        
        NSMutableArray *items = [[NSMutableArray alloc] initWithObjects:bigTv, whiteCouch, nil];
        
        BNRContainer *stuffInMyLivingRoom = [[BNRContainer alloc] initWithContainerName:@"Stuff In My Living Room" subItems:items];
        
        NSMutableArray *stuff = [[NSMutableArray alloc] initWithObjects:stuffInMyRoom, stuffInMyLivingRoom, nil];
        
        BNRContainer *stuffInMyHouse = [[BNRContainer alloc] initWithContainerName:@"Stuff In My House" subItems:stuff];
        
        NSLog(@"%@", stuffInMyHouse);
    }
    return 0;
}

Please notice that instead of creating a separate variable for the sum of values, I’m inheriting valueInDollars from the BNRItem class, and I’m re-using it as the sum of values for the BNRContainer.

This way, if I I only have one method to add a BNRContainer and BNRItem to the subItems. As in, I know that I will always have a value in dollars variable if I pass in a BNRItem object or a BNRContainer object.

Thoughts?


#2

Could you please post the output as well. Just needed it for some analysis.


#3

No problem, here you are:

2013-06-17 10:52:21.451 RandomItems[38623:303] Container Name: Stuff In My House, Sub Items: (
    "Container Name: Stuff In My Room, Sub Items: (\n    \"Blue Futon (A1B2C) : Worth $100, recorded on 2013-06-17 14:52:21 +0000\",\n    \"Silver MacBook Pro (L337) : Worth $1500, recorded on 2013-06-17 14:52:21 +0000\"\n), Total Container Value: 1600",
    "Container Name: Stuff In My Living Room, Sub Items: (\n    \"Big TV (Q1W2E) : Worth $2000, recorded on 2013-06-17 14:52:21 +0000\",\n    \"White Comfy Couch (A1S2D) : Worth $5000, recorded on 2013-06-17 14:52:21 +0000\"\n), Total Container Value: 7000"
), Total Container Value: 8600

#4

Yeah its alright. In fact, its good that you’ve incorporated the overriding concept in your code. Coz, as far as initialiser of BNRContainer goes, it need not have a relation to BNRItem’s initialiser. During implementation overriding the initialiser just didn’t make any sense (at least to me). As far as properties go, overriding them is a fine idea in BNRContainer class implementation. No problem there, though i didn’t do it this way myself. Its cool. Don’t have this many initialisers though u have a designated one implemented separately.

Help me understand one thing though. Where was the need to have “self” in +(id)randomItem method in the line—
BNRItem *newItem=[[self alloc] initWithItemName:randomName valueInDollars:randomValue serialNumber:randomSerialNumber];
In my code, I haven’t overriden this method (randomItem) in BNRContainer. Had i somehow done that (though i didn’t find it useful) then “self” wud have made perfect sense in the specified line. I mean, is self necessary in this case or optional? self just acts as placeholder for the current object (in main function).
Here’s my code:

BNRContainer.h

#import "BNRItem.h"

@interface BNRContainer : BNRItem
{
    NSMutableArray *contents;
    NSString *containerName;
    int totalValue;
    int totalItemsCost;
}
-(void)addItemsUpto:(int)numberOfItemsInAContainer;
-(void)setContainerName:(NSString *)name;
-(NSString *)containerName;
-(id)initWithContainerName:(NSString *)name;
-(void)setTotalValue:(int)valueOfContainer;
-(int)totalValue;
@end

BNRContainer.m

#import "BNRContainer.h"

@implementation BNRContainer
-(void)addItemsUpto:(int)numberOfItemsToBeAddedInAContainer{
    contents= [[NSMutableArray alloc] init];
    for (int i=0; i<numberOfItemsToBeAddedInAContainer; i++) {
        BNRItem *item=[BNRItem randomItem];
        totalItemsCost+=[item valueInDollars];
        [contents addObject:item];
    }
    //totalValue=totalItemsCost;
}
-(void)setContainerName:(NSString *)name{
    containerName=name;
}
-(NSString *)containerName{
    return containerName;
}
-(void)setTotalValue:(int)valueOfContainer{
    totalValue=totalItemsCost+valueOfContainer;
}
-(int)totalValue{
    return totalValue;
}
-(id)initWithContainerName:(NSString *)name {
    [self setContainerName:name];
        //totalValue=100
    return self;
}
-(NSString *)description{
    return [NSString stringWithFormat:@"Name of Container= %@, total value= %d, items contained= %@ ",containerName,totalValue,contents];
}
@end

main.m

int main(int argc, const char * argv[])
{
    
    @autoreleasepool {
        NSMutableArray *items=[[NSMutableArray alloc] init];
          for (int i=0; i<10; i++)
          {
            BNRItem *item=[BNRItem randomItem];
            [items addObject:item];
          }
        
                int total=0;
                for (BNRItem *item in items) {
                    total=total+[item valueInDollars];
                }
        /*Gold challenge solution-BNRContainer*/
                BNRContainer *container=[[BNRContainer alloc] initWithContainerName:@"container1"];
                [container addItemsUpto:5];  //addItemsUpto implemented in BNRContainer.m
                [container setTotalValue:100]; //Note: 100 is the value of Container1
                NSLog(@"%@",container);
        
                BNRContainer *container2=[[BNRContainer alloc] initWithContainerName:@"container2"];
                [container2 addItemsUpto:5];     //addItemsUpto implemented in BNRContainer.m
                [container2 setTotalValue:100]; //Note: 100 is the value of Container1
                NSLog(@"%@",container2);
                NSLog(@"Net Value= %d dollars",[container totalValue]+[container2 totalValue]);
            
        NSLog(@"Total=%d",total);
    }
}

#5

Hello,

I’m just curious, did you use - (id)initWithContainerName:(NSString *)name subItems:(NSMutableArray *)items valueOfContainer:(int)v in your code? It looks to me like it is not referenced.

I’d also like to say I was confused about this challenge and reading your answer helped me understand it a lot better.