python essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf ·...

132
Python Essentials Asim Jalis

Upload: others

Post on 16-May-2020

30 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials

AsimJalis

Page 2: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials i

Contents

1 Introduction 1

1.1 Instructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Introductions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.3 Hands-OnLearning . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 HistoryofPython 2

2.1 GuidovanRossum . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2.2 Python’sGoals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2.3 VersionsandTimeline . . . . . . . . . . . . . . . . . . . . . . . . . 2

2.4 Python2.7VersusPython3.0 . . . . . . . . . . . . . . . . . . . . . 3

2.5 Python2.7and3.0Differences . . . . . . . . . . . . . . . . . . . . 4

3 Introduction 4

3.1 WhatisPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3.2 PythonvsPerl, Ruby, PHP . . . . . . . . . . . . . . . . . . . . . . . 5

3.3 StartupsUsingPython . . . . . . . . . . . . . . . . . . . . . . . . . 5

3.4 JobsinDifferentLanguages . . . . . . . . . . . . . . . . . . . . . . 5

3.5 InstallingPython . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3.6 PythonScripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3.7 PythonBAT Files . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.8 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.9 InteractiveShell . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4 Numbers 9

4.1 IntegersandFloating-PointNumbers . . . . . . . . . . . . . . . . . 9

4.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

4.3 PythonConventions . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Page 3: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials ii

4.4 ArithmeticOperators . . . . . . . . . . . . . . . . . . . . . . . . . 11

4.5 AssignmentOperators . . . . . . . . . . . . . . . . . . . . . . . . . 12

4.6 IncrementingandDecrementing . . . . . . . . . . . . . . . . . . . 14

4.7 TipCalculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

5 Strings 14

5.1 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

5.2 Single-QuotesandDouble-Quotes . . . . . . . . . . . . . . . . . . 15

5.3 RawStrings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

5.4 TripleQuotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.5 ConcatenatingStrings . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.6 ConvertingBetweenNumbersandStrings . . . . . . . . . . . . . . . 18

5.7 StringFormatting . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

5.8 PercentStringFormatting . . . . . . . . . . . . . . . . . . . . . . . 20

5.9 FormatSyntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5.10 ConversionSpecifiers . . . . . . . . . . . . . . . . . . . . . . . . . 21

5.11 ConversionFlags . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5.12 ConversionTypes . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.13 NumericConverter . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.14 FormattingAddendum . . . . . . . . . . . . . . . . . . . . . . . . 22

5.15 ReadingInput . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.16 PopulationCalculator . . . . . . . . . . . . . . . . . . . . . . . . . 23

6 Functions 24

6.1 CallingFunctions . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

6.2 DefiningFunctions . . . . . . . . . . . . . . . . . . . . . . . . . . 26

6.3 VariablesInFunction . . . . . . . . . . . . . . . . . . . . . . . . . 27

6.4 DefaultArgumentValues . . . . . . . . . . . . . . . . . . . . . . . 28

Page 4: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials iii

6.5 KeywordArguments . . . . . . . . . . . . . . . . . . . . . . . . . . 28

6.6 MultipleReturnValues . . . . . . . . . . . . . . . . . . . . . . . . 29

6.7 ScopingRules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6.8 Globals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6.9 CreatingLibrariesofFunctions . . . . . . . . . . . . . . . . . . . . 32

7 Documentation 32

7.1 FunctionDocstrings . . . . . . . . . . . . . . . . . . . . . . . . . . 32

7.2 ModuleDocstrings . . . . . . . . . . . . . . . . . . . . . . . . . . 33

8 Objects 33

8.1 InteractingwithObjects . . . . . . . . . . . . . . . . . . . . . . . . 33

9 GeneratingReports 34

9.1 FileReadingandWriting . . . . . . . . . . . . . . . . . . . . . . . 34

9.2 HTML Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

10 Booleans 38

10.1 BooleanType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

10.2 BooleansFromComparisons . . . . . . . . . . . . . . . . . . . . . 38

10.3 ComparisonOperators . . . . . . . . . . . . . . . . . . . . . . . . 39

10.4 ConvertingBooleans . . . . . . . . . . . . . . . . . . . . . . . . . 40

10.5 BooleanOperators . . . . . . . . . . . . . . . . . . . . . . . . . . 42

11 ControlFlow: Branching 43

11.1 IfandElse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

11.2 If, Elif, andElse . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

11.3 If-ElseandBooleanOperators . . . . . . . . . . . . . . . . . . . . . 44

11.4 If-ElseOperator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

Page 5: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials iv

11.5 ValidatingNumericInputs . . . . . . . . . . . . . . . . . . . . . . . 46

11.6 CatchingControl-C . . . . . . . . . . . . . . . . . . . . . . . . . . 47

11.7 ThrowingExceptions . . . . . . . . . . . . . . . . . . . . . . . . . 48

12 ControlFlow: Looping 49

12.1 LoopingwithWhile . . . . . . . . . . . . . . . . . . . . . . . . . . 49

12.2 LoopingwithFor . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

13 Collections 52

13.1 DefiningLists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

13.2 AccessingListElements . . . . . . . . . . . . . . . . . . . . . . . . 53

13.3 ListSurgery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

13.4 CreatingLists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

13.5 ListOperations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

13.6 CommandLineArguments . . . . . . . . . . . . . . . . . . . . . . 56

13.7 SequencesandFunctions . . . . . . . . . . . . . . . . . . . . . . . 56

13.8 Lambda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

13.9 Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

13.10Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

13.11Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

13.12Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

13.13TuplesvsListPerf . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

13.14Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

13.15SetSyntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

14 OperatingSystem 63

14.1 SystemEnvironment . . . . . . . . . . . . . . . . . . . . . . . . . . 63

14.2 RunningShellCommands . . . . . . . . . . . . . . . . . . . . . . . 64

14.3 OtherProcessConstructs . . . . . . . . . . . . . . . . . . . . . . . 64

Page 6: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials v

15 Third-PartyModules 65

15.1 PipvsEasy_Install . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

15.2 WindowsPipInstall . . . . . . . . . . . . . . . . . . . . . . . . . . 66

15.3 Unix/MacPipInstall . . . . . . . . . . . . . . . . . . . . . . . . . 66

15.4 Demjson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

15.5 IPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

15.6 WebServices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

16 Objects 70

16.1 DefiningObjects . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

16.2 WhyObjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

16.3 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

16.4 ImplicitMethods . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

16.5 StrandLen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

16.6 StrvsRepr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

16.7 OperatorOverloading . . . . . . . . . . . . . . . . . . . . . . . . . 74

16.8 NewStyleandOldStyleObjects . . . . . . . . . . . . . . . . . . . 74

16.9 OperatorPrecedence . . . . . . . . . . . . . . . . . . . . . . . . . 75

17 RegexandWebScraping 76

17.1 Regex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

17.2 SpecialCharacters . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

17.3 AdvancedSpecialCharacters . . . . . . . . . . . . . . . . . . . . . 78

17.4 SpecialSequences . . . . . . . . . . . . . . . . . . . . . . . . . . 78

17.5 RegexFunctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

17.6 RegexFlags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

17.7 RegexExercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

17.8 WebScraping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Page 7: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials vi

18 CSV Files 83

18.1 ReadingCSV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

18.2 WritingCSV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

19 Database 86

19.1 CreatingTables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

19.2 InsertingRecords . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

19.3 BatchInserts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

19.4 SelectingRecords . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

19.5 CursorMethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

19.6 Querying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

19.7 MySQL andPostgreSQL . . . . . . . . . . . . . . . . . . . . . . . . 90

20 NoseTests 91

20.1 UnitTesting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

20.2 NoseTests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

20.3 NoseInstall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

20.4 NoseTestExample . . . . . . . . . . . . . . . . . . . . . . . . . . 93

20.5 NoseSetUp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

21 XML Parsing 96

21.1 xmltodict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

21.2 ElementTree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

22 WebApplicationsUsingFlask 99

22.1 SettingUpFlask . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

22.2 HelloWorldWebApp . . . . . . . . . . . . . . . . . . . . . . . . 100

22.3 TwoPageWebApp . . . . . . . . . . . . . . . . . . . . . . . . . . 100

22.4 TipCalculatorWebApp . . . . . . . . . . . . . . . . . . . . . . . . 102

Page 8: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials vii

22.5 DeployingonPythonAnywhere . . . . . . . . . . . . . . . . . . . . 105

22.6 MVC Application . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

23 ListComprehensions 111

23.1 ListComprehensions . . . . . . . . . . . . . . . . . . . . . . . . . 111

23.2 ListsofDictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . 112

24 Pexpect 112

24.1 Pexpect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

24.2 PexpectMethods . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

25 Threading 115

25.1 Threading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

26 MiscTopics 117

26.1 ArgsandKWArgs . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

26.2 ClassmethodandStaticmethod . . . . . . . . . . . . . . . . . . . . 118

26.3 Closures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

26.4 Decorators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

26.5 Memoizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

26.6 Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

27 Next 123

27.1 NextSteps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

Page 9: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 1

1 Introduction

1.1 Instructor

• AsimJalis

• HasworkedassoftwareengineeratMicrosoft, Hewlett-Packard, andSalesforce.

• http://linkedin.com/in/asimjalis

1.2 Introductions

• Whatisyourname? Whatdoyoudo?

• Howareyouplanningtousewhatyoulearnhere?

• Whatisyourperfectoutcome?

1.3 Hands-OnLearning

• Howwillthiscoursework?

– Hands-onclass.

– Learnbydoing.

• Whyhands-on?

– Helpsyougetmostoutofclass.

– Youinteractwithmaterialmoredeeply, learn.

– Encouragessmallmistakes, fasterlearning.

– Helpsgetissuesresolvedhere, now.

– Afterwardsyouretaintheexperience.

Page 10: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 2

2 HistoryofPython

2.1 GuidovanRossum

WhowrotePython?

PythonwaswrittenbyGuidovanRossum, alsoknownasPython’sBenevolentDictatorforLife(BDFL).

Whatdoeshelooklike?

Here isapicturefrom2006.

2.2 Python’sGoals

Whatledhimtowriteit?

Accordingto Guido, ”[In]December1989, I waslookingfora’hobby’programmingprojectthatwouldkeepmeoccupiedduringtheweekaroundChristmas. [...] I de-cidedtowriteaninterpreterforthenewscriptinglanguageI hadbeenthinkingaboutlately. [...] I chosePythonasaworkingtitlefortheproject, beinginaslightlyirrever-entmood(andabigfanofMontyPython’sFlyingCircus).”

Whatweresomeofitsgoals?

Ina1999DARPA fundingproposal, vanRossumdefinedPython’sgoalsasfollows:

• aneasyandintuitivelanguagejustaspowerfulasmajorcompetitors• opensource, soanyonecancontributetoitsdevelopment• codethatisasunderstandableasplainEnglish• suitabilityforeverydaytasks, allowingforshortdevelopmenttimes

2.3 VersionsandTimeline

WhathasbeenPython’stimeline?

PythonVersion Released Changes

Page 11: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 3

0.9.0 Feb1991 ReleasedbyGuidoVanRossumtoalt.sources

1.0 Jan1994 Added lambda, map, filter, reduce

1.5 Dec1997 Bugfixes

1.6 Sep2000 Licensechanges

2.0 Oct2000 Listcomprehensions

2.1 Apr2001 Generators

2.2 Dec2001

2.3 Jul2003

2.4 Nov2004

2.5 Sep2006

2.6 Oct2008

2.7 Jul2010

3.0 Dec2008 Compatibilitybreakingchanges

3.1 Jun2009

3.2 Feb2011

3.3 Sep2012

2.4 Python2.7VersusPython3.0

ShouldI usePython2.7orPython3.0?

YoushouldusePython2.7because:

• Manylibrarieshavenotbeenportedoverto3.0

• 2.7shipswithMacandothersystemsbydefault

• Youwillencountercodewrittenin2.7

Someofthechangesin3.0areunderthesurfaceanddonotaffectthesyntax. Othersdo. Wewilldiscussimportantdifferencesastheycomeup.

Page 12: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 4

2.5 Python2.7and3.0Differences

Differencesin print

• Use print("Hello world") not print "Hello world"• Use print("Hello world", end=" ") not print "Hello world",• Use print() not print• Use print("Error", file=sys.stderr) not print>>sys.stderr,

"error"• Use print((a, b)) not print (a,b)

Differencesinintegerdivision

• In2.7 3/2 isintegerdivisionandsoitequals 1.• In3.0 3/2 isfloatdivisionandsoitequals 1.5.• Inboth2.7and3.0 3//2 isintegerdivision.• Whenyouwantintegerdivisionuse 3//2 inbothtobesafe.

3 Introduction

3.1 WhatisPython

WhatisPython?

• Pythonisahigh-levelprogramminglanguage.

• Fastedit-compile-runcycle. Fast, interactive, programmingexperience.

• Greatforwritingquickprograms, thatovertimeevolveintobigprograms.

• Usefulforautomatingsysadmintasks, builds, websites.

• ShipswithMacandUnixmachinesbydefault. Easytoinstall. Everywhere.

• Object-orientedandthecodedoesnotbuckleoverasitgrowsovertime.

Page 13: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 5

3.2 PythonvsPerl, Ruby, PHP

All of these languages are scripting languages. The code canbe run immediatelywithoutwaiting for thecompiler. This leads toa fast interactive funprogrammingexperience.

Feature Python Perl Ruby PHP

Nocompilationneeded X X X X

Webframework Django, Flask Catalyst, Dancer Rails CakePHP,CodeIgniter

Forcommand-lineutilities X X X

Object-orientedbaked-in X X

Scalesforlargeapps X X

3.3 StartupsUsingPython

WhataresomeapplicationsandstartupsthatusePython?

• BitTorrent waswrittenbyBramCoheninPython. HestartedinApril2001, andreleaseditinJuly2001.

• eGroups waswritten in200,000 linesof Pythonaccording to founder ScottHassan. ItwaslateracquiredbyYahoo! andturnedintoYahoo! Groups.

• Yelp iswritteninPython.

• Reddit waswritteninLispandthenrewritteninPythoninoneweekend.

3.4 JobsinDifferentLanguages

HowdoesPythoncomparewiththeotherlanguagesinjobs?

Here istherelativenumberofjobsbasedondatafrom.

Page 14: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 6

3.5 InstallingPython

Exercise: InstallPython.

Solution:

• OnWindowsinstallPython2.7.5from http://www.python.org/getit/

• OnMacPython2.7comespreinstalled.

• Verifythatyouhave python.

python --version

3.6 PythonScripts

Exercise: Writeascriptthatprints Hello, world.

Solution:

• Savethisinatextfilecalled hello.py usinganeditorlikeSublimeText, Tex-tWrangler, NotePad++, orTextPad.

#!/usr/bin/env python

print "Hello, world."

• Type python hello.py torunit.

• Ortype chmod 755 hello.py andthentype ./hello.py torunit.

Notes:

• Itisconventionaltoputthe .py extensiononPythonscripts. However, itisnotrequired. Wecouldhavecalledtheprogram hello insteadof hello.py.

• WhitespaceissignificantinPython. Theindentationofthestatementindicateswhatblockitisinaswewillseelater. Forthisprogramtowork, thestatementmusthavezeroindentation.

