Search code examples
pythonclassconditional-statementsinstance-variables

Calling an instance variable in another class


I am trying to access the instance variable self.code in class Line in class Quote. I am trying to make the following rule pass: when a quote is made containing both a 'door_sign' and 'escape_sign' line they receive 10% off the entire quote.

Here's the code.

class Client:
    def __init__(self, postcode):
        self.postcode = postcode


class Line:
    def __init__(self, code, unit_cost, quantity=1):
        self.code = code
        self.unit_cost = unit_cost
        self.quantity = quantity

    def cost(self):

        if self.code == 'door_sign' and self.quantity >=3:
            return self.unit_cost * self.quantity * 0.8
        else:
            return self.unit_cost * self.quantity

class Quote:
    def __init__(self, client=None, lines=[]):
        self.client = client
        self.lines = lines

    def cost(self):

**** Here is where my problem lies ****

    for l in self.lines:
        if line.code == 'door_sign' and 'escape_sign':
            return sum([l.cost() * 0.9])
        else:
            return sum([l.cost()])

print('Rule')
assert Quote(client=Client(postcode=3000), lines=[
Line(code='escape_sign', unit_cost=20.0, quantity=10),
]).cost() == 200.0
assert Quote(client=Client(postcode=3000), lines=[
Line(code='door_sign', unit_cost=10.0, quantity=1),
Line(code='escape_sign', unit_cost=20.0, quantity=10),
]).cost() == 189.0

Solution

  • Looks like you are always giving a discount since escape_sign is always True and computing the cost incorrectly by returning early. Why don't you try this in the def cost method:

    def cost(self):
        needed = {'door_sign', 'escape_sign'}
        discount = {l.code for l in self.lines} & needed == needed
        cost = sum(l.cost() for l in self.lines)
        return (cost * 0.9) if discount else cost
    

    Quick edit, I missed that you want the discount if both escape_sign and door_sign are in the order.

    If you want it in one loop:

    def cost(self):
        door = False
        escape = False
        cost = 0
        for line in self.lines:
            if line.code == 'escape_sign':
                escape = True
            elif line.code == 'door_sign':
                door = True
            cost += line.cost()
        return (cost * 0.9) if (escape and door) else cost