-
Notifications
You must be signed in to change notification settings - Fork 28
/
content.xml
2 lines (2 loc) · 158 KB
/
content.xml
1
2
<?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:textooo="http://openoffice.org/2013/office" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" office:version="1.2"><office:scripts/><office:font-face-decls><style:font-face style:name="OpenSymbol1" svg:font-family="OpenSymbol" style:font-adornments="Regular" style:font-pitch="variable" style:font-charset="x-symbol"/><style:font-face style:name="Symbol" svg:font-family="Symbol" style:font-adornments="Regular" style:font-pitch="variable" style:font-charset="x-symbol"/><style:font-face style:name="OpenSymbol" svg:font-family="OpenSymbol"/><style:font-face style:name=".Helvetica Neue DeskInterface" svg:font-family="'.Helvetica Neue DeskInterface'" style:font-family-generic="swiss"/><style:font-face style:name="Lucida Sans1" svg:font-family="'Lucida Sans'" style:font-family-generic="swiss"/><style:font-face style:name="Courier New" svg:font-family="'Courier New'" style:font-family-generic="modern" style:font-pitch="fixed"/><style:font-face style:name="Arial1" svg:font-family="Arial" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Book Antiqua" svg:font-family="'Book Antiqua'" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Calibri" svg:font-family="Calibri" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Lucida Console" svg:font-family="'Lucida Console'" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Times New Roman" svg:font-family="'Times New Roman'" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/><style:font-face style:name="F" svg:font-family="" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Arial2" svg:font-family="Arial" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Book Antiqua1" svg:font-family="'Book Antiqua'" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Lucida Sans" svg:font-family="'Lucida Sans'" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="OpenSymbol2" svg:font-family="OpenSymbol" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="SimSun" svg:font-family="SimSun" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Symbol1" svg:font-family="Symbol" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Tahoma1" svg:font-family="Tahoma" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Times New Roman1" svg:font-family="'Times New Roman'" style:font-family-generic="system" style:font-pitch="variable"/></office:font-face-decls><office:automatic-styles><style:style office:name="__Annotation__3531_64743177111111111111111111111111111111111111111111111111111111111111111111" style:name="P1" style:family="paragraph" style:parent-style-name="Bullet_20_End_20__5b_PACKT_5d_" style:list-style-name="WWNum2"/><style:style style:name="P2" style:family="paragraph" style:parent-style-name="Bullet_20_End_20__5b_PACKT_5d_" style:list-style-name="WWNum4"/><style:style style:name="P3" style:family="paragraph" style:parent-style-name="Bullet_20_End_20__5b_PACKT_5d_" style:list-style-name="WWNum5"/><style:style style:name="P4" style:family="paragraph" style:parent-style-name="Bullet_20_End_20__5b_PACKT_5d_" style:list-style-name="WWNum6"/><style:style style:name="P5" style:family="paragraph" style:parent-style-name="Bullet_20_End_20__5b_PACKT_5d_" style:list-style-name="L2"/><style:style style:name="P6" style:family="paragraph" style:parent-style-name="Bullet_20__5b_PACKT_5d_" style:list-style-name="WWNum2"/><style:style style:name="P7" style:family="paragraph" style:parent-style-name="Bullet_20__5b_PACKT_5d_" style:list-style-name="WWNum3"/><style:style style:name="P8" style:family="paragraph" style:parent-style-name="Bullet_20__5b_PACKT_5d_" style:list-style-name="WWNum5"/><style:style style:name="P9" style:family="paragraph" style:parent-style-name="Bullet_20__5b_PACKT_5d_" style:list-style-name="WWNum6"/><style:style style:name="P10" style:family="paragraph" style:parent-style-name="Bullet_20__5b_PACKT_5d_" style:list-style-name="L2"/><style:style style:name="P11" style:family="paragraph" style:parent-style-name="Chapter_20_Number_20__5b_PACKT_5d_" style:master-page-name="First_20_Page"><style:paragraph-properties style:page-number="auto"/></style:style><style:style style:name="P12" style:family="paragraph" style:parent-style-name="Normal_20__5b_PACKT_5d_" style:list-style-name="WWNum4"/><style:style style:name="T1" style:family="text"/><style:style style:name="T2" style:family="text"><style:text-properties style:use-window-font-color="true" style:font-name="Times New Roman" style:font-name-asian="Times New Roman1" style:font-name-complex="Times New Roman1" style:font-size-complex="12pt"/></style:style><style:style style:name="T3" style:family="text"><style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/></style:style><style:style style:name="T4" style:family="text"><style:text-properties style:use-window-font-color="true" style:font-name="Times New Roman" style:font-name-asian="Times New Roman1" style:font-name-complex="Times New Roman1" style:font-size-complex="12pt"/></style:style><style:style style:name="T5" style:family="text"><style:text-properties style:font-name="Calibri" style:font-name-complex="F" style:font-size-complex="11pt" style:font-weight-complex="normal"/></style:style><style:style style:name="T6" style:family="text"><style:text-properties style:language-asian="zh" style:country-asian="CN" style:font-name-complex="F"/></style:style><style:style style:name="T7" style:family="text"><style:text-properties style:font-name="Calibri" fo:language="en" fo:country="IN" style:font-name-complex="F" style:font-size-complex="11pt" style:font-weight-complex="normal"/></style:style><style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="from-top" style:horizontal-pos="from-left" style:horizontal-rel="paragraph-content" draw:ole-draw-aspect="1"/></style:style><style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="from-top" draw:ole-draw-aspect="1"/></style:style><text:list-style style:name="L1"><text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" text:bullet-char="◦"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" text:bullet-char="▪"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1in" fo:text-indent="-0.25in" fo:margin-left="1in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" text:bullet-char="◦"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" text:bullet-char="▪"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2in" fo:text-indent="-0.25in" fo:margin-left="2in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" text:bullet-char="◦"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" text:bullet-char="▪"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in"/></style:list-level-properties></text:list-level-style-bullet></text:list-style><text:list-style style:name="L2"><text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1in" fo:text-indent="-0.25in" fo:margin-left="1in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" text:bullet-char="◦"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" text:bullet-char="▪"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" text:bullet-char="◦"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2in" fo:text-indent="-0.25in" fo:margin-left="2in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" text:bullet-char="▪"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" text:bullet-char="◦"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" text:bullet-char="▪"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3in" fo:text-indent="-0.25in" fo:margin-left="3in"/></style:list-level-properties></text:list-level-style-bullet><text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" text:bullet-char="•"><style:list-level-properties text:list-level-position-and-space-mode="label-alignment"><style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.25in" fo:text-indent="-0.25in" fo:margin-left="3.25in"/></style:list-level-properties></text:list-level-style-bullet></text:list-style></office:automatic-styles><office:body><office:text text:use-soft-page-breaks="true"><text:tracked-changes><text:changed-region xml:id="ct106102877733760" text:id="ct106102877733760"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:44:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102877727232" text:id="ct106102877727232"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:44:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875664448" text:id="ct106102875664448"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:44:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875682880" text:id="ct106102875682880"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:44:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875719936" text:id="ct106102875719936"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">a </text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877720128" text:id="ct106102877720128"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:s/>set</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875723200" text:id="ct106102875723200"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875748928" text:id="ct106102875748928"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119871872" text:id="ct105553119871872"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">S</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119883392" text:id="ct105553119883392"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">often</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121964608" text:id="ct105553121964608"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877732800" text:id="ct106102877732800"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">on the</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875696320" text:id="ct106102875696320"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:45:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119892800" text:id="ct105553119892800"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:46:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875689408" text:id="ct106102875689408"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:46:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121988800" text:id="ct105553121988800"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:46:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:s/>ordering</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875664256" text:id="ct106102875664256"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:46:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">(</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877734528" text:id="ct106102877734528"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:46:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">)</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121962688" text:id="ct105553121962688"><text:insertion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:50:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875723776" text:id="ct106102875723776"><text:deletion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:50:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">c</text:span></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875666560" text:id="ct106102875666560"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:51:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875724160" text:id="ct106102875724160"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:51:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875700352" text:id="ct106102875700352"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:47:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875723008" text:id="ct106102875723008"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:51:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875717632" text:id="ct106102875717632"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:51:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553119900672" text:id="ct105553119900672"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:48:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553121921216" text:id="ct105553121921216"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875685760" text:id="ct106102875685760"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">’s</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875678656" text:id="ct106102875678656"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875679040" text:id="ct106102875679040"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875680768" text:id="ct106102875680768"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553119916224" text:id="ct105553119916224"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119884160" text:id="ct105553119884160"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875643712" text:id="ct106102875643712"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">r</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875685376" text:id="ct106102875685376"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:49:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121992256" text:id="ct105553121992256"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">need to</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119919488" text:id="ct105553119919488"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875661952" text:id="ct106102875661952"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">explicit</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121979008" text:id="ct105553121979008"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121907008" text:id="ct105553121907008"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119896064" text:id="ct105553119896064"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875642176" text:id="ct106102875642176"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553122030656" text:id="ct105553122030656"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875640640" text:id="ct106102875640640"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877820352" text:id="ct106102877820352"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119894528" text:id="ct105553119894528"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875660992" text:id="ct106102875660992"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">simple</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875683264" text:id="ct106102875683264"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:50:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119902400" text:id="ct105553119902400"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:51:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875677888" text:id="ct106102875677888"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:51:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><office:annotation office:name="__Annotation__3476_64743177111111111111111111111111111111111111111111111111111111111111111111111"><dc:creator>Rui Carmo</dc:creator><dc:date>2014-11-22T19:04:00</dc:date><text:p><text:span text:style-name="T5">I suppose this is out of place here.</text:span></text:p></office:annotation>build<office:annotation-end office:name="__Annotation__3476_64743177111111111111111111111111111111111111111111111111111111111111111111111"/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875664064" text:id="ct106102875664064"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:51:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875650240" text:id="ct106102875650240"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:51:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877787136" text:id="ct106102877787136"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:52:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875704192" text:id="ct106102875704192"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:52:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102877737408" text:id="ct106102877737408"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:51:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875686528" text:id="ct106102875686528"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:51:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119894144" text:id="ct105553119894144"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:52:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875678848" text:id="ct106102875678848"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:52:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875678080" text:id="ct106102875678080"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:52:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875641792" text:id="ct106102875641792"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:53:00</dc:date></office:change-info><text:p text:style-name="Bullet_20__5b_PACKT_5d_">more</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121977088" text:id="ct105553121977088"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:53:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875672896" text:id="ct106102875672896"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:53:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553119911040" text:id="ct105553119911040"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:54:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875642560" text:id="ct106102875642560"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:54:00</dc:date></office:change-info><text:p text:style-name="Bullet_20__5b_PACKT_5d_"><office:annotation office:name="__Annotation__3531_64743177111111111111111111111111111111111111111111111111111111111111111111"><dc:creator>Rui Carmo</dc:creator><dc:date>2014-11-22T19:07:00</dc:date><text:p><text:span text:style-name="T5">make</text:span></text:p></office:annotation>may<office:annotation-end office:name="__Annotation__3531_64743177111111111111111111111111111111111111111111111111111111111111111111"/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875649664" text:id="ct106102875649664"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:54:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877764672" text:id="ct106102877764672"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:01:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119916416" text:id="ct105553119916416"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:01:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">w</text:span></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119835008" text:id="ct105553119835008"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:01:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875680576" text:id="ct106102875680576"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:01:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553124007232" text:id="ct105553124007232"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:01:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">u</text:span></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119878784" text:id="ct105553119878784"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:01:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553119899328" text:id="ct105553119899328"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:55:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875649856" text:id="ct106102875649856"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:55:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">R</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875660224" text:id="ct106102875660224"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:55:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875713216" text:id="ct106102875713216"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:56:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119891840" text:id="ct105553119891840"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:57:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119827328" text:id="ct105553119827328"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:55:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121977664" text:id="ct105553121977664"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:55:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">This</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119904896" text:id="ct105553119904896"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:55:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119897024" text:id="ct105553119897024"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:01:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121967488" text:id="ct105553121967488"><text:insertion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:54:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121955584" text:id="ct105553121955584"><text:deletion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:54:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">c</text:span></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121970560" text:id="ct105553121970560"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:54:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553121953856" text:id="ct105553121953856"><text:deletion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-12-05T16:03:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">“</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121903936" text:id="ct105553121903936"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:58:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121943104" text:id="ct105553121943104"><text:deletion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-12-05T16:03:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">”, </text:span></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877778496" text:id="ct106102877778496"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:00:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875681152" text:id="ct106102875681152"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:00:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121970752" text:id="ct105553121970752"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:00:00</dc:date></office:change-info><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875734336" text:id="ct106102875734336"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:00:00</dc:date></office:change-info><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875731648" text:id="ct106102875731648"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:04:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">Clearly, we don’t need </text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877756608" text:id="ct106102877756608"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:04:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875659840" text:id="ct106102875659840"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:07:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877819776" text:id="ct106102877819776"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:07:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877759296" text:id="ct106102877759296"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553124068672" text:id="ct105553124068672"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877766016" text:id="ct106102877766016"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121908352" text:id="ct105553121908352"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875684608" text:id="ct106102875684608"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121966528" text:id="ct105553121966528"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124068864" text:id="ct105553124068864"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877722240" text:id="ct106102877722240"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877742784" text:id="ct106102877742784"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:08:00</dc:date></office:change-info><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875623744" text:id="ct106102875623744"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875682496" text:id="ct106102875682496"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102877779264" text:id="ct106102877779264"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877793664" text:id="ct106102877793664"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877744896" text:id="ct106102877744896"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121911808" text:id="ct105553121911808"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877824768" text:id="ct106102877824768"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124067136" text:id="ct105553124067136"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875699392" text:id="ct106102875699392"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:09:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119868992" text:id="ct105553119868992"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:57:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553121926976" text:id="ct105553121926976"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:57:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875636416" text:id="ct106102875636416"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:10:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875706112" text:id="ct106102875706112"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:10:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877751232" text:id="ct106102877751232"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:10:00</dc:date></office:change-info><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877764096" text:id="ct106102877764096"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:10:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553121993216" text:id="ct105553121993216"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:11:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">“</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875680384" text:id="ct106102875680384"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:11:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875688640" text:id="ct106102875688640"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:11:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">”</text:span></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877766208" text:id="ct106102877766208"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:11:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">that </text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875644096" text:id="ct106102875644096"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:12:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875706496" text:id="ct106102875706496"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:12:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">A</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875705728" text:id="ct106102875705728"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:12:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875679616" text:id="ct106102875679616"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:12:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">three</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875683072" text:id="ct106102875683072"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:12:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119841920" text:id="ct105553119841920"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:12:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:s/>that are peers</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875745088" text:id="ct106102875745088"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:12:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119873024" text:id="ct105553119873024"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:13:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875639104" text:id="ct106102875639104"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:26:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121953664" text:id="ct105553121953664"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:13:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">e</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877724928" text:id="ct106102877724928"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:13:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121996288" text:id="ct105553121996288"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:14:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">works</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119877632" text:id="ct105553119877632"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:14:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875639296" text:id="ct106102875639296"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:14:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121975168" text:id="ct105553121975168"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:14:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:span text:style-name="T2"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124064064" text:id="ct105553124064064"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:14:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">we can</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124067328" text:id="ct105553124067328"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:14:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121982080" text:id="ct105553121982080"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:15:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875622016" text:id="ct106102875622016"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:15:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877737024" text:id="ct106102877737024"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:16:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119907200" text:id="ct105553119907200"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:16:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877826688" text:id="ct106102877826688"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:20:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877753728" text:id="ct106102877753728"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:20:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"><office:annotation><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:58:00</dc:date><textooo:sender-initials>SS</textooo:sender-initials><text:p>I guess we have missed the formula over here can you please check ?</text:p></office:annotation><text:bookmark text:name="_GoBack11111111111111111111111111111111111111"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This formula shows us that we’ll be summing the differences in rank, <text:s/>and , for all of the pairs of observed values</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121925632" text:id="ct105553121925632"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:58:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553121924864" text:id="ct105553121924864"><text:format-change><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T14:58:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102877796736" text:id="ct106102877796736"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:22:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">always</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875638720" text:id="ct106102875638720"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:22:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875656192" text:id="ct106102875656192"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:22:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">a </text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877767552" text:id="ct106102877767552"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:22:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877755648" text:id="ct106102877755648"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:23:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_">In this case, we’ll use only a function, instead of a full, polymorphic class hierarchy. This will rely on using <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">isinstance()</text:span> to handle several different data types.</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121983040" text:id="ct105553121983040"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:24:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102877731072" text:id="ct106102877731072"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:27:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_">for row in some_function( iter(seq_or_iter), key ): yield row</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553122017792" text:id="ct105553122017792"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:28:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119898560" text:id="ct105553119898560"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:29:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119922560" text:id="ct105553119922560"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:29:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>for row in rank_data( tuple(seq_or_iter), key ): yield row</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>return</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875681344" text:id="ct106102875681344"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:29:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875692288" text:id="ct106102875692288"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:29:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_">Collection of non-Rank_Data? </text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875719552" text:id="ct106102875719552"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:29:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119921408" text:id="ct105553119921408"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:29:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124063488" text:id="ct105553124063488"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124059648" text:id="ct105553124059648"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124058304" text:id="ct105553124058304"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875716480" text:id="ct106102875716480"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877798272" text:id="ct106102877798272"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553124052928" text:id="ct105553124052928"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102875639872" text:id="ct106102875639872"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877820544" text:id="ct106102877820544"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s/></text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121969792" text:id="ct105553121969792"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875688256" text:id="ct106102875688256"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877767936" text:id="ct106102877767936"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info><text:p text:style-name="Bullet_20__5b_PACKT_5d_">o</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877750080" text:id="ct106102877750080"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553124010688" text:id="ct105553124010688"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:30:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553124067712" text:id="ct105553124067712"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:31:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_">for rows in ranker( sorted_iter, 0, [head], key ): yield rows</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553121950976" text:id="ct105553121950976"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:31:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877748544" text:id="ct106102877748544"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:31:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102877728960" text:id="ct106102877728960"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:32:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>for rest in yield_sequence( (base+1+base+dups)/2, iter(same_rank_seq) ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>yield rest</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877817856" text:id="ct106102877817856"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:32:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875633536" text:id="ct106102875633536"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:32:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>for rows in ranker(sorted_iter, base, same_rank_seq+[value], key ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>yield rows</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877798080" text:id="ct106102877798080"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:32:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119914496" text:id="ct105553119914496"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:32:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_">for rest in yield_sequence( (base+1+base+dups)/2, iter(same_rank_seq) ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>yield rest</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="8"/>for rows in ranker(sorted_iter, base+dups, [value], key): yield rows</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct105553119911232" text:id="ct105553119911232"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:32:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121929856" text:id="ct105553121929856"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:33:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102875638144" text:id="ct106102875638144"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:33:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102877765056" text:id="ct106102877765056"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:33:00</dc:date></office:change-info><text:p text:style-name="Code_20__5b_PACKT_5d_">for rest in yield_sequence( rank, same_rank_iter ):</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="8"/>yield rest</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877826496" text:id="ct106102877826496"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:33:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553119926976" text:id="ct105553119926976"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:34:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct106102875696512" text:id="ct106102875696512"><text:deletion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T15:00:00</dc:date></office:change-info><text:p text:style-name="Heading_20_11">Looking Ahead</text:p></text:deletion></text:changed-region><text:changed-region xml:id="ct106102877825536" text:id="ct106102877825536"><text:insertion><office:change-info><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T15:00:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877754496" text:id="ct106102877754496"><text:format-change><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:34:00</dc:date></office:change-info></text:format-change></text:changed-region><text:changed-region xml:id="ct105553119919872" text:id="ct105553119919872"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:34:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877775808" text:id="ct106102877775808"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:35:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct106102877793088" text:id="ct106102877793088"><text:insertion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T10:36:00</dc:date></office:change-info></text:insertion></text:changed-region><text:changed-region xml:id="ct105553121914112" text:id="ct105553121914112"><text:deletion><office:change-info><dc:creator>Steven Lott</dc:creator><dc:date>2014-12-07T09:42:00</dc:date></office:change-info><text:p text:style-name="Normal_20__5b_PACKT_5d_"/><text:p text:style-name="Normal_20__5b_PACKT_5d_"/></text:deletion></text:changed-region></text:tracked-changes><text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls><text:p text:style-name="P11"><office:annotation office:name="__Annotation__3266_647431771"><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-12-05T16:03:00</dc:date><textooo:sender-initials>SS</textooo:sender-initials><text:p>Great work on the chapter</text:p><text:p/></office:annotation><office:annotation office:name="__Annotation__3265_647431771"><dc:creator>Sumeet Sawant</dc:creator><dc:date>2014-11-18T15:01:00</dc:date><textooo:sender-initials>SS</textooo:sender-initials><text:p>Great work on the chapter</text:p><text:p/></office:annotation>7<office:annotation-end office:name="__Annotation__3266_647431771"/><office:annotation-end office:name="__Annotation__3265_647431771"/></text:p><text:p text:style-name="Chapter_20_Title_20__5b_PACKT_5d_">Additional Tuple Techniques</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Many of the examples we’ve looked at have either been scalar functions, or relatively simply structures built from small tuples. We can often exploit Python’s immutable <text:change-start text:change-id="ct106102877733760"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuple</text:span><text:change-end text:change-id="ct106102877733760"/> as a way to build complex data structures. We’ll look at how we use and how we create <text:change-start text:change-id="ct106102877727232"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_"><office:annotation office:name="__Annotation__3274_647431771"><dc:creator>Rui Carmo</dc:creator><dc:date>2014-11-22T19:02:00</dc:date><text:p><text:span text:style-name="T5">Still think this should beset in monospaced font.</text:span></text:p></office:annotation></text:span><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuples</text:span><office:annotation-end office:name="__Annotation__3274_647431771"/><text:change-end text:change-id="ct106102877727232"/>. We’ll also look at ways that immutable <text:change-start text:change-id="ct106102875664448"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuples</text:span><text:change-end text:change-id="ct106102875664448"/> can be used instead of stateful object classes.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">One of the beneficial features of object-oriented programming is the ability to create complex data structures incrementally. In some respects<text:change-start text:change-id="ct106102875682880"/>,<text:change-end text:change-id="ct106102875682880"/> an object is simply a cache for results of functions; this will often fit well with functional design patterns. In other cases, the object paradigm provides for property methods which include sophisticated <text:s/>calculations. This is an even better fit for functional design ideas.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In some cases, however, object class definitions are used statefully to create complex objects. We’ll look at a number of alternatives that provide <text:change text:change-id="ct106102875719936"/>similar feature<text:change text:change-id="ct106102877720128"/><text:change-start text:change-id="ct106102875723200"/>s<text:change-end text:change-id="ct106102875723200"/> without the complexities of stateful objects. <text:change-start text:change-id="ct106102875748928"/>We can identify s<text:change-end text:change-id="ct106102875748928"/><text:change text:change-id="ct105553119871872"/>tateful class definitions <text:change text:change-id="ct105553119883392"/><text:change-start text:change-id="ct105553121964608"/>when then<text:change-end text:change-id="ct105553121964608"/> include meta-properties <text:change text:change-id="ct106102877732800"/><text:change-start text:change-id="ct106102875696320"/>for valid or required ord<text:change-end text:change-id="ct106102875696320"/><text:change-start text:change-id="ct105553119892800"/>ering of<text:change-end text:change-id="ct105553119892800"/> method function call<text:change-start text:change-id="ct106102875689408"/>s<text:change-end text:change-id="ct106102875689408"/><text:change text:change-id="ct105553121988800"/>. <text:change text:change-id="ct106102875664256"/>Statements like “If X.p() is called before X.q(), the results are undefined” are outside the formalism of the language, and are meta-properties of a class.<text:change text:change-id="ct106102877734528"/> Sometimes stateful classes include the overhead of explicit assertions and error checking to assure that methods are used in the proper order. If we avoid stateful classes, we eliminate these kinds of overheads.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ll also look at some techniques for writing generic functions outside any polymorphic class definition. Clearly, we can rely on <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Callable</text:span> classes to create a polymorphic class hierarchy. In some cases, this may be needless overhead in a functional design.</text:p><text:p text:style-name="Heading_20_11">Using an immutable namedtuple as a record</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In <text:change-start text:change-id="ct105553121962688"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">C</text:span><text:change-end text:change-id="ct105553121962688"/><text:change text:change-id="ct106102875723776"/><text:change-start text:change-id="ct106102875666560"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">hapter 3</text:span><text:change-end text:change-id="ct106102875666560"/>, “<text:change-start text:change-id="ct106102875724160"/><text:span text:style-name="Italics_20__5b_PACKT_5d_">Functions, Iterators and Generators</text:span><text:change-end text:change-id="ct106102875724160"/>”, we showed two common techniques for working with tuples. We’ve also hinted at a third way to handle complex structures. We can do any of these, depending on circumstances:</text:p><text:list xml:id="list8094448170377001391" text:style-name="WWNum2"><text:list-item><text:p text:style-name="P6">Use lambdas (or functions) to select a named item using the index.</text:p></text:list-item><text:list-item><text:p text:style-name="P6"><text:soft-page-break/>Use lambdas (or functions) with <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">*parameter</text:span> to select an item by parameter name, which maps to an index.</text:p></text:list-item><text:list-item><text:p text:style-name="P1">Use <text:change-start text:change-id="ct106102875700352"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuples</text:span><text:change-end text:change-id="ct106102875700352"/> to select an item by attribute name or index.</text:p></text:list-item></text:list><text:p text:style-name="Normal_20__5b_PACKT_5d_">Our trip data, introduced in <text:change-start text:change-id="ct106102875723008"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">Chapter 4</text:span><text:change-end text:change-id="ct106102875723008"/>, “<text:change-start text:change-id="ct106102875717632"/><text:span text:style-name="Italics_20__5b_PACKT_5d_">Working with Collections</text:span><text:change-end text:change-id="ct106102875717632"/>”, has a rather complex structure. The data started as an ordinary time-series of position reports. To compute the distances covered, we transposed the data into a sequence of legs with a start position, end position, and distance as a nested three-tuple.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Each item in the sequence of legs looks like this as a three-tuple:</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">first_leg= ((37.54901619777347, -76.33029518659048), (37.840832, -76.273834), 17.7246)</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">[<text:change-start text:change-id="ct105553119900672"/><text:span text:style-name="Italics_20__5b_PACKT_5d_">This is a short trip between two points on the Chesapeake Bay.</text:span><text:change-end text:change-id="ct105553119900672"/>]</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">A nested tuple of tuples is can be rather difficult to read: expressions like <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">first_leg[0][0]</text:span> aren’t very informative. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Let’s look at the three alternatives for selected values out of a tuple. The first technique involves defining some simple selection functions that can pick items from a tuple by index position:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">start= lambda leg: leg[0]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">end= lambda leg: leg[1]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">distance= lambda leg: leg[2]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">latitude= lambda pt: pt[0]</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">longitude= lambda pt: pt[1]</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">With these definitions, we can use <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">latitude(start(first_leg))</text:span> to refer to a specific piece of data.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">These definitions don’t provide much guidance on the data types involved. We can use a simple naming convention to make this a bit more clear. Here are some examples of selection functions which use a suffix:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">start_point = lambda leg: leg[0]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">distance_nm= lambda leg: leg[2]</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">latitude_value= lambda point: point[0]</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">When used judiciously, this can be helpful. It can also degenerate into elaborately complex Hungarian notation as prefix (or suffix) of each variable. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The second technique uses the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">*parameter</text:span> notation to conceal some details of the index positions. Here are some selection functions using <text:change-start text:change-id="ct105553121921216"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">*</text:span><text:change-end text:change-id="ct105553121921216"/> notation:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">start= lambda start, end, distance: start</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">end= lambda start, end, distance: end</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">distance= lambda start, end, distance: distance</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:soft-page-break/>latitude= lambda lat, lon: lat</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">longitude= lambda lat, lon: lon</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">With these definitions, we can use <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">latitude(*start(*first_leg))</text:span> to refer to a specific piece of data. This has the advantage of clarity. <office:annotation office:name="__Annotation__3382_647431771"><dc:creator>龚禕</dc:creator><dc:date>2014-12-05T16:03:00</dc:date><textooo:sender-initials>龚禕</textooo:sender-initials><text:p><text:span text:style-name="T6">Typo</text:span></text:p></office:annotation>It<text:change text:change-id="ct106102875685760"/> can<office:annotation-end office:name="__Annotation__3382_647431771"/> look a little odd to see the <text:change-start text:change-id="ct106102875678656"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">*</text:span><text:change-end text:change-id="ct106102875678656"/> in front of the tuple arguments to these selection functions.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The third technique is the <text:change-start text:change-id="ct106102875679040"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuple</text:span><text:change-end text:change-id="ct106102875679040"/>. In this case, we have nested <text:change-start text:change-id="ct106102875680768"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuples</text:span><text:change-end text:change-id="ct106102875680768"/><text:change-start text:change-id="ct105553119916224"/>:<text:change-end text:change-id="ct105553119916224"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">Leg = namedtuple( "Leg", ("start", "end", "distance") )</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">Point = namedtuple( "Point", ("latitude", "longitude") )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This allows us to use <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">first_leg.start.latitude</text:span> to fetch a particular piece of data. The change from prefix function names to post-fix attribute names can be seen as a helpful emphasis<text:change-start text:change-id="ct105553119884160"/>.<text:change-end text:change-id="ct105553119884160"/> <text:change text:change-id="ct106102875643712"/><text:change-start text:change-id="ct106102875685376"/>It can also be seen as<text:change-end text:change-id="ct106102875685376"/> a confusing shift in syntax.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We <text:change text:change-id="ct105553121992256"/><text:change-start text:change-id="ct105553119919488"/>will also<text:change-end text:change-id="ct105553119919488"/> replace <text:change text:change-id="ct106102875661952"/><text:s/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">tuple()</text:span> functions with appropriate <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Leg()</text:span> or <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Point()</text:span> function calls in our process that builds the raw data. We will also have to locate some <text:span text:style-name="T3">return</text:span> and <text:span text:style-name="T3">yield</text:span> statements that implicitly create tuples.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">For example, we’d change this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def float_lat_lon(<text:change text:change-id="ct105553121979008"/>row_iter<text:change text:change-id="ct105553121907008"/>):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>return ( </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>tuple(<text:change text:change-id="ct105553119896064"/>map(float, pick_lat_lon(*row))<text:change text:change-id="ct106102875642176"/>) </text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="8"/>for row in row_iter )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">to this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def float_lat_lon(<text:change text:change-id="ct105553122030656"/>row_iter<text:change text:change-id="ct106102875640640"/>):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>return ( </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>Point(<text:change text:change-id="ct106102877820352"/>*map(float, pick_lat_lon(*row))<text:change text:change-id="ct105553119894528"/>) </text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="8"/>for row in row_iter )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This would build <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Point</text:span> objects instead of <text:change text:change-id="ct106102875660992"/><text:change-start text:change-id="ct106102875683264"/>anon<text:change-end text:change-id="ct106102875683264"/><text:change-start text:change-id="ct105553119902400"/>ymous<text:change-end text:change-id="ct105553119902400"/> tuples of floating-point coordinates.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Similarly, we can introduce this to build the complete trip of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Leg</text:span> objects:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">with urllib.request.urlopen("file:./Winter%202012-2013.kml") as source:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>path_iter = float_lat_lon(row_iter_kml(source))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>pair_iter = legs(path_iter)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>trip_iter = (Leg(start, end, round(haversine(start, end),4)) </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>for start,end in pair_iter)</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>trip= tuple(trip_iter)</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This will <text:change text:change-id="ct106102875677888"/><text:s/>iterate through the basic path of points, pairing them up to make start and end for each <text:change-start text:change-id="ct106102875664064"/><text:span text:style-name="Code_20_Highlighted_20__5b_PACKT_5d_">Leg</text:span><text:change-end text:change-id="ct106102875664064"/><text:change-start text:change-id="ct106102875650240"/> object<text:change-end text:change-id="ct106102875650240"/>. These pairs are then used to build <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Leg</text:span> instances using the start point, end p<text:soft-page-break/>oint and the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">haversine()</text:span> function from <text:change-start text:change-id="ct106102877787136"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">Chapter 4</text:span><text:change-end text:change-id="ct106102877787136"/>, “<text:change-start text:change-id="ct106102875704192"/><text:span text:style-name="Italics_20__5b_PACKT_5d_">Working with Collections</text:span><text:change-end text:change-id="ct106102875704192"/>”. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The trip object will look like this when we try to print it:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">(Leg(start=Point(latitude=37.54901619777347, longitude=-76.33029518659048), end=Point(latitude=37.840832, longitude=-76.273834), distance=17.7246), </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">Leg(start=Point(latitude=37.840832, longitude=-76.273834), end=Point(latitude=38.331501, longitude=-76.459503), distance=30.7382),</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:span text:style-name="Italics_20__5b_PACKT_5d_">etc.</text:span></text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">Leg(start=Point(latitude=38.330166, longitude=-76.458504), end=Point(latitude=38.976334, longitude=-76.473503), distance=38.8019))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">It’s important to note that the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">haversine()</text:span> function was written to use simple tuples. We’ve reused this function with <text:change-start text:change-id="ct106102877737408"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuples</text:span><text:change-end text:change-id="ct106102877737408"/>. Since we carefully preserved the order the arguments, this small change in representation was handled gracefully by Python.<text:change-start text:change-id="ct106102875686528"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In spme cases, the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuple</text:span> <text:change-end text:change-id="ct106102875686528"/><text:change-start text:change-id="ct105553119894144"/>adds clarity. In other cases, the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuple</text:span> is a needless change in syntax from prefix to suffix.<text:change-end text:change-id="ct105553119894144"/></text:p><text:p text:style-name="Heading_20_11">Building namedtuples with functional constructors</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">There are three ways we can build <text:change-start text:change-id="ct106102875678848"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuple</text:span><text:change-end text:change-id="ct106102875678848"/> instances. The choice of which technique we use is generally based on how much additional information is available at the time of object construction. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve shown two of the three techniques in the examples in the previous section. We’ll emphasize the design considerations here. The choices include<text:change-start text:change-id="ct106102875678080"/> these<text:change-end text:change-id="ct106102875678080"/>:</text:p><text:list xml:id="list6722858324685092276" text:style-name="WWNum3"><text:list-item><text:p text:style-name="P7">We can provide the parameter values positionally. This works out well when there are one <text:change text:change-id="ct106102875641792"/><text:change-start text:change-id="ct105553121977088"/>or<text:change-end text:change-id="ct105553121977088"/> more expressions that we were evaluating. We used it when applying the <text:change-start text:change-id="ct106102875672896"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">haversine()</text:span><text:change-end text:change-id="ct106102875672896"/> function to start and end points to create a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Leg</text:span> object.</text:p></text:list-item></text:list><text:p text:style-name="Code_20_Within_20_Bullets_20_End_20__5b_PACKT_5d_">Leg(start, end, round(haversine(start, end),4))</text:p><text:list xml:id="list1830944883" text:continue-numbering="true" text:style-name="WWNum3"><text:list-item><text:p text:style-name="P7">We can use the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">*argument</text:span> notation to assign parameters <text:change-start text:change-id="ct105553119911040"/>positionally <text:change-end text:change-id="ct105553119911040"/>from a tuple. This works out well when we’re getting the arguments from another iterable or an existing tuple. We used it when using <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">map()</text:span> to apply the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">float()</text:span> function to latitude and longitude values.</text:p></text:list-item></text:list><text:p text:style-name="Code_20_Within_20_Bullets_20_End_20__5b_PACKT_5d_">Point( *map(float, pick_lat_lon(*row)) ) </text:p><text:list xml:id="list1997401309" text:continue-numbering="true" text:style-name="WWNum3"><text:list-item><text:p text:style-name="P7">We can use explicit keyword assignment. While not used in the previous example, we might see something like this as a way to <text:change text:change-id="ct106102875642560"/><text:change-start text:change-id="ct106102875649664"/>make<text:change-end text:change-id="ct106102875649664"/> the relationships more obvious:</text:p></text:list-item></text:list><text:p text:style-name="Code_20_Within_20_Bullets_20_End_20__5b_PACKT_5d_">Point( longitude=float(row[0]), latitude=float(row[1]) )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:soft-page-break/>It’s helpful to have the flexibility of a variety of ways of created namedtuple instances. This allows us to more easily transform the structure of data. We can emphasize features of the data structure that are relevant for reading and understanding the application. Sometimes the index number of 0 or 1 is an important thing to emphasize. Other times the order of start, end, and distance is important.</text:p><text:p text:style-name="Heading_20_11">Avoiding stateful classes by using families of tuples</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In several previous examples, we’ve shown the idea of <text:change-start text:change-id="ct106102877764672"/><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">W</text:span><text:change-end text:change-id="ct106102877764672"/><text:change text:change-id="ct105553119916416"/><text:change-start text:change-id="ct105553119835008"/><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">rap-</text:span><text:change-end text:change-id="ct105553119835008"/><text:change-start text:change-id="ct106102875680576"/><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">U</text:span><text:change-end text:change-id="ct106102875680576"/><text:change text:change-id="ct105553124007232"/><text:change-start text:change-id="ct105553119878784"/><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">nwrap</text:span><text:change-end text:change-id="ct105553119878784"/> design patterns that allow us to work with immutable tuples and named tuples. The point of these kinds of designs is to use immutable objects which wrap other immutable objects instead of mutable instance variables.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">A common statistical measure of correlation between two sets of data is the Spearman <text:change-start text:change-id="ct105553119899328"/>r<text:change-end text:change-id="ct105553119899328"/><text:change text:change-id="ct106102875649856"/>ank<text:change-start text:change-id="ct106102875660224"/> correlation<text:change-end text:change-id="ct106102875660224"/>. <text:change-start text:change-id="ct106102875713216"/>This compares the rankings of two variables. Rather than try to compare values, which may have different scales<text:change-end text:change-id="ct106102875713216"/><text:change-start text:change-id="ct105553119891840"/>, we’ll compare the relative orders. For more information, start here: <text:span text:style-name="URL_20__5b_PACKT_5d_">http://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient</text:span>.<text:change-end text:change-id="ct105553119891840"/><text:change-start text:change-id="ct105553119827328"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:change-end text:change-id="ct105553119827328"/><text:change text:change-id="ct105553121977664"/><text:change-start text:change-id="ct105553119904896"/>Computing the Spearman rank correlation<text:change-end text:change-id="ct105553119904896"/> requires assigning a rank value to each observation. It seems like we should be able to use <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">enumerate(sorted())</text:span> to do this. Given two sets of possibly correlated data, we can transform each set into a sequence of rank values and compute a measure of correlation.<text:change-start text:change-id="ct105553119897024"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ll apply the <text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">Wrap-Unwrap</text:span> design pattern to do this. We’ll wrap data items with their rank for purposes of computing the correlation coefficient.<text:change-end text:change-id="ct105553119897024"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In <text:change-start text:change-id="ct105553121967488"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">C</text:span><text:change-end text:change-id="ct105553121967488"/><text:change text:change-id="ct105553121955584"/><text:change-start text:change-id="ct105553121970560"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">hapter 3</text:span><text:change-end text:change-id="ct105553121970560"/>, <text:change text:change-id="ct105553121953856"/><text:change-start text:change-id="ct105553121903936"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">Functions, Iterators and Generators</text:span><text:change-end text:change-id="ct105553121903936"/><text:change text:change-id="ct105553121943104"/>we showed how to parse a simple dataset. We’ll extract the four samples from that dataset:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">from ch03_ex5 import series, head_map_filter, row_iter</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">with open("Anscombe.txt") as source:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>data = tuple(head_map_filter(row_iter(source)))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>series_I= tuple(series(0,data))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>series_II= tuple(series(1,data))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>series_III= tuple(series(2,data))</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>series_IV= tuple(series(3,data))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Each of these series is a tuple of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> objects. Each <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> object has an x and a y attribute. The data looks like this:</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">(Pair(x=10.0, y=8.04), Pair(x=8.0, y=6.95), …, Pair(x=5.0, y=5.68))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We can apply the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">enumerate()</text:span> function to create sequences of values:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:soft-page-break/>y_rank= tuple( enumerate( sorted(<text:change text:change-id="ct106102877778496"/>series_I, key=lambda p: p.y<text:change text:change-id="ct106102875681152"/>) ) )</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">xy_rank= tuple( enumerate( sorted(<text:change text:change-id="ct105553121970752"/>y_rank, key=lambda rank: rank[1].x<text:change text:change-id="ct106102875734336"/>) ) )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The first step will create simple two-tuples with (0) a rank number and (1) the original <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> object. Since the data was sorted by the y-value in each pair, the rank value will reflect this ordering.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The sequence looks like this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">((0, Pair(x=8.0, y=5.25)), (1, Pair(x=8.0, y=5.56)), ..., </text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">(10, Pair(x=19.0, y=12.5)))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The second step will wrap those two-tuples into yet another layer of wrapping. We’ll sort by the x value in the original raw data. The second enumeration will be by the x-value in each pair.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ll create more deeply nested objects which look like this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">((0, (0, Pair(x=4.0, y=4.26))), (1, (2, Pair(x=5.0, y=5.68))), ..., </text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">(10, (9, Pair(x=14.0, y=9.96))))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In principle, we can now compute rank-order correlations between the two variables by using the x and y rankings. The extraction expression, however, is rather awkward. For each ranked sample in the data set, <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r</text:span>, we have to compare <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r[0]</text:span> with <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r[1][0]</text:span>. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">To overcome these awkward references, we’ll can write selector functions.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">x_rank = lambda ranked: ranked[0]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">y_rank= lambda ranked: ranked[1][0]</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">raw = lambda ranked: ranked[1][1]</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This allows us to compute correlation using <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">x_rank(r)</text:span> and <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">y_rank(r)</text:span>, making the references to values less awkward.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve wrapped the original <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> object twice, creating new tuples with the ranking value. <text:change text:change-id="ct106102875731648"/><text:change-start text:change-id="ct106102877756608"/>We’ve avoided <text:change-end text:change-id="ct106102877756608"/>stateful class definitions to create complex data structures incrementally.<text:change-start text:change-id="ct106102875659840"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Why create deeply-nested tuples? The answer is simple laziness. The processing required to unpack a tuple and build a new, flat tuple, is simply overhead. There’s less processing involved in wrapping an existing tuple. There are some compelling reasons for giving up the deeply-nested structure.<text:change-end text:change-id="ct106102875659840"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">There are two improvements we’d like to make:</text:p><text:list xml:id="list5168916495503774997" text:style-name="WWNum4"><text:list-item><text:p text:style-name="P12">We’d like a flatter data structure. The use of a nested tuple of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">(x rank, (y rank, Pair()))</text:span> doesn’t feel expressive or succinct. </text:p></text:list-item><text:list-item><text:p text:style-name="P2"><text:soft-page-break/>The <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">enumerate()</text:span> function doesn’t deal properly with ties. If two observations have the same value, they should get the same rank. The general rule is to average the positions of equal observations. The sequence [0.8, 1.2, 1.2, 2.3, 18] should have rank values of 1, 2.5, 2.5, 4. The two ties in positions 2 and 3 have the midpoint value of 2.5 as their common rank.</text:p></text:list-item></text:list><text:p text:style-name="Heading_20_21">Assigning Statistical Ranks</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ll break the rank ordering problem into two parts. First, we’ll look at a generic, higher-order function that we can use to assign ranks to either the x or y values of a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> object. Then we’ll use this to create a wrapper around the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> object that includes both x ranking and y ranking.<text:change-start text:change-id="ct106102877819776"/> This will <text:change-end text:change-id="ct106102877819776"/><text:change-start text:change-id="ct106102877759296"/>avoid a deeply nested structure.<text:change-end text:change-id="ct106102877759296"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Here’s a function which will create a rank order for each observation in a dataset:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">from collections import defaultdict</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def rank(<text:change text:change-id="ct105553124068672"/>data, key=lambda obj:obj<text:change text:change-id="ct106102877766016"/>): <text:s text:c="3"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>def rank_output(<text:change text:change-id="ct105553121908352"/>duplicates, key_iter, base=0<text:change text:change-id="ct106102875684608"/>):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>for k in key_iter:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>dups= len(duplicates[k])</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>for value in duplicates[k]:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="16"/>yield (base+1+base+dups)/2, value</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>base += dups</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>def build_duplicates( duplicates, data_iter, key ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>for item in data_iter:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="13"/>duplicates[key(item)].append(item)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>return duplicates</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>duplicates= build_duplicates(<text:change text:change-id="ct105553121966528"/>defaultdict( list ), iter(data), key<text:change text:change-id="ct105553124068864"/>)</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>return rank_output(<text:change text:change-id="ct106102877722240"/>duplicates, iter(sorted(duplicates)), 0<text:change text:change-id="ct106102877742784"/>)</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Our function for creating the rank ordering relies on creating a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Counter</text:span>-like object to discover duplicate values. We can’t use a simple <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Counter</text:span>, since it uses the entire object to create a collection. We only want to use a key function applied to each object. This allows us to pick either the x value or the y value of a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> object.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">duplicates</text:span> collection in this example is a stateful object. We could have written a properly recursive function. We’d then have to do tail call optimization to allow working with large collections of data. We’ve shown the optimized version of that recursion here. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">As a hint to how this recursion would look, we’ve provided the arguments to <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">build_duplicates()</text:span> that expose state as argument values. Clearly, the base case for the recursion is when <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">data_iter</text:span> is empty. When <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">data_iter</text:span> is not empty, a new collection is built from the old collection and the head, <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">next(data_iter)</text:span>. A recursive evaluation of <text:s/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">build_duplicates()</text:span> will handle all items in the tail of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">data_iter</text:span>.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:soft-page-break/>Similarly, we could have written two properly recursive functions to emit the collection with the assigned rank values. Again, we’ve optimized that recursion into nested <text:span text:style-name="T3">for</text:span> loops. To make it clear how we’re computing the rank value, we’ve include the low-end of the range (<text:change-start text:change-id="ct106102875623744"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">base+1</text:span><text:change-end text:change-id="ct106102875623744"/>) and the high end of the range (<text:change-start text:change-id="ct106102875682496"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">base+dups</text:span><text:change-end text:change-id="ct106102875682496"/>) and take the midpoint of these two values. If there is only a single duplicate, we’re evaluating <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">(2*base+2)/2</text:span>, which has the advantage of being a general solution.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Here’s how we can test this to be sure it works.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> list(<text:change-start text:change-id="ct106102877779264"/> <text:change-end text:change-id="ct106102877779264"/>rank(<text:change text:change-id="ct106102877793664"/>[0.8, 1.2, 1.2, 2.3, 18]<text:change text:change-id="ct106102877744896"/>) )</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">[(1.0, 0.8), (2.5, 1.2), (2.5, 1.2), (4.0, 2.3), (5.0, 18)]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> data= ((2, 0.8), (3, 1.2), (5, 1.2), (7, 2.3), (11, 18))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> list(<text:change-start text:change-id="ct105553121911808"/> <text:change-end text:change-id="ct105553121911808"/>rank(<text:change text:change-id="ct106102877824768"/>data, key=lambda x:x[1]<text:change text:change-id="ct105553124067136"/>)<text:change-start text:change-id="ct106102875699392"/> <text:change-end text:change-id="ct106102875699392"/>)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">[(1.0, (2, 0.8)), (2.5, (3, 1.2)), (2.5, (5, 1.2)), (4.0, (7, 2.3)), (5.0, (11, 18))]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"/><text:p text:style-name="Normal_20__5b_PACKT_5d_">The sample data included two identical values. The resulting ranks split positions 2 and 3 to assign position 2.5 to both values. This is the common statistical practice for computing the Spearman rank-order correlation between two sets of values.</text:p><text:p text:style-name="Heading_20_21">Wrapping instead of state changing</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Note that the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank()</text:span> function involves rearranging the input data as part of discovering duplicated values. If we want to rank on both the x and the y values in each <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span>, we need to reorder the data twice. We have two general strategies for doing this kind of thing.</text:p><text:list xml:id="list4824500736329387675" text:style-name="WWNum5"><text:list-item><text:p text:style-name="P8"><text:change-start text:change-id="ct105553119868992"/><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">Parallelism</text:span><text:change-end text:change-id="ct105553119868992"/>. We can create two copies of the data and rank each copy. We then need to reassemble the two copies into a final result that includes both rankings. This can be a bit awkward because we’ll need to somehow merge two sequences which are likely to be in different orders.</text:p></text:list-item><text:list-item><text:p text:style-name="P3"><text:change-start text:change-id="ct105553121926976"/><text:span text:style-name="Key_20_Word_20__5b_PACKT_5d_">Serialism</text:span><text:change-end text:change-id="ct105553121926976"/>. We can compute ranks on one variable and save the results as a wrapper that includes the original raw data. We can then rank this wrapped data on the other variable. While this can create a complex structure, we can optimize it slightly to create a flatter wrapper for the final results. </text:p></text:list-item></text:list><text:p text:style-name="Normal_20__5b_PACKT_5d_">Here’s how we can create an object which wraps a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> with the rank order based in the y value:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">Ranked_Y= namedtuple("Ranked_Y", ("r_y", "raw",) )</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def rank_y(<text:change text:change-id="ct106102875636416"/>pairs<text:change text:change-id="ct106102875706112"/>):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>return (Ranked_Y(*row)</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="12"/>for row in rank( pairs, lambda pair: pair.y<text:change text:change-id="ct106102877751232"/>) )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:soft-page-break/>We’ve defined a <text:change-start text:change-id="ct106102877764096"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuple</text:span><text:change-end text:change-id="ct106102877764096"/> which contains the y value rank plus the original (<text:change text:change-id="ct105553121993216"/><text:change-start text:change-id="ct106102875680384"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">raw</text:span><text:change-end text:change-id="ct106102875680384"/><text:change text:change-id="ct106102875688640"/>) value. Our <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_y()</text:span> function will create instances of this tuple by applying the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank()</text:span> function using a lambda which selects the y value of each <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> object. We then created instances of the resulting two-tuples. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The idea is that we can provide input like this:</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">>>> data = (Pair(x=10.0, y=8.04), Pair(x=8.0, y=6.95), ..., Pair(x=5.0, y=5.68))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">And we can get output like this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> list(rank_y(data))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">[Ranked_Y(r_y=1.0, raw=Pair(x=4.0, y=4.26)), </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">Ranked_Y(r_y=2.0, raw=Pair(x=7.0, y=4.82)), </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">... </text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">Ranked_Y(r_y=11.0, raw=Pair(x=12.0, y=10.84))]</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The raw <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> objects have been wrapped in a new object that includes the rank. This isn’t all <text:change text:change-id="ct106102877766208"/>we need; we’ll need to wrap this one more time to create an object that has both x-rank and y-rank information.</text:p><text:p text:style-name="Heading_20_21"><office:annotation office:name="__Annotation__3835_647431771"><dc:creator>Rui Carmo</dc:creator><dc:date>2014-11-22T19:13:00</dc:date><text:p><text:span text:style-name="T7">By this time, I'm kind of losing the point – we're delving so much into the problem that the applicability of the techniques outlined at the start of the chapter is out of sight.</text:span></text:p><text:p><text:span text:style-name="T7">Maybe this needs a less contrived example.</text:span></text:p></office:annotation>Rewrapping instead of state changing<office:annotation-end office:name="__Annotation__3835_647431771"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We could use a namedtuple named <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Ranked_X</text:span> which contains two attributes: <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r_x</text:span> <text:s/>and <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">ranked_y</text:span>. The <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">ranked_y</text:span> attribute would be an instance of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Ranked_Y</text:span> which has two attributes: <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r_y</text:span> and <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">raw</text:span>. While simple, the resulting objects are annoying to work with because the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r_x</text:span> and <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r_y</text:span> values aren’t simple peers in a flat structure. We’ll introduce a slightly more complex wrapping process which produces a slightly simpler result.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We want the output to look like this:</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">Ranked_XY= namedtuple("Ranked_XY", ("r_x", "r_y", "raw",) )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:change-start text:change-id="ct106102875644096"/>We’re going to create a<text:change-end text:change-id="ct106102875644096"/><text:change text:change-id="ct106102875706496"/> flat <text:change-start text:change-id="ct106102875705728"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuple</text:span><text:change-end text:change-id="ct106102875705728"/> with <text:change text:change-id="ct106102875679616"/><text:change-start text:change-id="ct106102875683072"/>multiple peer<text:change-end text:change-id="ct106102875683072"/> attributes<text:change text:change-id="ct105553119841920"/>.<text:change-start text:change-id="ct106102875745088"/> This kind of expansion is often easier to <text:change-end text:change-id="ct106102875745088"/><text:change-start text:change-id="ct105553119873024"/>work with than deeply-nested structures. In some applications, we may have a number of transformations. For this application, we have only two: x-ranking and y-ranking.<text:change-end text:change-id="ct105553119873024"/><text:change-start text:change-id="ct106102875639104"/> We’ll break this into two steps. First we’ll look at a simplistic wrapping like the one shown above, then a more general unwrap-rewrap.<text:change-end text:change-id="ct106102875639104"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Here’s how th<text:change text:change-id="ct105553121953664"/> <text:change-start text:change-id="ct106102877724928"/>x-y <text:change-end text:change-id="ct106102877724928"/>ranking <text:change text:change-id="ct105553121996288"/><text:change-start text:change-id="ct105553119877632"/>builds on the y-ranking<text:change-end text:change-id="ct105553119877632"/>:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def rank_xy( pairs ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>return (Ranked_XY(r_x=r_x, r_y=rank_y_raw[0], raw=rank_y_raw[1])</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>for r_x, rank_y_raw in </text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="12"/>rank( rank_y(pairs), lambda r: r.raw.x ) )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:soft-page-break/>We’ve used the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_y()</text:span> function to build <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Y</text:span> objects. Then we applied the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank()</text:span> function to those objects to order them by the original x values. The result of the second rank function will be two-tuples with (0) the x rank and (1) the <text:s/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Y </text:span>object. We build a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Ranked_XY</text:span> object from the x ranking (<text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r_x)</text:span>, the <text:s/>y ranking (<text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_y_raw[0]</text:span>), and the original object (<text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_y_raw[1]</text:span>).<text:change-start text:change-id="ct106102875639296"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">What we’ve shown <text:span text:style-name="T2">in this second function is a more general approach to adding data to a tuple. The</text:span><text:change-end text:change-id="ct106102875639296"/><text:change text:change-id="ct105553121975168"/> construction of the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Ranked_XY</text:span> object shows how <text:change text:change-id="ct105553124064064"/><text:change-start text:change-id="ct105553124067328"/>to<text:change-end text:change-id="ct105553124067328"/> unwrap the values from one data and rewrap to create a second, more complete structure.<text:change-start text:change-id="ct105553121982080"/> This approach can be used generally to introduce new variables to a tuple. <text:change-end text:change-id="ct105553121982080"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Here is some sample data:</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">>>> data = (Pair(x=10.0, y=8.04), Pair(x=8.0, y=6.95), ..., Pair(x=5.0, y=5.68))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This allows us to create ranking objects like this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> list(rank_xy(data))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">[Ranked_XY(r_x=1.0, r_y=1.0, raw=Pair(x=4.0, y=4.26)), </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">Ranked_XY(r_x=2.0, r_y=3.0, raw=Pair(x=5.0, y=5.68)), </text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">..., </text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">Ranked_XY(r_x=11.0, r_y=10.0, raw=Pair(x=14.0, y=9.96))]</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">One we have this data with appropriate x and y rankings, we can compute the Spearman rank-order correlation value. We can compute the Pearson correlation from the raw data.<text:change-start text:change-id="ct106102875622016"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Our multi-ranking approach involves decomposing a tuple and building a new, flat tuple with the additional attributes <text:change-end text:change-id="ct106102875622016"/><text:change-start text:change-id="ct106102877737024"/>we need. We will often need this kind of design when computing multiple derived values from source data.<text:change-end text:change-id="ct106102877737024"/></text:p><text:p text:style-name="Heading_20_21">Computing <office:annotation office:name="__Annotation__3961_647431771"><dc:creator>龚禕</dc:creator><dc:date>2014-12-05T16:03:00</dc:date><textooo:sender-initials>龚禕</textooo:sender-initials><text:p><text:span text:style-name="T6">It’s better to give a reference of </text:span>Spearman Rank-Order Correlation</text:p></office:annotation>Spearman Rank-Order Correlation<office:annotation-end office:name="__Annotation__3961_647431771"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The Spearman rank order correlation is a comparison between the rankings of two variables. It neatly bypasses the magnitude of the values and it can often find a correlation even when the relationship is not linear. The formula is this:<text:change-start text:change-id="ct105553119907200"/></text:p><text:p text:style-name="Standard"><text:change-end text:change-id="ct105553119907200"/><text:change-start text:change-id="ct106102877826688"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><draw:frame draw:style-name="fr2" draw:name="Object3" text:anchor-type="as-char" svg:y="-0.2925in" svg:width="1.4752in" svg:height="0.4772in" draw:z-index="2"><draw:object xlink:href="./Object 3" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><draw:image xlink:href="./ObjectReplacements/Object 3" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><svg:desc>formula</svg:desc></draw:frame></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This formula shows us that we’ll be summing the differences in rank, <draw:frame draw:style-name="fr1" draw:name="Object1" text:anchor-type="as-char" svg:y="-0.1484in" svg:width="0.2071in" svg:height="0.2091in" draw:z-index="0"><draw:object xlink:href="./Object 1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><draw:image xlink:href="./ObjectReplacements/Object 1" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><svg:desc>formula</svg:desc></draw:frame> and <draw:frame draw:style-name="fr1" draw:name="Object2" text:anchor-type="as-char" svg:y="-0.1484in" svg:width="0.2146in" svg:height="0.2091in" draw:z-index="1"><draw:object xlink:href="./Object 2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><draw:image xlink:href="./ObjectReplacements/Object 2" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/><svg:desc>formula</svg:desc></draw:frame>, for all of the pairs of observed values.<text:change-end text:change-id="ct106102877826688"/><text:change text:change-id="ct106102877753728"/>. <text:s/>The Python version of this depends on the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">sum()</text:span> and <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">len()</text:span> functions.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:soft-page-break/>def rank_corr( pairs ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>ranked= rank_xy( pairs )</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>sum_d_2 = sum( (r.r_x - r.r_y)**2 for r in ranked )</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>n = len(pairs)</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>return 1-6*sum_d_2/(n*(n**2-1))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve created <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_XY</text:span> objects for each Pair. Given this, we can then subtract the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r_x</text:span> and <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r_y</text:span> values from those pairs to compare their difference. We can then square and sum the differences.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">A good article on statistics will provide detailed guidance on what the coefficient means. A value around zero means there is no correlation between the data ranks of the two series of data points. A scatter plot would show a random scattering of points. A value around +1 or -1 indicates a strong relationship between the two values. A graph would show a clear line or curve.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Here’s an example based on Anscombe’s Quartet series I.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> data = (Pair(x=10.0, y=8.04), Pair(x=8.0, y=6.95), …, Pair(x=5.0, y=5.68))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> round(rank_corr( data ), 3)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">0.818</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">For this particular data set the correlation is strong. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In <text:change-start text:change-id="ct105553121925632"/><text:span text:style-name="Chapterref_20__5b_PACKT_5d_">Chapter 4</text:span><text:change-end text:change-id="ct105553121925632"/>, “<text:change-start text:change-id="ct105553121924864"/><text:span text:style-name="Italics_20__5b_PACKT_5d_">Working with Collections</text:span><text:change-end text:change-id="ct105553121924864"/>”, we showed how to compute the Pearson correlation coefficient. The function we showed, <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">corr()</text:span>, worked with two separate sequences of values. We can use it with our sequence of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> objects like this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">import ch04_ex4</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def pearson_corr( pairs ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>X = tuple( p.x for p in pairs )</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>Y = tuple( p.y for p in pairs )</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>return ch04_ex4.corr( X, Y )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve unwrapped the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Pair</text:span> objects to get the raw values which we can use with the existing <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">corr()</text:span> function. This provides a different correlation coefficient. The Pearson value is based on how well the standardized values <text:s/>compare between two sequences. For many data sets, the difference between Pearson and Spearman correlation is relatively small. For some datasets, however, the differences can be quite large. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">To see the importance of having multiple statistical tools for exploratory data analysis, compare the Spearman and Pearson correlations for the four sets of data in the Anscombe Quartet.</text:p><text:p text:style-name="Heading_20_11"><text:soft-page-break/>Polymorphism and Pythonic pattern matching</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Some functional programming languages offer clever approaches to working with statically typed function definitions. The issue is that many functions we’d like to write are entirely generic with respect to data type. For example, most of our statistical functions are identical for integer or floating-point numbers, as long as division returns a value which is a subclass of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">numbers.Real</text:span> (e.g., <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Decimal</text:span>, <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Fraction</text:span>, or <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">float</text:span>). In order to make a single generic definition work for multiple data types, sophisticated type or pattern matching rules are used by the compiler.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Instead of the (possibly) complex features of statically-typed functional languages, Python changes the issue by using dynamic selection of the final implementation of an operator based on the data types being used. This means that a compiler doesn’t certify that our functions are expecting and producing the proper data types. We generally rely on unit testing for this.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In Python, we’re <text:change text:change-id="ct106102877796736"/><text:change-start text:change-id="ct106102875638720"/>effectively<text:change-end text:change-id="ct106102875638720"/> writing <text:change text:change-id="ct106102875656192"/>generic definition<text:change-start text:change-id="ct106102877767552"/>s<text:change-end text:change-id="ct106102877767552"/> because the code isn’t bound to any specific data type. The Python run-time will locate the appropriate operations using a simple set of matching rules. Section 3.3.7 of the language reference manual and the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">numbers</text:span> module in the library provide details on how this mapping from operation to special method name works.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In rare cases, we may need to have different behavior based on the types of the data elements. We have two ways to tackle this.</text:p><text:list xml:id="list6384050904100289530" text:style-name="WWNum6"><text:list-item><text:p text:style-name="P9">We can use the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">isinstance()</text:span> function to distinguish the different cases.</text:p></text:list-item><text:list-item><text:p text:style-name="P4">We can create our own subclass of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">numbers.Number</text:span> or <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">tuple</text:span> and implement a properly polymorphic special method names.</text:p></text:list-item></text:list><text:p text:style-name="Normal_20__5b_PACKT_5d_">In some cases, we’ll actually need to do both so that we can include appropriate data type conversions. <text:change text:change-id="ct106102877755648"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">When we look back the ranking example in the previous section, we’re tightly bound to the idea of applying rank-ordering to simple pairs. While this is the way Spearman correlation is defined, we might have a multivariate data set, and have a need to do rank-order correlation among all the variables.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The first thing we’ll need to do is generalize our idea of rank-order information. Here’s a namedtuple which handles a tuple of ranks and a tuple of raw data.</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">Rank_Data = namedtuple( "Rank_Data", ("rank_seq", "raw") )</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">For any specific piece of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span>, <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r</text:span>, we can use <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r.rank_seq[0]</text:span> to get a specific ranking, and <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">r.raw</text:span> to get the original observation.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ll add some syntactic sugar to our ranking function. In many previous examples, we’ve required either an iterable or a collection. The <text:span text:style-name="T3">for</text:span> statement is graceful about <text:soft-page-break/>working with either one. But we don’t always use the <text:change-start text:change-id="ct105553121983040"/><text:span text:style-name="T3">for</text:span><text:change-end text:change-id="ct105553121983040"/> statement, and for some functions, we’ve had to explicitly use <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">iter()</text:span> to make an iterable out of a collection. We can handle this situation with a simple <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">isinstance()</text:span> check:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def some_function( seq_or_iter ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>if not isinstance(seq_or_iter,collections.abc.Iterator):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/><text:change text:change-id="ct106102877731072"/><text:change-start text:change-id="ct105553122017792"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>yield from some_function(iter(seq_or_iter), key)<text:change-end text:change-id="ct105553122017792"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>return</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/># Do the real work of the function using the iterable</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve included a type check to handle the small difference between a collection, which doesn’t work with <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">next()</text:span>, and an iterable, which does support <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">next()</text:span>.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In context of our rank ordering function we would use this variation on the design pattern:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def rank_data( seq_or_iter, key=lambda obj:obj ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/># Not a sequence? Materialize a sequence object</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>if isinstance(seq_or_iter,<text:change-start text:change-id="ct105553119898560"/> <text:change-end text:change-id="ct105553119898560"/>collections.abc.Iterator):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:change text:change-id="ct105553119922560"/><text:change-start text:change-id="ct106102875681344"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>yield from rank_data(tuple(seq_or_iter), key)<text:change-end text:change-id="ct106102875681344"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>data = seq_or_iter</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>head= seq_or_iter[0]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/># <text:change text:change-id="ct106102875692288"/>Convert to Rank_Data and process.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>if not isinstance(<text:change text:change-id="ct106102875719552"/>head, Rank_Data<text:change text:change-id="ct105553119921408"/>):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>ranked= tuple( Rank_Data((),d) for d in data )</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>for r, rd in rerank(<text:change text:change-id="ct105553124063488"/>ranked, key<text:change text:change-id="ct105553124059648"/>):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="12"/>yield Rank_Data(<text:change text:change-id="ct105553124058304"/>rd.rank_seq+(r,), rd.raw<text:change text:change-id="ct106102875716480"/>)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>return</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/># Collection of Rank_Data is what we prefer.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>for r, rd in rerank(<text:change text:change-id="ct106102877798272"/>data, key<text:change text:change-id="ct105553124052928"/>):</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="8"/>yield Rank_Data(<text:change text:change-id="ct106102875639872"/>rd.rank_seq+(r,), rd.raw<text:change text:change-id="ct106102877820544"/>)</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve decomposed the ranking into three cases for three different types of data. We’re forced to do this when the different kinds of data aren’t polymorphic subclasses of a common superclass. <text:change-start text:change-id="ct105553121969792"/>Here are the three cases:</text:p><text:list xml:id="list2852396844559145993" text:style-name="L2"><text:list-item><text:p text:style-name="P10"><text:change-end text:change-id="ct105553121969792"/>Given an iterable (without a usable <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">__getitem__()</text:span> method), we’ll materialize a tuple that we can work <office:annotation office:name="__Annotation__4225_647431771"><dc:creator>Rui Carmo</dc:creator><dc:date>2014-11-22T19:12:00</dc:date><text:p><text:span text:style-name="T5">with</text:span></text:p></office:annotation>w<text:change-start text:change-id="ct106102875688256"/>i<text:change-end text:change-id="ct106102875688256"/><text:change text:change-id="ct106102877767936"/>th<office:annotation-end office:name="__Annotation__4225_647431771"/>. <text:change-start text:change-id="ct106102877750080"/></text:p></text:list-item><text:list-item><text:p text:style-name="P10"><text:change-end text:change-id="ct106102877750080"/>Given a collection of some unknown type of data, we’ll wrap the unknown objects into <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span> tuples. <text:change-start text:change-id="ct105553124010688"/></text:p></text:list-item><text:list-item><text:p text:style-name="P5"><text:change-end text:change-id="ct105553124010688"/><text:soft-page-break/>Finally, given an collection of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span> tuples, we’ll add yet another ranking to the tuple of ranks inside the each <text:s/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span> container.</text:p></text:list-item></text:list><text:p text:style-name="Normal_20__5b_PACKT_5d_">This relies on a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rerank()</text:span> function that inserts returns another ranking into the <text:s/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span> tuple. This will build up a collection of individual rankings from a complex record of raw data values. The <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rerank()</text:span> function follows a slightly different design than the example of the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank()</text:span> function shown previously.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This version of the algorithm uses sorting instead of creating a groups in a <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Counter</text:span>-like object. Here’s the code:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def rerank( rank_data_collection, key ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>sorted_iter= iter( sorted( rank_data_collection,</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>key=lambda obj: key(obj.raw) ) )</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>head = next(sorted_iter)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/><text:change text:change-id="ct105553124067712"/><text:change-start text:change-id="ct105553121950976"/></text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>yield from ranker( sorted_iter, 0, [head], key )<text:change-end text:change-id="ct105553121950976"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve started by reassembling a single, sortable collection from the head and the data iterator. In the context in which this is used, we can argue that this is a bad idea.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This function relies on two other functions. They could be declared within the body of <text:change-start text:change-id="ct106102877748544"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rerank()</text:span><text:change-end text:change-id="ct106102877748544"/>. We’ll show them separately. Here is the ranker, which accepts an iterable, a base rank number, a collection of values with the same rank, and a key:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def ranker( sorted_iter, base, same_rank_seq, key ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>"""Rank values from a sorted_iter using a base rank value.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>If the next value's key matches same_rank_seq, accumulate those.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>If the next value's key is different, accumulate same rank values</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>and start accumulating a new sequence.</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>"""</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>try:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>value= next(sorted_iter)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>except StopIteration:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>dups= len(same_rank_seq)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:change text:change-id="ct106102877728960"/><text:change-start text:change-id="ct106102877817856"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>yield from yield_sequence( (base+1+base+dups)/2, iter(same_rank_seq) )<text:change-end text:change-id="ct106102877817856"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>return</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>if key(value.raw) == key(same_rank_seq[0].raw):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:change text:change-id="ct106102875633536"/><text:change-start text:change-id="ct106102877798080"/><text:soft-page-break/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>yield from ranker(sorted_iter, base, same_rank_seq+[value], key )<text:change-end text:change-id="ct106102877798080"/></text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>else:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/>dups= len(same_rank_seq)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="8"/><text:change text:change-id="ct105553119914496"/><text:change-start text:change-id="ct105553119911232"/></text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:change-end text:change-id="ct105553119911232"/><text:change-start text:change-id="ct105553121929856"/><text:s text:c="8"/>yield from yield_sequence( (base+1+base+dups)/2, iter(same_rank_seq) )</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="8"/>yield from ranker(sorted_iter, base+dups, [value], key)<text:change-end text:change-id="ct105553121929856"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve extracted the next item from the iterable collection of sorted values. If this fails, there is no next item, and we need to emit the final collection of equal-valued items in the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">same_rank_seq</text:span> sequence. If this works, then we need to use the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">key()</text:span> function to see if the next item, value, has the same key as the collection of equal-ranked items. If the key is the same, the overall value is defined recursively: the re-ranking is the rest of the sorted items, the same base value for the rank, a larger collection of same_rank items, and the same key function.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">If the next item’s key doesn’t match the sequence of equal-valued items, the result is a sequence of equal-valued items. This will be follows by the re-ranking of the rest of the sorted items, a base value incremented by the number of equal-valued items, a fresh list of equal-rank items with just the new value, and the same key extraction function.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">This depends on the <text:change-start text:change-id="ct106102875638144"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">yield_sequence()</text:span><text:change-end text:change-id="ct106102875638144"/> function which looks like this:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">def yield_sequence( rank, same_rank_iter ):</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>head= next(same_rank_iter)</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>yield rank, head</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/><text:change text:change-id="ct106102877765056"/><text:change-start text:change-id="ct106102877826496"/></text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>yield from yield_sequence( rank, same_rank_iter )<text:change-end text:change-id="ct106102877826496"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve written this in a way that emphasizes the recursive definition. We don’t really need to extract the head, emit that, and then recursively emit the remaining items. While a single <text:span text:style-name="T3">for</text:span> statement might be shorter, it’s sometimes more clear to emphasize the recursive structure which has been optimized into a <text:span text:style-name="T3">for</text:span> loop.</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Here are some examples of using this function to rank (and rerank) data. We’ll start with a simple collection of scalar values:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:soft-page-break/>>>> scalars= [0.8, 1.2, 1.2, 2.3, 18]</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_">>>> list(ranker(scalars))</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_">[Rank_Data(rank_seq=(1.0,), raw=0.8), Rank_Data(rank_seq=(2.5,), raw=1.2), Rank_Data(rank_seq=(2.5,), raw=1.2), Rank_Data(rank_seq=(4.0,), raw=2.3), Rank_Data(rank_seq=(5.0,), raw=18)]</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">Each value becomes the “raw” attribute of a <text:change-start text:change-id="ct105553119926976"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span><text:change-end text:change-id="ct105553119926976"/> object. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">When we work with a slightly more complex object, we can do multiple rankings, also. Here is a sequence of two-tuples:</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>>>> pairs= ((2, 0.8), (3, 1.2), (5, 1.2), (7, 2.3), (11, 18))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>>>> rank_x= tuple(ranker(pairs, key=lambda x:x[0] ))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>>>> rank_x</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>(Rank_Data(rank_seq=(1.0,), raw=(2, 0.8)), Rank_Data(rank_seq=(2.0,), raw=(3, 1.2)), Rank_Data(rank_seq=(3.0,), raw=(5, 1.2)), Rank_Data(rank_seq=(4.0,), raw=(7, 2.3)), Rank_Data(rank_seq=(5.0,), raw=(11, 18)))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>>>> rank_xy= (ranker(rank_x, key=lambda x:x[1] ))</text:p><text:p text:style-name="Code_20__5b_PACKT_5d_"><text:s text:c="4"/>>>> tuple(rank_xy)</text:p><text:p text:style-name="Code_20_End_20__5b_PACKT_5d_"><text:s text:c="4"/>(Rank_Data(rank_seq=(1.0, 1.0), raw=(2, 0.8)), Rank_Data(rank_seq=(2.0, 2.5), raw=(3, 1.2)), Rank_Data(rank_seq=(3.0, 2.5), raw=(5, 1.2)), Rank_Data(rank_seq=(4.0, 4.0), raw=(7, 2.3)), Rank_Data(rank_seq=(5.0, 5.0), raw=(11, 18)))</text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We defined a collection of pairs. Then we ranked the two-tuples, assigning the sequence of <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span> objects to the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_x</text:span> variable. We ranked then ranked this collection of <text:s/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span> objects, creating a second rank value and assigning the result to the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_xy</text:span> variable. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">The resulting sequence can be used to a slightly modified <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_corr()</text:span> function to compute the rank correlations of any of the available values in the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">rank_seq</text:span> attribute of the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">Rank_Data</text:span> objects. We’ll leave this modification as an exercise for the readers.</text:p><text:p text:style-name="Heading_20_11"><text:change text:change-id="ct106102875696512"/><text:change-start text:change-id="ct106102877825536"/>Summary<text:change-end text:change-id="ct106102877825536"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In this chapter, we’ve looked at different ways to use namedtuple objects to implement more complex data structures. The essential features of a namedtuple are a good fit with functional design. They can be created with a creation function, and accessed by position as well as name. </text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">We’ve looked at how to use immutable <text:change-start text:change-id="ct106102877754496"/><text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">namedtuples</text:span><text:change-end text:change-id="ct106102877754496"/> instead of stateful object definitions. The core technique was to wrap an object in an immutable tuple to provide additional attribute <office:annotation office:name="__Annotation__4529_647431771"><dc:creator>龚禕</dc:creator><dc:date>2014-12-05T16:03:00</dc:date><textooo:sender-initials>龚禕</textooo:sender-initials><text:p><text:span text:style-name="T6">Another important topic is </text:span>Polymorphism</text:p></office:annotation>values<office:annotation-end office:name="__Annotation__4529_647431771"/>. <text:change-start text:change-id="ct105553119919872"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_"><text:soft-page-break/>We’ve also looked at ways to handle multiple data types in Python. <text:change-end text:change-id="ct105553119919872"/><text:change-start text:change-id="ct106102877775808"/>For most arithmetic operations, Python’s internal method dispatch locates proper implementations. For working with collections, however, we might want to handle iterators and <text:change-end text:change-id="ct106102877775808"/><text:change-start text:change-id="ct106102877793088"/>sequences slightly differently.<text:change-end text:change-id="ct106102877793088"/></text:p><text:p text:style-name="Normal_20__5b_PACKT_5d_">In the next two chapters, we’ll look at the <text:span text:style-name="Code_20_In_20_Text_20__5b_PACKT_5d_">itertools</text:span> module. This library module provides a number of functions that help us to work with iterators in sophisticated ways. Many of these tools are examples of higher-order functions. They can help make a functional design stay succinct and expressive.<text:change text:change-id="ct105553121914112"/></text:p></office:text></office:body></office:document-content>