Page 15: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 7

• Nosemicolonisrequiredtoendthestatement.

• Printautomaticallyputsanewlineaftertheoutput.

• Ifyouwanttoprintoutputwithoutanewlineputacommaafterit.

• Thiswillnotprintanewline.

#!/usr/bin/env python

print "Hello, world.",

3.7 PythonBAT Files

Exercise: CreateaWindowsBAT filethatprintshelloworldusingPython.

Solution:

• OnWindowssavethisto file.bat andthenyoucanrunitfromthecommandline.

@echo off & python.exe -x "%~f0" %* & goto :EOF

print "Hello, world."

• OryoucansavePythonin file.py andthenusethis file.bat.

@echo offpython file.py

3.8 Documentation

Exercise: Findthedocumentationforthe raw_input function.

Solution:

• InthePythonconsoletype help(raw_input).

• help canbeusedwithPythonfunctionsandobjects.

Page 16: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 8

3.9 InteractiveShell

Exercise: Calculate 3 + 4 ontheinteractiveshell.

Solution:

• Type python.

• AtthePythonprompt, enter 3 + 4.

Notes:

• NotethedifferencebetweenbeinginthePythonshellandintheterminalshell.Itislike Inception--shellinsideashell.

• Pythonhasastrongopiniononeverything, includinghowyoushouldexittheshell. Toseethistryexitingtheshellbytyping exit or quit.

Exercise: WhatistheZenofPython?

Solution:

• Type python.

• AtthePythonprompt, enter import this.

Exercise: RunascriptfromthePythonshell.

Solution: YoucanrunaPythonscriptfromthePythonshellusing execfile asfol-lows.

execfile(r'/path/to/script/hello.py')

Notes:

• ComparethedifferencebetweenrunningscriptsfromthePythonshellversusrunningthescriptfromtheterminalorthecmdshell.

Page 17: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 9

4 Numbers

4.1 IntegersandFloating-PointNumbers

ThemostbasicdatatypeinPythonisthenumber. Pythonhasbothintegersaswellasfloatingpointnumbers. Youcanenternumbersliterallyintotheshelltoseetheirvalues.

Exercise: Guessthevaluesandtypesofthesenumberliterals: 123, 0x10, 010, 0, 1.1,1.1e3, 0.0

Solution:

Literal Value Type

123 123 integer

0x10 16 integer

010 8 integer

0 0 integer

1.1 1.1 floating-point

1.1e3 1100.0 floating-point

0.0 0.0 floating-point

Notes:

• Youcandeterminethetypeofavaluebytyping type(123) or type(123.0).

• Thefunction type returnsthetypeasastring.

4.2 Variables

Exercise: Writeaprogramthatdividesarestaurantcheckof$43between3friends.

Solution:

Page 18: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 10

# Divide restaurant check of $43 between 3 people.

persons = 3amount = 43.0amount_per_person = \

amount / personsprint "Amount per person:", amount_per_person

Notes:

• Variablesareslotsinmemorywheredatasuchasnumbersarestored.

• A variableacquiresavalueafteritisassigned.

• The = operatorassignsthevaluefromtherighttothevariableonitsleft. Itslefthandsidecanonlycontainasinglevariable.

• Variablesandnumberscanbecombinedontherighthandsideinarithmeticexpressions.

SyntacticNotes:

• Statementsareexecutedinsequence.

• Statementsendwithnewline.

• Whitespaceandindentationisimportant.

• Statementsmustoccurononeline.

• Ifastatementmustcontinueonthefollowingline, endthelinewitha \.

• Commentsstartwith # andendattheendofline.

• Pythonprograms areminimal and have very little syntactic noise: no semi-colons, no $ beforevariablenames, nomysterioussymbols.

Page 19: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 11

4.3 PythonConventions

• Variablenamesaremadeupofaletterorunderscore, followedbyletters, un-derscores, ornumbers.

• Python convention is to use snake_case rather than camelCase orPascalCase forvariableandfunctionnames.

• Pythonclassnamesuse PascalCase.

• Pythonmodulenameswhicharethesameasfilenamesalsouse snake_case.

• NamingconventionsandstyleguidelinesarediscussedinmoredetailinPEP 8http://www.python.org/dev/peps/pep-0008.

• PEP standsfor PythonEnhancementProposal.

4.4 ArithmeticOperators

WhatarithmeticoperatorsdoesPythonhave?

Expression Result

a + b Adding a and b

a - b Subtracting b from a

a * b Multiplying a and b

a / b Dividing a by b (producesfractionin3.0)

a // b Dividing a by b (integerdivision)

a b Ra ising a tothepower b

a % b Remainderofdividing a by b

Notes:

• Theseoperatorsdon’tchangethevalueofthevariablesintheexpression.

• Theyproduceanewvaluewhichcanbeassignedtoavariable.

Page 20: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 12

• In x = a + b thevalueof a and b arenotchanged. Onlythevalueof x. Onlythevariabletotheleftof = changes.

4.5 AssignmentOperators

Exercise: A large14”pizzaat ExtremePizza costs$14.45. Each topping is$1.70.Supposewewantjalapenos, olives, artichokehearts, andsun-driedtomatoes. Howmuchwillthetotalbe?

Solution1:

crust = 14.45topping = 1.70

price = crustprice = price + topping # jalapenosprice = price + topping # olivesprice = price + topping # artichoke heartsprice = price + topping # sun-dried tomatoes

print "Pizza Price:", price

Notes:

• A variablecanbeassignedtomultipletimes.

• A variablecanrecycleitsownpreviousvalueontheleftof =.

• = isnotmathematicalequality. So price = price + topping isnotaparadox.

• = issimplyassignment.

Solution2:

crust = 14.45topping = 1.70

Page 21: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 13

price = crustprice += topping # basilprice += topping # olivesprice += topping # cilantroprice += topping # pesto

print "Pizza Price:", price

Notes:

• Becausethepattern x = x + a occursalotthereisashort-handforit: x +=a.

• Readthisas: modify x byadding a toit.

• += iscalledanassignmentoperator.

• Itisarelativeof =.

• Ittoochangesthevalueofthevariableonlyonitslefthandside.

Whatarethedifferentassignmentoperators?

Assignment Meaning

a = b Modify a bysettingitto b

a += b Modify a byadding b toit

a -= b Modify a bysubtracting b fromit

a *= b Modify a bymultiplying b withit

a /= b Modify a bydividingitby b

a = b Mo dify a byraisingittothepower b

a %= b Modify a bysettingittotheremainderofdividingitby b

Page 22: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 14

4.6 IncrementingandDecrementing

Exercise: Writethestatementforincrementingthevalueof a by 1.Solution:

a += 1

Exercise: Writethestatementfordecrementingthevalueof a by 1.Solution:

a -= 1

4.7 TipCalculator

Exercise: Writeaprogramthatdividesarestaurantcheckof$43between3friendsandaddsatipaswell.

Solution:

persons = 3amount = 43.0tip_rate = 0.15tip = amount * tip_rateamount_per_person = amount / personstip_per_person = tip / personsamount_per_person += tip_per_personprint "Amount per person:", amount_per_person

5 Strings

5.1 Strings

Besidesintegersandfloating-pointnumbersyoucanalsousestringsasadatatype.Stringrepresenttext.

Stringsaremarkedbydouble-quotesorsingle-quotes. Thesequoteshavethesamemeaning.

Page 23: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 15

message1 = 'Hello'message2 = 'Goodbye'print message1print message2

5.2 Single-QuotesandDouble-Quotes

What’sthedifferencebetweensingle-quotesanddouble-quotes?

• ThereisnodifferenceinPython.

• Youcanencloseasingle-quoteeasilyinadouble-quotedstring, andadouble-quoteinasingle-quotedstring.

• Escape sequences like \n work in both double-quotes, aswell as in single-quotes.

Whatotherescapesequencesarethere?

Sequence Value

\n Newline

\t Tab

\a Bell

\' Single-quote

\" Double-quote

\\ Backslash

Exercise: Print Jim's Garage.

Solution1:

print 'Jim\'s Garage'

Solution2:

Page 24: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 16

print "Jim's Garage"

5.3 RawStrings

Exercise: Print c:\temp\dir\file.txt.

Solution1::

print 'c:\\temp\\dir\\file.txt'

Solution2:

print r'c:\temp\dir\file.txt'

Solution3:

print r"c:\temp\dir\file.txt"

Notes:

• The r prefixbeforethestringturnsitintoarawstring.

• Whatyouseeiswhatyouget.

• Thebackslashesarenolongerescapecharacters. Insteadtheyare justback-slashes.

• Therawstringislikeaziplockbag. Thestringispreservedexactlyasyousaveit.

• Youcanputthe r prefixbeforeasingle-quotedstring, adouble-quotedstring,oratriple-quotedstring. Ithasthesameeffectinallcases.

Page 25: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 17

5.4 TripleQuotes

Pythonalsohastriple-quotesforstringsthatspanmultiplelines.

Exercise: Define usage_text foratipcalculator.

Solution:

usage_text= '''TIP CALCULATOR

USAGEpython tip.py AMOUNT PERSONS TIP_RATE

NOTESPrints out the total amount due per person including tip.'''

Notes:

• Theopening ''' havetobeimmediatelybeforethefirstlinetoavoidablanklineatthebeginning.

• Theclosing ''' havetobeimmediatelyafterthelastlinetoavoidanewlineattheend.

5.5 ConcatenatingStrings

Stringscanbeconcatenatedusingthe + operator.

Exercise: Combineafirstnameandlastnamewithaspaceinthemiddle.

Solution1:

first_name = 'Dmitri'last_name = 'Hayward'full_name = first_name + ' ' + last_nameprint full_name

Solution2:

Page 26: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 18

name = ''name += 'Dmitri'name += ' 'name += 'Hayward'print name

Notes:

• Wecouldhavewritten name += 'Dmitri' as name = name + 'Dmitri'aswell.

• Theassignmentoperator += forstringsmeansmodifythevariableonthelefthandsidebyappendingtheexpressionontherighthandsidetoit.

5.6 ConvertingBetweenNumbersandStrings

Exercise: Convertastring "43.0" toafloating-pointnumber.

Solution:

amount_string = "43.0"amount = float(amount_string)

Exercise: Convertastring "3" toaninteger.

Solution:

people_string = "3"people = int(people_string)

Exercise: Convertanumber 14.33 toastring.

Solution:

amount_per_person = 14.33amount_per_person_string = str(14.33)

Notes:

Page 27: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 19

• Thefunction int convertsalldatatypestointegers.

• Similarly, thefunction float convertsitsinputtofloating-pointnumber.

• Andthefunction str convertanydatatypetoastring.

Exercise: Checkwhathappensifyoucall float("hello").

5.7 StringFormatting

Exercise: Writeaprogramthatdividesarestaurantcheckof$43between3friends.Printtheanswerformattednicelywithadollarsign.

Solution:

persons = 3amount = 43.0amount_per_person = amount / personsprint "Amount per person: ${0}".format(amount_per_person)

Notes:

• The .format functionisappliedtoastringandreturnsastringwhichisprintedby print.

• Wecouldhavesaveditasavariableaswell.

output = "Amount per person: ${0}".format(amount_per_person)print output

Exercise: Trimtheamounttotwodecimalplaces.

Solution:

persons = 3amount = 43.0amount_per_person = amount / personsprint "Amount per person: ${0:.2f}".format(amount_per_person)

Page 28: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 20

Exercise: Whatwillbetheoutputoftheseformatstrings?

print "{0}, {1}, {2}".format("a", "b", "c")print "{1}, {2}, {0}".format("a", "b", "c")print "{2}, {2}, {2}".format("a", "b", "c")

Solution:

a, b, cb, c, ac, c, c

Notes:

• Thenumberintheparenthesesreferstothepositionoftheargumentofformat.

• Youcanuseanargumentasmanytimesasyouwant. Andinanyorder.

5.8 PercentStringFormatting

Exercise: Writeaprogramthatdividesarestaurantcheckof$43between3friends.Printtheanswerformattednicelywithadollarsign.

Solution:

persons = 3amount = 43.0amount_per_person = amount / personsprint "Amount per person: %.2f" % (amount_per_person,)

Notes:

• The % operatorislikethe format function, exceptitusestraditionalC printfformatsyntax.

• ThisisdeprecatedinPython3.0and format isthepreferredwayofformattingoutput.

• However, thisiscommonlyusedandyouwillseethisincodeoften.

Page 29: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 21

5.9 FormatSyntax

Syntax Meaning

"%d %s" % (10, "hello") Substitutevaluesfromtuple

"%(k)d %(k2)s" % {"k1":10, "k2":"hello"} Substitutevaluesfromdictionary

5.10 ConversionSpecifiers

Conversionspecifiersarestringsofform %d and %s. Hereistheirfullsyntax.

• The’%’character, whichmarksthestartofthespecifier.• Optionalmappingkey, ofform (key). Formatargumentisdictionaryinstead

oftuple.• Optional conversionflags (seebelow), whichaffecttheresultofsomeconver-

siontypes.• Minimumfieldwidth(optional). Ifspecifiedas * valuereadfromtuple.• Optionalprecision. Givenas . followedbyprecision. Ifspecifiedas * value

readfromtuple.• Conversiontype (seebelow).

5.11 ConversionFlags

Flag Meaning

# Put 0 beforeoctal, 0X or 0x beforehexadecimal, anddecimalpointinfloatingpointalways

0 Zeropadnumericvalues

- Leftadjustconvertedvalue(overrides 0 conversionifbothgiven)

‘‘ Blankinsertedbeforepositivenumber(oremptystring)

+ Signcharacter(+ or -)precedesconversion(overridesblankflag)

Page 30: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 22

5.12 ConversionTypes

Conversion Meaning

d Signedinteger

i Signedinteger

o Signedoctal

x Signedhexadecimal(lowercase)

X Signedhexadecimal(uppercase)

e Floatingpointexponential(lowercase)

E Floatingpointexponential(uppercase)

f Floatingpoint

F Floatingpoint

g Floatingpoint. Useslowercaseexponentialformatifexponent<-4

G Floatingpoint. Usesuppercaseexponentialformatifexponent<-4

c Singlecharacter

r String(convertsobjectusing repr())

s String(convertsobjectusing str())

% The % character

5.13 NumericConverter

Exercise: Writeaprogramthatconvertsdecimalintegerstooctalandhexadecimal.

Exercise: WriteaprogramthatgeneratesanHTML pagefromtitleandbodystrings.

5.14 FormattingAddendum

Formattingusing .format ismostlylike % formatting. However, therearesomedif-ferences.

Page 31: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 23

http://docs.python.org/2/library/string.html

Pythonintroducesa 0o13 asanewnotationforoctalinPython3.0. "{0:#o}".format(x)outputswiththe 0o prefix. Thismakesoctalsimilartohexadecimalwhichuses 0x.Also 0b isusedforbinary.

5.15 ReadingInput

Exercise: Writeaprogramthatasksauserforhisnameandthensayshellotohimorher.

Solution:

import readlineuser_name = raw_input('What is your name? ')print 'Hello, {0}!'.format(user_name)

Notes:

• Youcanput import readline atthetopofthefile. ThislineenablesUnixreadlineeditingoftheinput.

