2016-12-22 12 views
2

私はPythonを学ぶ難しい方法(ex 48)で練習をしています。目的は、私たちのレキシコンを参照してユーザー入力をグループ化することです。私はスクリプトをテストするために鼻を使っていますが、複数のエラーがあります。私はnosetestsを実行すると6から5失敗を取得します。なぜ私はこれらのエラーを取得しているのか分かりません。どんな助け?Python - ユーザー入力を分割してグループ化する

エラー

FAIL: tests.ex48_tests.test_verbs 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "c:\python\lib\site-packages\nose\case.py", line 198, in runTest 
    self.test(*self.arg) 
    File "C:\Python\projects\skeleton2\tests\ex48_tests.py", line 13, in test_verbs 
    assert_equal(scan("go").result, [('verb', 'go')]) 
AssertionError: <bound method scan.result of <ex48.lexicon.scan object at 0x03A8F3F0>> != [('verb', 'go')] 

====================================================================== 
FAIL: tests.ex48_tests.test_stops 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "c:\python\lib\site-packages\nose\case.py", line 198, in runTest 
    self.test(*self.arg) 
    File "C:\Python\projects\skeleton2\tests\ex48_tests.py", line 21, in test_stops 
    assert_equal(scan("the").result(), [('stop', 'the')]) 
AssertionError: Lists differ: [('stop', 'the'), ('error', 'the')] != [('stop', 'the')] 

First list contains 1 additional elements. 
First extra element 1: 
('error', 'the') 

- [('stop', 'the'), ('error', 'the')] 
+ [('stop', 'the')] 

====================================================================== 
FAIL: tests.ex48_tests.test_noun 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "c:\python\lib\site-packages\nose\case.py", line 198, in runTest 
    self.test(*self.arg) 
    File "C:\Python\projects\skeleton2\tests\ex48_tests.py", line 29, in test_noun 
    assert_equal(scan("bear").result(), [('noun', 'bear')]) 
AssertionError: Lists differ: [('noun', 'bear'), ('error', 'bear')] != [('noun', 'bear')] 

First list contains 1 additional elements. 
First extra element 1: 
('error', 'bear') 

- [('noun', 'bear'), ('error', 'bear')] 
+ [('noun', 'bear')] 

====================================================================== 
FAIL: tests.ex48_tests.test_numbers 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "c:\python\lib\site-packages\nose\case.py", line 198, in runTest 
    self.test(*self.arg) 
    File "C:\Python\projects\skeleton2\tests\ex48_tests.py", line 35, in test_numbers 
    assert_equal(scan("1234").result(), [('number', 1234)]) 
AssertionError: Lists differ: [('error', '1234')] != [('number', 1234)] 

First differing element 0: 
('error', '1234') 
('number', 1234) 

- [('error', '1234')] 
?  --- - - 

+ [('number', 1234)] 
? ++++ 


====================================================================== 
FAIL: tests.ex48_tests.test_errors 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "c:\python\lib\site-packages\nose\case.py", line 198, in runTest 
    self.test(*self.arg) 
    File "C:\Python\projects\skeleton2\tests\ex48_tests.py", line 45, in test_errors 
    ('noun', 'princess')]) 
AssertionError: Lists differ: [('no[20 chars]r', 'bear'), ('error', 'IAS'), ('noun', 'princ[24 chars]ss')] != [('no[20 chars]r', 'IAS'), ('noun', 'princess')] 

First differing element 1: 
('error', 'bear') 
('error', 'IAS') 

First list contains 2 additional elements. 
First extra element 3: 
('noun', 'princess') 

+ [('noun', 'bear'), ('error', 'IAS'), ('noun', 'princess')] 
- [('noun', 'bear'), 
- ('error', 'bear'), 
- ('error', 'IAS'), 
- ('noun', 'princess'), 
- ('error', 'princess')] 

---------------------------------------------------------------------- 
Ran 6 tests in 0.027s 

FAILED (failures=5) 

lexicon.py

class scan(object): 
    dirs = ['north','south','east','west','down','up','left','right','back'] 
    verbs = ['go','stop','kill','eat'] 
    stops = ['the','in','of','from','at','it'] 
    nouns = ['door','princess','bear','cabinet'] 
    numbers = ['0','1','2','3','4','5','6','7','8','9'] 

    def __init__(self, user_input): 
     self.user_input = user_input 

    def result(self): 
     words = self.user_input.split() 
     results = [] 

     for item in words: 
      if item in scan.dirs: 
       result = ('direction', item.lower()) 
       results.append(result) 
      if item in scan.verbs: 
       result = ('verb', item.lower()) 
       results.append(result) 
      if item in scan.stops: 
       result = ('stop', item.lower()) 
       results.append(result) 
      if item in scan.nouns: 
       result =('noun', item.lower()) 
       results.append(result) 
      if item in scan.numbers: 
       result = ('number', int(item)) 
       results.append(result) 
      if item not in (scan.dirs or scan.verbs or scan.stops or 
          scan.nouns or scan.numbers): 
       result = ('error', item) 
       results.append(result) 

     return results 

