Class and external method call
<p>I am going through a data structures course and I am not understanding how a Class can call a method that's in another Class.<br>
The code below has 2 classes: <code>Printer</code> and <code>Task</code>.<br>
Notice that class <code>Printer</code> has a method called <code>startNext</code>, and this has a variable <code>self.timeRemaining</code> that gets assigned the result of <code>newTask.getPages() * 60/self.pagerate</code>.</p>

<p>How can <code>newTaks</code> reference the <code>getPages()</code> method from the Task class?<br>
The code that passes this object to the Printer class never references the Task class.<br>
The code works, since this is what the course gives out but, I just cannot understand how that method is accessed.<br>
Code:</p>

<pre><code>from pythonds.basic.queue import Queue

import random

class Printer:

    def __init__(self, ppm):
        self.pagerate = ppm
        self.currentTask = None
        self.timeRemaining = 0

    def tick(self):
        if self.currentTask != None:
            self.timeRemaining = self.timeRemaining - 1

            if self.timeRemaining &lt;= 0:
                self.currentTask = None

    def busy(self):
        if self.currentTask != None:
            return True
        else:
            return False

    def startNext(self, newTask):
        self.currentTask = newTask
        self.timeRemaining = newTask.getPages() * 60/self.pagerate

class Task:

    def __init__(self, time):
        self.timeStamp = time
        self.pages = random.randrange(1, 21)

    def getStamp(self):
        return self.timeStamp

    def getPages(self):
        return self.pages

    def waitTime(self, currentTime):
        return currentTime - self.timeStamp

def simulation(numSeconds, pagesPerMinute):

    labPrinter = Printer(pagesPerMinute)
    printQueue = Queue()
    waitingTimes = []

    for currentSecond in range(numSeconds):

        if newPrintTask():
            task = Task(currentSecond)
            printQueue.enqueue(task)

        if (not labPrinter.busy()) and (not printQueue.isEmpty()):
            nextTask = printQueue.dequeue()
            waitingTimes.append(nextTask.waitTime(currentSecond))
            labPrinter.startNext(nextTask)

        labPrinter.tick()

    averageWait = sum(waitingTimes)/len(waitingTimes)
    print "Average Wait %6.2f secs %3d tasks remaining." % (averageWait, printQueue.size())

def newPrintTask():
    num = random.randrange(1, 181)

    if num == 180:
        return True
    else:
        return False

for i in range(10):
    simulation(3600, 5)
</code></pre>

<p>If I understand clearly your question, it is because you are adding task object to Queue list. Then when you are getting object (list item) back, you are getting again Task object:</p>

<pre><code>#creating Task object and adding to Queque list
task = Task(currentSecond)
printQueue.enqueue(task)

class Queue:
    def __init__(self):
        #list of task objects
        self.items = []

    def enqueue(self, item):
        #you are inserting Task object item to list
        self.items.insert(0,item)

    def dequeue(self):
       #returns task object
       return self.items.pop()
</code></pre>

<p>So then you can call startNext() method from Printer class, because the dequeue() method is returning Task object.</p>

<p>And because of the object in startNext() is type of Task, you can call getPages() method on that object.</p>

<p>Is it sufficient answer?</p>

python