~ubuntu-branches/ubuntu/karmic/tovid/karmic

« back to all changes in this revision

Viewing changes to libtovid/odict.py

  • Committer: Bazaar Package Importer
  • Author(s): Matvey Kozhev
  • Date: 2008-01-24 22:04:40 UTC
  • Revision ID: james.westby@ubuntu.com-20080124220440-x7cheljduf1rdgnq
Tags: upstream-0.31
ImportĀ upstreamĀ versionĀ 0.31

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
# odict.py
 
3
 
 
4
"""Ordered dictionary class, from a Python Cookbook recipe:
 
5
 
 
6
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
 
7
 
 
8
"""
 
9
__all__ = ['Odict']
 
10
 
 
11
from UserDict import UserDict
 
12
 
 
13
class Odict (UserDict):
 
14
    def __init__(self, keys=None, values=None):
 
15
        """Create an Odict from the given keys and values."""
 
16
        keys = keys or []
 
17
        values = values or []
 
18
        if len(keys) != len(values):
 
19
            raise ValueError("keys and values are not the same length")
 
20
        self._keys = keys
 
21
        UserDict.__init__(self, dict(zip(keys, values)))
 
22
 
 
23
    def __delitem__(self, key):
 
24
        UserDict.__delitem__(self, key)
 
25
        self._keys.remove(key)
 
26
 
 
27
    def __setitem__(self, key, item):
 
28
        UserDict.__setitem__(self, key, item)
 
29
        if key not in self._keys: self._keys.append(key)
 
30
 
 
31
    def clear(self):
 
32
        UserDict.clear(self)
 
33
        self._keys = []
 
34
 
 
35
    def copy(self):
 
36
        dict = UserDict.copy(self)
 
37
        dict._keys = self._keys[:]
 
38
        return dict
 
39
 
 
40
    def items(self):
 
41
        return zip(self._keys, self.values())
 
42
 
 
43
    def keys(self):
 
44
        return self._keys
 
45
 
 
46
    def popitem(self):
 
47
        try:
 
48
            key = self._keys[-1]
 
49
        except IndexError:
 
50
            raise KeyError('dictionary is empty')
 
51
 
 
52
        val = self[key]
 
53
        del self[key]
 
54
 
 
55
        return (key, val)
 
56
 
 
57
    def setdefault(self, key, failobj = None):
 
58
        UserDict.setdefault(self, key, failobj)
 
59
        if key not in self._keys: self._keys.append(key)
 
60
 
 
61
    def update(self, dict):
 
62
        UserDict.update(self, dict)
 
63
        for key in dict.keys():
 
64
            if key not in self._keys: self._keys.append(key)
 
65
 
 
66
    def values(self):
 
67
        return map(self.get, self._keys)
 
68
    
 
69
    def __str__(self):
 
70
        lines = []
 
71
        for key, value in self.items():
 
72
            lines.append("%s: %s" % (key, value))
 
73
        return '\n'.join(lines)
 
74
 
 
75
 
 
76
def convert_list(choices):
 
77
    """Convert a list of choices to an Odict (ordered dictionary).
 
78
    choices may be in one of several formats:
 
79
 
 
80
               string: 'one|two|three'
 
81
                 list: ['one', 'two', 'three']
 
82
                 dict: {'a': "Choice A", 'b': "Choice B"}
 
83
        list-of-lists: [['a', "Choice A"], ['b', "Choice B"], ..]
 
84
    
 
85
    Note: the dict form does not preserve order. Use list-of-lists
 
86
    to maintain the specified order.
 
87
    """
 
88
    if type(choices) not in [str, list, dict]:
 
89
        raise TypeError("choices must be a string, list, or dictionary.")
 
90
 
 
91
    if type(choices) == str:
 
92
        choices = choices.split('|')
 
93
        return Odict(choices, choices)
 
94
 
 
95
    if type(choices) == dict:
 
96
        return Odict(choices.keys(), choices.values())
 
97
 
 
98
    # choices is a list, but what kind?
 
99
    first = choices[0]
 
100
    # list of strings
 
101
    if type(first) == str:
 
102
        return Odict(choices, choices)
 
103
    # list of 2-element string lists
 
104
    elif type(first) == list and len(first) == 2:
 
105
        choices, values = zip(*choices)
 
106
        return Odict(choices, values)
 
107
    else:
 
108
        raise TypeError("choices lists must either be"\
 
109
            "['a', 'b', 'c'] or [['a', 'A'], ['b', 'B']] style.")