0

Learn Python The Hard Wayという本の「 Exercise 48: Advanced User Inputtest_errors() 」の関数を解こうと一日中試みていました。

assert_equal()、テストの関数が順番にタプルを要求してきましたが、そのようにコーディングできませんでした。

私のループは常に最初に名詞を返し、最後にエラータプルを返します。ループを中断する方法がわからないため、ループを再開しますが、正しい値で続行するか、このタプルをあるべき順序でソートするために必要なものを使用します。

コードは次のとおりです。

class Lexicon(object):

def scan(self, stringo):
    vocabulary = [[('direction', 'north'), ('direction', 'south'), ('direction',     'east'), ('direction', 'west')],
                    [('verb', 'go'), ('verb', 'kill'), ('verb', 'eat')],
                    [('stop', 'the'), ('stop', 'in'), ('stop', 'of')],
                    [('noun', 'bear'), ('noun', 'princess')],    # Remember numbers
                    [('error', 'ASDFADFASDF'), ('error', 'IAS')],
                    [('number', '1234'), ('number','3'), ('number', '91234')]]

    self.stringo = stringo
    got_word = ''
    value = []
    rompe = self.stringo.split() #split rompe en los espacios

    for asigna in vocabulary: 
        for encuentra in asigna:          
            if encuentra[1]  in rompe:
                value.append(encuentra)

    return value   

eLexicon = Lexicon()


from nose.tools import *
from ex48.ex48 import eLexicon 

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

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

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

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

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

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

======================================================================
FAIL: tests.ex48_tests.test_errors
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/totoro/Desktop/Python/projects/ex48/tests/ex48_tests.py", line 43, in         test_errors
    ('noun', 'princess')])
AssertionError: Lists differ: [('noun', 'bear'), ('noun', 'p... != [('noun', 'bear'),     ('error', '...

First differing element 1:
('noun', 'princess')
('error', 'IAS')

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

----------------------------------------------------------------------
Ran 5 tests in 0.006s

お時間を割いていただき、誠にありがとうございました。

4

4 に答える 4

1

これは私にとってはうまくいきました。より短いコードです。この本はしばらく前に作成されましたが、ありがたいことにまだファイルを持っています...

def check(word):
    lexicon = {
        'direction': ['north', 'south', 'east', 'west'],
        'verb': ['go', 'kill', 'eat'],
        'stop': ['the', 'in', 'of'],
        'noun': ['bear', 'princess'],
        'error': ['ASDFADFASDF', 'IAS']
    }
word = str(word)
for key in lexicon:
    if word in lexicon[key]:
        return (key, word)
    elif word.isdigit():
        return ('number', int(word))

def scan(words):
    words = words.split()
    to_return = []
    for i in words:
        to_return.append(check(i))
    return to_return

そして、これが現れました:

......
----------------------------------------------------------------------
Ran 6 tests in 0.008s

OK

このコードにエラーがあるかどうか教えてください。以下にコメントしてください:D。

于 2015-03-18T12:32:00.060 に答える
0

テストの単語は、出てくるのと同じ順序で出てきます。forそのため、最初に入力を反復処理するようにループの順序を変更する必要があります。

    value = []
    for rompe in stringo.split():
        for asigna in vocabulary:
            for encuentra in asigna:
                if encuentra[1] == rompe:
                    value.append(encuentra)

encuentraこれにより、正しい順序で sが返されます。

注 1 : 数値またはエラーをハードコーディングしないでください。

注 2 : 辞書を 1 つまたは 2 つ使用することで、このアルゴリズムの複雑さを大幅に軽減できます。

例:

vocabulary = {
    'direction': 'north east south west up down left right back'.split(),
    'noun': 'bear princess door cabinet'.split(),
    'stop': 'the in of from at it'.split(),
    'verb': 'go kill eat stop'.split(),
}

'''
This creates a lookup using a dictionary-comprehension:
{'at': 'stop',
# [...]
 'up': 'direction',
 'west': 'direction'}
'''
classifications = {i: k for k, v in vocabulary.iteritems() for i in v}


def classify(word):
    try:
        return 'number', int(word)
    except ValueError:
        return classifications.get(word, 'error'), word


def scan(words):
    return [classify(word) for word in words.split()]
于 2013-07-06T07:44:00.067 に答える
0
    for word in self.stringo.split(): 
        for pair in vocabulary:             
            if pair[0][1] == word:
                value.append(pair[0])
            elif pair[1][1] == word:
                value.append(pair[1])
            elif pair[2][1] == word:
                value.append(pair[2])
            elif pair[3][1] == word:
                value.append(pair[3])
于 2013-07-06T14:08:36.057 に答える