• InPython3.0 raw_input hasbeenrenamedto input.

5.16 PopulationCalculator

Exercise: EstimatethepopulationofCaliforniain2021. Thepopulationin2012was38,000,000andthegrowthratewas1%. Thepopulationcanbeestimatedas

pop = pop_initial * (1 + growth_rate)**years

Here years isthenumberofyearssince2012, pop_initialisthepopulationin2012.

Solution:

Page 32: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 24

pop_initial = 38 * 1000 * 1000year_initial = 2012year_final = 2021year_count = year_final - year_initialpop_rate = 0.01pop_final = pop_initial * ((1 + pop_rate) ** year_count)print "The population of California in year {0} will be {1:,.0f}".format(

year_final, pop_final)

Notes:

• {1:,.0f} printsafloatingpointnumberwithzerodecimalplacesandwithcommas.

Exercise: Are theparenthesesaround (1 + $pop_rate) ** $year_count re-quired?

Solution:

• Precedencefromhighertoloweris: ** * / + -

• Sostrictlyparenthesesarenotneeded.

• However, it is safer touseparenthesesandnotguessprecendence if it’snotclear.

Exercise: Generalizethisprogramtotakeanyyearasinput.

6 Functions

6.1 CallingFunctions

Exercise: Writeaprogramthatthrowsadice.

Solution1:

Page 33: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 25

import randomdice = random.randint(1,6)print 'The dice was {0}'.format(dice)

Solution2:

from random import *dice = randint(1,6)print 'The dice was {0}'.format(dice)

Solution3:

import random as rdice = r.randint(1,6)print 'The dice was {0}'.format(dice)

Notes:

• import pullsinfunctionsfromotherpackages.

• Besidesbuilt-infunctions, allfunctionsandclassesrequire import.

• Usually import isputatthebeginningofthefile, butitcanoccuranywherebeforethefunctioncall.

• import random importsfunctionsandvariablesintothe random namespace.

• from random import * imports functionsandvariables into thecurrentnamespace.

• import random as r importsfunctionsandvariablesintothenamespace r.Thisisusefulifyouwanttoabbreviatealongnamespacename.

Page 34: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 26

6.2 DefiningFunctions

Exercise: Writeafunctionthattakesanameandreturnsagreeting, andthencallit.

Solution:

name = 'Jim'

def greet(name):greeting = "Hello, " + name + "!"return greeting

print greet(name)print greet('Dmitri')print greet('Alice')print greet('Jim')

Notes:

• Theindentationisimportant. Pythondetermineswherethefunctionendsbasedontheindentation.

• Thefunctionparameter name containsacopyofthevaluethatispassedintothefunctioncall. Ifyoumodify name inthefunctionthatwillnotaffectthecaller’svariablevalue.

• Ifafunctionhasnobodyyoucansimplyput pass init.

• Functionscannotbecalledbeforetheyaredefined.

Exercise: Writetwofunctions. ThefirstconvertsCelsiustoFahrenheit. ThesecondconvertsFahrenheittoCelsius.

Solution:

def c2f(c):f = (c * 9./5.) + 32.return f

Page 35: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 27

def f2c(f):c = (f - 32.) * 5./9.return c

Notes:

• Allvariablesintroducedinthefunctionforexample f and c disappearassoonasthefunctionexits.

• Theydonothaveanyconnectiontovariablesof thesamenameoutsidethefunction.

6.3 VariablesInFunction

Exercise: Verifythatafunctioncannotaffectthevariablesoutsideitsscope.

Solution:

var1 = "hello"

def f(arg1):# New unrelated var1 is created.# New var1 will go away with scope.var1 = "goodbye"

# Arg1 value is overwritten.# Does not affect calling parameter.arg1 = "new"

# Access local var1.print var1

# Call will not change global var1 value.f(var1)

Page 36: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 28

6.4 DefaultArgumentValues

Exercise: Createatipcalculatorfunctionthatassumesadefaulttiprateof15%.

Solution:

def calculate_tip(amount, tip_rate = 0.15):tip = amount * float(tip_rate)return tip

print calculate_tip(10, 0.20)print calculate_tip(10, 0.15)print calculate_tip(10)

6.5 KeywordArguments

Exercise: Createatipcalculatorfunctionthatcalculatesthetotalamountperpersonincludingtip. Itassumesadefaulttiprateof15%andassumesthatbydefaultthereisonlyoneperson.

Solution:

def calculate_tip(amount, persons=1, tip_rate=0.15):tip = amount * float(tip_rate)amount += tipamount_per_person = amount / personsreturn amount_per_person

print calculate_tip(43, 3, 0.15)print calculate_tip(43, persons=3, tip_rate=0.20)print calculate_tip(amount=43, persons=3, tip_rate=0.20)print calculate_tip(amount=43, tip_rate=0.20)print calculate_tip(amount=43, tip_rate=0.20, persons=3)print calculate_tip(tip_rate=0.20, persons=3, amount=43)

Notes:

• Youcancombinepositionargumentsandkeywordarguments.

Page 37: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 29

• However, onceyoustartusingkeywordsargumentsyoucannotgobacktopo-sitionalargumentsinthatfunctioncall.

6.6 MultipleReturnValues

Exercise: Writeafunctionthatpromptstheuserforamount, people, andtiprate, andthenreturnsallthreevalues.

Solution1:

def get_input():amount = float(raw_input('Amount: '))people = int(raw_input('People: '))tip_rate = float(raw_input('Tip Rate: '))return amount, people, tip_rate

amount, people, tip_rate = get_input()

print amount, people, tip_rate

Solution2:

def get_input():amount = float(raw_input('Amount: '))people = int(raw_input('People: '))tip_rate = float(raw_input('Tip Rate: '))return (amount, people, tip_rate)

(amount, people, tip_rate) = get_input()

print amount, people, tip_rate

Notes:

• Ineffectthetwosolutionsareequivalent.

Page 38: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 30

• Inbothcasesthethreevariables amount, people, and tip_rate willgetthevaluestheuserentered.

• UnderthehoodSolution1returnsatuple. Solution2makesthatexplicitbyusingthetuplenotation. Wewilldiscusstuplesinafuturesection.

• Solution1ismoreidiomaticandiscommonlyusedinPythoncode.

6.7 ScopingRules

Python’sscopingrulescanberememberedusingthismneumonic: LEGB.

Scope Meaning

Local Definedinthecurrent def

Enclosed Definedintheenclosing def

Global Definedinthemodule

Builtin Pythonbuiltin

Notethatthismeansthatyoucanoverridebuiltinvariables.

Exercise: Redefine raw_input tothrowanexception.

Solution:

def raw_input(message):raise Exception(

"raw_input: not implemented")

name = raw_input("What is your name? ")print "Hello " + name + "!"

Notes:

• Whenavariable is read it is lookedupfirst in the local scope, and then inenclosed, thenglobal, thenbuiltin. Ifitisnotfoundinanyofthemanerrorisraised.

Page 39: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 31

• Whena variable is assigned to it becomesattached to the scopewhere theassignmenthappens.

• A morelocalvariablecanhidealesslocalvariablewithinitsscope.

• Newscopesareintroducedinfunctiondefinitions.

• Ingeneralafunctioncanreadthevariablesdefinedinouterscopes, butcannotwritetothem.

6.8 Globals

Exercise: Defineamodulevariableusing VERBOSE = True. Thenresetitto Falseinafunctioncalled disableVerbose().

Solution:

VERBOSE = True

def disableVerbose():global VERBOSEVERBOSE = False

disableVerbose()print 'Verbose: ' + str(VERBOSE)

Notes:

• The global keywordputsvariablesinthemoduleorglobalscopewithinthescopeinwhichitisused.

• Withoutthe global keywordthe VERBOSE inside disableVerbose willberedefinedasalocalvariable, andsettingitto False willhavenoeffectontheVERBOSE intheglobalscope.

• If global isusedinthemoduleorglobalscopeithasnoeffect.

Page 40: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 32

6.9 CreatingLibrariesofFunctions

Exercise: Createa util.py fileandthenimportitintoyourprogram.

Solution:

In util.py, type:

def greet():print "Hello, world"

InyourPythonfiletype:

import utilutil.greet()

Notes:

Ifthefileisnotinthesamedirectoryaddtheselinesfirst.

import sysdir = '/path/to/dir-containing-file'sys.path.append(dir)

7 Documentation

7.1 FunctionDocstrings

Youcandocumentafunctionsimplybyinsertingadocumentationstringor docstringimmediatelyafterstartingthefunction.

Exercise: Createahelloworldfunctionthatdocumentsitself.

Solution1:

def hello():'Prints hello world'print "Hello world!"

Page 41: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 33

Solution2:

def hello():'''Prints hello world'''print "Hello world!"

Notes:

• Thetwosolutionshaveidenticaleffect.

• UseSolution2ifyouhavedocumentationthatislongerthanoneline.

Exercise: Use help(hello) toviewthedocumentation.

Exercise: Lookat hello.__doc__ toviewtherawdocstring.

Notes:

• Docstringsareattachedtotheobjectstheyaredefinedwith.

7.2 ModuleDocstrings

Exercise: Add a docstring to util.py. Observe that it is visible in help and as__doc__.

8 Objects

8.1 InteractingwithObjects

Howdoyouinteractwithobjects?

• InPythoneverythingisanobject.

• Hereishowyouinteractwithobjects.

obj.method(arg1, arg2, arg3)

Page 42: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 34

• Everyobjecthasmethodsonit, whicharelikefunctions, excepttheyarespe-cializedtothatobject.

• Forexample, acarandacomputerbothhavea start function, buttheymeanspecificthingsforthatobject.

Whyisthepointofallthis?

• Objectsallowthecodetobemodularandmoreorganized.

• Eachpartofthesystemonlyknowsaboutitself.

• Objectsareintroverts.

• Sochangestoanobject’sinsidesarelesslikelytobreakthesystem.

Exercise: Look at the string functionson thePython console and thenfindawaytouppercaseastring. Youcanfindthefunctionsforanobjectusingthe dir(obj)function.

Exercise: Findoutifastringendswithaquestionmark.

Exercise: Findthe format functiononthestring.

9 GeneratingReports

9.1 FileReadingandWriting

Howcanyouread, write, andappendtoafile?

# Read.f = open('tmp_file.txt', 'r')contents = f.read()f.close()

# Write.f = open('tmp_file.txt', 'w')f.write(contents)

Page 43: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 35

f.close()

# Append.f = open('tmp_file.txt', 'a')f.write(contents)f.close()

Exercise: Writeaprogramthatlogsthecurrentdateandtimeinafilecalled time.log.

Hint: Usethiscodetogetthecurrentdateandtimeasastring.

import datetimetime = str(datetime.datetime.now())

Solution1:

# Get current time.import datetimetime = str(datetime.datetime.now())

# Compose log message.event = 'Program executed'message = time + "\t" + event + "\n"

# Write to log file.log_file = open('tmp.log', 'a')log_file.write(message)log_file.close()

Solution2:

# Get current time.import datetimetime = str(datetime.datetime.now())

# Compose log message.event = 'Program executed'

Page 44: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 36

message = time + "\t" + event + "\n"

# Write to log file.with open('tmp.log', 'a') as log_file:

log_file.write(message)

Notes:

• with isamoreconcisewayofdoingfileoperations.

• with automaticallyclosesthefileaftertheblockofcodeisexecute.

• Thiswayyoudon’thavetoremembertoclosethefile.

• Alsoincaseofanerroryoudon’thavetoworryaboutthefilenotgettingclosed.

• Closingafileisimportantbecause:

– Onwritessometimesthesystembufferstheoutputandwritesittothefilewhenthefileisclosed.

– Sometimesthereisalimitonhowmanyfilescanbeopenatonetime.

Howcanyouread, write, andappendtoafileusing with?

# Read.with open('tmp_file.txt', 'r') as f:

contents = f.read()

# Write.with open('tmp_file.txt', 'w') as f:

f.write(contents)

# Append.with open('tmp_file.txt', 'a') as f:

f.write(contents)

Page 45: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 37

9.2 HTML Report

Exercise: GenerateHTML expensereportfora3-daybusinesstriptoPittsburg, PA.Theairfarewas$512, thehotelwas$63pernight, therentalcarwas$30daily.

Solution:

# Define HTML template.REPORT_TEMPLATE = '''\<h1>Expense Report</h1><table border="1"><tr>

<th>Description</th><th>Amount</th>

</tr><tr>

<td>Airfare</td><td>${0:.2f}</td>

</tr><tr>

<td>Hotel</td><td>${1:.2f}</td>

</tr><tr>

<td>Rental Car</td><td>${2:.2f}</td>

