这几天有点时间,想学点Python基础,今天看到了《learn python the hard way》的 Ex48,这篇文章主要记录一些工具的安装,以及scan 函数的实现。


首先与Ex48相关的章节有前面的Ex46, Ex47,故我们需要先安装一些工具,主要是一些包管理和测试框架的软件:

 

Install the following Python packages:

  1. pip from http://pypi.python.org/pypi/pip
  2. distribute from http://pypi.python.org/pypi/distribute
  3. nose from http://pypi.python.org/pypi/nose/
  4. virtualenv from http://pypi.python.org/pypi/virtualenv

实际上对于Linux用户来说安装比较简单,首先安装 sudo apt-get install python-pip,接下去的3个都可以使用pip 来安装,即

pip install distribute/nose/virtualenv


模仿Ex46 的描述,新建工程目录为ex47,进而建立以下目录和文件:

《Learn python the hard way》Exercise 48: Advanced User Input_ico


setup.py 如下,一些参数可以设置成自己想要的,如NAME 更改为需要测试的多个模块名:

 

 Python Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
try:
     from setuptools  import setup
except  ImportError:
     from distutils.core  import setup

config = {
     'description''My Project',
     'author''My Name',
     'url''URL to get it at.',
     'download_url''Where to download it.',
     'author_email''My email.',
     'version''0.1',
     'install_requires': [ 'nose'],
     'packages': [ 'NAME'],
     'scripts': [],
     'name''projectname'
}

setup(**config)

 

在ex47 和 tests 目录下各touch新建一个__init__.py 文件。


测试文件 tests/lexicon_tests.py 摘自网站:

 

 Python Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
from nose.tools  import *
from ex47  import lexicon


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

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


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


def test_nouns():
    assert_equal(lexicon.scan( "bear"), [( 'noun''bear')])
    result = lexicon.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(lexicon.scan( "ASDFADFASDF"), [( 'error''ASDFADFASDF')])
    result = lexicon.scan( "bear IAS princess")
    assert_equal(result, [( 'noun''bear'),
                          ( 'error''IAS'),
                          ( 'noun''princess')])

 

 

上面程序中 from ex47 import lexicon 表示从ex47 中 导入lexicon 模块,即现在我们要在ex47 目录下写一个lexicon.py 文件,文件主要是scan 函数的实现,根据网站的提示,自己实现如下:


 

 Python Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 
#!/usr/bin/env python
#coding=utf-8

import re

def convert_number(s):
     try:
         return  int(s)
     except  ValueError:
         return  None


def scan(input_str):

    words = input_str. split( ' ')

    pattern = re. compile(r '\d+')

    
    direction_list = [ 'north''south''west''east''down''up''left''right''back']
    verb_list = [ 'go''kill''stop''eat']
    stop_list = [ 'the''in''of''from''at''it']
    noun_list = [ 'door''bear''princess''cabinet']
    sentence_list = []

     for word  in words:
        
         bool = pattern.match(word)
         if  bool:
            sentence = ( 'number', convert_number(word))
            sentence_list. append(sentence)
        
         elif word  in direction_list:
            sentence = ( 'direction', word)
            sentence_list. append(sentence)
        
        
         elif word  in verb_list:
            sentence = ( 'verb', word)
            sentence_list. append(sentence)

         elif word  in stop_list:
            sentence = ( 'stop', word)
            sentence_list. append(sentence)

         elif word  in noun_list:
            sentence = ( 'noun', word)
            sentence_list. append(sentence)
        
         else:
            sentence = ( 'error', word)
            sentence_list. append(sentence)
    
     return sentence_list

 

 

程序中使用正则表达式来匹配数字字符串,请google re 模块之。

执行测试命令,即使用lexicon_tests.py 去测试lexicon.py 里面的函数,输出如下:

simba@ubuntu:~/Documents/code/python/projects/ex47$ nosetests
.........
----------------------------------------------------------------------
Ran 9 tests in 0.081s


OK

为什么是9个tests 呢,上面只有6个,实际上我在ex47 下还有个game.py,而针对这个模块的测试文件game_tests.py也存在tests 目录下,且里面有3个test, 故这个项目总的测试个数是9个,需要针对一个模块写一个测试文件。


参考 :http://learnpythonthehardway.org/book/ex48.html