lexicon_test.py

from nose.tools import * 
from ex48.lexicon import scan 


def test_direction(): 
    assert_equal(scan('north').result(), [('direction', 'north')]) 
    result = scan("north east south").result() 
    assert_equal(result, [('direction', 'north'), 
          ('direction', 'east'), 
          ('direction', 'south')]) 

def test_verbs(): 
    assert_equal(scan("go").result, [('verb', 'go')]) 
    result = scan("go kill eat").result() 
    assert_equal(result, [('verb', 'go'), 
          ('verb', 'eat') 
          ('verb', 'kill')]) 


def test_stops(): 
    assert_equal(scan("the").result(), [('stop', 'the')]) 
    result = scan("the in of").result() 
    assert_equal(result, [('stop', 'the'), 
          ('stop', ' in'), 
          ('stop', 'of')]) 


def test_noun(): 
    assert_equal(scan("bear").result(), [('noun', 'bear')]) 
    result = scan("bear princess").result() 
    assert_equal(result, [('noun', 'bear'), 
          ('noun', 'princess')]) 

def test_numbers(): 
    assert_equal(scan("1234").result(), [('number', 1234)]) 
    result = scan("3 91234").result() 
    assert_equal(result, [('number', 3), 
          ('number', 91234)]) 

def test_errors(): 
    assert_equal(scan("ASDFADFASDF").result(), [('error', 'ASDFADFASDF')]) 
    result = scan("bear IAS princess").result() 
    assert_equal(result, [('noun', 'bear'), 
          ('error', 'IAS'), 
          ('noun', 'princess')]) 
+0

「スキャン中のアイテム」をチェックする前に、単語を 'lower'したくないでしょう。 '? – depperm

+0

投稿を失敗した質問の1つに減らし、エラーメッセージを含めます。 **最小**失敗の例を常に提供してください。努力だけでおそらくエラーを見つけるのに役立ちます。 – Anthon

+0

'(scan.dirsまたはscan.verbsまたはscan.stopsまたはscan.nounsまたはscan.numbers):'あなたがしたいことをしない場合。 –

答えて

1

あなたはあなたのコードとロジックのカップルにタイプミスのカップルを持っていますエラー。

ここに修復されたバージョンのコードがありますが、noseモジュール(これは私にはありません)なしで実行するように修正されています。

class scan(object): 
    dirs = ['north','south','east','west','down','up','left','right','back'] 
    verbs = ['go','stop','kill','eat'] 
    stops = ['the','in','of','from','at','it'] 
    nouns = ['door','princess','bear','cabinet'] 
    numbers = ['0','1','2','3','4','5','6','7','8','9'] 

    def __init__(self, user_input): 
     self.user_input = user_input 

    def result(self): 
     words = self.user_input.split() 
     results = [] 

     for item in words: 
      if item in scan.dirs: 
       result = ('direction', item.lower()) 
       results.append(result) 
      elif item in scan.verbs: 
       result = ('verb', item.lower()) 
       results.append(result) 
      elif item in scan.stops: 
       result = ('stop', item.lower()) 
       results.append(result) 
      elif item in scan.nouns: 
       result =('noun', item.lower()) 
       results.append(result) 
      elif all(c in scan.numbers for c in item): 
       result = ('number', int(item)) 
       results.append(result) 
      else: 
       result = ('error', item) 
       results.append(result) 

     return results 

def assert_equal(u, v): 
    print(u, v, u == v) 

def test_direction(): 
    assert_equal(scan('north').result(), [('direction', 'north')]) 
    result = scan("north east south").result() 
    assert_equal(result, [('direction', 'north'), 
          ('direction', 'east'), 
          ('direction', 'south')]) 

def test_verbs(): 
    assert_equal(scan("go").result(), [('verb', 'go')]) 
    result = scan("go kill eat").result() 
    assert_equal(result, [('verb', 'go'), 
          ('verb', 'kill'), 
          ('verb', 'eat')]) 


def test_stops(): 
    assert_equal(scan("the").result(), [('stop', 'the')]) 
    result = scan("the in of").result() 
    assert_equal(result, [('stop', 'the'), 
          ('stop', 'in'), 
          ('stop', 'of')]) 


