2016-12-22 1 views
2

나는 파이썬을 어려운 길 (예 : 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

'검사중인 항목'을 확인하기 전에 단어를'낮추고 싶지 않습니다. '? – depperm

+0

게시물을 하나의 실패한 질문으로 줄이고 오류 메시지를 포함시킵니다. ** 최소한 ** 실패한 예제를 제공하십시오. 노력만으로도 오류를 찾을 수 있습니다. – 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 

제 1 논리 I 목격 오류 하지 테스트 item 경우 그 중 하나에 있지 않는

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

이었다 기울기. 대신, 먼저 파이썬의 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이 파이썬에서 작동하는 방법에 대한 자세한 내용은 올해 초에 쓴 this answer을 참조하십시오.

우리는

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

을 사용하여 해당 테스트를 구현할 수 그러나 우리는 그렇게 할 필요가 없습니다. 대신에 우리는 if의 대부분을 elif으로 바꾼다. 그리고 성공적으로 스캔되지 않은 것은 오류 일 것이므로 else 블록에서이를 처리 할 수있다.

두 번째 큰 논리 오류는 번호 테스트입니다.당신은 여러 자리의 숫자 문자열

if item in scan.numbers: 

있는 유효한 (양)의 정수가 있는지 확인하기 위해 노력하고 있었다 그러나 item가 한 자리 인 경우 그 테스트는 성공합니다.

대신 우리는 수의 _all_digits 사실, 자리에 있는지 확인해야하고, 그

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

가하는 일입니다.

그러나, 더 나은 방법이있다 : 우리는 단지 str 유형의 .isdigit 방법을 사용하십시오

if item.isdigit(): 

나는 당신의 검사 목록을 사용하고 싶었 기 때문에 나는 내 코드에서 그것을 사용하지 않았다. 또한 .isdigit은 음수 또는 소수점을 처리 할 수 ​​없지만 '-''.'scan.numbers에 쉽게 추가 할 수 있습니다.

+0

정말 고마워. 나는 그 테스트 스크립트에서 내가 얼마나 많은 오타를 만들 었는지 알지 못했다. –

+0

실제로 'all'키워드에 대해 전혀 알지 못했기 때문에 scan.numbers는 0-9 사이에 있어야하기 때문에 isdigit() 메서드를 사용하는 것이 좋습니다. –

+0

@Jephthah'all'과 그 자매 함수'any'는 여러 항목의 일반적인 테스트에 매우 유용합니다. 그러나 'isdigit'과 같이 원하는 것을 수행하는 내장 된 특정 테스트가있는 경우 확실히 대신 사용해야합니다. –