</tr></table>'''

# Calculate amounts.hotel_rate = 63car_rate = 30.0days = 3airfare = 512.0hotel = hotel_rate * dayscar = car_rate * days

Page 46: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 38

# Generate report HTML.report_html = REPORT_TEMPLATE.format(

airfare, hotel, car)

# Save report to file.report_file = 'report.html'with open(report_file, 'w') as f:

f.write(report_html)

Notes:

• Thetemplateislaidoutsoitlooksassimilartotheactualfileaspossible.

• Thetemplateisgeneric.

• Thesametemplatecanbeusedwithdifferentamountvalues.

10 Booleans

10.1 BooleanType

Whatisabooleantype?

• Variablesofbooleantypeholdoneoftwovalues: True or False.

10.2 BooleansFromComparisons

Exercise: GuessthebooleanvalueoftheseexpressionsandthenverifyonthePythonconsole.

# Numeric equality.3 == 33 == 03.0 == 33.00 == 3

Page 47: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 39

3.0 == 3.0

# String equality."hello" == "hello""hello" == "world""hello" == "HELLO"

# Boolean equality.True == TrueFalse == FalseTrue == False

# Inequality.3 != 33 != 4"hello" != "world"

# Numeric ordering.1 < 21 <= 23 >= 43 > 43 >= 3

# String ordering."hello" > "world""hello" < "world""hello" >= "hello""hello" > "0"

# Boolean ordering.True < FalseFalse < True

10.3 ComparisonOperators

Whatarethedifferentcomparisonoperators?

Page 48: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 40

ComparisonOperators IsTrueWhen

a < b a islessthan b

a <= b a islessthanorequalto b

a > b a isgreatthan b

a >= b a isgreatthanorequalto b

a == b a isequalto b

a != b a isnotequalto b

a <> b a isnotequalto b (removedinPython3.0)

a is b a and b pointtothesameobjectinmemory

a is not b a and b pointtodifferentobjectsinmemory

Notes:

• Rememberthat = isassignmentandnotequality. Equalityis ==.

• Everyonetripsonthisseveraltimes.

• Forstrings, thecomparisonsaredoneindictionaryorder.

• Forindividualcharacters, "0" < "A" and "A" < "a"

10.4 ConvertingBooleans

Exercise: Guesswhetherthesecallsto bool(x) produce True or False andthenverifyonthePythonconsole.

# String to boolean.bool("True")bool("true")bool("TRUE")bool("False")

Page 49: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 41

bool("")bool("1")bool("0")

# Numbers to boolean.bool(0)bool(1)bool(2)bool(-1)bool(-2)bool(0.0)bool(1.0)bool(2.0)bool(300.0)bool(-1.0)

# None to boolean.bool(None)

Notes:

• Allstringsaretrue, excepttheemptystringwhichisfalse.

• Thestring "False" istrue. Wrapyourheadaroundthatone.

• Allnumbersconverttotrueexcept 0 and 0.0.

• None isthezeroforobjects. Itisalsofalse.

Exercise: Guesswhatthe str() functiondoesto True and False andthenverifyonthePythonconsole.

Solution:

str(True)str(False)

Notes:

• True and False arecase-sensitive.

• Trytyping true and false intothePythonconsoleandseewhathappens.

Page 50: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 42

10.5 BooleanOperators

Whatarebooleanoperators?

• Pythonprovidesthesebooleanoperators: and, or, not.

• Thesecanbeusedtocombinebooleanvaluestocreatecomplexlogicalexpres-sions.

Exercise: Basedonwhether is_raining and has_umbrella calculatethevalueofshould_eat_out.

Solution:

is_raining = Truehas_umbrella = Falseshould_eat_out = (not is_raining) or has_umbrella

Whatarethedifferentbooleanoperators?

Operator IsTrueWhen

a and b a istrueand b istrue

a or b a istrueor b istrue

not a a isfalse

Notes:

• The and and or operatorsshort-circuit. Chainsof and and or areonlyevalu-atedasfarasneededtodeterminetheirvalue. Forexampleifan and expressioncontainsa False evaluationstopsandtheresultis False. Ifan or expressioncontainsa True evaluationstopsandtheresultis True.

Page 51: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 43

11 ControlFlow: Branching

11.1 IfandElse

Exercise: Writeacoinflippingappthatprints”heads”whenitgetsahead, and”tails”whenitgetsatail. Assume0istailsand1isheads.

Solution:

import random

flip = random.randint(0,1)if flip == 0:

result = "tails"else:

result = "heads"

print "Coin flip:", result

Notes:

• The if/else constructrepresentsabranchin theroad. Theprogramhas tochoosebetweentwodoors: eitherthe if orthe else.

• Iftheconditioninthe if istrueitexecutesthecodeinsidethe if block. Oth-erwiseitexecutesthecodeinthe else block.

11.2 If, Elif, andElse

Exercise: Writeaprogramthatcalculatesalettergradebasedonastudent’sGPA.

Grade GPA Minimum

A 3.5

B 2.5

C 1.5

D 1.0

F 0.0

Page 52: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 44

Solution:

gpa = float(raw_input("Enter GPA: "))

if gpa >= 3.5:grade = "A"

elif gpa >= 2.5:grade = "B"

elif gpa >= 1.5:grade = "C"

elif gpa >= 1.0:grade = "D"

else:grade = "F"

print "Grade: " + grade

Notes:

• The if/elif/else constructrepresentsaforkintheroad.

• Theprogramevaluateseachconditionandtakesthefirstbranchwhosecondi-tionistrue.

• Ifnoconditionistruethenittakesthe else clause.

• The elif andthe else areoptional.

• Soifnoconditionistrue, andthereisno else clausethenitignoresthewholeconstruct.

11.3 If-ElseandBooleanOperators

Exercise: Writeacoinflippingappthatflipsthecointhreetimesanddeclaresawinnerbasedonwhichsidedidbetter.

Solution:

Page 53: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 45

import random

def flip_to_str(flip):if flip == 0:

return "Tails"else:

return "Heads"

# Flip coins 3 times.flip1 = random.randint(0,1)flip2 = random.randint(0,1)flip3 = random.randint(0,1)

# Print result of all coin flips.print \

"Result: " + \flip_to_str(flip1) + ", " + \flip_to_str(flip2) + ", " + \flip_to_str(flip3)

# Figure out which side won.flips = flip1 + flip2 + flip3if flips == 2 or flips == 3:

winner = "Heads"else:

winner = "Tails"

# Print which side won.print "Winner: " + winnerprint "Good job, " + winner + "!"

Notes:

• Insteadofcheckingfor flips == 2 or flips == 3 youcancheckfor flips>= 2.

Page 54: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 46

11.4 If-ElseOperator

Pythonhasanif-elseoperatorforshortconditionalstatements.

Exercise: Createafunctionthatproduces "Heads" ifitispassed 1 and "Tails" ifitispassed 0.

Solution:

def coin_to_string(coin):return "Heads" if coin == 1 else "Tails"

11.5 ValidatingNumericInputs

Exercise: Writefunctionstovalidatestringasvalidnumbers.

Solution1 :

def is_int(x):try:

value = int(x)is_valid = True

except:is_valid = False

return is_valid

amount = raw_input("Amount: ")if not is_int(amount):

print "Amount has to be a number."

Solution2 :

def is_int(x):try:

int(x)except:

return Falsereturn True

Page 55: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 47

amount = raw_input("Amount: ")if not is_int(age):

print "Amount has to be a number."

Notes:

• Thetwosolutionsareequivalent.

• Solution2ismoreconcise.

• Youcanalsocatchtheexceptioninyourcodedirectly.

• Thecodeinthe except blockexecutesonlyifanexceptionisthrown. Other-wiseitisnotrun.

• Assoonasanexceptionoccursthecodeinthe try blockbailsout. Itdoesnotcontinueprocessingstatementsinthatblock.

11.6 CatchingControl-C

Exercise: Writefunctionstovalidatestringasvalidnumbers. EndtheprogramiftheuserpressesControl-C.

Solution: Oneoftheproblemswiththeprevioussolutionsisthattheyeatallexceptionsincludingkeyboardinterrupts. Soitisdifficulttoterminatetheprograms.

def is_int(x):try:

int(x)except Exception as e:

# print type(e)return False

return True

try:amount = raw_input("Amount: ")

except KeyboardInterrupt:

Page 56: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 48

exit(1)if not is_int(amount):

print "Amount has to be a number."

Notes:

• Thefixistocatch KeyboardInterrupt.

• Alsothegenericexceptioniscaughtastype Exception andtheexceptioncanbecapturedinthevariable e. Thisletsyouexamineitstypeincaseadifferentexceptiongetsthrown.

• Discusstheprosandconstocatchingallexceptionsversuscatchingspecificexceptions.

• Youcandeclaretheexceptionvariablein except ifyouneedtousetheinfor-mationfromtheexception.

11.7 ThrowingExceptions

Exercise: Terminateaprogrambythrowinganexception.

Solution:

def die_now():raise Exception("Game over")

Exercise: Writetoafileguaranteeingthatitgetsclosedevenifanexceptionisraisedin write.

Solution1:

f = open("file.txt", "w")try:

f.write("Hello world\n")finally:

f.close()

Page 57: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 49

Solution2:

with open("file.txt", "w") as f:f.write("Hello world\n")

Notes:

• Thecodeinthe finally blockexecutesbothwhenthereisanexceptionandwhenthereisnotanexception. Itisusefulforclosinghandles, andfortakingcareofrequiredcleanup.

• Solution2uses with toautomaticallyclosethefile.

12 ControlFlow: Looping

12.1 LoopingwithWhile

Exercise: Pickanumberfrom1to10andthenprompttheusertoguessit.

Solution:

import randomnumber = random.randint(1,10)guess = -1print "I picked a number."while number != guess:

guess = raw_input("Guess what number I picked: ")guess = int(guess)if number == guess:

print "Yes, you guessed right."else:

print "You were wrong. Try again."

Notes:

• Theprogramkeepsrunningthecodein the while blockuntil theconditionbecomesfalse.

Page 58: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 50

Exercise: Theprogramshouldgivetheuserahintandmentionifthenumberishigherorlower.

Solution:

import randomnumber = random.randint(1,10)guess = -1print "I picked a number."while number != guess:

guess = raw_input("Guess what number I picked: ")guess = int(guess)if number == guess:

print "Yes, you guessed right."elif guess < number:

print "Too low. Try again."else:

print "Too high. Try again."

Exercise: Rewritetheprogramasaninfiniteloop. Terminatetheprogramwhentheuserguessescorrectlyorwhentheusertypes q.

Solution:

import randomnumber = random.randint(1,10)print "I picked a number."while True:

guess = raw_input("Guess what number I picked: ")if guess == "q":

breakguess = int(guess)if number == guess:

print "Yes, you guessed right."break

elif guess < number:print "Too low. Try again."

else:print "Too high. Try again."

Page 59: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 51

Notes:

• Use break tobreakoutofaloopearly.

• Use continue tostartfromthebeginningoftheblockagain.

• With the while statementwearenowcapableof lockingupamachinebycreatingaloopthatneverterminates.

12.2 LoopingwithFor

Exercise: Printthesquaresofthenumbersfrom0through19.

Solution1:

i = 0while i < 20:

square = i ** 2print "square of {0} = {1}".format(

i, square)i += 1

Solution2: Loopsforgoingthroughsequencesofnumbersaresocommonlyusedthatthereisaspecialconstructforit: the for loop.

for i in range(20):square = i ** 2print "square of {0} = {1}".format(

i, square)

Solution3: xrange isjustlike range exceptitproducesalazysequenceinsteadofalist.

for i in xrange(20):square = i ** 2print "square of {0} = {1}".format(

i, square)

Page 60: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 52

Notes:

• xrange useslessmemorythan range.

Exercise: Rewrite thetipcalculatorwithinputvalidation. Incasetheusersubmitsinvalidinputuseawhilelooptokeeppromptingtheuserforvalidinput. Theloopcanendwhentheusersubmitsvalidinput.

Exercise: WriteanN-diceappwhichrollsN dice, X times, andthenreportsthetotalandaveragedicevalue.

Exercise: Writeabot. Whenitseesaquestionitsays”I don’tknow.”Andwhenitseesastatementitshouldsay, ”I totallyagree.”

13 Collections

13.1 DefiningLists

Exercise: PrintthelistofcountiesintheSanFranciscoBayArea.

Solution:

# Build a list.counties = [

"Alameda County","Contra Costa County","Marin County","Napa County","San Francisco County","San Mateo County","Santa Clara County","Solano County","Sonoma County",

]

# Loop through the list.for county in counties:

print county

Page 61: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 53

13.2 AccessingListElements

Exercise: Yahoo! provideshistoricalstockdataasCSV.Hereisasampleline.

Date,Open,High,Low,Close,Volume,Adj Close2013-03-28,23.63,23.77,23.45,23.53,17611900,23.53

Writeaprogramthatprintsthedateandtheclosingprice.

Solution:

# Date,Open,High,Low,Close,Volume,Adj Closeline = "2013-03-28,23.63,23.77,23.45,23.53,17611900,23.53"fields = line.split(',')date = fields[0]close = fields[4]print "Date: " + dateprint "Close: " + close

Notes:

• TheYahoodataisavailablefromthisURL http://finance.yahoo.com/q/hp?s=YHOO.

• The .split(',') functionwhichappliestostringobjects, splitsthestringtocreatealist.

• Hereishowyousplitastringoncommas.

tokens = string.split(',')

• Listindexingiszero-based.

• Thei-thelementofthelistisaccessibleas fields[i]

13.3 ListSurgery

Exercise: Whatarethedifferentwaysofaccessingelementsinthelist?

Solution:

Inthefollowing i isapositiveintegeror 0.

Page 62: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 54

Expression Meaning

list[0] Firstelementof list

list[1] Secondelementof list

list[i] i+1thelementof list

list[-1] Lastelementof list

list[-i] ith-lastelementof list

list[1:3] Sublistof2ndand3rdelementsof list

list[0:2] Sublistoffirst2elementsof list

list[:2] Sublistoffirst2elementsof list

list[2:] Sublistoffirst3rdandfollowingelementsof list

13.4 CreatingLists

Whatarethedifferentwaysofcreatingalist?

• Youcandefinealistdirectly.

words = ["a","b","c"]

• Youcangetalistfromafunctionlike .split().

words = "a b c".split(' ')

• Youcanappendtoanexistinglist.

words = []words.append("a")words.append("b")words.append("c")

Page 63: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 55

13.5 ListOperations

Whataresomeusefuloperationsavailableonalist?

• Hereishowyougetasortedlistfromanunsortedlist.

sorted_words = sorted(words)

• Hereishowyousortalist. Thischangesthelistitself.

words.sort()

• Hereishowyoureversealist.

words.reverse()

• Hereishowyoufindthelengthofalist.

print len(words)

Exercise: Generateasequenceof20randomnumbersfrom1through10, storetheminalist, calculatetheiraverage, minimum, andmaximum, andprintthemout.

Solution:

import randomnumbers = []for i in range(20):

numbers.append(random.randint(1,10))average = float(sum(numbers)) / len(numbers)print "Avg: " + str(average)print "Min: " + str(min(numbers))print "Max: " + str(max(numbers))

Page 64: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 56

13.6 CommandLineArguments

Exercise: Writea tipcalculator that takes theamount, people, and tip rateon thecommandline.

Hint:

import sysscript_name = sys.argv[0]amount = float(sys.argv[1])people = int(sys.argv[2])tip_rate = float(sys.argv[3])

Notes:

• sys.argv[0] containsthenameofthescript.

• sys.argv[1] containsthefirstargument, sys.argv[2] containsthesecondargument, andsoon.

13.7 SequencesandFunctions

Expression Meaning

len(seq) Numberofelementsin seq

sorted(seq) Sortedcopyof seq

sorted(seq,f) Sortedcopyof seq sortedaccordingto f

reversed(seq) Reversedcopyof seq

map(f,seq) Copyof seq with f appliedtoeachelement

filter(f,seq) Subsequenceof seq containingelementsforwhich f istrue

seq[i] ithelementof seq

seq[i:j] Subsequenceof seq from i until j-1

seq[i:] Subsequenceof seq from i untiltheend

Page 65: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 57

seq[:j] Subsequenceof seq fromthebeginningto i-1

seq[:] Copyof seq

list1 + list2 Copyofconcatenationof list1 and list2

list1 * n n copiesof list1 concatenatedtogether

str1 + str2 Copyofconcatenationof str1 and str2

str1 * n n copiesof str1 concatenatedtogether

Exercise: Createaprogramthatasksauserforanumberandthenprintsabirthdaycakewiththatmanycandles.

13.8 Lambda

Exercise: Createaonelinefunctionthatreturnstrueifanumberiseven.

Solution:

is_positive = lambda x: x % 2 == 0

Notes:

• Lambdaprovidesasimplewayofcreatinganonymousone-linefunctions.

• Theyareparticularlyusefulwith functions that takeother functions as argu-ments, suchas map, filter, andsort.

Exercise: Listalltheevennumbersbetween0and100.

13.9 Map

Exercise: Writeafunctionthatsquaresalistofnumbers.

Solution:

def square(list):map(lambda x: x*x, list)

Page 66: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 58

13.10 Filter

Exercise: WriteaprogramthatasksforahostnameandprintsoutitsIP addressusingnslookup.

Solution1:

import os

hostName = raw_input("Host: ")output = os.popen('nslookup ' + hostName).read()output_lines = output.split('\n')

addresses = []for line in output_lines:

if line.startswith('Address:'):addresses.append(line)

key,value = addresses[-1].split(' ')print value

Solution2:

import os

hostName = raw_input("Host: ")output = os.popen('nslookup ' + hostName).read()output_lines = output.split('\n')

addresses = filter(lambda line: line.startswith('Address:'),output_lines)

key,value = addresses[-1].split(' ')print value

Notes:

Page 67: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 59

• Solution1usesthetraditionalloopandifconstruct.

• Solution2uses filter.

13.11 Dictionaries

Exercise: ConvertthefinancialdatainCSV formatintoadictionarymappingcolumnnamestovalues. Thenprintoutthedateandtheclose.

Date,Open,High,Low,Close,Volume,Adj Close2013-03-28,23.63,23.77,23.45,23.53,17611900,23.53

Solution:

# Date,Open,High,Low,Close,Volume,Adj Closeline = "2013-03-28,23.63,23.77,23.45,23.53,17611900,23.53"row = line.split(',')record = {

"date" : row[0],"open" : row[1],"high" : row[2],"low" : row[3],"close" : row[4],"volume" : row[5],"adj" : row[6],

}

print "Date: " + record['date']print "Close: " + record['close']

Notes:

• Hereishowyoudefineadictionary.

d = {"key1" : "value1","key2" : "value2","key3" : "value3",

}

Page 68: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 60

• Hereishowyoureadavaluefromadictionary.

print d["key1"]

• Hereishowyouaddanewvaluetoadictionary.

d["key4"] = "value4"

• Hereishowyouupdateavalueinadictionary.

d["key1"] = "new-value1"

• Hereishowyoufindthelengthofadictionary.

print len(d)

• Hereishowyoucheckifakeyexists.

"key1" in d

• Hereishowyoudeleteakeyfromadictionary.

del d["key1"]

• Hereishowyouloopthroughadictionary.

for key in d.keys():print d[key]

13.12 Tuples

Herearesomeexamplesofhowtocreatetuples. Tuplesarejustlikelists, excepttheyareimmutable.

# Defining tuplest1 = (1,2,3)t2 = 1,2,3print t1print t2

Page 69: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 61

# Emptyt3 = ()print t3

# Singletont4 = (1,)print t4

# Tuple unpackinga,b,c = t1print a,b,c

Exercise: Writeafunctionthatfindsthedistancebetweentwopointsrepresentedattuples. Testthefunction.

13.13 TuplesvsListPerf

• Hereishowtomeasuretheperformancefortupleversuslistcreation.

/Users/asimjalis> python -m timeit "x=[1,2,3,4,5,6,7,8]"1000000 loops, best of 3: 0.244 usec per loop/Users/asimjalis> python -m timeit "x=(1,2,3,4,5,6,7,8)"10000000 loops, best of 3: 0.0328 usec per loop

• Hereishowtomeasuretheperformancefortupleversuslistaccess.

/Users/asimjalis> python -m timeit -s "x=(1,2,3,4,5,6,7,8)" "y=x[3]"10000000 loops, best of 3: 0.07 usec per loop/Users/asimjalis> python -m timeit -s "x=[1,2,3,4,5,6,7,8]" "y=x[3]"10000000 loops, best of 3: 0.054 usec per loop

• -s takesasetupstatementwhichisexecutedonce.

• Hereishowtomeasuretheperformanceofafunctioncalled func inthe Fooclassinyourcode.

python -m timeit -s "import mylib1, mylib2; a = Foo()" "a.func()"

Exercise: Measuretheperformanceofusing .format versus % forformatting.

Page 70: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 62

13.14 Sets

Exercise: Createsetofengineers, programmers, managers. Definethesetofengineer-ingmanagementandfull-timemanagement. Printallthesetsout.

Solution:

# Define setsengineers = { 'John', 'Jane', 'Jack', 'Janice' }programmers = { 'Jack', 'Sam', 'Susan', 'Janice' }managers = { 'Jane', 'Jack', 'Susan', 'Zack' }

# Unionemployees = engineers | programmers | managers

# Intersectionengineering_management = engineers & managers

# Differencefulltime_management = managers - engineers - programmers

# Add elementengineers.add('Marvin')print engineers

# Superset testemployees.issuperset(engineers)

# Updateemployees.update(engineers)employees.issuperset(engineers)

# Remove elementfor group in [engineers, programmers, managers, employees]:

group.discard('Susan')print group

# Alternative syntax for defining sets.engineers2 = set(['John', 'Jane', 'Jack', 'Janice'])

Page 71: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 63

13.15 SetSyntax

Expression Meaning

{ "e1", "e2", "e3" } Createaset

set([ "e1", "e2", "e3" ]) Createaset

a & b Setofelementsinboth a and b (intersection)

a | b Setofelementsineither a or b (union)

a - b Setofelementsin a butnotin b

k in a Element k isinset a

Exercise: Createaprogramthatchecksifanaddressislocalhost.

Hint: Createasetofvariationsof localhost (localhost, 127.0.0.1), andcheckuserinputagainstit.

14 OperatingSystem

14.1 SystemEnvironment

Exercise: Printthe HOME directory.

Hint: ThesystemenvironmentisavailableinPythonasadictionary.

Solution:

import osprint os.environ['HOME']

Exercise: Printthecontentsof os.environ.

Exercise: Getthe PATH variable, thensplititintoalist, andprintitoutonepathperline.

Page 72: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 64

14.2 RunningShellCommands

Exercise: Runthepingcommandandprintitsoutput.

Solution1: OnMacandUnixrunpingwiththe -c 1 option. Thiswillpingtheserveronce.

import subprocessoutput = subprocess.check_output('ping -c 1 google.com', shell=True)print output

Solution2: OnWindowsthe -c optionisnotsupported. Sorunthiscommandwiththe -c 1 option.

import subprocessoutput = subprocess.check_output('ping google.com', shell=True)print output

Notes:

• check_output returnstheoutputoftheshellcommand.

• Iftheshellcommandfails, check_output willthrowanexception.

14.3 OtherProcessConstructs

Exercise: Runaprocesswithoutcapturingoutput.

Solution:

os.system("echo 'hello world'")

os.system("echo 'hello world' > /dev/null")

Exercise: Runaprocessandcapturetheoutputanderror.

Solution1:

Page 73: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 65

# Stdout can be captured.print os.popen("echo 'hello world'").read()

# Stderr not captured.print os.popen("bad 'hello world'").read()

# Capture stderr by combining with stdout.print os.popen("bad 'hello world' 2>&1").read()

Solution2:

import subprocess

proc = subprocess.Popen("bad 'hello world'",stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)

print proc.stdout.read()print proc.stderr.read()

15 Third-PartyModules

15.1 PipvsEasy_Install

Whatare pip and easy_install?

• Therearetwowaysofinstallingpackages: pipandeasy_install.

• Pipisthe”newhotness”andisrecommended.

• Ithasbetterdocumentationandrecoversinmorecases.

• Theseprogramsgrab themodulesyouwantandall theircorrectly-versioneddependencies.

• Soyoucanbelikeakidinacandystore. Whateveryoupointatisyours.

Page 74: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 66

Whatis PyPI?

• PyPI isthePythonPackageIndex.

• Itisacollectionoflibrariesthatyoucandownloadusingpip.

• TobrowsePyPI goto https://pypi.python.org andclickon BrowsePack-ages.

15.2 WindowsPipInstall

Exercise: InstallpiponWindows.

Solution:

• Installsetuptoolsfrom http://www.lfd.uci.edu/~gohlke/pythonlibs/#setuptools

• Installpipfrom http://www.lfd.uci.edu/~gohlke/pythonlibs/#pip

• IneachcasemakesureyoupicktheversionthatmatchesyourprocessorandtheversionofPythonthatyouareusingonyourmachine.

• Pipshouldgetinstalledinalocationsimilarto C:\Python27\Scripts\pip.exe.Youcaneitheraddthe Scripts foldertoyourPATH orrunitdirectlyfromthislocation.

15.3 Unix/MacPipInstall

Exercise: InstallpiponUnixorMac.

Solution:

sudo easy_install pip

Page 75: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 67

15.4 Demjson

Exercise: Install demjson.

Solution:

• CheckthatitisnotinstalledbytypingthisinthePythonconsole.

import demjson

• Lookatpip’sdocumentation.

pip help

• Findfullnameof demjson.

pip search demjson

• Install demjson.

sudo pip install demjson

• OnWindowsyouwon’tneed sudo butyoumightneedtoruninacmdconsolewindowthatisrunningasadministrator.

• Checkthatthemoduleisinstalled. Thisshouldnownotthrowerrors.

import demjson

• Youcanuse demjson toconvertPythondatastructurestoJSON strings.

import demjsonrecord = {

"date" : "2012-10-10","open" : 10,"close" : 11,

}json = demjson.encode(record)print json

Page 76: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 68

• YoucanalsouseittoconvertJSON stringstoPythondatastructures.

import demjsonjson = '[1, 2, 3, 4]'data = demjson.decode(json)print data

15.5 IPython

Exercise: InstallIPython.

Solution:

sudo pip install ipython

# Optional for autocompletesudo pip install readline

Notes:

• Ifpipinstallfailstryinstallingipythonandreadlinewitheasy_install.

• IPythongivesyouautocomplete.

• Itprettyprintsthedatastructures.

• Also itprovidesaneatworkflowwhere itautomatically reloadsall themod-ules for you each time you call a function. See http://ipython.org/ipython-doc/dev/config/extensions/autoreload.html fordetails.

Exercise: EnableautoreloadinIPython.

Solution:

%load_ext autoreload%autoreload 2

Notes:

• Testthisoutbyimportingamodule, invokingafunctiononit, andthenchangingthemodule.

Page 77: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 69

15.6 WebServices

Exercise: FindouthowmanyUS dollarsareinaBritishpound, usingthisJSON webservice http://www.google.com/ig/calculator?hl=en&q=1GBP=?USD.

Solution:

import urllib2import demjson

url = 'http://www.google.com' \+ '/ig/calculator' \+ '?hl=en&q=1GBP=?USD'

json = urllib2.urlopen(url).read()data = demjson.decode(json)dollars = data['rhs'].split(' ')[0]dollars = float(dollars)print "1 GBP = {0} USD".format(

dollars)

Notes:

• urllib2.urlopen(url).read() gets thecontentsat url andisasimplewaytoaccesswebservices.

• Pythonshipswithajsonencoderanddecoderaswell. Hereisanexampleofhowtouseit.

import json

# Convert JSON to Python data.data = json.loads('{"a" : 1, "b" : 2}')print type(data)print data

# Convert Python data to JSON.json = json.dumps({"a" : 1, "b" : 2})print type(json)print json

Page 78: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 70

• However, demjsonismoreresilientinthefaceofbadorlazyinput.

• Forexample, Python’sjsonmodulefailsiftheJSON usesunquotedkeys, whiledemjsonisabletoparsethiscorrectly.

16 Objects

16.1 DefiningObjects

Exercise: Createanobjectthatsplitsrestaurantbills.

Solution:

class CheckSplitter:

def __init__(self, tip_rate):self.tip_rate = tip_rate

def split(self, amount, people):amount = \

amount + amount * self.tip_ratesplit_amount = amount / float(people)return split_amount

check_splitter = CheckSplitter(0.15)split_amount = check_splitter.split(43, 3)print "Split amount: ${0:.2f}".format(split_amount)

Notes:

• CheckSplitter isa class, and check_splitter isan object oran instance.

• Classesare likePlatonic ideals. Andobjectsor instancesare their concretemanifestations.

• Objectsarelikefunctions. Excepttheyhavememory. Theyrememberstate.

Page 79: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 71

• Forexample, check_splitter holdsapermanentmemoryof tip_rate. Itkeepsthisinside self.tip_rate.

• Objectfunctionsareknownasmethods.

• Withinamethodtheparametersandlocalvariablesareaccessedjustlikeinnormalfunctions, withtheirnames.

• Withinamethodinstancevariables(forexmaple tip_rate)areaccessedusingself.tip_rate.

NamingConventions:

• Classnamesstartwithupper-caseletters. Objectnamesstartwithlower-caseletters.

• Classnamesarespelledwithmixedcaseinsteadofunderscores. Objectandmethodnamesarespelledusingunderscores.

16.2 WhyObjects

Whyuseobjects?

• Thinkofobjectsassmallblackboxesinsideaprogramthathavesomeinternalstate.

• Youcanuseanobjecttodousefulthingswithoutunderstandinghowitisdoingthem. Itislikeaprogramwithinaprogram.

• Objectswerefirstinventedinsimulationsoftware.

• Intuitivelytheyarelikeobjectsinreallife.

• Whenyouapproachalargeproblemyoucandivideitintoobjectsandmakeiteasiertosolve.

• Objectsformakindofknowledgebarrier. Theyknownothingabouthowtheyarebeingused. Andthecallerknowsnothingabouthowtheobjectisdoingwhatitisdoing.

Page 80: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 72

• Theyhaveaminimalcontract--definedbythemethods.

Thisisgreat. Butwhyhaveobjects?

• Objectsmakeiteasierforhumanstothinkaboutprograms.

• Objectsareawayofbreakingupthecomplexlogicofaprogramintosmallbite-sizedpieces.

• Computershavenoneed forobjects. Theyareperfectlyhappy if thewholeprogramwasonebigfilewithnofunctionsorobjects.

Whyisthedifferencebetweenfunctionsandobjects? Whycan’tweusefunctionstobreakupaprogramintopieces?

• Functionshavenostate. Theyhavenomemoryofwhatjusthappened. Theyareusefulforstate-lesscomputations.

• Whenyouwantcomputationswithstateyouneedobjects.

• Bothfunctionsandobjectsmakeiteasiertotestapplications.

16.3 Inheritance

Python supports inheritance. However, it is generallynotusedverymuch. Sinceeverythingisanobjectitiseasyparameterizeonclassfunctionstoachievethesameeffect.

However, inheritance isuseful in frameworks to indicatea relationship. Also it isusefulforbuildinguphierarchiesofexceptions.

Exercise: CreateasubclassofExceptioncalled AppError forcustomerapplicationexceptions.

Solution:

class AppError(Exception):def __init__(self, message):

super(AppError, self).__init__(message)

Page 81: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 73

Notes:

• Youcantestthisusing raise AppError('hi') andthenobservingtheex-ceptiongettingthrown.

16.4 ImplicitMethods

Pythonobjectshavesomespecialmethodsthatcanbeoverriddentochangethebe-havioroftheunderlyingclass.

Exercise: Createa Point objectwithtwofields, x and y. Changetheobjectsothatstr(p) displaysthecoordinatesofthepoint.

Hint: Overridethe __str__ methodoftheobject.

Exercise: Createageneralsolutionthatworksforanyobject.

Hint: Usethe __dict__ propertyinthe __str__ method.

16.5 StrandLen

Functionslike str and len relyonimplicitfunctionsattachedtoallobjects.

Exercise: Cleanuptheoutputof str of Point byreturning str(self.__dict__).

Exercise: Make len returnthedistanceofapointfromtheorigin.

16.6 StrvsRepr

__repr__ isthestringthatisusedintheconsolewhenyouinspectanobject.

• __repr__ goalistobeunambiguous

• __str__ goalistobereadable

• Container’s __str__ usescontainedobjects’ __repr__

• If __repr__ isprovideditisalsousedfor __str__

• If __str__ isprovideditisnotusedfor __repr__

Page 82: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 74

Notes:

• A commonoutputfor __repr__ is

"%s(%r)" % (self.__class__, self.__dict__)

• Pythondoesnotdothisbydefaultbecauseitcouldleadtoinfiniterecursion.

16.7 OperatorOverloading

Exercise: Allowtwopointstobeaddedtocreateathirdpoint.

Hint: Overridethe __add__(self, new_point) method.

Operator Function

a + b a.__add__(b)

a * b a.__mul__(b)

a & b a.__and__(b)

a | b a.__or__(b)

Exercise: Define * tocomputethedot-productofthetwovectorscorrespondingtothepoints.

Exercise: Define * tocomputethedot-productif theotherelementisapoint, andscalethepointifitisan int ora float.Hint: Usethesemethodcallstofigureoutthetypeof p:

instanceof(p, Point)instanceof(p, int)instanceof(p, float)

16.8 NewStyleandOldStyleObjects

Youwillnoticethat type doesnotworkonobjectsoftype Point. Thereisawaytofixthis.

Page 83: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 75

Exercise: Make type workwith Point.

Solution:

• Declare Point as class Point(object) insteadof class Point.

• Python2.*hastwokindsofobjects: old-styleobjectsandnew-styleobjects.

• Ifyouinheritfrom object yougetnew-styleobjectsthatworkwith type. Oth-erwiseyougetold-styleobjectsthatdon’tworkwithtype.

• Python3cleansupthisareaandgivesyouthesamekindofobjectregardlessofhowyoudeclareyourclass.

16.9 OperatorPrecedence

Operatorshavefixedprecedencedescribedbythefollowingtable.

Description Operator

Lambdaexpression lambda

Conditionalexpression if – else

BooleanOR or

BooleanAND and

BooleanNOT not x

Comparisons in, not in, is, is not, <, <=, >, >=, <>, !=, ==

BitwiseOR |

BitwiseXOR ˆ

BitwiseAND &

Shifts <<, >>

Additionandsubtraction +, -

Multiplication, division, remainder *, /, //, %

Positive, negative, bitwiseNOT +x, -x, ~x

Page 84: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 76

Exponentiation[9] **

Arrayandobjectaccess x[index], x[index:index], x(arguments...), x.attribute

Tuple, list, dictionary (a,b,c), [a,b,c], {key: value}

17 RegexandWebScraping

17.1 Regex

Exercise: ThisistheresponsefromCraigslistonsearchingforPythonjobs. Extractthenumberinthestring.

'>found 524 postings<'

Solution:

import retext = '>found 524 postings<'found = re.findall(r'>found (\d+)', text)count = int(found[0])

Notes:

• Thefirstargumentto findall isaregularexpression.

• findall returnsalistcontainingjust 524.

• Withoutparenthesesintheregular findall wouldreturntheentirestring.

• Whatwill re.findall(r'\d+', input) return?

Page 85: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 77

17.2 SpecialCharacters

Character Matches

. Anycharacterexceptanewline

ˆ Startofstring

$ Endofstringorjustbeforenewlineatendofstring

X* 0ormore(greedy)repetitionsofX

X+ 1ormore(greedy)repetitionsofX

X? 0or1(greedy)ofX

X*?,X+?,X?? Non-greedyversionsofpreviousspecialcharacters

X{m} m repetitionsofX

X{m,n} From m to n repetitionsofX

X{m,n}? Non-greedyversionofabove

X{m,} m ormorerepetitionsofX

X{m,}? Non-greedyversionofabove

X{,m} m orfewerrepetitionsofX

X{,m}? Non-greedyversionofabove

\\ Backslash

[abcd] a through d

[a-z] Lowercaseletters

[-a-z] Hyphenandlowercaseletters

[A-Z] Uppercaseletters

[a-zA-Z] Lowercaseanduppercaseletters

[ˆa-d] Not a through d

X|Y Either X or Y

(X) Match X andcaptureinregister 1, 2 etc.

(?iLmsux) SettheI,L,M,S,U,orX flagfortheRE

Page 86: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 78

Exercise: Writearegexthatmatchesaninteger.

Exercise: Writearegexthatmatchesafloatingpointnumber.

Exercise: WritearegexthatmatchesanXML tag.

17.3 AdvancedSpecialCharacters

Character Matches

(?:X) Match X withoutcapturingit

(?P<foo>X) Match X andcaptureinregister foo

(?P=foo) Matchvalueinregister foo

(?#comment) A comment; ignored

(?=X) Matchesif X matchesnext, withoutconsumingstring

(?!X) Matchesif X doesn’tmatchnext

(?<=X) Matchesifprecededby X (mustbefixedlength)

(?<!X) Matchesifnotprecededby X (mustbefixedlength)

(?(foo)X|Y) Matches X if foo wascaptured, matches Y otherwise

(?(1)X|Y) Matches X if 1 wascaptured, matches Y otherwise

Exercise: Writearegexthatmatchesall q followedbya u. Thenwriteonethatfindsall q notfollowedbya u.

17.4 SpecialSequences

Sequence Matches

\1 Contentsofregister 1

\12 Contentsofregister 12

\g<1> Contentsofregister 1 (onlyinreplacement)

Page 87: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 79

\g<foo> Contentsofregister foo (onlyinreplacement)

\A Startofstring

\Z Endofthestring

\b Iswordboundary

\B Isnotwordboundary

\d Decimaldigitcharacter; equivalentto [0-9]

\D Complementof \d

\s Whitespacecharacter; equivalentto [ \t\n\r\f\v]

\S Complementof \s

\w Alphanumericcharacter; equivalentto [a-zA-Z0-9_]

\W Complementof \w

\\ Literalbackslash

Exercise: Writearegexthatmatchesanemailaddress.

17.5 RegexFunctions

Function Meaning

match() Returnmatchobjectifpatternoccursatbeginningofstring

search() Returnmatchobjectifpatternoccursanywhereinstring

sub() Substitutepattern, returnnewstring

subn() Substitutepattern, returnnewstring, substitutioncount

split() Splitstringbyoccurrencesofpattern

findall() Returnlistofpatternoccurrences

finditer() Returniteratorofmatchobjects

compile() Compilepatterninto RegexObject

purge() Clearregexcache

escape() Backslashescapeallnon-alphanumericsinpattern

Page 88: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 80

Function Signature

match() match(pattern, string, flags=0)

search() search(pattern, string, flags=0)

sub() sub(pattern, repl, string, count=0, flags=0)

subn() subn(pattern, repl, string, count=0, flags=0)

split() split(pattern, string, maxsplit=0, flags=0)

findall() findall(pattern, string, flags=0)

finditer() finditer(pattern, string, flags=0)

compile() compile(pattern, flags=0)

purge() purge()

escape() escape(pattern)

Notes:

• Youcanaccesscaptureregistersusing m.group(1) and m.group('foo')

• Here m isthematchobjectreturnedby match, search, and finditer.

17.6 RegexFlags

Short Long Meaning

I IGNORECASE Usecase-insensitivematching.

L LOCALE Uselocalefor \w, \W, \b, \B

S DOTALL . matchesallcharactersincludingnewline.

M MULTILINE ˆ matchesbeginningofeachlineandstring

$ matchesendofeachlineandstring

X VERBOSE Ignorewhitespaceandcomments

U UNICODE UseUnicodelocalefor \w, \W, \b, \B

Page 89: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 81

17.7 RegexExercises

Exercise: Writeagrep-likeprogramthatprintseachlineinitsinputfilesthatcontainsaregexmatch.

Exercise: Writeased-likeprogramthattakesapattern, replacement, andalistoffiles,andprintsouttheresultafterthereplacements.

17.8 WebScraping

Exercise: WriteaprogramthattakesakeywordandreturnsthenumberofjobsonCraigslistcontainingthatkeyword.

Solution:

import reimport urllib2

keyword = 'python'

# Compose the URL.url = 'http://sfbay.craigslist.org' + \

'/search/jjj?query=' + keyword

# Get contents.contents = urllib2.urlopen(url).read()

# Extract count.found = re.findall(r'>found (\d+)', contents)count = int(found[0])

# Print result.print '{keyword} jobs: {count}'.format(

keyword=keyword, count=count)

Exercise: Writeaprogram that takesa listofkeywordson thecommand lineandgeneratesareport

Solution:

Page 90: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 82

import reimport urllib2import sys

for keyword in sys.argv[1:]:url = 'http://sfbay.craigslist.org' + \

'/search/jjj?query=' + keywordcontents = urllib2.urlopen(url).read()found = re.findall(r'>found (\d+)',

contents)count = int(found[0])

print '{keyword} jobs: {count}'.format(keyword=keyword, count=count)

Exercise: WritethesameprogramanddisplaytheresultsinanHTML page.

Solution: ThisprogramwilloutputHTML.Tosaveittoafileredirectitwhenrunningitusing python program.py > output.html.

import reimport urllib2import sys

# Check args.program = sys.argv[0]if len(sys.argv) <= 1:

print 'Craiglist SF Job Tracker'print 'Usage: ' + program + ' ' + \

'KEYWORD1 [KEYWORD2] ... > OUT.HTML'sys.exit(1)

# Print heading.print '<h1>SF Jobs By Keywords</h1>'

# Print table header row.print '<table border="1">'print '<tr>'

Page 91: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 83

print '<th>Keyword</th>'print '<th>Jobs</th>'print '</tr>'

# Find jobs for all languages.for keyword in sys.argv[1:]:

# Get keyword count from Craigslist.url = 'http://sfbay.craigslist.org' + \

'/search/jjj?query=' + keywordcontents = urllib2.urlopen(url).read()found = re.findall(r'>found (\d+)',

contents)count = found[0]

# Print row.print '<tr>'print '<td>' + keyword + '</td>'print '<td>' + count + '</td>'print '</tr>'

# End table.print '</table>'

18 CSV Files

18.1 ReadingCSV Files

Exercise: CreateaprogramthatreadsandprintshistoricalstockpricedataforAppleavailableasCSV fromYahoo!.

Solution1:

Tofindout thehistoricalprices forApple (AAPL) go to http://finance.yahoo.com/q/hp?s=AAPL. Onthebottomofthepageclickon DownloadtoSpreadsheet.Savethisas table.csv.

In demo.py:

Page 92: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 84

# Read CSV rows as lists.import csvwith open('table.csv', 'rb') as csvfile:

reader = csv.reader(csvfile)for row in reader:

print row

Solution2:

SetupthefilethesameasSolution1. ThiswillreadtheCSV fileasasequenceofdictionaries.

# Read CSV rows as dictionaries.import csvwith open('table.csv', 'rb') as csvfile:

reader = csv.DictReader(csvfile)for row in reader:

print row

18.2 WritingCSV Files

Exercise: CreateaCSV filecontainingthefollowingsalesdata: wehadsalesof$300,$350, $250ondays1, 2, 3.

Solution1:

In demo.py:

import csv

# Define sales data.sales_data = [

{ "day" : 1, "sales" : 300 },{ "day" : 2, "sales" : 350 },{ "day" : 3, "sales" : 250 },

]

# Write CSV file.

Page 93: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 85

import csvwith open('output.csv', 'wb') as f:

writer = csv.DictWriter(f,fieldnames=('day','sales',))

writer.writeheader()writer.writerows(sales_data)

Notes:

• Thecommand writer.writeheader() willputaCSV headeronthefile.

• Thecommand writer.writerows() willoutput the sales_data asCSVintothefile.

Solution2:

In demo.py:

import csv

# Define sales data.sales_data = [

( 1, 300, ),( 2, 350, ),( 3, 250, ),

]

# Write CSV file.import csvwith open('output.csv', 'wb') as f:

writer = csv.writer(f)writer.writerow(('day','sales'))writer.writerows(sales_data)

Notes:

• Whenyouusearegular writer (asopposedtoa DictWriter)thedatahastobeasequenceoflistsortuples.

• Alsoyouhavetowritetheheaderrowyourself.

Page 94: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 86

19 Database

19.1 CreatingTables

Exercise: Createadatabasetableforholdingstocktransactions.

Solution:

import sqlite3

with sqlite3.connect('test.db') as connection:cursor = connection.cursor()

# Create table.cursor.executescript(

"DROP TABLE " +"IF EXISTS stocks;" +

"CREATE TABLE stocks ( " +"date text, " +"action text, " +"symbol text, " +"quantity real, " +"price real " + ")")

# Commit changes.connection.commit()

Notes:

• executescript canbeusedtorunmultipleSQL statementstogether.

• Oryoucanuse execute toruneachstatementseparately.

• commit ensuresthatthechangestothedatabasearecommittedandnotthrownaway.

• with ensuresthatthedatabaseconnectionisclosedevenincaseofexceptions.

Page 95: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 87

• Ifanexceptionoccursin executescript, thecodewilldropoutofthe withand commit willnotgetcalled.

• Closingdatabaseconnectionsisimportant, becauseotherwisetheconnectioncankeepconsumingsystemresources.

• Youcanalsoexplicitlyclosetheconnection, usingthissyntax:

importsqlite3connection=sqlite3.connect(’test.db’)asconnection: cursor=connection.cursor()#RunSQL throughcursor. connection.commit()connec-tion.close()

• Thisisdangerousbecauseifanexceptionoccurstheconnectionwillnotclose.

• ThisisusefulthoughifyouareinteractingwiththedatabasethroughthePythonconsole.

19.2 InsertingRecords

Exercise: Insertasinglerowofdata.

Solution:

import sqlite3

with sqlite3.connect('test.db') as connection:cursor = connection.cursor()cursor.execute(

"INSERT INTO stocks VALUES (?,?,?,?,?)",('2006-01-05','BUY','RHAT',200,40.14))

cursor.commit()

Notes:

• UsingbindvariablesismoresecurethanembeddingvaluesintotheSQL be-causethispreventsSQL injectionattacks.

• Usingbindvariablesalsohasbetterperformance.

• Youcanalsouse UPDATE and DELETE usingsimilarsyntax.

Page 96: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 88

19.3 BatchInserts

Exercise: Insertmultiplerecordsinonecall.

Solution:

purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),('2006-04-06', 'SELL', 'IBM', 500, 53.00), ]

cursor.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)',purchases)

Notes:

• Insteadofalistofrecordsyoucanalsoinsertanarbitrarysequenceofrecords.

19.4 SelectingRecords

Exercise: Selectallrowsofdata.

Solution:

import sqlite3

with sqlite3.connect('test.db') as connection:cursor = connection.cursor()cursor.execute(

"SELECT * FROM stocks WHERE action=?",('BUY',))

for row in cursor:print row

Notes:

• Allinteractionisthroughthe cursor object.

Page 97: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 89

• The cursor objectletsyouiterateoveralltherowsjustselected.

• Besidesiteratingovertherowsyoucanalsofetchasingleroworfetchmultiplerowsfromthe cursor object.

# Fetch one row.print cursor.fetchone()

# Fetch all rows as a list.print cursor.fetchall()

# Fetch 3 rows.print cursor.fetchmany(3)

• However, iteratingovertherowsisthemostscalablewayofdoingselects.

• Thiswaythedatabasedoesnothavetoloadlargevolumesofdatainmemory.

19.5 CursorMethods

CursorMethod Meaning

execute(sql) ExecuteSQL withoutvars

execute(sql, (v1,v2,)) ExecuteSQL onceforvartuple

executemany(sql, ExecuteSQL repeatedlyforeachvartuple

[(v1,v2,),(v11,v22,)]

executescript(sqls) ExecuteSQL statementsseparatedby ;

fetchone() Fetchonerowastuple

fetchmany(size=2) Fetch size rowsastuplesequence

fetchall() Fetchallrowsastuplesequence

lastrowid LastrowID forinsert

rowcount Rowsaffectedbyinsert, update, delete

Page 98: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 90

19.6 Querying

Exercise: Createacommandlinetoolwiththeseusages.

# List all tables in database.dbtool database

# List all columns in tabledbtool database table

# List table row countdbtool database table count

Hint:

• Hereishowtogetalltablenames.

cursor.execute("SELECT name FROM sqlite_master " +"WHERE type='table'")

• Hereishowtogetalltablecolumns.

cursor.execute('PRAGMA TABLE_INFO(stocks)')

• Hereishowtogetthenumberofrowsinatable.

cursor.execute('SELECT COUNT(*) FROM stocks')

19.7 MySQL andPostgreSQL

Note: TheSQL API weusedforSqlitewillworkwithotherdatabases, withoneimpor-tantdifference:

• InMySQL andPostgreSQL insteadof ? youuse %s asthebindvariableplaceholderinqueries.

Page 99: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 91

• Hereishowthequeriesdiffer:

– QueryinSqlite:

cursor.execute("SELECT * FROM stocks WHERE symbol=?", ('T',))

– QueryinMySQL andPostgreSQL:

cursor.execute("SELECT * FROM stocks WHERE symbol=%s", ('T',))

20 NoseTests

20.1 UnitTesting

Exercise: Writeasimpleclasscalled TipCalc whichcalculatesthetipforagivenamount. Writeaunittestthatchecksthatthetipon$100is$15.

Solution:

In tip.py:

import sys, unittest

class TipCalc:def __init__(self, tip_rate):

self.tip_rate = tip_rate

def compute(self, amount):return amount * self.tip_rate

class TipCalcTest(unittest.TestCase):def test_computeTip(self):

tip_calc = TipCalc(0.15)assert 15 == tip_calc.compute(100)

def main(argv):# Main program logic goes here.

Page 100: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 92

# Command line args available in argv.print "Now in tip.py main()"print "argv = " + str(argv)

def start():print '__name__: ' + __name__if __name__ == '__main__':

if len(sys.argv) > 1 and sys.argv[1] in \["-test", "/test", "--test"]:

sys.argv.pop(0)unittest.main()

else:main(sys.argv)

start()

In demo.py:

import foo

print "Now in demo.py"

Runtheprogramas:

python demo.py arg1 arg2

Runthemaininthemodule tip.py as:

python tip.py arg1 arg2

Runthetestsinfooas:

python tip.py --test

Notes:

Page 101: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 93

• Towriteunittestsyouhavetoimport unitttest.

• Testshavetoliveinsideaclassthatextends unittest.TestCase.

• Testsliveinsidetestmethods.

• Everytestmethodnamemuststartwith test.

• The start() functionandthecallto start() areboilerplatecodethatyouneedtoincludeeverytimeyouhaveunittestsandproductioncodeinthesamefile. Thisfunctiondecideswhethertorunthemaincodeorthetestcode.

20.2 NoseTests

Nose testsmakeiteasiertorununittests. Youdon’thavetomodifythecodewithboilerplatecode.

20.3 NoseInstall

Exercise: Install nose.

sudo pip install nose

20.4 NoseTestExample

Exercise: Writeasimpleclasscalled TipCalc whichcalculatesthetipforagivenamount. Writeaunittestthatchecksthatthetipon$100is$15.

Solution

In tip.py:

import sys, unittest

class TipCalc:def __init__(self, tip_rate):

self.tip_rate = tip_rate

Page 102: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 94

def compute(self, amount):return amount * self.tip_rate

class TipCalcTest(unittest.TestCase):def test_computeTip(self):

tip_calc = TipCalc(0.15)assert 15 == tip_calc.compute(100)

def multiply(a,b):return a * b

def test_multiply():assert 12 == multiply(3,4)

Runthetestsas:

# Quietnosetests tip.py

# Verbosenosetests -v tip.py

# Another syntax for verbose.nosetests --verbose tip.py

# Don't capture output.nosetests --nocapture tip.py

Notes:

• Nosemakesiteasytoruntests.

• Itrunsteststhatliveinsubclassesof unittest, forexample, TipCalcTest.

• It also runs tests that are in methods that start with test, for example,test_multiply.

Page 103: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 95

• Bydefaultnosecapturesthestandardoutputtomaketestsquiet. Todisablethisfeaturefordebugging, runitusing --nocapture.

• Nosemakesiteasytowriteconcisetests.

• Noseistherecommendedwayofwritingandmaintainingunittests.

20.5 NoseSetUp

Exercise: Runsetupbeforerunningthetests. Runteardownafterrunningthetests.Setupisusefulforsettingupsomecontextforthetest. Teardownisusefulforcleaningupthecontext.

In demo.py:

import unittest

from nose import with_setup # optional

def setup_module(module):print ("") # this is to get a newline after the dotsprint ("setup_module before anything in this file")

def teardown_module(module):print ("teardown_module after everything in this file")

def my_setup_function():print ("my_setup_function")

def my_teardown_function():print ("my_teardown_function")

@with_setup(my_setup_function, my_teardown_function)def test_multiply():

print 'test_multiply'assert 3*4 == 12

class TestStuff(unittest.TestCase):

Page 104: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 96

def setUp(self):print ("TestStuff:setUp() before each test method")

def tearDown(self):print ("TestStuff:tearDown() after each test method")

@classmethoddef setUpClass(cls):

print ("setup_class() before any methods in this class")

@classmethoddef tearDownClass(cls):

print ("teardown_class() after any methods in this class")

def test_multiply(self):print 'test_multiply()'assert 5*6 == 30

Runthiswith:

nosetests --nocapture demo.py

Notes:

• Noseprovidesdifferentwaysofdoingsetupandteardown.

• Youcanrunsetuponceforthewholefile, oryoucanrunsetupbeforeeachtest, oryoucanrunsetupbeforeeachtestinatestclass.

• Theabovecodeillustratesallthesedifferentscenarios.

21 XML Parsing

21.1 xmltodict

Exercise: Findthetemperatureforagivenzipcode.

Page 105: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 97

Hint:

Generalizethefollowingcodetouseazipcodefrom sys.argv.

import urllibimport urllib2import xmltodict

zip = '27709'print "zip =", zip

# Get WOEID.wid_query = \

"select woeid" \+ " from geo.places" \+ " where text='" + zip + "' limit 1"

wid_url = \'http://query.yahooapis.com' \+ '/v1/public/yql' \+ '?format=xml&q=' \+ urllib.quote_plus(wid_query)

wid_xml = urllib2.urlopen(wid_url).read()

data = xmltodict.parse(wid_xml)wid = data['query']['results']['place']['woeid']

# Get temperature.weather_url = \

"http://weather.yahooapis.com" \+ "/forecastrss" \+ "?format=xml" \+ "&w=" + wid \+ "&u=f"

weather_xml = urllib2.urlopen(weather_url).read()

weather_data = xmltodict.parse(weather_xml)temp = weather_data['rss']['channel']['item']['yweather:condition']['@temp']

Page 106: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 98

print "temp = ", temp

Notes:

• xmltodict.parse convertsXML to a nested structure of Pythondicts andarrays.

• FormorelowlevelaccesstoXML takealookatthismodule.

import xml.etree.ElementTree

21.2 ElementTree

Exercise: FindthenameoftheairportwithcodeSFO.

Solution:

import xml.etree.ElementTree as ElementTree

xml = '''\<?xml version="1.0"?><airports>

<airport code="SFO"><name>San Francisco</name><terminals>4</terminals>

</airport><airport code="SJC">

<name>San Jose</name><terminals>3</terminals>

</airport><airport code="OAK">

<name>Oakland</name><terminals>2</terminals>

</airport></airports>'''

Page 107: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 99

# Parse XML.data = ElementTree.fromstring(xml)

# Find all elements called name.data.findall('.//name')

# Find name of airport with code SFO.data.findall(".//airport[@code='SFO']/name")[0].text

# Get first child of root node.data.getchildren()[0]

# Get inner text of node.data.text

# Get attributes of node.data.attrib

# Print out XML.ElementTree.tostring(data)

22 WebApplicationsUsingFlask

22.1 SettingUpFlask

Exercise: Install flask onyourmachine.

Solution:

• Checkifflaskisalreadyinstalledonyourmachine: OpenthePythonconsoleandtype import flask.

• Ifyougetanerrorthenitisnotinstalled.

• Toinstallitgrabitusingpip.

sudo pip install Flask

Page 108: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 100

22.2 HelloWorldWebApp

Exercise: Writeahelloworldwebapp.

Solution:

from flask import Flask, requestapp = Flask(__name__)

INDEX_HTML = '''\<h1>Hello World</h1>Hello world!'''

@app.route('/')def index():

return INDEX_HTML

if __name__ == '__main__':app.debug = Trueapp.run()

Notes:

• app.debug = True ishelpfulduringdevelopment. Ithotswapsthecodeifyoumakeachangewhileitisrunning. Alsoitprintsbettererrormessagesiftherearefailures.

• The route attachesaURL pathtothisspecificmethod.

• ThemethodhastocomposeandreturntheHTML thatthebrowserwilldisplay.

22.3 TwoPageWebApp

Exercise: Writeatwo-pagewebsite.

Solution:

Page 109: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 101

from flask import Flask, requestapp = Flask(__name__)

HOME_HTML = '''\<h1>Hello World</h1>[ <a href='/home'>Home</a> |

<a href='/about'>About</a> ]<br><br>