def test_noun(): 
    assert_equal(scan("bear").result(), [('noun', 'bear')]) 
    result = scan("bear princess").result() 
    assert_equal(result, [('noun', 'bear'), 
          ('noun', 'princess')]) 

def test_numbers(): 
    assert_equal(scan("1234").result(), [('number', 1234)]) 
    result = scan("3 91234").result() 
    assert_equal(result, [('number', 3), 
          ('number', 91234)]) 

def test_errors(): 
    assert_equal(scan("ASDFADFASDF").result(), [('error', 'ASDFADFASDF')]) 
    result = scan("bear IAS princess").result() 
    assert_equal(result, [('noun', 'bear'), 
          ('error', 'IAS'), 
          ('noun', 'princess')]) 

tests = (
    test_direction, 
    test_verbs, 
    test_stops, 
    test_noun, 
    test_numbers, 
    test_errors, 
) 

for test in tests: 
    print('\n' + test.__name__) 
    test() 

出力

test_direction 
[('direction', 'north')] [('direction', 'north')] True 
[('direction', 'north'), ('direction', 'east'), ('direction', 'south')] [('direction', 'north'), ('direction', 'east'), ('direction', 'south')] True 

test_verbs 
[('verb', 'go')] [('verb', 'go')] True 
[('verb', 'go'), ('verb', 'kill'), ('verb', 'eat')] [('verb', 'go'), ('verb', 'kill'), ('verb', 'eat')] True 

test_stops 
[('stop', 'the')] [('stop', 'the')] True 
[('stop', 'the'), ('stop', 'in'), ('stop', 'of')] [('stop', 'the'), ('stop', 'in'), ('stop', 'of')] True 

test_noun 
[('noun', 'bear')] [('noun', 'bear')] True 
[('noun', 'bear'), ('noun', 'princess')] [('noun', 'bear'), ('noun', 'princess')] True 

test_numbers 
[('number', 1234)] [('number', 1234)] True 
[('number', 3), ('number', 91234)] [('number', 3), ('number', 91234)] True 

test_errors 
[('error', 'ASDFADFASDF')] [('error', 'ASDFADFASDF')] True 
[('noun', 'bear'), ('error', 'IAS'), ('noun', 'princess')] [('noun', 'bear'), ('error', 'IAS'), ('noun', 'princess')] True 

第ロジックIは、スポットエラーがない試験item場合には、それらのいずれにもないん

if item not in (scan.dirs or scan.verbs or scan.stops 
    or scan.nouns or scan.numbers): 

ということでしたリスト。代わりに、それは最初のPythonのorオペレータのための標準的なルールを使用して

scan.dirs or scan.verbs or scan.stops or scan.nouns or scan.numbers 

を計算します。 scan.dirsは空ではないリストなので、その式の結果は単にscan.dirsです。

if文はあなたがするつもり何明確ではありません

if item not in scan.dirs: 

と同等になるように。

orandがPythonで動作する方法の詳細については、今年初めに書いたthis answerを参照してください。

我々

if not any(item in seq for seq in (scan.dirs, scan.verbs, scan.stops, 
    scan.nouns, scan.numbers)): 

を使用して、そのテストを実装することができますが、我々はそれをする必要はありません。代わりに、ifのほとんどをelifに変更し、正常にスキャンされなかったものはエラーである必要がありますので、elseブロックで処理できます。

2番目の大きな論理エラーは番号テストです。あなたは、多桁の数字列が

if item in scan.numbers: 

で有効な(正の)整数であるかどうかを確認しようとしていたが、itemが一桁の場合はそのテストにのみ成功します。

代わりに、私たちは数の_all_digitsが、実際には、数字であり、それは

all(c in scan.numbers for c in item) 

が何をするかということをチェックする必要があります。

はしかし、より良い方法があります:私はあなたのスキャンリストを使用したかったので、私は私のコードでそれを使用していませんでした

if item.isdigit(): 

:私たちはstrタイプの.isdigitメソッドを使用します。また、.isdigitでは負数や小数点は扱えませんが、'-''.'scan.numbersに簡単に追加できます。

+0

ありがとうございました。私はそのテストスクリプトでいくつのタイプミスをしたのか分からなかった。 –

+0

私は実際に 'all'キーワードを知りませんでした。scan.numbersは0-9の範囲内にあるため、isdigit()メソッドが好きです。 –

+0

@Jephthah 'all'とその" sister "関数' any'は、複数項目の一般的なテストに非常に便利です。しかし、 'isdigit'のように、あなたが望むことをする組み込みのテストがあるときは、代わりにそれらを使うべきです。 –

関連する問題