Should I investigate how to convert object to string? I think that’s what I need to do here because Sentence returns an object in “parser.parse_sentence(word_list)”.
I know Sentence does this here “self.subject = subject[1]” by taking the second item in the tuple, but i’m missing something because I get the object back instead of a string.
Here is my test and the error I’m getting when I run nosetests:
from nose.tools import *
from ex48 import parser
from ex48.lexicon import *
def test_peek():
# test peeking at the first item in the list
word_list = Lexicon.scan('run')
assert_equal(parser.peek(word_list), 'verb')
assert_equal(parser.peek(None), None)
def test_match():
# # test popping item off list if word[0] == expecting
word_list = Lexicon.scan('princess')
assert_equal(parser.match(word_list, 'noun'), ('noun', 'princess'))
assert_equal(parser.match(None, 'noun'), None)
def test_skip():
# test if this skips while word_list == word_type
word_list = Lexicon.scan('run north')
assert_equal(word_list, [('verb', 'run'), ('direction', 'north')])
parser.skip(word_list, 'noun')
assert_equal(word_list, [('verb', 'run'), ('direction', 'north')])
word_list = Lexicon.scan('I run north')
parser.skip(word_list, 'stop')
assert_equal(word_list, [('verb', 'run'), ('direction', 'north')])
def test_parse_verb():
# test if this returns the word from match(word_list..) when peek(word_list) == 'verb'
# test if this raises ParseError when peek(word_list) != 'verb'
word_list = Lexicon.scan('eat door')
assert_equal(parser.parse_verb(word_list), ('verb', 'eat'))
word_list = Lexicon.scan('bear eat princess')
assert_raises(parser.ParserError, parser.parse_verb, word_list)
def test_parse_object():
word_list = Lexicon.scan('bear run north')
assert_equal(parser.parse_object(word_list), ('noun', 'bear'))
word_list = Lexicon.scan('head north')
assert_equal(parser.parse_object(word_list), ('direction', 'north'))
assert_raises(parser.ParserError, parser.parse_object, word_list)
def test_parse_subject():
word_list = Lexicon.scan('bear run north')
assert_equal(parser.parse_subject(word_list), ('noun', 'bear'))
word_list = Lexicon.scan('run north')
assert_equal(parser.parse_subject(word_list), ('noun', 'player'))
def test_parse_sentence():
word_list = Lexicon.scan('run north')
assert_equal(word_list, [('verb', 'run'), ('direction', 'north')])
assert_equal(parser.parse_sentence(word_list), ('player run north')) <---- this bugger
# ??maybe pile
# s = parser.parse_sentence(word_list)
# assert_equal(s.verb, ('run'))
~~~Lexicon.py
class Lexicon(object):
def convert_numbers(s):
try:
return int(s)
except ValueError:
return None
def scan(sentence):
words = sentence.split()
pairs = []
for word in words:
if word in direction:
word_type = 'direction'
tupes = (word_type, word)
pairs.append(tupes)
elif word in verb:
word_type = 'verb'
tupes = (word_type, word)
pairs.append(tupes)
elif word in stop:
word_type = 'stop'
tupes = (word_type, word)
pairs.append(tupes)
elif word in noun:
word_type = 'noun'
tupes = (word_type, word)
pairs.append(tupes)
elif Lexicon.convert_numbers(word):
word_type = 'number'
tupes = (word_type, int(word))
pairs.append(tupes)
else:
word_type = 'error'
tupes = (word_type, word)
pairs.append(tupes)
return pairs
direction = ['north', 'south', 'east', 'west']
verb = ['run', 'go', 'kill', 'eat']
stop = ['the', 'in', 'of', 'I', 'it', 'head']
noun = ['bear', 'princess']
~~~parser.py
class ParserError(Exception):
pass
class Sentence(object):
def __init__(self, subject, verb, obj):
# here take ('noun', 'princes') tuples and convert them
self.subject = subject[1]
self.verb = verb[1]
self.obj = obj[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')
if peek(word_list) == 'verb':
return match(word_list, 'verb')
else:
raise ParserError("Expected a verb next.")
def parse_object(word_list):
skip(word_list, 'stop')
next_word = peek(word_list)
if next_word == 'noun':
return match(word_list, 'noun')
elif next_word == 'direction':
return match(word_list, 'direction')
else:
raise ParserError("Expected a noun or direction next")
def parse_subject(word_list):
skip(word_list, 'stop')
next_word = peek(word_list)
if next_word == 'noun':
return match(word_list, 'noun')
elif next_word == 'verb':
return ('noun', 'player')
else:
raise ParserError("Expected a verb next")
def parse_sentence(word_list):
subj = parse_subject(word_list)
verb = parse_verb(word_list)
obj = parse_object(word_list)
return Sentence(subj, verb, obj)
~~~Traceback
Traceback (most recent call last):
File "/Users/jdaniel/.venvs/lpthw/lib/python3.9/site-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/Users/jdaniel/PycharmProjects/pytex/ex48/tests/parser_tests.py", line 56, in test_parse_sentence
assert_equal(parser.parse_sentence(word_list), ('player run north'))
AssertionError: <ex48.parser.Sentence object at 0x10e3d9400> != 'player run north'
----------------------------------------------------------------------
Ran 13 tests in 0.003s
FAILED (failures=1)
Please send help.
Edit 5/21:
I changed the test_parse_sentence function and the below worked.
def test_parse_sentence():
word_list = Lexicon.scan('run north')
assert_equal(word_list, [('verb', 'run'), ('direction', 'north')])
s = parser.parse_sentence(word_list)
assert_equal(s.subject, ('player'))
assert_equal(s.verb, ('run'))
assert_equal(s.object, ('north'))