Ex 15 learnmpthw

Why does this work in pytest:

def test_top():
    fruit = stackqueue.Stack()
    fruit.push("Banaan")
    assert fruit.x() == "Banaan"
    def x(self):
        return self.top.value

But this doesn’t:

def test_top():
    fruit = stackqueue.Stack()
    fruit.push("Banaan")
    assert fruit.top() == "Banaan"
def top(self):
        return self.top.value

When I use the top version I get the following error:

TypeError: ‘StackNode’ object is not callable

Is it not possible to use “top”?

You can’t have methods and attributes with the same name. When you call fruit.top(), Python finds fruit.top first, which is an attribute of type StackNode, and then it tries to call it.

Also as a general rule of thumb, be descriptive with you test names. Imagine you had 100 unit tests in a folder, would ‘Top’ failing tell you why the problem was?

Right. But when I go like this:

def pop(self):

        popped = self.top

        self.top = self.top.next

        return popped.value
def test_pop():
    fruit = stack.Stack()
    fruit.push("Banaan")
    assert fruit.count() == 1
    fruit.push("Meloen")
    assert fruit.count() == 2
    fruit.push("Aardbei")
    assert fruit.count() == 3
    assert fruit.pop() == "Aardbei"
    assert fruit.count() == 2
    assert fruit.pop() == "Meloen"
    assert fruit.count() == 1
    assert fruit.pop() == "Banaan"
    assert fruit.count() == 0

It does work.

Isn’t this exactly the same but then just with pop?

Well I wanted to test the “top” function, but I understand what you are saying? How do you propose I would structure the test names best?

Perhaps include an action or outcome as well as the target?

test_pushed_item_is_at_top():

Will try to implement, thank you!

No, it’s not the same, because the topmost thing on your stack is still called stack.top, not stack.pop. Different names, no possibility for a name clash.

A free service run by Zed A. Shaw for learncodethehardway.org.