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

s1mba發表於2013-09-27

這幾天有點時間,想學點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 的描述,新建工程目錄為ex48,進而建立以下目錄和檔案:



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)

在ex48 和 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 ex48 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 ex48 import lexicon 表示從ex48 中 匯入lexicon 模組,即現在我們要在ex48 目錄下寫一個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/ex48$ nosetests
.........
----------------------------------------------------------------------
Ran 6 tests in 0.007s


OK


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


-------------------------------------------------------------------------------------------------------------------------------------------------

後記:

如果在使用pip or easy_install 時提示url不正確,可以臨時修改或者修改配置檔案中的index-url為國內映象點。

下載完成,編譯安裝過程中如果提示不存在python.h,可以 sudo apt-get install python-dev     or  yum install python-devel




相關文章