Description marred when container contains another container


#1

Hi guys,

I was wondering what you guys did with the BNRContainer description method.
As you are well aware, the description method works fine until you have another BNRContainer in your BNRContainer object because instead of printing the array or set properly, it takes everything literally.

[ul]
2013-10-25 11:17:20.856 iOS_BNR[1048:303] Samsonite (): Worth $89, containing (
“Fluffy Mac (3A6T4): Worth $30, recorded on 2013-10-25 02:17:20 +0000”,
“InCase (): Worth $75, containing (\n “Fluffy Bear (3R2Q6): Worth $88, recorded on 2013-10-25 02:17:20 +0000”,\n “Shiny Mac (7E4L1): Worth $77, recorded on 2013-10-25 02:17:20 +0000”,\n “Fluffy Spork (1K1G7): Worth $71, recorded on 2013-10-25 02:17:20 +0000”,\n “Rusty Mac (9X6C8): Worth $40, recorded on 2013-10-25 02:17:20 +0000”,\n “Fluffy Bear (3H0R6): Worth $54, recorded on 2013-10-25 02:17:20 +0000”,\n “Fluffy Spork (1P5F4): Worth $29, recorded on 2013-10-25 02:17:20 +0000”,\n “Shiny Bear (8K9Y2): Worth $35, recorded on 2013-10-25 02:17:20 +0000”,\n “Fluffy Spork (8J8T0): Worth $94, recorded on 2013-10-25 02:17:20 +0000”,\n “Rusty Bear (5E2Z1): Worth $42, recorded on 2013-10-25 02:17:20 +0000”,\n “Rusty Bear (4X7P8): Worth $38, recorded on 2013-10-25 02:17:20 +0000”\n) (Total: $643 including InCase), recorded on 2013-10-25 02:17:20 +0000”,
“Shiny Spork (3P9B1): Worth $10, recorded on 2013-10-25 02:17:20 +0000”,
) (Total: $692 including Samsonite), recorded on 2013-10-25 02:17:20 +0000
Program ended with exit code: 0
[/ul]

Any solutions without deviating too much from the classes we have used thus far?


#2

Hi BossaGroove,

I am not sure I understand what you mean when you say that the description is marred, and that the printing takes everything literally. It appears that the contents of your “Samsonite” are printed, that one of the items in your “Samsonite” is your “InCase”, and that the contents of the “InCase” are also printed.

Are you referring to the formatting of the description? i.e., Are you wondering if it is (easily) possible to print the contents of an inner container so that it shows a proper level of indentation when printed? I struggled with this for a while, but came up with a solution that seems to work. For the solution, I did have to add a new method to the BNRItem class. The new method prints an item with a specified level of indentation. Here is what I did…

For BNRItemh…

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
    NSString            *itemName;
    NSString            *serialNumber;
    int                 valueInDollars;
    NSDate              *dateCreated;
}

+ (id) randomItem;

- (id) initWithItemName: (NSString *) name
         valueInDollars: (int) value
           serialNumber: (NSString *) serialNbr;

- (void) setItemName: (NSString *) newItemName;
- (NSString *) itemName;

- (void) setSerialNumber: (NSString *) newSerialNumber;
- (NSString *) serialNumber;

- (void) setValueInDollars: (int) newValueInDollars;
- (int) valueInDollars;

- (NSDate *) dateCreated;

- (NSString *) descriptionWithIndent: (int) level;

@end

For BNRItem.m…


#import "BNRItem.h"

@implementation BNRItem


/*****************************************************************************
 *                                                                            *
 * randomItem():                                                              *
 *                                                                            *
 ******************************************************************************/

+ (id) randomItem
{
    // Create an array of three adjectives.

    NSArray             *randomAdjectiveList = [NSArray arrayWithObjects: @"Fluffy",
                                                                          @"Rusty",
                                                                          @"Shiny",
                                                                          nil
                                               ];


    // Create an array of three nouns:

    NSArray             *randomNounList = [NSArray arrayWithObjects: @"Bear",
                                                                     @"Spork",
                                                                     @"Mac",
                                                                     nil
                                        ];


    // Get the index of a random adjective / noun from the lists.

    NSInteger           adjectiveIndex = rand() % [randomAdjectiveList count];
    NSInteger           nounIndex = rand() % [randomNounList count];

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

    int                 randomValue = rand() % 100;

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

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

    return newItem;
}


/*****************************************************************************
 *                                                                            *
 * initWithItemName: valueInDollars: serialNumber:                            *
 *                                                                            *
 ******************************************************************************/

- (id) initWithItemName: (NSString *) name
         valueInDollars: (int) value
           serialNumber: (NSString *) serialNbr
{
    self = [super init];

    if (self)
    {
        [self setItemName: name];
        [self setValueInDollars: value];
        [self setSerialNumber: serialNbr];

        dateCreated = [[NSDate alloc] init];
    }

    return self;
}


