mirror of
https://github.com/kennethreitz/dive-into-python3.git
synced 2026-06-05 23:10:17 +00:00
css fiddling
This commit is contained in:
+98
-26
@@ -27,49 +27,92 @@ body{counter-reset:h1 11}
|
||||
<p>[FIXME here's why ordered dicts are useful: http://www.gossamer-threads.com/lists/python/dev/656556 ]
|
||||
|
||||
<p class=d>[<a href=examples/ordereddict.py>download <code>ordereddict.py</code></a>]
|
||||
<pre><code class=pp>import collections
|
||||
import itertools
|
||||
|
||||
class OrderedDict(dict, collections.MutableMapping):
|
||||
<pre><code class=pp>class OrderedDict(dict, MutableMapping):
|
||||
'Dictionary that remembers insertion order'
|
||||
# An inherited dict maps keys to values.
|
||||
# The inherited dict provides __getitem__, __len__, __contains__, and get.
|
||||
# The remaining methods are order-aware.
|
||||
# Big-O running times for all methods are the same as for regular dictionaries.
|
||||
|
||||
# The internal self.__map dictionary maps keys to links in a doubly linked list.
|
||||
# The circular doubly linked list starts and ends with a sentinel element.
|
||||
# The sentinel element never gets deleted (this simplifies the algorithm).
|
||||
# The prev/next links are weakref proxies (to prevent circular references).
|
||||
# Individual links are kept alive by the hard reference in self.__map.
|
||||
# Those hard references disappear when a key is deleted from an OrderedDict.
|
||||
|
||||
def __init__(self, *args, **kwds):
|
||||
'''Initialize an ordered dictionary. Signature is the same as for
|
||||
regular dictionaries, but keyword arguments are not recommended
|
||||
because their insertion order is arbitrary.
|
||||
|
||||
'''
|
||||
if len(args) > 1:
|
||||
raise TypeError('expected at most 1 arguments')
|
||||
if not hasattr(self, '_keys'):
|
||||
self._keys = []
|
||||
raise TypeError('expected at most 1 arguments, got %d' % len(args))
|
||||
try:
|
||||
self.__root
|
||||
except AttributeError:
|
||||
self.__root = root = _Link() # sentinel node for the doubly linked list
|
||||
root.prev = root.next = root
|
||||
self.__map = {}
|
||||
self.update(*args, **kwds)
|
||||
|
||||
def clear(self):
|
||||
del self._keys[:]
|
||||
'od.clear() -> None. Remove all items from od.'
|
||||
root = self.__root
|
||||
root.prev = root.next = root
|
||||
self.__map.clear()
|
||||
dict.clear(self)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
'od.__setitem__(i, y) <==> od[i]=y'
|
||||
# Setting a new item creates a new link which goes at the end of the linked
|
||||
# list, and the inherited dictionary is updated with the new key/value pair.
|
||||
if key not in self:
|
||||
self._keys.append(key)
|
||||
self.__map[key] = link = _Link()
|
||||
root = self.__root
|
||||
last = root.prev
|
||||
link.prev, link.next, link.key = last, root, key
|
||||
last.next = root.prev = _proxy(link)
|
||||
dict.__setitem__(self, key, value)
|
||||
|
||||
def __delitem__(self, key):
|
||||
'od.__delitem__(y) <==> del od[y]'
|
||||
# Deleting an existing item uses self.__map to find the link which is
|
||||
# then removed by updating the links in the predecessor and successor nodes.
|
||||
dict.__delitem__(self, key)
|
||||
self._keys.remove(key)
|
||||
link = self.__map.pop(key)
|
||||
link.prev.next = link.next
|
||||
link.next.prev = link.prev
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._keys)
|
||||
'od.__iter__() <==> iter(od)'
|
||||
# Traverse the linked list in order.
|
||||
root = self.__root
|
||||
curr = root.next
|
||||
while curr is not root:
|
||||
yield curr.key
|
||||
curr = curr.next
|
||||
|
||||
def __reversed__(self):
|
||||
return reversed(self._keys)
|
||||
|
||||
def popitem(self):
|
||||
if not self:
|
||||
raise KeyError('dictionary is empty')
|
||||
key = self._keys.pop()
|
||||
value = dict.pop(self, key)
|
||||
return key, value
|
||||
'od.__reversed__() <==> reversed(od)'
|
||||
# Traverse the linked list in reverse order.
|
||||
root = self.__root
|
||||
curr = root.prev
|
||||
while curr is not root:
|
||||
yield curr.key
|
||||
curr = curr.prev
|
||||
|
||||
def __reduce__(self):
|
||||
'Return state information for pickling'
|
||||
items = [[k, self[k]] for k in self]
|
||||
tmp = self.__map, self.__root
|
||||
del self.__map, self.__root
|
||||
inst_dict = vars(self).copy()
|
||||
inst_dict.pop('_keys', None)
|
||||
return (self.__class__, (items,), inst_dict)
|
||||
self.__map, self.__root = tmp
|
||||
if inst_dict:
|
||||
return (self.__class__, (items,), inst_dict)
|
||||
return self.__class__, (items,)
|
||||
|
||||
setdefault = MutableMapping.setdefault
|
||||
update = MutableMapping.update
|
||||
@@ -78,25 +121,54 @@ class OrderedDict(dict, collections.MutableMapping):
|
||||
values = MutableMapping.values
|
||||
items = MutableMapping.items
|
||||
|
||||
def __repr__(self):
|
||||
def popitem(self, last=True):
|
||||
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
|
||||
Pairs are returned in LIFO order if last is true or FIFO order if false.
|
||||
|
||||
'''
|
||||
if not self:
|
||||
return '{0}()'.format(self.__class__.__name__,)
|
||||
return '{0}({1})'.format(self.__class__.__name__, repr(list(self.items())))
|
||||
raise KeyError('dictionary is empty')
|
||||
key = next(reversed(self) if last else iter(self))
|
||||
value = self.pop(key)
|
||||
return key, value
|
||||
|
||||
def __repr__(self):
|
||||
'od.__repr__() <==> repr(od)'
|
||||
if not self:
|
||||
return '%s()' % (self.__class__.__name__,)
|
||||
return '%s(%r)' % (self.__class__.__name__, list(self.items()))
|
||||
|
||||
def copy(self):
|
||||
'od.copy() -> a shallow copy of od'
|
||||
return self.__class__(self)
|
||||
|
||||
@classmethod
|
||||
def fromkeys(cls, iterable, value=None):
|
||||
'''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
|
||||
and values equal to v (which defaults to None).
|
||||
|
||||
'''
|
||||
d = cls()
|
||||
for key in iterable:
|
||||
d[key] = value
|
||||
return d
|
||||
|
||||
def __eq__(self, other):
|
||||
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
|
||||
while comparison to a regular mapping is order-insensitive.
|
||||
|
||||
'''
|
||||
if isinstance(other, OrderedDict):
|
||||
return all(p==q for p, q in itertools.zip_longest(self.items(), other.items()))
|
||||
return dict.__eq__(self, other)</code></pre>
|
||||
return len(self)==len(other) and \
|
||||
all(p==q for p, q in zip(self.items(), other.items()))
|
||||
return dict.__eq__(self, other)
|
||||
|
||||
def __ne__(self, other):
|
||||
'''od.__ne__(y) <==> od!=y. Comparison to another OD is order-sensitive
|
||||
while comparison to a regular mapping is order-insensitive.
|
||||
|
||||
'''
|
||||
return not self == other</code></pre>
|
||||
|
||||
<p class=a>⁂
|
||||
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
|
||||
"Dive Into Python 3" layout stylesheet
|
||||
|
||||
Copyright (c) 2009, Mark Pilgrim, All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
@page {
|
||||
size: US-Letter;
|
||||
margin: 1.75in;
|
||||
padding: 0;
|
||||
@bottom-center {
|
||||
font: 12pt/1.75 serif;
|
||||
content: counter(page);
|
||||
}
|
||||
}
|
||||
body, .w a {
|
||||
font: 10pt/1.3 serif;
|
||||
}
|
||||
pre, kbd, samp, code, var, .b {
|
||||
font: 8pt/1.3 monospace;
|
||||
}
|
||||
span {
|
||||
font-size: 10pt;
|
||||
}
|
||||
.baa {
|
||||
font-size: 11pt;
|
||||
}
|
||||
.q span {
|
||||
font-size: 13pt;
|
||||
}
|
||||
.f:first-letter {
|
||||
color: #888;
|
||||
font: normal 48pt/0.68 serif;
|
||||
}
|
||||
p, ul, ol {
|
||||
margin: 0;
|
||||
font-size: 11pt;
|
||||
}
|
||||
p + p {
|
||||
text-indent: 1em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
page-break-before: always;
|
||||
prince-bookmark-level: 1;
|
||||
}
|
||||
h2 {
|
||||
prince-bookmark-level: 2;
|
||||
}
|
||||
h3 {
|
||||
prince-bookmark-level: 3;
|
||||
}
|
||||
@@ -288,7 +288,7 @@ import whichdb</code></pre>
|
||||
<th>Python 2
|
||||
<th>Python 3
|
||||
<tr><th>
|
||||
<td><code class=pp>import <dfn>xmlrpclib</dfm></code>
|
||||
<td><code class=pp>import <dfn>xmlrpclib</dfn></code>
|
||||
<td><code class=pp>import xmlrpc.client</code>
|
||||
<tr><th>
|
||||
<td><pre><code class=pp>import <dfn>DocXMLRPCServer</dfn>
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ for filename in chapters:
|
||||
for line in open(filename, encoding="utf-8"):
|
||||
if line.count('<h1>'):
|
||||
include = True
|
||||
if line.count('<p class=nav') or line.count('<p class=c>©'):
|
||||
if line.count('<p class=v') or line.count('<p class=c>©'):
|
||||
include = False
|
||||
if line.count('<p id=toc'):
|
||||
line = line.replace(' id=toc', '')
|
||||
|
||||
Reference in New Issue
Block a user