Hello world!'''

ABOUT_HTML = '''\<h1>About</h1>[ <a href='/home'>Home</a> |

<a href='/about'>About</a> ]<br><br>

This is the about page.'''

@app.route('/')@app.route('/home')def home():

return HOME_HTML

@app.route('/about')def about():

return ABOUT_HTML

if __name__ == '__main__':app.debug = Trueapp.run()

Notes:

• Multipleroutescanbeattachedtoasinglemethod.

• DependingontheURL theappropriatemethodisinvoked.

Page 110: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 102

22.4 TipCalculatorWebApp

Exercise: Writeaweb-basedtipcalculatorapp.

Solution:

from flask import Flask, requestapp = Flask(__name__)

def parse_float(x):try:

return float(x)except:

return None

def get_error(x, name):x_value = parse_float(x)if x_value == None:

return name + ' "' + x + \'" is not a number.<br>'

return ''

class Calc:def __init__(self, amount, people, tip_rate):

self.result = ''self.error = ''

# Build error.self.error += get_error(amount, 'Amount')self.error += get_error(people, 'People')self.error += get_error(tip_rate, 'Tip rate')

# Build result.amount = parse_float(amount)people = parse_float(people)tip_rate = parse_float(tip_rate)

Page 111: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 103

if amount == None: returnif people == None: returnif tip_rate == None: return

tip = amount * (tip_rate / 100.0)amount_per_person = (amount + tip) / peopleself.result = \

'Amount per person: ${0}'.format(amount_per_person)

def get_error(self):return self.error

def get_result(self):return self.result

HOME_HTML='''\<h1>Tip Calculator</h1>