/*****************************************************************************
 *                                                                            *
 * init                                                                       *
 *                                                                            *
 ******************************************************************************/

- (id) init
{
    return [self initWithItemName: @"Item" valueInDollars: 0 serialNumber:@""];
}


/*****************************************************************************
 *                                                                            *
 * setItemName:                                                               *
 *                                                                            *
 ******************************************************************************/

- (void) setItemName: (NSString *) newItemName
{
    itemName = newItemName;
}


/*****************************************************************************
 *                                                                            *
 * itemName                                                                   *
 *                                                                            *
 ******************************************************************************/

- (NSString *) itemName
{
    return itemName;
}


/*****************************************************************************
 *                                                                            *
 * setSerialNumber:                                                           *
 *                                                                            *
 ******************************************************************************/

- (void) setSerialNumber: (NSString *) newSerialNumber
{
    serialNumber = newSerialNumber;
}


/*****************************************************************************
 *                                                                            *
 * serialNumber                                                               *
 *                                                                            *
 ******************************************************************************/

- (NSString *) serialNumber
{
    return serialNumber;
}


/*****************************************************************************
 *                                                                            *
 * setValueInDollars:                                                         *
 *                                                                            *
 ******************************************************************************/

- (void) setValueInDollars: (int) newValueInDollars
{
    valueInDollars = newValueInDollars;
}


/****************************************************************************
 *                                                                            *
 * valueInDollars                                                             *
 *                                                                            *
 ******************************************************************************/

- (int) valueInDollars
{
    return valueInDollars;
}


/*****************************************************************************
 *                                                                            *
 * dateCreated                                                                *
 *                                                                            *
 ******************************************************************************/

- (NSDate *) dateCreated
{
    return dateCreated;
}

/*****************************************************************************
 *                                                                            *
 * description                                                                *
 *                                                                            *
 ******************************************************************************/

- (NSString *) description
{
    return [self descriptionWithIndent: 0];
}

/****************************************************************************
 *                                                                            *
 * descriptionWithIndent:                                                     *
 *                                                                            *
 ******************************************************************************/

- (NSString *) descriptionWithIndent: (int) level
{
    NSString        *descriptionString = [[NSString alloc] init];


    // Indent to the specified level.

    for (int i = 0; i < level; i++)
    {
        descriptionString = [descriptionString stringByAppendingString: @"    "];
    }


    // Append the actual description string.

    descriptionString = [descriptionString stringByAppendingFormat:
                          @"%@ (%@): Worth $%d, recorded on %@",
                          itemName,
                          serialNumber,
                          [self valueInDollars],
                          dateCreated
                        ];

    return descriptionString;
}

For BNRContainer.h…

#import "BNRItem.h"

@interface BNRContainer : BNRItem
{
    NSMutableArray          *subItems;
}

-(void) addItem: (BNRItem *) newItem;

@end

And for BNRContainer.m…

#import "BNRContainer.h"

@implementation BNRContainer

/*****************************************************************************
 *                                                                            *
 * initWithItemName: valueInDollars: serialNumber:                            *
 *                                                                            *
 ******************************************************************************/

- (id) initWithItemName: (NSString *) name
         valueInDollars: (int) value
           serialNumber: (NSString *) serialNbr
{
    self = [super initWithItemName: name
                    valueInDollars: value
                      serialNumber: serialNbr
           ];

    if (self)
    {
        subItems = [[NSMutableArray alloc] init];
    }

    return self;
}


/*****************************************************************************
 *                                                                            *
 * valueInDollars                                                             *
 *                                                                            *
 ******************************************************************************/

- (int) valueInDollars
{
    int                 totalValue;


    totalValue = valueInDollars;

    for (BNRItem *item in subItems)
    {
        totalValue += [item valueInDollars];
    }

    return totalValue;
}


/*****************************************************************************
 *                                                                            *
 * descriptionWithIndent:                                                     *
 *                                                                            *
 ******************************************************************************/

- (NSString *) descriptionWithIndent: (int) level
{
    NSString        *myDescription = [super descriptionWithIndent: level];


    myDescription = [myDescription stringByAppendingString: @" Containing the following items..."];

    for (BNRItem *item in subItems)
    {
        myDescription = [myDescription stringByAppendingString: @"\n"];
        myDescription = [myDescription stringByAppendingString: [item descriptionWithIndent: level + 1]];
    }

    return myDescription;
}


/*****************************************************************************
 *                                                                            *
 * addItem:                                                                   *
 *                                                                            *
 ******************************************************************************/

-(void) addItem: (BNRItem *) newItem
{
    [subItems addObject: newItem];

}


@end

#3

Thanks for the help. Yes I was talking about the contents of the inner container. :slight_smile: