Search code examples
pythonnosetests

Confusion about LPTHW exercise 49


I am trying to write a nosetest for the following code:

class ParserError(Exception):
    pass 

class Sentence(object):
    def __init__(self, subject, verb, object):
        self.subject = subject[1]
        self.verb = verb[1]
        self.object = object[1]

def peek(word_list):
    if word_list:
        word = word_list[0]
        return word[0]
    else:
        return None 

def match(word_list, expecting):
    if word_list:
        word = word_list.pop(0)

        if word[0] == expecting:
            return word
        else:
            return None 
    else:
        return None 

def skip(word_list, word_type):
    while peek(word_list) == word_type:
        match(word_list, word_type)

def parse_verb(word_list):
    skip(word_list, 'stop')
    first = peek(word_list)

    if first == 'verb':
        return match(word_list, 'verb')
    else:
        raise ParserError("Expected a verb next, not %s." % first)

def parse_object(word_list):
    skip(word_list, 'stop')
    next = peek(word_list)

    if next == 'noun':
        return match(word_list, 'noun')
    if next == 'direction':
        return match(word_list, 'direction')
    else:
        return ParserError("Expected a noun next.")

def parse_subject(word_list, subj):
    verb = parse_verb(word_list)
    obj = parse_object(word_list)

    return Sentence(subj, verb, obj)

def parse_sentence(word_list):
    skip(word_list, 'stop')

    start = peek(word_list)

    if start == 'noun':
        subj = match(word_list, 'noun')
        return parse_subject(word_list, subj)
    elif start == 'verb':
        return parse_subject(word_list, ('noun', 'player'))
    else:
        raise ParserError("Must start with subject, object or verb, not %s." % start)

I have tried this and got the ParserError: Expected a verb, not None, which refers to the parse_verb method :

from nose.tools import *
from ex49 import parser

def test_parse_subject():
    word_list = [('verb', 'catch'),
             ('noun', 'things')]
    subj = ('noun', 'player')
    verb = parser.parse_verb(word_list)
    obj = parser.parse_object(word_list)
    result = parser.Sentence(subj, verb, obj)
    assert_equal(parser.parse_subject(word_list, subj), result)

Any ideas? I wish that I could post more than just a code that failed, but I have been struggling with this chapter for the total of 8 hours now and my brain is shot.


Solution

  • parse_verb removes the verb from word_list. parse_subject tries to find a verb there and fails, hence the exception.

    I think the exercise is silly in asking to write tests without offering any documentation what the code is supposed to do.

    You can write the test like this:

    def test_parse_subject():
        word_list = [('verb', 'catch'),
                 ('noun', 'things')]
        subj = ('noun', 'player')
        result = parser.Sentence('player', 'catch', 'things')
        assert_equal(parser.parse_subject(word_list, subj), result)
    

    ...but that should still fail. Because Sentence does not define an __eq__ method, the two instances are compared by identity.

    Try this instead:

    def test_parse_subject():
        word_list = [('verb', 'catch'),
                 ('noun', 'things')]
        subj = ('noun', 'player')
        result = parser.parse_subject(word_list, subj)
        assert_equal((result.subject, result.verb, result.object), 
                     ('player', 'catch', 'things'))