finished string formatting section

This commit is contained in:
Mark Pilgrim
2009-03-24 00:51:02 -04:00
parent d7df09e509
commit 18b0144075
6 changed files with 101 additions and 9 deletions
+2
View File
@@ -23,3 +23,5 @@ h1:before{content:""}
</ol>
<p>Send corrections and feedback to <a href="mailto:mark@diveintomark.org">mark@diveintomark.org</a>.
<p class=c>&copy; 2001&ndash;9 <span>&#x2133;</span>ark Pilgrim
<script src=jquery.js></script>
<script src=dip3.js></script>
+56
View File
@@ -1,3 +1,59 @@
/*
"Dive Into Python 3" stylesheet
vv-- begin MIT open source license --vv
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.
^^-- end MIT open source license --^^
Classname Legend
.w = "widgets" = wrapper block for hide/open/download links dynamically inserted into code listings
.b = "block" = internal block dynamically inserted into code listings
.d = "download" = download link for code listings
.p = "prompt" = command-line or interactive shell prompt within code listings
.q = "quote" = quote at beginning of each chapter
.f = "fancy" = first paragraph of each chapter (gets a fancy drop-cap)
.c = "centered" = centered footer text
.note = "note/caution/important" = indented block for tips/gotchas/language comparisons
.baa = "best available ampersand" = wrapper block for ampersands
Acknowledgements & Inspirations
"The Elements of Typographic Style Applied to the Web" ... http://webtypography.net/toc/
"Setting Type on the Web to a Baseline Grid" ............. http://www.alistapart.com/articles/settingtypeontheweb
"Compose to a Vertical Rhythm" ........................... http://24ways.org/2006/compose-to-a-vertical-rhythm
"Use the Best Available Ampersand" ....................... http://simplebits.com/notebook/2008/08/14/ampersands.html
"Unicode Support in HTML, Fonts, and Web Browsers" ....... http://alanwood.net/unicode/
*/
/* typography */
body,.w a{font:medium 'Gill Sans','Gill Sans MT',Corbel,Helvetica,Jara,'Nimbus Sans L',sans-serif;line-height:1.75;word-spacing:0.1em}
pre,kbd,code,samp{font-family:Consolas,'Andale Mono',Monaco,'Liberation Mono','Bitstream Vera Sans Mono','DejaVu Sans Mono',monospace;font-size:medium;line-height:1.75;word-spacing:0}
+2
View File
@@ -55,3 +55,5 @@ h1:before{content:""}
<p class=c>This site is optimized for Lynx just because fuck you.<br>I&#8217;m told it also looks good in graphical browsers.
<p class=c>&copy; 2001&ndash;9 <a href=about.html><span>&#x2133;</span>ark Pilgrim</a>
<script src=jquery.js></script>
<script src=dip3.js></script>
+3
View File
@@ -19,6 +19,9 @@ http://www.alanwood.net/unicode/dingbats.html
&#x203D; - interrobang
&#x275D; - heavy double turned left comma quotation mark ornament
&#x275E; - heavy double turned right comma quotation mark ornament
&#x25C9; - fisheye
&#x2365; - APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS
&#x203B; - reference mark
http://docs.python.org/dev/library/turtle.html
http://svn.python.org/projects/python/trunk/Demo/turtle/
+37 -9
View File
@@ -146,10 +146,10 @@ def approximate_size(size, a_kilobyte_is_1024_bytes=True):
<samp>"mark's password is PapayaWhip"</samp></pre>
<ol>
<li>No, my password is not really <kbd>PapayaWhip</kbd>.
<li>There's a lot going on here. First, that's a method call on a string literal. <em>Strings are objects</em>, and objects have methods. Second, the whole expression evaluates to a string. Third, <code>{0}</code> and <code>{1}</code> are <i>format specifiers</i>, which are replaced by the arguments passed to the <code>format()</code> method.
<li>There's a lot going on here. First, that's a method call on a string literal. <em>Strings are objects</em>, and objects have methods. Second, the whole expression evaluates to a string. Third, <code>{0}</code> and <code>{1}</code> are <i>replacement fields</i>, which are replaced by the arguments passed to the <code>format()</code> method.
</ol>
<p>The previous example shows the simplest case, where the format specifiers are simply integers. Integer format specifiers are treated as positional indices into the argument list of the <code>format()</code> method. That means that <code>{0}</code> is replaced by the first argument (<var>username</var> in this case), <code>{1}</code> is replaced by the second argument (<var>password</var>), <i class=baa>&amp;</i>c. You can have as many positional indices as you have arguments, and you can have as many arguments as you want. But format specifiers are much more powerful than that.
<p>The previous example shows the simplest case, where the replacement fields are simply integers. Integer replacement fields are treated as positional indices into the argument list of the <code>format()</code> method. That means that <code>{0}</code> is replaced by the first argument (<var>username</var> in this case), <code>{1}</code> is replaced by the second argument (<var>password</var>), <i class=baa>&amp;</i>c. You can have as many positional indices as you have arguments, and you can have as many arguments as you want. But replacement fields are much more powerful than that.
<pre class=screen>
<samp class=p>>>> </samp><kbd>import humansize</kbd>
@@ -179,20 +179,39 @@ def approximate_size(size, a_kilobyte_is_1024_bytes=True):
<pre class=screen>
<samp class=p>>>> </samp><kbd>import humansize</kbd>
<samp class=p>>>> </samp><kbd>import sys</kbd>
<a><samp class=p>>>> </samp><kbd>"1MB = 1000{0.modules[humansize].SUFFIXES[1000][0]}".format(sys)</kbd>
<samp class=p>>>> </samp><kbd>"1MB = 1000{0.modules[humansize].SUFFIXES[1000][0]}".format(sys)</kbd>
<samp>'1MB = 1000KB'</samp></pre>
<p>Here's how it works:
<ul>
<li>The <code>sys</code> module holds information about the currently running Python instance. Since you just imported it, you can pass the <code>sys</code> module itself as an argument to the <code>format()</code> method. So the format specifier <code>{0}</code> refers to the <code>sys</code> module.
<li><code>sys.modules</code> is a dictionary of all the modules that have been imported in this Python instance. The keys are the module names as strings; the values are the module objects themselves. So the format specifier <code>{0.modules}</code> refers to the dictionary of imported modules.
<li><code>sys.modules["humansize"]</code> is the <code>humansize</code> module which you just imported. The format specifier <code>{0.modules[humansize]}</code> refers to the <code>humansize</code> module. Note the slight difference in syntax here. In real Python code, the keys of the <code>sys.modules</code> dictionary are strings; to refer to them, you need to put quotes around the module name (<i>e.g.</i> <code>"humansize"</code>). But within a format specifier, you skip the quotes around the dictionary key name (<i>e.g.</i> <code>humansize</code>).
<li><code>sys.modules["humansize"].SUFFIXES</code> is the dictionary defined at the top of the <code>humansize</code> module. The format specifier <code>{0.modules[humansize].SUFFIXES}</code> refers to that dictionary.
<li><code>sys.modules["humansize"].SUFFIXES[1000]</code> is a list of <abbr>SI</abbr> suffixes: <code>['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']</code>. So the format specifier <code>{0.modules[humansize].SUFFIXES[1000]}</code> refers to that list.
<lI><code>sys.modules["humansize"].SUFFIXES[1000][0]</code> is the first item of the list of <abbr>SI</abbr> suffixes: <code>'KB'</code>. Therefore, the complete format specifier <code>{0.modules[humansize].SUFFIXES[1000][0]}</code> is replaced by the two-character string <code>KB</code>.
<li>The <code>sys</code> module holds information about the currently running Python instance. Since you just imported it, you can pass the <code>sys</code> module itself as an argument to the <code>format()</code> method. So the replacement field <code>{0}</code> refers to the <code>sys</code> module.
<li><code>sys.modules</code> is a dictionary of all the modules that have been imported in this Python instance. The keys are the module names as strings; the values are the module objects themselves. So the replacement field <code>{0.modules}</code> refers to the dictionary of imported modules.
<li><code>sys.modules["humansize"]</code> is the <code>humansize</code> module which you just imported. The replacement field <code>{0.modules[humansize]}</code> refers to the <code>humansize</code> module. Note the slight difference in syntax here. In real Python code, the keys of the <code>sys.modules</code> dictionary are strings; to refer to them, you need to put quotes around the module name (<i>e.g.</i> <code>"humansize"</code>). But within a replacement field, you skip the quotes around the dictionary key name (<i>e.g.</i> <code>humansize</code>).
<li><code>sys.modules["humansize"].SUFFIXES</code> is the dictionary defined at the top of the <code>humansize</code> module. The replacement field <code>{0.modules[humansize].SUFFIXES}</code> refers to that dictionary.
<li><code>sys.modules["humansize"].SUFFIXES[1000]</code> is a list of <abbr>SI</abbr> suffixes: <code>['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']</code>. So the replacement field <code>{0.modules[humansize].SUFFIXES[1000]}</code> refers to that list.
<lI><code>sys.modules["humansize"].SUFFIXES[1000][0]</code> is the first item of the list of <abbr>SI</abbr> suffixes: <code>'KB'</code>. Therefore, the complete replacement field <code>{0.modules[humansize].SUFFIXES[1000][0]}</code> is replaced by the two-character string <code>KB</code>.
</ul>
<p>But wait! There's more! Let's take another look at that strange line of code from <code>humansize.py</code>:
<pre><code>if size < multiple:
return "{0:.1f} {1}".format(size, suffix)</code></pre>
<p><code>{1}</code> is replaced with the second argument passed to the <code>format()</code> method, which is <var>suffix</var>. But what is <code>{0:.1f}</code>? It's two things: <code>{0}</code>, which you recognize, and <code>:.1f</code>, which you don't. The second half (including and after the colon) defines the <i>format specifier</i>, which further refines how the replaced variable should be formatted.
<blockquote class="note compare clang">
<p><span>&#x261E;</span>Format specifiers allow you to munge the replacement text in a variety of useful ways, like the <code>printf()</code> function in C. You can add zero- or space-padding, align strings, control decimal precision, and even convert numbers to hexadecimal.
</blockquote>
<p>Within a replacement field, a colon (<code>:</code>) marks the start of the format specifier. The format specifier &#8220;<code>.1</code>&#8221; means &#8220;round to the nearest tenth&#8221; (<i>i.e.</i> display only one digit after the decimal point). The format specifier &#8220;<code>f</code>&#8221; means &#8220;fixed-point number&#8221; (as opposed to exponential notation or some other decimal representation). Thus, given a <var>size</var> of <code>698.25</code> and <var>suffix</var> of <code>'GB'</code>, the formatted string would be <code>'698.3 GB'</code>, because <code>698.25</code> gets rounded to one decimal place, then the suffix is appended after the number.
<pre class=screen>
<samp class=p>>>> </samp><kbd>"{0:.1f} {1}".format(698.25, 'GB')</kbd>
<samp>'698.3 GB'</samp></pre>
<p>For all the gory details on presentation types, check the <a href="http://docs.python.org/dev/3.0/library/string.html#format-specification-mini-language">Format Specification Mini-Language</a> in the official Python documentation.
<div class=s>
<p>Note that <code>(k, v)</code> is a tuple. I told you they were good for something.
@@ -342,6 +361,15 @@ is an object. You might have thought I meant that string <em>variables</em> are
<li><a href="http://blog.whatwg.org/the-road-to-html-5-character-encoding">Character encoding in HTML</a>
</ul>
<p>On strings and string formatting:
<ul>
<li><a href="http://docs.python.org/dev/3.0/library/string.html"><code>string</code> &mdash; Common string operations</a>
<li><a href="http://docs.python.org/dev/3.0/library/string.html#formatstrings">Format String Syntax</a>
<li><a href="http://docs.python.org/dev/3.0/library/string.html#format-specification-mini-language">Format Specification Mini-Language</a>
<li><a href="http://www.python.org/dev/peps/pep-3101/"><abbr>PEP</abbr> 3101: Advanced String Formatting</a>
</ul>
<p class=c>&copy; 2001&ndash;9 <a href=about.html><span>&#x2133;</span>ark Pilgrim</a>
<script src=jquery.js></script>
<script src=dip3.js></script>
+1
View File
@@ -194,6 +194,7 @@ ul li ol{margin:0;padding:0 0 0 2.5em}
<li>XML Processing
<ol>
<li>...major changes afoot...
<li><a href="http://groups.google.com/group/comp.lang.python.announce/browse_thread/thread/1539788b6ec118d9/00803392361a2ef6?show_docid=00803392361a2ef6">lxml 2.2</a> officially supports Python 3
</ol>
<li>HTTP web services
<ol>