0

I am aware of * operator but this one does not seem to work. I basically want to unpack this list consisting of tuple pairs:

sentence_list = [('noun', 'I'), ('verb', 'kill'), ('noun', 'princess')]

Consider my class Sentence:

class Sentence(object):

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

Now I create an object called test_obj and when I try to unpack sentence_list it does not seem to work:

test_obj = Sentence(*sentence_list)

When I test it with nose.tools using:

assert_is_instance(test_obj, Sentence)

I get this:

TypeError: __init__() takes exactly 4 arguments (3 given)

But when I change it to:

test_obj = Sentence(('noun', 'I'), ('verb', 'kill'), ('noun', 'princess'))

It passes the test. What am I doing wrong?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user3056783
  • 2,265
  • 1
  • 29
  • 55

1 Answers1

1

Your code works just fine, provided you actually pass in a list of 3 elements:

>>> class Sentence(object):
...     def __init__(self, subject, verb, object):
...         self.subject = subject[1]
...         self.verb = verb[1]
...         self.object = object[1]
... 
>>> sentence_list = [('noun', 'I'), ('verb', 'kill'), ('noun', 'princess')]
>>> Sentence(*sentence_list)
<__main__.Sentence object at 0x10043c0d0>
>>> del sentence_list[-1]
>>> Sentence(*sentence_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 4 arguments (3 given)

Note the error message here; __init__ takes four arguments, including self.

Ergo, it is your sentence_list value that is at fault here, not your technique.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Yes I've tried putting the code directly into interpreter. However how should I write the test so it passes? – user3056783 Apr 28 '14 at 19:15
  • @user3056783: You haven't shown us what `sentence_list` is in your test. It is **not** a list with enough elements. – Martijn Pieters Apr 28 '14 at 19:16
  • I'm sorry I'm probably missing something here.. I'm still very new to programming, it's `sentence_list = [('noun', 'I'), ('verb', 'kill'), ('noun', 'princess')]` like I wrote before. My test file is something like this: from nose.tools import * import p sentence_list = [('noun', 'I'), ('verb', 'kill'), ('noun', 'princess')] def test_parse_subject_class(): test_obj = p.Sentence(*sentence_list) assert_is_instance(test_obj, p.Sentence) assert_equal(test_obj.subject, 'I') Where `p` is other module where the actual code is. I'm using `nosetests` to test it. – user3056783 Apr 28 '14 at 19:22
  • 1
    @user3056783: You'll want to print `sentence_list` then, because the *only* way you are getting your exception is if `sentence_list` contains two and not 3 elements. Add a `print` statement just before invoking `Sentence(*sentence_list)` (making sure you run `nose -s` so stdout is not being captured) and see what is being printed. – Martijn Pieters Apr 28 '14 at 19:34
  • Hmm you are right it prints out this at the beginning: `........[('verb', 'kill'), ('noun', 'princess')] E....... ====================================================================== ERROR: p_test.test_parse_subject_class` – user3056783 Apr 28 '14 at 19:43
  • @user3056783: See, now you know what to debug! :-) – Martijn Pieters Apr 28 '14 at 19:48
  • OK I think I found a mistake... I've probably done newbie mistake. `sentence_list` is used in numerous test functions. Some of the functions contain `list.pop` and those tests run first. So when this test, which is at the end of the test file runs, the list is different. I've created new list that is contained within the test function and the test passes. I feel really stupid for not noticing but I feel like I learned from this. – user3056783 Apr 28 '14 at 19:49
  • 1
    You have what is called a test isolation bug; the bug isn't there in isolation, but when you run multiple tests your test breaks. Don't reuse data between tests. ;-) – Martijn Pieters Apr 28 '14 at 19:50
  • Yes it seems logical now :) I am still trying to figure out this testing thing because up until now I've been learning how to minimize code... seems like the same approach is not smart for testing. – user3056783 Apr 28 '14 at 19:53