Python sorted 

#ソートするデーター

| ID   | 名前 | 国語 | 英語 |
|:--   |:--  |   --:|  --:|
| 0001 | A   | 10   | 40  |
| 0003 | B   | 30   | 20  |
| 0002 | D   | 40   | 30  |
| 0004 | C   | 20   | 10  |

# データーを格納する汎用基底クラスを作成

## 参考文献
Happy Programming &raquo; Pythonのクラスを辞書のようにして使う
http://blog.beanz-net.jp/happy_programming/2008/11/python-5.html
特殊メソッド名 - Dive Into Python 3 日本語版
http://diveintopython3-ja.rdy.jp/special-method-names.html

```BASE.py
# coding: utf-8

class BASE(object):

    def __init__(self):
        pass

    def __setitem__(self, key, value):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> print(b.key1)
        value1

        '''
        self.__dict__[key] = value
        return (self.__dict__[key], value)

    def __getitem__(self, key):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> print(b['key2'])
        value2

        '''
        return self.__dict__[key]

    def __len__(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> len(b)
        2

        '''
        return len(self.__dict__)

    def __iter__(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> for i in b: print(i)
        ('key2', 'value2')
        ('key1', 'value1')

        '''
        return self.__dict__.iteritems()

    def __contains__(self, key):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> 'key' in b
        True

        '''
        if key in self.__dict__.keys(): return True
        else: return False

    def __str__(self):
        '''
        >>> b = BASE()
        >>> b['key3'] = 10.0 / 3
        >>> print(b.key3)
        3.33333333333
        >>> print(b['key3'])
        3.33333333333

        '''
        return str(self.__dict__)

    def __repr__(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> print(b)
        {'key3': 3.3333333333333335, 'key2': 'value2', 'key1': 'value1'}

        '''
        return repr(self.__dict__)

    def keys(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> b.keys()
        ['key3', 'key2', 'key1']

        '''
        return self.__dict__.keys()

    def values(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> b.values()
        [3.3333333333333335, 'value2', 'value1']

        '''
        return self.__dict__.values()

    def items(self):
        '''
        >>> b = BASE()
        >>> b['key1'] = 'value1'
        >>> b['key2'] = 'value2'
        >>> b['key3'] = 10.0 / 3
        >>> b.items()
        [('key3', 3.3333333333333335), ('key2', 'value2'), ('key1', 'value1')]

        '''
        return self.__dict__.items()

def usage():

    class Example(BASE):
        pass

    ex = Example()

    ex['key1'] = 'value1'
    ex.key2    = 'value2'
    ex.key3    = 10.0 / 3

    print('''\n### usage ### \n\n'''
          '''class Example(BASE):\n'''
          '''    pass\n'''
          '''\n'''
          '''ex = Example()\n'''
          '''ex['key1'] = 'value1'\n'''
          '''ex.key2    = 'value2'\n'''
          '''ex.key3    = 10.0 / 3\n'''
          )

    print('print(type(ex))\n')
    print('    =>  %s\n' % type(ex))

    print('print(ex)\n')
    print('    =>  %s\n' % ex)

    print('print(ex.key1)\n')
    print('    =>  %s\n' % ex.key1)

    print('''print(ex['key2'])\n''')
    print('    =>  %s\n' % ex['key2'])

    print('''print(ex['key3'])\n''')
    print('    =>  %s\n' % ex['key3'])

    print('print(len(ex))\n')
    print('    =>  %d\n' % len(ex))

    print('print(ex.keys())\n')
    print('    =>  %s\n' % ex.keys())

    print('print(ex.values())\n')
    print('    =>  %s\n' % ex.values())

    print('print(ex.items())\n')
    print('    =>  %s\n' % ex.items())

    print('print([ i for i in ex ])\n')
    print('    =>  %s\n' % [ i for i in ex ])

    print('''print('key1' in ex)\n''')
    print('    =>  %s\n' % ('key1' in ex))

    print('''print('key4' in ex)\n''')
    print('    => %s\n'  % ('key4' in ex))

if __name__ == '__main__' : usage()
```
# sorted()でソートさせる
ソートするデーターは汎用基底クラス(BASE.py)を継承したオブジェクトに格納する
ソートには sorted() http://docs.python.jp/2/howto/sorting.html  を利用し sorted() のkey パラメータに 
lambda と operator モジュールの attrgetter()を指定した2パターンで出力させる。

