-2

Why is it giving me an error " 'int' object is not subscriptable " when i run the program? I looked if i was doing anything wrong, i understand it has to be an integer on line 24, but when I'm changing capacity[1] to capacity(int[1]) , it gives me the same error. Any hint would be appreciated.

class Bag():
    __slots__=('name', 'weight', 'value')

def mkBag(name, weight, value):
    thisBag = Bag()
    thisBag.name = name
    thisBag.weight = weight
    thisBag.value = value
    return thisBag

def ratio(treasure):
     print(treasure)
     print(treasure)
     return treasure[2]//treasure[1]

def plunder(treasure, capacity):
    treasure = sorted(treasure, key=ratio, reverse=True)
    bagLst = []
    current = 0
    while current < capacity:
        if capacity != 0:
            if capacity > current[1]:
                bagLst.append(mkBag(treasure[0],weight[1],current[2]))
                capacity = capacity - current[1]
            else:
                bagLst.append(mkBag(current[0], capacity, (current[2]/current[1]), capacity))
                capacity = 0
    return bagLst


def main():
    capacity = 10
    name = ''
    weight = 0
    value = 0
    treasure = [('silver', 20, 100), ('platinum', 10, 400), ('paladium',10,800), ('diamonds',5,900), ('gold', 10,60)]
    bagLst = plunder(treasure, capacity)

    for line in bagLst:
        print('bagLst')

2 Answers2

2

current is an int:

current = 0

but you are trying to use it as a list:

if capacity > current[1]:
    bagLst.append(mkBag(treasure[0],weight[1],current[2]))
    capacity = capacity - current[1]
else:
    bagLst.append(mkBag(current[0], capacity, (current[2]/current[1]), capacity))

everywhere you use current[index] you are trying to index the integer value.

If you expected current to be a sequence instead, you'd need to set it to one.

I suspect you want to inspect the current treasure to add to the bag; you didn't pick any treasure item however. Something along the lines of:

current = 0

while capacity and current < len(treasure):
    item = treasure[current]
    current += 1
    if capacity > item[1]:
        bagLst.append(mkBag(item[0], item[1], item[2]))
        capacity = capacity - item[1]
    else:
        bagLst.append(mkBag(item[0], capacity, (item[2]/item[1]), capacity))
        capacity = 0
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

"int" object not subscriptable means you're trying to do 1234[1]. That doesn't make any sense! You can subscript a string ('abcdefg'[1] == 'b') and a list ([1,2,3,4,5][1] == 2) but you can't get the "nth element" of an integer.

In your line:

# in def plunder(...):
if capacity > current[1]:

You're trying to access the 2nd element of current, which is currently equal to the integer 0. Are you trying to make that a list? What are you expecting to be in current[1]?

Here's a substantially better way to accomplish this

Hey there, so I figured you meant that current[1] was actually item[1], meaning the weight of the item you were looking at. Instead, current was intended to be the running-weight of the bag. Understood! That said, I wrote up a better solution for this: take a look see!

class Treasure(object):
    def __init__(self,name,weight=0,value=0,id_=0):
        self.name = name
        self.weight = weight
        self.value = value
        self.id = id_ # bootstrap for further development
    @property
    def ratio(self):
        return self.value/self.weight

class BagFullError(ValueError):
    pass

class Bag(object):
    def __init__(self,owner=None,capacity=10):
        self.owner = owner
        self.capacity = capacity
        self.contents = list()
    def __str__(self):
        return_value = "CONTENTS:"
        for item in self.contents:
            return_value += "\n  ${0.value:4}  {0.name:10}{0.weight} lb".format(item)
        return return_value
    def add(self,other):
        if not isinstance(other,Treasure):
            raise TypeError("Must pick up Treasure")
        if self.weight + other.weight > self.capacity:
            raise BagFullError("Bag cannot fit {}({} lb) ({} lb/{} lb)".format(
                other.name,other.weight,self.weight,self.capacity))
        self.contents.append(other)
    def remove(self,other):
        self.contents.remove(other)
        # may throw ValueError if `other` not in `self.contents`
    @property
    def weight(self):
        return sum(item.weight for item in self.contents)

treasure = [Treasure('silver', 20, 100), Treasure('platinum', 10, 400),
            Treasure('paladium',10,800), Treasure('diamonds',5,900),
            Treasure('gold', 10,60)]
## map(lambda x: Treasure(*x), [('silver',20,100), ... ])

def plunder(treasure_list,bag=None):
    _bag = bag or Bag()
    treasures = sorted(treasure_list,
                       key = lambda x: x.ratio,
                       reverse = True)
    while True:
        for treasure in treasures:
            try: _bag.add(treasure)
            except BagFullError as e:
                print(e)
                return _bag

bag = Bag("Adam",100)
print(bag)
plunder(treasure,bag)
print(bag)
print("Total Value: {}".format(sum(item.value for item in bag.contents)))
Community
  • 1
  • 1
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • well I'm trying to say by "if capacity > current[1]" if the amount of weight i can take into the bag is greater than weight of a treasure, than, take everything from that treasure... – user3408174 Mar 11 '14 at 22:18
  • @user3408174 I mean, what is `current[1]`? For that matter, what would `current[0]` or `current[65535]` be? Isn't `current` what you mean? – Adam Smith Mar 11 '14 at 22:21
  • i mean the value for example current[1] i mean cost – user3408174 Mar 11 '14 at 22:25
  • @user3408174 how is that different from `current`? What do you expect `current` to be? It's just a number! EDIT: OH I think I understand. Hang on, you're going about this a funny way but I think I follow your line of reasoning now........ – Adam Smith Mar 11 '14 at 22:29
  • thank you for your answer i will accept it as a right answer, it worked actually... but since my professor does not allow us a more complex code i can't implement it like this, looking forward on learning more tho – user3408174 Mar 11 '14 at 23:36
  • @user3408174 Then Martijn's is the correct answer -- no reason to change your "accepted" :) – Adam Smith Mar 11 '14 at 23:39