Gold Challenge Complete


#1

I was thinking of adding a similar object like that in the Stocks application from the objective C book where you add a stock to the portfolio, but in this case it would be you add the item to the container, which in turn would let you add the container to another container. It took a bit less code to do it using a simple master container to hold all of the containers holding items. Doing this did give me a problem. When I printed the containers only the sub-containers printed their values. I had to add an if statement in the description override for the containers class basically saying if the array has a master value print the master conainer and if it has a container value print the container array. About to start looking at all the other solutions to see how everyone else did it.

Main.m

[code]//
// main.m
// RandomItems
//
// Created by Matthew Raby on 9/25/14.
// Copyright © 2014 Matthew Raby. All rights reserved.
//

#import <Foundation/Foundation.h>
#import “JMRItem.h”
#import “JMRContainer.h”

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

@autoreleasepool {
    // create master array to hold all containers
    // This container holds an instance of JMRContainer as
    // required in the gold Challenge.
    NSMutableArray *masterContainer = [[NSMutableArray alloc]init];
    // create containers array to hold individual containers
    NSMutableArray *containers = [[NSMutableArray alloc]init];
    // initialize the master container and set its value to 0
    JMRContainer *master = [[JMRContainer alloc]init];
    master.masterValue = 0;
    // add the master container to masterContainer array
    [masterContainer addObject:master];

    // create loop to create 5 random containers, each containing 5 instances of JMRItem
    for (int i = 0; i<5; i++) {
        // initialize the container, add the container to the containers array, set its value to 0
        JMRContainer *container = [JMRContainer randomContainer];
        [containers addObject:container];
        container.containerValue = 0;
        // create 5 instances of JMRItem
        for (int i = 0; i<5; i++) {
            // initialize instance of JMRItem with a random item
            JMRItem *item = [JMRItem randomItem];
            // add it to the container array
            [containers addObject:item];
            // calculate container value
            container.containerValue += item.valueInDollars;
        }
        // calculate master container value
        master.masterValue += container.containerValue;
    }
    [masterContainer addObject:containers];
    
    NSLog(@"%@", masterContainer);
    
    
    // bronze challenge, try to print the 11th (inexistent) array object in items
    // NSLog(@"%@", items[10]);
    // it throws the NSRangeException stating index 10 is beyond bounds [0 .. 9]
    
    
    containers = nil;
    masterContainer = nil;
    
}
return 0;

}

[/code]

JMRItem.h

[code]//
// JMRItem.h
// RandomItems
//
// Created by Matthew Raby on 9/25/14.
// Copyright © 2014 Matthew Raby. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface JMRItem : NSObject

@property (nonatomic) NSString *itemName;
@property (nonatomic) NSString *serialNumber;
@property (nonatomic) int valueInDollars;
@property (nonatomic) NSDate *dateCreated;

+(instancetype)randomItem;

-(instancetype)initWithItemName:(NSString *)name valueInDollars:(int)value serialNumber:(NSString *)sNumber;
-(instancetype)initWithItemName:(NSString *)name serialNumber:(NSString *)sNumber;
-(instancetype)initWithItemName:(NSString *)name;

@end
[/code]

JMRItem.m

[code]//
// JMRItem.m
// RandomItems
//
// Created by Matthew Raby on 9/25/14.
// Copyright © 2014 Matthew Raby. All rights reserved.
//

#import “JMRItem.h”

@implementation JMRItem

+(instancetype)randomItem
{
// create an immutable array of adjectives
NSArray *randomAdjectiveList = @[@“Fluffy”, @“Rusty”, @“Shiny”, @“Sharp”, @“Blunt”];

// create an immutable array of three nouns
NSArray *randomNounList = @[@"Bear", @"Spork", @"Mac"];

// get the index of a random adjective/noun from the lists
// note: the modulus % operator gives
// you the remainder. so adjectiveIndex is a random number

// from 0 to 2 inclusive
NSInteger adjectiveIndex = arc4random() % [randomAdjectiveList count];
NSInteger nounIndex = arc4random() % [randomNounList count];
// note that nsinteger is not an object, but a type definition
// for "long"

NSString *randomName = [NSString stringWithFormat:@"%@ %@", randomAdjectiveList[adjectiveIndex], randomNounList [nounIndex]];

int randomValue = arc4random() % 100;

NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
                                '0' + arc4random() % 10,
                                'A' + arc4random() % 26,
                                '0' + arc4random() % 10,
                                'A' + arc4random() % 26,
                                '0' + arc4random() % 10];

