NameError: name 'parse_sentence' is not defined


#1

Hi Everyone,

For ex48.parser.py. I am trying to run the code from python.

if I try to make x and instance of class Sentence() and feed it tuples. I still get error:

TypeError: init() takes exactly 4 arguments (2 given)


#2

Hi @tcratius I’m not on ex48 now but when I look at the error-message in your image I guess you haven’t defined parse_sentence before you assigned it to x. Did you?


#3

@tcratius Maybe you can post your code so it will be easier to help.


#4

See the thing is, it’s actually Zeds code for the parser. The stuff he thinks is simple is beautiful yet simple. Maybe one day it can think like this… I do like your thinking though;

you haven’t defined parse_sentence before you assigned it to x. Did you?

and I don’t really want to spoil it for you, but the class method actually returns the instance of the class. Just had a thought. I’ll watch the video for it and see if he gives away some clues, as well as read the code aloud again :stuck_out_tongue: One thing I’ve learned about programmers and their style of teaching is, they never show you all of the magic. :space_invader: Cheers for the mental flossing.


#5

Yeah, it looks like parse_sentence isn’t defined in ex48.parser. Name errors are pretty common until you get comfortable with how python’s import stuff works.

As you haven’t shown us the code, then I can’t fix it for you.

But, for debugging this sort of issue in Python, you want to use the globals() function. It’s one of pythons built-in function. And it’s helpful. (https://docs.python.org/3.5/library/functions.html#globals).

The python 3 documentation is brief. But, the function returns a dictionary saying what variable names you can use right now.

From your picture, after getting NameError, into the python interpreter, I’d type:

$ globals()

You will then be shown a dictionary of what names are available to you. If you could the name ‘parse_sentence’, then you’d find it in the dictionary printed to the terminal.

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'parse_sentence': <function 'parse_sentence at 'C0x000001E0D4F2ED90'>}

Then you’d be able to use it. But, it’ll not be there.


#6

Hi @didierCH and @donal_m,

Sorry I should have just given the code, https://github.com/tcratius/ex48.git (parser.py), but now I’m curious to learn this debugging. I’m not really used to this sharing and helping thing. Spent most of my time up till now alone and web searching.


#7

In the video, Zed changes the parser.py from approximately line 58 to the code below, both get the same error that seems to point to the function name. I think I’ll head to the library when it opens and print it out. Hard to follow on screen. I could be stuffing myself up with adding all the self.word_list. From what I can make of it, it makes a class Sentence with self, subject, verb, and object is created when the parse_subject method is called. However, to me this seems odd since the parse_subject is a method of the uncreated object, if that makes any sense :confused:

 def parse_subject(word_list, subject):
        verb = parse_verb(word_list)
        object = parse_object(word_list)

        return Sentence(subject, verb, object)


    def parse_sentence(word_list):
        skip(word_list, 'stop')
        next_word = peek(word_list)

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

#8

Thanks for trying to help (no sarcasm, being real). Not sure why I can not run it in python on terminal but can get the parser_tests.py file to worked so I guess that’s going to be good enough for me

import pytest
from ex48.parser import *

@pytest.fixture()
def test_sentence():
    sentence = Sentence([("noun","player"),("verb", "go"),("noun", "bear")])
    assert_equal(sentence.subj, 'player')
    assert_equal(sentence.verb, 'go')
    assert_equal(sentence.obj, 'north')

#9

Hello @tcratius.
I really hope I can help you on this ( the last part in this topic). I am far from expert in pytest. Just a gigolo… No I mean beginner. :slight_smile:

I also used a fixture in my pytest code. The fixture is suposed to “setup” or “prepare” test functions for the test.
I have an example here that I wrote to understand it myself.

@pytest.fixture()
def test_some():
word = (‘apple’ , ‘banana’)
return word

def test_word1(test_some):
assert test_some[0] == ‘apple’

def test_word2(test_some):
assert test_some[1] == ‘banana’

def test_word3(test_some):
assert test_some[0] != ‘pineapple’

Thats one way to use it. There are a lot more ways one can use pytest.fixture.
I used this kind of fixure in my test_parser.py
If you want you can have a look at my code at Github Ex 49

Your code looks like nosetest

assert_equal(sentence.obj, 'north)

The advantage of Pytest is that there is as far I have seen just “assert”. I think this would be the pytest way for your code.

assert sentence.obj == ‘north’

Please forgive and correct me if I am wrong. I just want to help whenever I can do so. Even if its just one step on a 1000 mile journey


#10

Hi @ulfen69,

Haha, I stole that off you after reading other peoples code, yours was the best solution. I hope in time just by seeing the solution and problem I can develop better code myself. I will add you to the my acknowledgements on README. :slight_smile:

I love the example you gave and will look into pytest fixture some more. Very nice code my friend.

Cheers tc

Ps figured if Bill Gates can steal it, so can I LOL :space_invader:


#11

Hi.
That is perfectly ok by me.
Just make sure the test works. Change a word or letter to see if you get a Fail.
I have wrote some test that accept anything. Probably I did something wrong. But it passed. So I was quite pleased until I found out.


#12

Ok, My friend, will do, something tells me that main code needs a tweak :slight_smile: But tests first.


#13

Hi @ulfen69,

I managed to hack this. Testing method peek() through pytest fixture test_sentence(). Thought I’d share :smile:;

@pytest.fixture()
def test_sentence():
    sentence = Sentence.parse_sentence([("noun","player"),("verb", "go"),("noun", "bear")])
    return sentence

@classmethod
def test_peek():
    result = test_sentence()
    assert Sentence.peek(result) != None  

Took me forever lol.


#14

I ran into this issue too. I even signed up just to post, lol. I just completed this example on the lp3thw and realized that it was easy to confuse peek and all of the remaining function definitions as being in the same block as the class Sentence, when they’re all individual blocks. Hope it saves people some time.

btw, donal_m tip helped alot. Thanks. :slight_smile:


#15

Oh, I found out that that the above is incorrect. Will have to redo soz


#16

Hey, not sure if you solved this yet, but your indentation from def parse_sentence on is wrong. You see how it’s nested under def parse_subject rather than at column 0 just like def parse_subject? You should be able to select that whole block and then “dedent” it, depending your editor. Sometimes it’s shift-tab or ctrl-tab but look at the docs.


#17

Slaps head, :confounded: the amount of times I looked at that code and didn’t notice. I swear I did pay attention when you said “read out aloud the code and match it to your code”, and I went line by line checking for mistakes, couldn’t find any, yet there it is as clear as day. Man I’m a silly goose. Oh well, hopes this helps others. Minus 5 :space_invader: Thank you for the feed back :smiley: