Python - 打破和分组用户输入
Python - breaking and grouping user input
我正在做一个练习,我在学习 Python 艰难之路(ex 48)中找到了。目的是通过参考我们的词典对用户输入进行分组。我正在使用 nose 来测试我的脚本,但我遇到了多个错误。当我 运行 鼻子测试时,我在 6 次中失败了 5 次。我不明白为什么我会收到这些错误。有帮助吗?
错误
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')])
您的代码中有几个拼写错误和几个逻辑错误。
这是您的代码的修复版本,修改为 运行,没有 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
我发现的第一个逻辑错误是
if item not in (scan.dirs or scan.verbs or scan.stops
or scan.nouns or scan.numbers):
不会 测试 item
是否不在任何这些列表中。相反,它首先计算
scan.dirs or scan.verbs or scan.stops or scan.nouns or scan.numbers
使用 Python 的 or
运算符的标准规则。 scan.dirs
是一个非空列表,因此该表达式的结果只是 scan.dirs
.
所以 if
语句等同于
if item not in scan.dirs:
这显然不是你想要做的。
有关 or
和 and
如何在 Python 中工作的更多信息,请参阅我今年早些时候写的 。
我们可以使用
实施该测试
if not any(item in seq for seq in (scan.dirs, scan.verbs, scan.stops,
scan.nouns, scan.numbers)):
但我们不需要那样做。相反,我们将大部分 if
s 更改为 elif
s,然后任何未成功扫描的都一定是错误,因此我们可以在 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
.
我正在做一个练习,我在学习 Python 艰难之路(ex 48)中找到了。目的是通过参考我们的词典对用户输入进行分组。我正在使用 nose 来测试我的脚本,但我遇到了多个错误。当我 运行 鼻子测试时,我在 6 次中失败了 5 次。我不明白为什么我会收到这些错误。有帮助吗?
错误
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')])
您的代码中有几个拼写错误和几个逻辑错误。
这是您的代码的修复版本,修改为 运行,没有 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
我发现的第一个逻辑错误是
if item not in (scan.dirs or scan.verbs or scan.stops
or scan.nouns or scan.numbers):
不会 测试 item
是否不在任何这些列表中。相反,它首先计算
scan.dirs or scan.verbs or scan.stops or scan.nouns or scan.numbers
使用 Python 的 or
运算符的标准规则。 scan.dirs
是一个非空列表,因此该表达式的结果只是 scan.dirs
.
所以 if
语句等同于
if item not in scan.dirs:
这显然不是你想要做的。
有关 or
和 and
如何在 Python 中工作的更多信息,请参阅我今年早些时候写的
我们可以使用
实施该测试if not any(item in seq for seq in (scan.dirs, scan.verbs, scan.stops,
scan.nouns, scan.numbers)):
但我们不需要那样做。相反,我们将大部分 if
s 更改为 elif
s,然后任何未成功扫描的都一定是错误,因此我们可以在 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
.