<div style='color:red'>{error}</div>

<br>

<form>

Amount<br><input type="text" name="amount" value="{amount}"><br><br>

People<br><input type="text" name="people" value="{people}"><br><br>

Tip Rate<br><input type="text" name="tip_rate" value="{tip_rate}"><br><br>

Page 112: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 104

<button name="button">Calculate</button>

</form>

{result}'''

@app.route('/', methods=['GET','POST'])def index():

amount = request.values.get('amount','')people = request.values.get('people','')tip_rate = request.values.get('tip_rate','')button = request.values.get('button', None)

# First pass.if button == None:

return HOME_HTML.format(amount=amount,people=people,tip_rate=tip_rate,error="",result="")

# Second pass.calc = Calc(amount, people, tip_rate)html = HOME_HTML.format(

amount=amount,people=people,tip_rate=tip_rate,error=calc.get_error(),result=calc.get_result())

return html

if __name__ == '__main__':app.debug = Trueapp.run('localhost',8000)

Page 113: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 105

Notes:

[email protected] hasanadditionalparameterinit: methods=['GET','POST'].This indicates toFlask that themethodcanhandlebothGET andPOST.ThisisneededbecausetheformsubmitsitsinputsusingPOST.

• Thismightseemlikealotofcode. Thisisnormalasourtipcalculatorgraduallyturnsintoarealprogram. Handlingallthedetailsmakestheprogramlarger.

22.5 DeployingonPythonAnywhere

Exercise: Deploythisapponthecloudusing PythonAnywhere.

Solution:

• Goto https://www.pythonanywhere.com andsignupforafree N00b ac-countunder Pricing&signup.

• Makesureyouareloggedin.

• Clickonthe Web tab.

• Clickon Addanewwebapp --> Next --> Flask

• Notethepathwhereyourappwillbedeployed.

• Clickon Files --> mysite --> flask_app.py

• Thiswillputyouintheeditor.

• Copyandpasteyourtipcalculatorcodehere.

• Clickon Save.

• Clickon mysite --> Web --> Reloadapp.

• Clickonthelinktoyourappnextto Youcanseeyourwebappat.

• Nowtryvisitingyourappwithyourmobilephone.

Page 114: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 106

22.6 MVC Application

Exercise: Createasimpleblogapplicationwithadatabasebackend.

Solution:

• The following solution isbasedon the flaskr applicationdescribed in theFlaskdocumentation.

• Create a directory called flaskr. Create two subdirectories in it called:templates and static.

• Create flaskr/schema.sql withthesecontents:

drop table if exists entries;create table entries (id integer primary key autoincrement,title text not null,text text not null

);

• Create flaskr/flaskr.py withthesecontents:

import sqlite3from flask import Flask, request, \

session, g, redirect, url_for, abort, \render_template, flash

# configurationDATABASE = '/tmp/flaskr.db'DEBUG = TrueSECRET_KEY = 'development key'USERNAME = 'admin'PASSWORD = 'default'

# create our little application :)app = Flask(__name__)app.config.from_object(__name__)app.config.from_envvar('FLASKR_SETTINGS', silent=True)

Page 115: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 107

def connect_db():return sqlite3.connect(app.config['DATABASE'])

from contextlib import closingdef init_db():

with closing(connect_db()) as db:with app.open_resource('schema.sql', mode='r') as f:

db.cursor().executescript(f.read())db.commit()

@app.before_requestdef before_request():

g.db = connect_db()

@app.teardown_requestdef teardown_request(exception):

db = getattr(g, 'db', None)if db is not None:

db.close()

@app.route('/')def show_entries():

cur = g.db.execute('select title, text from entries order by id desc')entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]return render_template('show_entries.html', entries=entries)

@app.route('/add', methods=['POST'])def add_entry():

if not session.get('logged_in'):abort(401)

g.db.execute('insert into entries (title, text) values (?, ?)',[request.form['title'], request.form['text']])

g.db.commit()flash('New entry was successfully posted')return redirect(url_for('show_entries'))

@app.route('/login', methods=['GET', 'POST'])

Page 116: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 108

def login():error = Noneif request.method == 'POST':

if request.form['username'] != app.config['USERNAME']:error = 'Invalid username'

elif request.form['password'] != app.config['PASSWORD']:error = 'Invalid password'

else:session['logged_in'] = Trueflash('You were logged in')return redirect(url_for('show_entries'))

return render_template('login.html', error=error)

@app.route('/logout')def logout():

session.pop('logged_in', None)flash('You were logged out')return redirect(url_for('show_entries'))

if __name__ == '__main__':app.run()

• Create static/style.css withthesecontents:

body {font-family: sans-serif;background: #eee;

}a, h1, h2 {

color: #377ba8;}h1, h2 {

font-family: 'Georgia', serif;margin: 0;

}h1 { border-bottom: 2px solid #eee; }h2 { font-size: 1.2em; }.page {

Page 117: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 109

margin: 2em auto;width: 35em;border: 5px solid #ccc;padding: 0.8em;background: white;

}.entries {

list-style: none;margin: 0;padding: 0;

}.entries li { margin: 0.8em 1.2em; }.entries li h2 { margin-left: -1em; }.add-entry {

font-size: 0.9em;border-bottom: 1px solid #ccc;

}.add-entry dl { font-weight: bold; }.metanav {

text-align: right;font-size: 0.8em; padding: 0.3em;margin-bottom: 1em;background: #fafafa;

}.flash {

background: #cee5F5;padding: 0.5em;border: 1px solid #aacbe2;

}.error {

background: #f0d6d6;padding: 0.5em;

}

• Create template/layout.html withthesecontents:

<!doctype html><title>Flaskr</title>

Page 118: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 110

<link rel=stylesheet type=text/csshref="{{ url_for('static', filename='style.css') }}">

<div class=page><h1>Flaskr</h1><div class=metanav>{% if not session.logged_in %}

<a href="{{ url_for('login') }}">log in</a>{% else %}

<a href="{{ url_for('logout') }}">log out</a>{% endif %}</div>{% for message in get_flashed_messages() %}

<div class=flash>{{ message }}</div>{% endfor %}{% block body %}{% endblock %}

</div>

• Create template/login.html withthesecontents:

{% extends "layout.html" %}{% block body %}<h2>Login</h2>{% if error %}<p class=error><strong>Error:</strong>{{ error }}{% endif %}<form action="{{ url_for('login') }}" method=post>

<dl><dt>Username:<dd><input type=text name=username><dt>Password:<dd><input type=password name=password><dd><input type=submit value=Login>

</dl></form>

{% endblock %}

• Create templates/show_entries.html withthesecontents:

Page 119: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 111

{% extends "layout.html" %}{% block body %}{% if session.logged_in %}

<form action="{{ url_for('add_entry') }}"method=post class=add-entry>

<dl><dt>Title:<dd><input type=text size=30 name=title><dt>Text:<dd><textarea name=text rows=5 cols=40></textarea><dd><input type=submit value=Share>

</dl></form>

{% endif %}<ul class=entries>{% for entry in entries %}

<li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}{% else %}

<li><em>Unbelievable. No entries here so far</em>{% endfor %}</ul>

{% endblock %}

• Runthisas python flaskr.py.

• ThentestitbyvisitingtheURL thatitprintsout.

23 ListComprehensions

23.1 ListComprehensions

Exercise: Generateallthepowersof2from1through6.

Solution1:

powers_of_two = [2**n for n in range(1, 6)]

Page 120: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 112

Solution2:

powers_of_two = (2**n for n in range(1, 6))

Notes:

• Listcomprehensionsgeneratelistsusinganotationthatissimilartothe forallinmathematics.

• Solution1producesalist.

• Solution2producesaniterator. Thisisbasicallylikealist. Youcanuseitinsidea for. However, itislazyandthereforemoreefficient. Itdoesnotdotheworkuntilyoutrytoconsumethiswitha for.

23.2 ListsofDictionaries

Exercise: Createa listofdictionaries, containingkeys i and square. Here i isanumberfrom0to9and square isitssquare.

Solution: d=[dict(i=i,square=i*i)foriinxrange(10)]

Notes:

• Wearecreatingthedictionariesusinglistcomprehensions.

• dict(k1=v1,k2=v2,k3=v3) isanotherwaytocreatedictionaries.

• Wecouldhaveused {} hereinsteadaswell.

[{"i":i,"square":i*i} for i in xrange(10)]

24 Pexpect

24.1 Pexpect

Exercise: SimulateHTTP accessusingtelnet. WriteapexpectscripttoaccessGoogleandprintouttheresponsestatus.

Solution:

Page 121: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 113

import pexpectimport sys

host = 'google.com'

# Start telnet.proc = pexpect.spawn(

'telnet ' + host + ' 80')

# Echo to stdout.proc.logfile = sys.stdout

# Wait for connectionproc.expect('Trying [\d\.]+')proc.expect('Connected to ' + host)proc.expect("Escape character is .*")

# Send HTTP request.proc.sendline ('GET / HTTP/1.1')proc.sendline ('host: ' + host)proc.sendline ('')

# Wait for status line.index = proc.expect([

'HTTP/1.1 301','HTTP/1.1 404','HTTP/1.1 200',pexpect.EOF,pexpect.TIMEOUT,

])

# Report status.if index == 0: r = "301"elif index == 1: r = "404"elif index == 2: r = "200"elif index == 3: r = "EOF"elif index == 4: r = "TIMEOUT"else: r = "UNKNOWN"

Page 122: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 114

print "Result: " + r

# Give control to user.proc.interact()

Notes:

• Insteadof logfile youcanalsoset logfile_send and logfile_read tologwhatissentandwhatisreadfromtheprocess.

• Insteadofsettingthelogfilesto sys.stdout youcanalsosetthemtoafileobjectthatyougetthrough open.

24.2 PexpectMethods

Inthefollowingmethods, p istheobjectreturnedby pexpected.spawn(command)

Method Meaning

spawn(command) Startsanewprocess

p.sendline(line) Sendlinewithlinefeed

p.expect(re) Waitsforregexmatchon re

p.expect([re1,re2,]) Returnsindexofmatchingregex

p.interact() Givecontroltouser

p.wait() Waituntilprocessexits

p.terminate() Sends SIGHUP, SIGINT,then SIGKILL

Page 123: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 115

25 Threading

25.1 Threading

Exercise: Createtwoqueuesandtwosetsofthreads. Thefirstsetpicksintegersoffthefirstqueueandputsthemonthesecondqueue. Thesecondremovesthemfromthesecondqueue. Eachthreadlogsthedatathatitreceivesinalogqueue.

Solution:

import Queueimport threadingimport sysimport time

# Create two queues and a log queue.queue1 = Queue.Queue()queue2 = Queue.Queue()log_queue = Queue.Queue()

# Thread to move from queue1 to queue2.class Thread1(threading.Thread):

def __init__(self, in_queue, out_queue):threading.Thread.__init__(self)self.in_queue = in_queueself.out_queue = out_queue

def run(self):while True:

# Grab item from in queue.item = self.in_queue.get()

# Log it on log queue.log_queue.put("1:"+str(item))

# Put it on out queue.self.out_queue.put(item)

Page 124: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 116

# Inform in queue we are done.self.in_queue.task_done()

# Thread to consume from queue2.class Thread2(threading.Thread):

def __init__(self, in_queue):threading.Thread.__init__(self)self.in_queue = in_queue

def run(self):while True:

# Grab item from queue.item = self.in_queue.get()

# Log it on log queue.log_queue.put("2:"+str(item))

# Inform in queue we are done.self.in_queue.task_done()

# Remember when we started.start = time.time()

# How many threads to run.thread_count = 10

# Start all Thread1.for i in range(thread_count):

t = Thread1(queue1, queue2)t.setDaemon(True)t.start()

# Start all Thread2.for i in range(thread_count):

t = Thread2(queue2)t.setDaemon(True)

Page 125: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 117

t.start()

# Fill up queue1.for x in range(10):

queue1.put(x)

# Wait for queues to empty.queue1.join()queue2.join()

# Print out log queue contents.while not log_queue.empty():

x = log_queue.get()print x

print "Elapsed Time: %s" % (time.time() - start)

Notes:

• Python’ssynchronizationmechanismis Queue.Queue.

• Threadsshouldnotmodifyshareddatastructures. Insteadtheyshouldcommu-nicatethroughqueues.

• Thinkofthreadsasworkersontheassemblyline.

• Eachthreadpicksupanitemfromtheincomingqueue, worksonit, andplacesitsoutputontheoutgoingqueue.

26 MiscTopics

26.1 ArgsandKWArgs

Exercise: HowdoyouwriteavariableargfunctioninPython?

Solution:

Page 126: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 118

def f(*args,**kwargs): print "f:", args,kwargsdef g1(*args,**kwargs): f(*args,**kwargs)def g2(*args,**kwargs): f(args,kwargs)

g1(1,2,3,a=10,b=20)g2(1,2,3,a=10,b=20)

Notes:

• g1 isavariableargsfunction. Itreceivesitspositionalargumentsin args anditskeywordargumentsin kwargs.

• Ifyouwanttocallanothervariableargfunctionfrom g1 youhavetopassontheargumentsas *args and **kwargs.

• Ifyouwanttoconsumethemin g1 youaccessthemdirectlyas args (whichwillgiveyoualist)and kwargs (whichwillgiveyouadictionary).

26.2 ClassmethodandStaticmethod

Exercise: HowdoyouputclassmethodsinPython?

Solution:

class A(object):@classmethoddef class_foo(cls,x):

print "executing class_foo(%s,%s)"%(cls,x)@staticmethoddef static_foo(x):

print "executing static_foo(%s)"%xdef foo(self,x):

print "executing foo(%s,%s)"%(self,x)

a=A()

a.foo("Hello")a.class_foo("Hello")a.static_foo("Hello")

Page 127: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 119

Notes:

• Youcanaddclassmethodsusing @classmethod.

• Youcanaddstaticmethodsusing @staticmethod.

• Staticmethodsdonotknowwhatclasstheyareinandonlyhaveaccesstotheargumentstheyarepassed. Theyarelikemethodsthatareoutsideaclass.

• Classmethodsarepassedtheclassnameoftheclasstheywerecalledon.

• Staticmethodsaremostlyanorganizationalconvenience. Itisawayofputtingutilityfunctionsonclasses.

26.3 Closures

Exercise: Createafunctionthatapproximatesthederivativeof f usinganintervalofdx.

Solution:

def make_derivative(f, dx):def derivative(x):

return (f(x + dx) - f(x)) / dxreturn derivative

import mathff = make_derivative(math.sin, 0.01)print ff(0)

Notes:

• The make_derivative functionisafunctionfactory. Ittakessomeparametersandhard-wiresthemintothefunctionthatitproduces.

• Theinnerfunctioncalled derivative herekeepsreferencestotheparametersthatwereinitscontextwhenitwascreated. Inthiscaseitholdsreferencestof and dx.

Page 128: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 120

• Whenwecall ff withaparticularvalueof x itusesthevaluesof f and dx thatwerehard-wiredintoitwhenitwascreated.

• A closureisthiscontextwheretheoriginalvaluesof f and dx arestored. Itrepresentsthehard-wiredvaluesthatthecreatedfunctionrememberswhenitisinvokedlater.

26.4 Decorators

Exercise: Create a custom decorator that can be applied to functions using@my_decorator. Thedecoratorshouldprint”Callingdecoratedfunction”whenitsfunctionisinvoked.

Solution:

from functools import wrapsdef my_decorator(f):

@wraps(f)def wrapper(*args, **kwds):

print 'Calling decorated function'return f(*args, **kwds)

return wrapper

@my_decoratordef example():

"""Docstring"""print 'Called example function'

example()example.__name__example.__doc__

Notes:

• A decoratorallowsyoutoexecutecodebeforeandafteradecoratedfunction.

• functools.wraps isaconveniencefunctionthatensuresthatthewrappedfunctionretainsitsnameanddocstring.

Page 129: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 121

26.5 Memoizer

Exercise: Createamemoizerdecorator. A memoizercachesthevalueitproducedforagivensetofarguments. Thenthenexttimeitiscalleditreturnstheresultfromitscache. Ifitiscalledwithnewarguments, itcomputesanewvalue, andthensavesthatinthecacheaswell.

Solution:

import functools

def memoize(obj):cache = obj.cache = {}

@functools.wraps(obj)def memoizer(*args, **kwargs):

key = str(args) + str(kwargs)if key not in cache:

cache[key] = obj(*args, **kwargs)return cache[key]

return memoizer

@memoizedef hello(name):

print "Computing value"return "Hello, " + name

# First time it computes the value.print hello('Jim')

# Second time it returns cached value.print hello('Jim')

26.6 Iterators

Exercise: Createafunctionthatuppercasesthecharactersofastringandthenreturnsaniteratorforiteratingthroughthem. Aniteratorisanobjectyoucanconsumeina

Page 130: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 122

for loop. Itislikealistexceptitis lazy andonlyproducesitsresultswhenthe forloopdemandsit. Iteratorsaremoreefficientmemory-wisethanlists. Theycanalsobefasterbecausetheyonlydotheminimumworknecessary.

Solution1:

# Generatordef upper_case_gen(text):

for char in text:yield char.upper()

for c in upper_case_gen("hello"): print c

Solution2:

# Generator Expressiondef upper_case_genexp(text):

return (char.upper() for char in text)

for c in upper_case_genexp("hello"): print c

Solution3:

# Iteratorclass upper_case_iter():

def __init__(self, text):self.text = textself.index = 0

def __iter__(self):return self

def next(self):try:

result = self.text[self.index].upper()except IndexError:

Page 131: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 123

raise StopIterationself.index += 1return result

for c in upper_case_iter("hello"): print c

Solution4:

# Getitemclass upper_case_getitem():

def __init__(self, text):self.text = text

def __getitem__(self, index):result = self.text[index].upper()return result

for c in upper_case_getitem("hello"): print c

Notes:

• Hereare4differentwaysofdoingthis.

• OftheseSolutions1and2arethepreferredones.

27 Next

27.1 NextSteps

Congratulations. Youhavecompletedthecourse.

Whatshouldyoudonext?

Oneofthebestwaystolearnprogrammingistotypecodemanuallyfromexamplesandmake itwork. Youcanuse this techniquewithexamples from thisbookandexamplesfromotherplaces.

OnceyoufeelcomfortablewithPython, considertakingonasmallproject. Picksome-thingthatcanbedoneinadayorso. Iftheprojectistoolargeitdelaysexperiencing

Page 132: Python Essentials - wokkil.pair.comwokkil.pair.com/asim/tmp/metaprose/python/python-book.pdf · Python Essentials v 15 Third-Party Modules 65 15.1Pip vs Easy_Install . . . . .

PythonEssentials 124

thegratificationofgettingdone. Thisisnotasmuchfunassomethingthatgetsdonequickly.

Whenitfinallyworksthatwillproduceasweetfeelingofgratificationandaccomplish-mentthatishardtobeat.

Goodluckonyourapps, andI hopeyouenjoyyournewexperienceswithPython.