```example.py
# -*- coding: utf-8 -*-

from BASE import BASE
from operator import attrgetter

# 汎用基底クラスを継承して名簿クラス作成
class Persons(BASE):
    pass

# 汎用基底クラスを継承して成績データクラスの作成
class Data(BASE):
    def __init__(self, id, name, kokugo, eigo):
        self.id     = id
        self.name   = name
        self.kokugo = kokugo
        self.eigo   = eigo

# 成績データーリストを返す
def get_persons():
    '''
    >>> get_persons()
    [{'eigo': 10, 'id': '0004', 'kokugo': 20, 'name': 'C'},
     {'eigo': 40, 'id': '0001', 'kokugo': 10, 'name': 'A'},
     {'eigo': 30, 'id': '0002', 'kokugo': 40, 'name': 'D'},
     {'eigo': 20, 'id': '0003', 'kokugo': 30, 'name': 'B'}]
    ]
    '''
    # 名簿オブジェクト作成
    p = Persons()
    # 名簿オブジェクトに成績データオブジェクトを入れる
    p['0001'] = Data('0001', 'A', 10, 40)
    p['0003'] = Data('0003', 'B', 30, 20)
    p['0002'] = Data('0002', 'D', 40, 30)
    p['0004'] = Data('0004', 'C', 20, 10)
    persons   = p.values()
    return persons

# 出力時のデコレーション用
def output_decoration(func):
    def wrapper(*args,**kwargs):
        print('# sort_key: %(sort_key)s' % kwargs)
        print('+----+-----+------+------+')
        print('|%-4s|%-5s|%-6s|%-6s|' % ('id', 'name', 'kokugo', 'eigo'))
        print('+----+-----+------+------+')
        func(*args,**kwargs)
        print('+----+-----+------+------+')
    return wrapper

# sorted の keyパラメータに operator モジュールの attrgetter 関数 を指定したソート
@output_decoration
def output_use_operator(persons, sort_key):
    for person_data in sorted(persons, reverse=False, key=attrgetter(sort_key)):
        print('|%(id)4s|%(name)-5s|%(kokugo)6d|%(eigo)6d|' % person_data)

# sorted の keyパラメータに lambda を指定したソート
@output_decoration
def output_use_lambda(persons, sort_key):
    for person_data in sorted(persons, reverse=False, key=lambda x: x[sort_key]):
        print('|%(id)4s|%(name)-5s|%(kokugo)6d|%(eigo)6d|' % person_data)

if __name__ == '__main__' :

    # 名簿オブジェクト取得
    persons = get_persons()
    # 国語の点数をソートキーとして出力する (sortedのkeyパラメータは attrgetter 関数)
    print "\n# sort_parameter: operator.attrgetter"
    output_use_operator(persons, sort_key='kokugo')
    # 英語の点数をソートキーとして出力する (sortedのkeyパラメータは lambda)
    print "\n# sort_parameter: lambda"
    output_use_lambda(persons, sort_key='eigo')
```
#結果
```
# sort_parameter: operator.attrgetter
# sort_key: kokugo
+----+-----+------+------+
|id  |name |kokugo|eigo  |
+----+-----+------+------+
|0001|A    |    10|    40|
|0004|C    |    20|    10|
|0003|B    |    30|    20|
|0002|D    |    40|    30|
+----+-----+------+------+

# sort_parameter: lambda
# sort_key: eigo
+----+-----+------+------+
|id  |name |kokugo|eigo  |
+----+-----+------+------+
|0004|C    |    20|    10|
|0003|B    |    30|    20|
|0002|D    |    40|    30|
|0001|A    |    10|    40|
+----+-----+------+------+
```