JMRItem *newItem = [[self alloc]initWithItemName:randomName valueInDollars:randomValue serialNumber:randomSerialNumber];

return newItem;

}

// designated initializer, calls super
-(instancetype)initWithItemName:(NSString *)name valueInDollars:(int)value serialNumber:(NSString *)sNumber
{
// call the superclass’s designated initializer
self = [super init];

// did the superclass's designated initiializer succeed?
if (self) {
    //give the instance variables intiial values
    _itemName = name;
    _serialNumber = sNumber;
    _valueInDollars = value;
    _dateCreated = [[NSDate alloc]init];
    
}
return self;

}

// Silver Challenge Initializer
-(instancetype)initWithItemName:(NSString *)name serialNumber:(NSString *)sNumber
{
return [self initWithItemName:name
valueInDollars:0
serialNumber:@“Item”];
}

// second initializer calls designated initializer
-(instancetype)initWithItemName:(NSString *)name
{
return [self initWithItemName:name
serialNumber:@“Item”];
}

// override init to call initWithItemName
-(instancetype)init
{
return [self initWithItemName:@“Item”];
}

-(NSString *)description
{
NSString *descriptionString = [[NSString alloc]initWithFormat:@"%@ (%@): Worth $%d, recorded on %@", self.itemName, self.serialNumber, self.valueInDollars, self.dateCreated];
return descriptionString;
}

@end
[/code]

JMRContainer.h

[code]//
// JMRContainer.h
// RandomItems Gold Challenge
//
// Created by Matthew Raby on 9/26/14.
// Copyright © 2014 Matthew Raby. All rights reserved.
//

#import “JMRItem.h”

@interface JMRContainer : JMRItem

@property (nonatomic, copy) NSArray *masterContainer;
@property (nonatomic) int containerValue;
@property (nonatomic) int masterValue;
@property (nonatomic) NSString *containerName;

+(instancetype)randomContainer;
-(instancetype)initWithContainerName:(NSString *)name containerValue:(int)value;

//-(void)addToMasterContainer:(JMRContainer *)a;

@end
[/code]

JMRContainer.m

[code]//
// JMRContainer.m
// RandomItems Gold Challenge
//
// Created by Matthew Raby on 9/26/14.
// Copyright © 2014 Matthew Raby. All rights reserved.
//

#import “JMRContainer.h”

@implementation JMRContainer

+(instancetype)randomContainer
{
NSArray *name = @[@“Bob”, @“Steve”, @“Joe”, @“Matt”, @“Kim”, @“Sharon”];
NSArray *lastName = @[@“DaBuilder’s”, @“Jobs’”, @“Flacco’s”, @“Montana’s”];
NSString const *cont = @“Container”;

NSInteger nameIndex = arc4random() % [name count];
NSInteger lastIndex = arc4random() % [lastName count];

NSString *randomContainer = [NSString stringWithFormat:@"%@ %@ %@", name[nameIndex], lastName[lastIndex], cont];

JMRContainer *newContainer = [[self alloc]initWithContainerName:randomContainer containerValue:0];

return newContainer;

}

-(instancetype)initWithContainerName:(NSString *)name containerValue:(int)value
{
self = [super init];

if (self) {
    _containerName = name;
    _containerValue = value;
}
return self;

}

-(instancetype)initWithContainerName:(NSString *)name
{
return [self initWithContainerName:name containerValue:0];
}

-(instancetype)init
{
return [self initWithContainerName:@“Master Container”];
}

-(NSString *)description
{
// create description string, do not assign a value
NSString *descriptionString;

// create if statement to determine if the container has a master value or a container value
if (self.masterValue) {
    // if master value exists print container name with master value
    descriptionString = [[NSString alloc]initWithFormat:@"%@, valued at %d", self.containerName, self.masterValue];
}else{
    // if master value doesn't exist print container name with container value
    descriptionString = [[NSString alloc]initWithFormat:@"%@, valued at %d", self.containerName, self.containerValue];
}

return descriptionString;

}

@end
[/code]


#2

Hey,
How and where did you declare the identifier for ‘valueInDollar’?
As I am using Xcode 5.1.1 (5B1008) on Mac OS X Yosemite and that is the only error that I have.