illustrated guide to python 3: a complete walkthrough of beginning python with unique illustrations...

267

Upload: others

Post on 11-Sep-2021

52 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works
Page 2: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TreadingonPythonSeriesIllustratedGuidetoPython3

ACompleteWalkthroughofBeginningPythonwithUniqueIllustrationsShowinghowPythonReallyWorks

MattHarrison

TechnicalEditors:RogerA.Davidson,AndrewMcLaughlinVersion:Oct2,2017Copyright©2017While every precaution has been taken in the preparation of this book, thepublisher and author assumes no responsibility for errors or omissions, or fordamagesresultingfromtheuseoftheinformationcontainedherein.

Page 3: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TableofContents

IntroductionWhyPython?WhichVersionofPython?TheInterpreterRunningProgramsWritingandReadingDataVariablesMoreaboutObjectsNumbersStringsdir,help,andpdbStringsandMethodsComments,Booleans,andNoneConditionalsandWhitespaceContainers:Lists,Tuples,andSetsIterationDictionariesFunctionsIndexingandSlicingFileInputandOutputUnicodeClassesSubclassingaClassExceptionsImportingLibrariesLibraries:PackagesandModulesACompleteExampleOntoBiggerandBetterFileNavigationUsefulLinksAbouttheAuthor

Page 4: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

AlsoAvailableOnemorething

Page 5: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Introduction

AREYOUREADYTOJUMPSTARTYOURPYTHONPROGRAMMINGCAREER?THISBOOKWILL

armyouwithyearsofknowledgeandexperiencethatarecondensedintoaneasyto follow format. Rather than taking months reading blogs, websites, andsearchingmailinglistsandgroups,thisbookwillallowaprogrammertoquicklybecomeknowledgeableandcomfortablewithPython.ProgrammingisfunandPythonmakesitdelightful.BasicPythonisnotonly

easy,butapproachableforallages.Ihavetaughtelementarystudents,teenagers,“industry” professionals and “golden years” folks the Python programminglanguage.Ifyouarewillingtoreadandtype,youareabouttobeginanexcitingpath.Where it ultimately takes you depends on how hard you are willing towork.TherearedifferentlevelsofPython.BasicPythonsyntaxissmallandeasyto

learn.OnceyoumasterbasicPython,doorswillopentoyou.Youshouldbeableto read a lot of Python and understand it. From there, you can learn moreadvanced topics, specific toolkits, start contributing to open source projectswritteninPython,orusethatknowledgetolearnotherprogramminglanguages.Arecommendedapproachfor learning the language is to readachapterand

then sit down at a computer and type out some of the examples found in thechapter. Python makes it easy to get started, eliminating much of the hasslefoundinrunningprogramsinotherlanguages.Thetemptationwill likelybetomerelyreadthebook.Byjumpinginandactuallytypingtheexamplesyouwilllearnalotmorethanbyjustreading.

Page 6: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

WhyPython?

PYTHONISBOOMING!ITISTHETOPLANGUAGEBEINGTAUGHTINUNIVERSITIES.PYTHONdevelopersareamongthehighestpaid.Withtheboomindatascience,Pythonisquickly becoming one of themost desired skills for analytics. Operations arealso adopting Python tomanage their backend systems. They are discoveringwhatweb developers using Python have known for a long time; namely, thatPythonwillmakeyouproductive.Pythonhascrossedthetippingpoint.Nolongerareonlysmall,agilestartups

relyingonit.Lookingtotakeadvantageofitspowerandefficiency,enterpriseshave also converged on Python. Over the past year, I've taught Python tohundreds of seasoneddeveloperswith years of experience at large companies,whoaremovingtoPython.Python enables increased productivity. I came to Python as a Perl

programmer.Atwork,Iwasassignedtoateamwithaco-workerwhowaswellversed in Tcl. Neither of us wanted to jump ship though both of us wereinterested in learning Python. In 3 days our prototype was completed, muchfaster than we expected, and we both promptly forgot our previous “goto”language.Whatappealed tomeaboutPythonwas that it fitmybrain. I firmlybelieveifyouhavesomeexperienceinprogramming,youcanlearnthebasicsofPythoninafewdays.Python is easy to learn. For beginning programmers, Python is a great

steppingstone.Learningtowritesimpleprogramsisprettyeasy,yetPythonalsoscalesuptocomplex“enterprise”systems.Pythonalsoscaleswithage—Ihavepersonallyseenpeoplefrom7-80+learnbasicprogrammingskillsusingPython.

Page 7: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

WhichVersionofPython?

THIS BOOK WILL FOCUS ON PYTHON 3. PYTHON 2 HAS SERVED US WELL OVER THEyears. The Python Software Foundation, which manages releases of thelanguage,hasstatedthatPython2iscomingtoanend.Assuch,after2020theywillnolongersupportthelanguage.Python3,hasbeenoutforabitnowandissomewhatbackwardincompatible

with the2series.Forgreen fielddevelopment,youshouldmove forwardwithPython3.IfyouhavelegacysystemsonPython2,donotfret.Infact,mostofthecontentinthisbookisperfectlyapplicabletoPython2.IfyouwanttofocusonPython2,checkoutthepriorversionofthisbook.

Pythoninstallation

Python3isnotinstalledonmostplatforms.SomeLinuxdistributionsshipwithit,butWindowsandMacuserswillneedtoinstallit.ForWindowsfolks,gotothedownloadareaofthePythonwebsite1andfinda

linkthatsays“Python3.6WindowsInstaller”.Thiswill linktoa .msifile thatwill install Python on yourWindowsmachine. Download the file, open it bydouble-clickingit,andfollowtheinstructionstofinishtheinstallation.

NOTE

On the Windows installer there is an option labeled "Add Python toPATH".Pleasemake sure it is checked.Thatway,whenyou runpythonfrom the command prompt, it will know where to find the Pythonexecutable.Otherwise,youcangotoSystemproperties(clickWIN+Pause,orrunenvironfromthestartmenu),Advancedsystemsettings,andclick

Page 8: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

on the Environment Variables button. There you can update the PATHvariablebyaddingthefollowing:

C:\ProgramFiles\Python3.6;C:\ProgramFiles\Python3.6\Scripts

If you have UAC (User Account Control) enabled onWindows, thenpathis:

C:\Users\<username>\AppData\Local\Programs\Python\Python36

Likewise, Mac users should download the Mac installer from the Pythonwebsite.

NOTE

Anotheroptionfor installingPython is touse theAnaconda 2distribution.ThisrunsonWindows,Mac,andLinux,andalsoprovidesmanypre-builtbinariesfordoingscientificcalculations.Traditionally,theselibrarieshavebeenannoyingtoinstallastheywraplibrarieswritteninCandFortran,thatrequiresomesetupforcompiling.Macusersmightalsowant to lookinto theHomebrewversion 3. Ifyou

arealreadyfamiliarwithHomebrew,itisasimplebrewinstallpython3away.

Whicheditor?

Inadditionto installingPython,youwillneeda texteditor.Aneditor isa toolforwritingcode.Askilledcraftsmanwillinvestthetimetolearntousetheirtoolappropriatelyanditwillpaydividends.Learningtousethefeaturesofaneditorcan make churning out code easier. Many modern editors today have somesemblanceofsupportforPython.

Page 9: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

IfyouarejustbeginningwithPythonandhavenothadmuchexperiencewithreal text editors, most Python installations include IDLE, which has decentPython editing features. The IDLE development environment also runs onWindows,MacandLinux.Afeature to lookfor ineditors is integrationwith thePythonREPL 4.Later

youwillseeanexamplewithIDLE.Hopefullyyoureditorofchoicewillhavesimilarfeatures.Popular editors with decent Python support include Emacs, Vim, Atom,

Visual Studio Code, and Sublime Text. If you are interested in more fancyeditors that have support for refactoring tools and intelligent completion,PyCharmandWingIDEarealsopopular.

Summary

Python 3 is the current version of Python.Unless you areworking on legacycode,youshouldfavorusingthisversion.YoucanfindthelatestversiononthePythonwebsite.Most modern editors contain some support for Python. There are various

levels of features that editors and IDEs provide. If you are getting startedprogramming,givetheIDLEeditoratry.Itisagreatplacetostartout.

Exercises

1. InstallPython3onyourcomputer.MakesureyoucanstartPython.2. Ifyouareusedtoaparticulareditor,dosomeinvestigationintoitssupport

forPython.Forexample,doesit:

DosyntaxhighlightingofPythoncode?RunPythoncodeinaREPLforyou?ProvideadebuggerforsteppingthroughyourPythoncode?

1-https://www.python.org/download

Page 10: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

2-https://www.anaconda.com/download/3-https://brew.sh/4 -REPLstands forRead,Evaluate,Print, andLoop.Youwill soon seean

exampleusingit.

Page 11: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TheInterpreter

PYTHONISCOMMONLYCLASSIFIEDASANINTERPRETEDLANGUAGE.ANOTHERTERMUSEDto describe an interpreted language is scripting language. To run a computerprogramontheCPU,theprogrammustbeinaformatthattheCPUunderstands,namelymachinecode.Interpretedlanguagesdonotcompiledirectlytomachinecode,instead,thereisalayerabove,aninterpreterthatperformsthisfunction.

Differencebetweenacompiledlanguageandaninterpretedlanguage.Acompilerrunstocreateanexecutable.Aninterpreterisanexecutablethatloadscodeandrunsitontopofitself.

There are pros and cons to this approach. As you can imagine, on the flytranslatingcanbe timeconsuming.InterpretedcodelikePythonprogramstend

Page 12: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

to runon theorderof10–100 timesslower thanCprograms.On the flipside,writingcodeinPythonoptimizesfordeveloper time.It isnotuncommonforaPython program to be 2–10 times shorter than its C equivalent. Also, acompilation step can be time consuming and actually a distraction duringdevelopmentanddebugging.Manydevelopersandcompaniesarewillingtoaccept this trade-off.Smaller

programs (read fewer lines of code) take less time to write and are easier todebug.Programmerscanbeexpensive—ifyoucanthrowhardwareataproblem,itcanbecheaperthanhiringmoreprogrammers.Debugging10linesofcodeiseasierthandebugging100linesofcode.Studieshaveshownthatthenumberofbugsfoundincodeisproportionaltothenumbersoflinesofcode.Hence,ifalanguagepermitsyoutowritefewer linesofcodetoachieveagiventask,youwill likely have fewer bugs. Sometimes program execution speed is not thatimportantandPythonissufficientlyfastformanyapplications.Inaddition,thereareeffortstoimprovethespeedofPythoninterpreterssuchasPyPy5.

REPL

PythonhasaninteractiveinterpreterorREPL(ReadEvaluatePrintLoop).Thisisaloopthatwaitsuntilthereisinputtoreadin,thenevaluatesit(interpretsit),andprints out the result.Whenyou run thepython3 executableby itself, youlaunchtheinteractiveinterpreterinPython.Otherenvironments,suchasIDLE,alsoembedaninteractiveinterpreter.

Page 13: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TolaunchtheREPL,typepython3inthepromptanditwillstartaPythonsession

NOTE

This book generally starts Python 3 with the python3 executable. OnWindows,theexecutableisnamedpython.IfyouareonWindows,replacepython3 with python. On Unix systems you shouldn't have to changeanything.

Whenyou start the interpreter, itwill printout theversionofPython, someinformationaboutthebuild,andsomehintstotype.Finally,theinterpreterwillgiveyouaprompt,>>>.Another option is to start IDLE, the editor includedwithPython, by typing

python3-midlelib.idle.

Page 14: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TolaunchtheREPLinIDLE,clickontheIDLEiconortypepython3-midlelib.idle

NOTE

Some Linux distributions do not ship with all of the libraries from thePython standard library.This is annoying, but justified by the idea that aserver doesn't need libraries to create client side applications. As such,UbuntuandArch (amongothers)don'tprovide thegui librariesnecessaryforIDLEonthedefaultinstallation.Ifyouseeanerrorlike:

$python3-midlelib.idle**IDLEcan'timportTkinter.YourPythonmaynotbeconfiguredforTk.**

itisanindicationyouaremissingthetkinterlibrary.OnUbuntu,youneedtorun:

$sudoapt-getinstalltk-dev

OnArch,youneedtorun:

$sudopacman-Stk

AREPLexample

BelowisanexampletoshowwhytheRead,Evaluate,PrintLoopwasgiventhisname. Ifyou typedpython3 from thecommand line 6,or launched IDLE,youwillsee>>>.Type2+2likeshownbelowandhitenter:

$python3>>>2+24>>>

Intheaboveexample,python3wastyped,whichopenedtheinterpreter.Thefirst>>>couldbethoughtofasthereadportion.Pythoniswaitingforinput.2+

Page 15: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

2istypedin,read,andevaluated.Theresultofthatexpression—4—isprinted.Thesecond>>> illustrates the loop,becausetheinterpreter iswaitingformoreinput.The REPL, by default, prints the result of an expression to standard out

(unless the result is None, which will be explained in a later chapter). ThisbehaviorisinconsistentwithnormalPythonprograms,wheretheprintfunctionmustbeexplicitlyinvoked.ButitsavesafewkeystrokeswhenintheREPL.

NOTE

The>>>promptisonlyusedonthefirstlineofeachinput.IfthestatementtypedintotheREPLtakesmorethanoneline,the...promptfollows:

>>>sum([1,2,3,4,5,...6,7])

Thesepromptsaredefinedinthesysmodule:

>>>importsys>>>sys.ps1'>>>'>>>sys.ps2'...'

Alaterchapterwillexplainwhatmodulesare.Fornow,knowthattherearevariablesthatdefinewhatthepromptslooklike.

TheREPLendsupbeingquitehandy.Youcanusetheinteractiveinterpreterto write small functions, to test out code samples, or even to function as acalculator. Perhapsmore interesting is to go the other way. Run your PythoncodeintheREPL.Yourcodewillrun,butyouwillhaveaccesstotheREPLtoinspectthestateofyourcode.(YouwillseehowtodothisinIDLEsoon).The >>> is a prompt. That is where you type your program. Type

print("helloworld")afterthe>>>andhittheenterkey.Makesuretherearenotanyspacesortabsbeforethewordprint.Youshouldseethis:

Page 16: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>print("helloworld")helloworld

If you see this, congratulations, you are writing Python. Consider yourselfinductedinto theworldofprogramming.Youhavejustrunaprogram—“helloworld”. Hello world is the canonical program that most people write whenencounteringanewlanguage.ToexittheREPLfromtheterminal,typequit().UnixusersmayalsotypeCtl-D.

NOTE

Programmingrequiresprecision. Ifyouwerenotcareful in typingexactlyprint("helloworld")youmighthaveseensomethinglikethis:

>>>print("helloworldFile"<stdin>",line1print("helloworld^SyntaxError:EOLwhilescanningstringliteral

Computers are logical, and if your logic does not make sense, thecomputercanwarnyou,performirrationally(oratleastwhatappearssotoyou), or stop working. Do not take it personally, but remember thatlanguageshaverules,andanycodeyouwritehastofollowthoserules.Inthepreviousexample, therules thatstates ifyouwant toprint texton thescreen you need to start and end the text with quotes was violated. AmissingquoteontheendofthelineconsequentlyconfusedPython.

Page 17: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

IDLEwilltrytohighlightwheretheerroroccurred.Thehighlightfollowingworldissupposedtoindicatewherethesyntaxerroroccurred.Itisnormallyasalmoncolor.

Summary

AsPython is an interpreted language, it provides aREPL.This allows you toexplorefeaturesofPythoninteractively.Youdon'tneedtowritecode,compileit,andrunit.YoucanlaunchaREPLandstarttryingoutcode.For users who have used compiled languages, this might seem somewhat

novel.Giveitatrythough,itcanmakedevelopmenteasyandquick.Also,don'tbeafraidtotryoutcodefromtheREPL.IfindthatnewPythonuserstendtobetimidtousetheREPL.Don'tfeartheREPL!ThereareotherREPLsforPython.OnepopularoneisJupyter,whichpresents

aweb-basedREPL 7.StartusingtheREPL,thenyoucanjumpintoothermoreadvancedREPLs.

Exercises

1. OpenthePython3REPLandrun"helloworld".Reviewthechaptertoseewhatthisonelineprogramlookslike.

2. OpentheREPLIDLEandrun"helloworld".

Page 18: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

5-https://www.pypy.org6 -From theWindows runmenu, typecmd (orWin-R) togetaprompt.On

Macs,youcanquicklylaunchaterminalbytypingcommand-space,thetypingTerminal and return. If you have installed Python 3, you should be able tolaunchitnowoneitherplatformbytypingpython3.7-https://jupyter.org/

Page 19: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

RunningPrograms

WHILEUSINGTHEINTERACTIVEINTERPRETERCANBEUSEFULDURINGDEVELOPMENT,YOU(andothers)willwanttodeployyourprogramandrunitoutsideoftheREPL.InPython,thisiseasyaswell.TorunaPythonprogramnamedhello.py,openaterminal,gotothedirectorycontainingthatprogramandtype:

$python3hello.py

NOTE

Whenrunningacommandfromthecommandline,thisbookwillprecedethe command with a $. This will distinguish it from interpreter contents(>>>or...)andfilecontents(nothingprecedingthecontent).

NOTE

Thepreviouscommand,python3hello.py,willprobablyfailunlessyouhaveafilenamedhello.py.

In the previous chapter you used theREPL to run “helloworld”, howdoesonerunthesameprogramstandalone?Createafilenamedhello.pyusingyourfavoritetexteditor.Inyourhello.pyfiletype:

print("helloworld")

Save the file, go to its directory, andexecute the file (hereexecute and runhave the same meaning, i.e. type python3 before the file name, and let the

Page 20: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Pythoninterpreterevaluatethecodeforyou.)

NOTE

Typing python3 standalone launches the interpreter. Typing python3some_file.pyexecutesthatfile.

Ifyouweresuccessfulatrunninghello.py,itwouldprintouthelloworld.

RunningfromIDLE

YoucanalsoeditandrunprogramsfromIDLE.StartbylaunchingIDLE,eitherbyclickingontheapplicationicononyourcomputerorbytyping:

$python3-midlelib.idle

WhenIDLElaunches,youseetheShellwindow.ThisisaPythonREPL.YoucantypecodeandPythonwillimmediatelyevaluateit.TocreateaprogramyouneedtocreateafilewithPythoncodeinit.Todothat,clickonthe“File”menu,andselect“NewFile”.Youshouldseeanewwindowpopup.ThiswindowisnotaShellwindow,itisaneditorwindow.YouwillnoticethatitisemptyandthereisnoPythonpromptinit.Inthiswindow,youwilltypePythoncode.

Page 21: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

IDLEhasbeenlaunchedandaneweditorwindow(Untitledbecauseithasnotbeensaved)hasbeenopened

Type your code into the window. Since you are doing the hello worldexample,type:

print("helloworld")

You'llnoticethatIDLEusesadifferentcolorforprintand"helloworld".Thisiscalledsyntaxhighlightingandismeanttoaidinunderstandingyourcode.Now,youneedtorunthecode.TheeasiestwaytodothisistohittheF5keyonyourkeyboard.Alternatively,youcanclickon“Run”,andselect“RunModule”.IDLEwillaskyoutosaveyourfile.Saveitashello.py. IDLEwillbringtheshellwindowtofocus,printalinestatingthatithasrestartedtheshell,andprintouthelloworld.

Page 22: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Codetypedintotheeditorwindow.

Thismightseemtrivial,buttheshellwindownowhasthestateofyourcode.Inthiscase,youonlyprintedtothescreen,sothereisnotmuchstate.Infutureexamples,youwillseehowyoucanusetheintegrationbetweentheeditorandshell to provide an environment where you can quickly try out code, see theresults,andinspecttheoutputofaprogram.

ResultofrunningHelloWorldfromIDLE

If you need help navigating from the command prompt check out theappendix.

Unixyembellishments

OnUnixplatforms(LinuxandOSXamongothers),filessuchashello.pyareoftenreferredtoasscripts.Ascript isaprogram,but thetermisoftenusedtodistinguishnativecodefrominterpretedcode.Inthiscase,scriptsareinterpretedcode,whereastheoutputfromthecompilationstepofalanguagethatcompilestomachinecode(suchasC)isnativecode.

NOTE

Itisnotuncommontohearaboutshellscripts,Perlscripts,Pythonscripts,etc.WhatisthedifferencebetweenaPythonscriptandaPythonprogram?Nothing, really it is only semantics. A Python script usually refers to aPythonprogramrunfromthecommandline,whereasaPythonprogramisany programwritten inPython (which run the gamut of small 1-liners tofancyGUIapplications,to“enterprise”classservices).

Page 23: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Unixenvironmentsprovideahandywaytomakeyourscriptexecutableonitisown.Byputtingahashbang(#!)onthefirstlineofthefile,followedbythepath to the interpreter, andbychanging theexecutablebiton the file,youcancreateafilethatcanrunitself.To have the script execute with the Python interpreter found in the

environment,updateyourhello.pyfileto:

#!/usr/bin/envpython3print("helloworld")

NOTE

Thisnewfirstlinetellstheshellthatexecutesthefiletoruntherestofthefilewith the#!/usr/bin/envpython3 executable. (Shell scripts usuallystartwith#!/bin/bashor#!/bin/sh.)Savehello.pywiththenewinitialline.

TIP

#!/usr/bin/env is a handy way to indicate that the first python3executable found on your PATH environment variable should be used.Because thepython3executable is located indifferentplacesondifferentplatforms, thissolutionturnsout tobecross-platform.NotethatWindowsignores this line.Unlessyouareabsolutelycertain thatyouwant to runaspecificPythonversion,youshouldprobablyuse#!/usr/bin/env.Usinghardcodedhashbangssuchas:

#!/bin/python3

#!/usr/bin/python3.3

mightworkfineonyourmachine,butcouldleadtoproblemswhenyoutrytoshareyourcodeandothersdonothavepython3whereyouspecified

Page 24: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

it.IfyourequireaspecificversionofPython,itiscommontospecifythatintheREADMEfile.

Now you need to make the file executable. Open a terminal, cd to thedirectorycontaininghello.pyandmakethefileexecutablebytyping:

$chmod+xhello.py

This sets theexecutablebit on the file.TheUnix environment hasdifferentpermissions (set by flipping a corresponding bit) for reading, writing, andexecutingafile.Iftheexecutablebitisset,theUnixenvironmentwilllookatthefirstlineandexecuteitaccordingly,whenthefileisrun.

TIP

If you are interested in knowingwhat thechmod command does, use theman(manual)commandtofindoutbytyping:

$manchmod

Nowyoucanexecute the fileby typing itsname in the terminalandhittingenter.Type:

$./hello.py

And your program (or script) should run. Note the ./ included before thenameoftheprogram.Normallywhenyoutypeacommandintotheterminal,theenvironment looksforanexecutable in thePATH (anenvironmentvariable thatdefinesdirectorieswhereexecutablesreside).Unless.(ortheparentdirectoryofhello.py)isinyourPATHvariableyouneedtoinclude./beforethename(orthefullpathtotheexecutable).Otherwise,youwillgetamessagelikethis:

$hello.pybash:hello.pycommandnotfound

Page 25: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Yes,all thatwork just toavoid typingpython3hello.py.Why?Themainreason is thatyouwantyourprogram tobenamedhello (without the trailing.py).AndperhapsyouwanttheprogramonyourPATHsoyoucanrunitatanytime.Bymakingafileexecutable,andaddingahashbang,youcancreateafilethatlookslikeanordinaryexecutable.Thefilewillnotrequirea.pyextension,norwillitneedtobeexplicitlyexecutedwiththepython3command.

Summary

Running Python programs is easy. There is no lengthy compilation step.Youneed topointPython to theprogramyouwould like to run.ManyeditorsalsohavetheabilitytorunPythoncode.Itisworthwhiletoinvestigatehowtodoitwithyoureditor.WithIDLE,itissimple:youhitF5.

Exercises

1. Createafilehello.pywiththecodefromthischapterinit.2. Runhello.pyfromaterminal.3. Runhello.pyfromwithinIDLE.4. Ifyouhaveanothereditorthatyouprefer,runhello.pyfromit.5. If you are on a Unix platform, create a file called hello. Add the hello

worldcode to it, andmake theappropriateadjustments such thatyoucanrunthecodebytyping:

./hello

Page 26: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

WritingandReadingData

PROGRAMSWILLTYPICALLYHAVE INPUTANDOUTPUT.THISCHAPTERWILLSHOWHOWtoprintvaluestothescreenandallowtheendusertotypeinavalue.InPython,bothofthesearereallystraightforward.

Simpleoutput

The easiestway to provide the userwith output is to use theprint function,which writes to standard out. Standard out is where the computer writes itsoutput.Whenyouareinaterminal,standardoutisprintedontheterminal

>>>print('Hellothere')Hellothere

If youwant to print outmultiple items, you can provide them separated bycommas. Python will insert a space between them. You can put strings andnumbersinaprintfunction:

>>>print('Iam',10,'yearsold')Iam10yearsold

Alaterchapterwilllookatstringsindetail.Itwilldiscusshowtoformatthemtogetoutputtolookacertainway.

Gettinguserinput

Thebuilt-ininputfunctionwillreadtextfromaterminal.Thisfunctionacceptstextwhichitprintsoutasaprompttothescreenandwaitsuntil theusertypessomethingonstandardinandhitsenter.Standardiniswherethecomputerreadsitsinput.Inaterminal,standardinputcanbereadfromwhatyoutypein:

>>>name=input('Enteryourname:')

Page 27: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

If you typed the above into the interpreter (the spaces around the= are notrequired but convention suggests that you type them tomake your codemorereadable), it might look like your computer is frozen. In reality, Python iswaitingforyoutotypeinsomeinputandhitenter.Afteryoutypesomethinginandpressenter,thevariablenamewillholdthevalueyoutyped.TypethenameMatt andpress theenterkey. Ifyouprintname itwillprint thevalueyou justtyped:

>>>print(name)Matt

NOTE

Thevalueenteredintotheterminalwheninputiscalledisalwaysastring.If you tried to performmath operations on it, it might not give you theansweryouwant:

>>>value=input('Enteranumber:')3>>>other=input('Enteranother:')4

Ifyoutrytoaddvalueandotherrightnow,youconcatenatethem(orjointhemtogether)becausetheyarestrings:

>>>type(value)<class'str'>>>>value+other'34'

If youwant to add these strings as if theywere numbers you need tochange them from a string into a number type. To convert a string toanothertypelikeaninteger(awholenumber)orfloat(adecimalnumber),youwillneedtousetheintandfloatfunctionsrespectively.If youwant to numerically addvalue andother, youhave to convert

themtonumbersusingint:

>>>int(value)+int(other)7

Page 28: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

7

Afuturechapterwilltalkmoreaboutstringsandnumbertypes.

Summary

Pythongivesyoutwofunctionsthatmakeitreallyeasytoprintdataouttothescreen and read input from the user. These functions are print and input.Rememberthatwhenyoucall theinput function,youwillalwaysgetastringback.

Exercises

1. CreatesomePythoncodethatwillpromptyoutoenteryourname.PrintoutHelloandthenthename.

2. Createaprogramthatwillaskauserhowoldtheyare.Printoutsometexttellingthemhowoldtheywillbenextyear.

Page 29: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Variables

NOW THAT YOU KNOW ABOUT RUNNING PROGRAMS VIA THE INTERPRETER (OR THEREPL) and the command line, it is time to start learning about programming.Variablesarethebasicbuildingblocksofcomputerprograms.VariablesareimportantinPython,becauseinthePythonworld,everythingis

anobject.(Thisisnotquitetrue,keywordsarenotobjects).Variablesallowyoutoattachnamestotheseobjectssoyoucanrefertotheminfuturecode.

Mutationandstate

Twoimportantprogrammingconceptsarestateandmutation.Statedealswithadigitalrepresentationofamodel.Forexample,ifyouwanttomodelalightbulb,you may want to store its current status—is it on or off? Other possiblyinterestingstatesyoucouldstoreincludethetypeofbulb(CFLorincandescent),wattage,size,dimmable,etc.Mutationdealswithchangingthestatetoanewordifferentstate.Forthelight

bulbexample,itcouldbeusefultohaveapowerswitchthattogglesthestateandchangesitfromofftoon.How is this related to variables?Remember that inPython everything is an

object.Objectshavestate,andmightbemutated.Tokeeptrackoftheseobjects,youusevariables.Onceyouhaveobjectsthatholdstateandaremutable,thenyouhaveopened

aworld of possibilities.You canmodel almost anything youwant if you candeterminewhatstateitneeds,andwhatactionsormutationsneedtoapplytoit.

Pythonvariablesareliketags

Page 30: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Variablesarethebuildingblocksofkeepingtrackofstate.Youmightthinkofavariableasalabelortag.Importantinformationistaggedwithavariablename.Tocontinuethelightbulbexample,supposethatyouwanttorememberthestateofyourlightbulb.Havingthatdataisonlyusefulifyouhaveaccesstoit.Ifyouwant toaccess itandkeep trackof itsstateyouneed tohaveavariable to tagthatdata.Herethestateofthebulbisstoredinavariablenamedstatus:

>>>status="off"

Thisrequiresalittlemoreexaminationbecausethereisabitgoingonthere.Startingfromtheright,thereistheword"off"surroundedbyquotes.Thisisastringliteral,orabuiltindatatypethatPythonhasspecialsyntaxfor.ThequotestellPython that thisobject isastring.SoPythonwillcreatea stringobject.Astringstorestextualdata—inthiscase,thelettersoff.Thisobjecthasafewpropertiesofinterest.First,ithasanid.Youcanthinkof

the idaswherePythonstores thisobject inmemory. Italsohasa type, in thiscase, a string. Finally, it has a value, here the value is'off', because it is astring.The= sign is theassignmentoperator inmanyprogramming languages.Do

not be afraid of these technical terms, they aremore benign than they appear.The assignment operator connects or binds together a variable name and itsobject.Itindicatesthatthenameontheleftofitisavariablethatwillholdtheobjectontheright.Inthiscase,thevariablenameisstatus.When Python creates a variable, it tells the object to increase its reference

count.Whenobjectshavevariablesorotherobjectspointingtothem,theyhavea positive reference count.When variables go away (an example iswhen youexitafunction,variablesinthatfunctionwillgoaway),thereferencecountgoesdown.When this countgoesdown to zero, thePython interpreterwill assumethatnoonecaresabouttheobjectanymoreandgarbagecollectsit.Thismeansitremovesitfromitsmemory,soyourprogramdoesn'tgetoutofcontrolanduseallthememoryofyourcomputer.

Page 31: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

NOTE

If you want to inspect the reference count of an object, you can callsys.getrefcountonit:

>>>importsys>>>names=[]>>>sys.getrefcount(names)2

Do note that as this count may seem high, the documentation for thisfunctionstates:

Returnthereferencecountofobject.Thecountreturnedisgenerallyonehigherthanyoumightexpect,becauseitincludesthe(temporary)referenceasanargumenttogetrefcount().

Even though Python gives you this ability, typically you don't worryaboutthereferencecountandletPythonhandlecleaningupobjectsforus.

This is a feature of Python, and typically Python does this for youautomatically,withoutanypromptingfromauser.Inotherlanguages,youneedtomanuallytelltheprogramtoallocateanddeallocatememory.To drive the point home, reading the code again from the left this time.

statusisavariablethatisassignedtotheobjectthatPythoncreatedforus.Thisobjecthasatype,string,andholdsthevalueof"off".

Page 32: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Twostepsofanassignmenttoaliteral.First,Pythoncreatesanobject.Theobjecthasavalue,"off",atype,string,andanid(thelocationoftheobjectinmemory).Aftertheobjectiscreated,Pythonlooksforanyvariablenamedstatus.Ifitexists,Pythonupdateswhatobjectthevariableis

pointingto,otherwise,Pythoncreatesthevariableandpointsittotheobject.

Cattletags

Mygrandfatherhadacattleranch,soIwillpulloutanon-nerdyanalogy.Ifyouhaveacattleranchofanysize,itmakessensetohaveagoodforemanwhowillkeeptrackofyourcattle(yourinvestment).Onewaytokeeptrackofcattleistousecattletags.Thesesmalltagsattached

totheearofacowcanbeusedtoidentifyandtrackindividualcows.Topullthisbacktoprogramming,ratherthanrunningacattleranch,youare

managingaspectsofyourprogram.Aprogramcanholdmanydistinctpiecesofinformationthatyouwanttorememberorkeeptrackof.Thisinformationisthe

Page 33: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

state.Forexample, ifyouneeded to trackdatapertinent tohumansyoumightwanttotrackage,address,andname.Just like how ranchers tag their cattle to keep track of them, programmers

createvariablestokeeptrackofdata.Lookattheexampleagain:

>>>status="off"

ThistellsPythontocreateastringwiththecontentsofoff.Createavariablenamedstatus, and attach it to that string. Later on,when you need to knowwhatthestatusis,youcanaskyourprogramtoprintitoutlikeso:

>>>print(status)off

It isentirelypossible tocreatestateandloseit to theether ifyouneglect toputit inavariable.It issomewhatuselesstocreateobjectsthatyouwouldnotuse, but again it is possible. Suppose you want to keep track of the bulb’swattage.Ifyouwrite:

>>>"120watt"

IttellsPythontocreateastringobjectwiththecontentof120watt.Thisisproblematicbecauseyouforgottoassignittoavariable.Now,youhavenowayof using this object. Python will only let you access data that is stored invariables,soitisimpossibleforyoutousethisitemnow.Objectsareaccessedbyusing theirvariablenames. If thiswas information thatyouneeded inyourprogram,abettersolutionwouldbethefollowing:

>>>wattage="120watt"

Lateron,inyourprogramyoucanaccesswattage,youcanprintitout,andyou can even assign another variable to it, or assignwattage to another newvalue (say if your incandescent bulb broke and you replaced it with an LEDbulb):

>>>incandescent=wattage>>>wattage="25watt">>>print(incandescent,wattage)

Page 34: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>print(incandescent,wattage)120watt25watt

Managing state is a core aspect of programming. Variables are onemechanismtomanageit.

Rebindingvariables

Muchlikecowtags,variables tend tostaywithanobject forawhile,but theyaretransferable.Pythonletsyoueasilychangethevariable:

>>>num=400>>>num='400'#nownumisastring

Intheaboveexamplenumwasoriginallypointingtoanintegerbutthenwastoldtopointtoastring.

Page 35: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratesrebindingvariables.Variablescanbereboundtoanytype.Pythonmakesnoefforttopreventthisorcomplain.Whenanobjectnolongerhasanyvariablepointingtoit,itiscleanedup

byPython,orgarbagecollected.

NOTE

Thevariabledoesnotcareaboutthetype.InPython,thetypeisattachedtotheobject.

Thereisnolimittohowoftenyoucanchangeavariable.Butyoushouldbecarefulnottochangeavariableifyoustillneedaccesstotheolddata.Onceyou

Page 36: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

removeallvariablesfromanobject,youareessentiallytellingPythontodestroy(garbagecollectisthepropergeekyterm)theobjectwhenithasthechance,tofreeupanyinternalmemoryitoccupies.

TIP

ThisisacasewherePythonallowsyoutodosomething,butyouprobablydon'twanttodoit inreallife.Justbecauseyoucanrebindavariabletoadifferenttype,doesn'tmeanyoushould.Changingthetypeofavariableisconfusing to you when you read your code later. It is also confusing toothers who are using your code. Don't use the same variable to point todifferenttypes.This is a point of confusion for those who are new to Python. They

sometimes reuse the same variable throughout their code because theymistakenlybelieve that itwill savememory.Asyouhaveseen this isnotthe case. The variable itself is very lightweight. The object is what usesmemory. Reusing a variable is not going to change howmemory on theobject is handled, but itwill be confusing to thosewho have to read thecodelater.

Namingvariables

Python is somewhat particular about namingvariables. It has conventions thatmost Python programmers follow. Some of these are enforced, some are not.Onethatisenforcedbytheinterpreterisavariableshouldnothavethenameofa keyword. The word break is a keyword and hence cannot be used as avariable.Youwill get aSyntaxError if you try to use it as a variable. Eventhoughthiscodelooksperfectlylegal,Pythonwillcomplain:

>>>break='foo'File"<stdin>",line1break='foo'^SyntaxError:invalidsyntax

Page 37: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

SyntaxError:invalidsyntax

IfyoufindyourselfwithaSyntaxErrorthatlookslikenormalPythoncode,checkthatthevariablenameisnotakeyword.

NOTE

KeywordsarereservedforuseinPythonlanguageconstructs,soitconfusesPythonifyoutrytomakethemvariables.Themodulekeywordhasakwlistattribute,whichisalistcontainingall

thecurrentkeywordsforPython:

>>>importkeyword>>>print(keyword.kwlist)['False','None','True','and','as','assert','break','class','continue','def','del','elif','else','except','finally','for','from','global','if','import','in','is','lambda','nonlocal','not','or','pass','raise','return','try','while','with','yield']

AnothermethodforexaminingkeywordsintheREPListorunhelp().This puts you in a help utility in the REPL, from which you can typecommands(thataren'tPython).Thentypekeywordsandhitenter.Youcantype any of the keywords and it will give you some documentation andrelatedhelptopics.Toexitthehelputilityhitenterbyitself.

Additionalnamingconsiderations

In addition to the aforementioned rule about not naming variables afterkeywords,thereareafewbestpracticesencouragedbythePythoncommunity.Therulesaresimple—variablesshould:

belowercaseuseanunderscoretoseparatewordsnotstartwithnumbersnotoverrideabuiltinfunction

Page 38: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Hereareexamplesofvariablenames,bothgoodandbad:

>>>good=4>>>bAd=5#bad-capitalletters>>>a_longer_variable=6#thisstyleisfrownedupon>>>badLongerVariable=7#bad-startswithanumber>>>3rd_bad_variable=8File"<stdin>",line13rd_bad_variable=8^SyntaxError:invalidsyntax#bad-keyword>>>for=4File"<stdin>",line1for=4^SyntaxError:invalidsyntax#bad-builtinfunction>>>compile=5

TIP

RulesandconventionsfornaminginPythoncomefromadocumentnamed“PEP 8 – Style Guide for Python Code” 8. PEP stands for PythonEnhancementProposal,which is a communityprocess for documenting afeature, enhancement, or best practice for Python. PEP documents arefoundonthePythonwebsite.

NOTE

AlthoughPythonwillnotallowkeywordsasvariablenames, itwillallowyou touseabuiltin nameasavariable.Builtinsare functions, classes,orvariablesthatPythonautomaticallypreloadsforyou,soyougeteasyaccessto them.Unlikekeywords,Pythonwill let youuse a builtin as a variable

Page 39: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

namewithoutsomuchasapeep.However,youshouldrefrainfromdoingthis,itisabadpractice.Using a builtin nameas a variablename shadows thebuiltin.Thenew

variable name prevents you from getting access to the original builtin.Doingsoessentially takes thebuiltinvariableandco-opts it foryouruse.Asaresult,accesstotheoriginalbuiltinmayonlybeobtainedthroughthe__builtins__module.But it ismuchbetter not to shadow it in the firstplace.Here is a list of Python’s builtins that you should avoid using as

variables:

>>>dir(__builtins__)

['ArithmeticError','AssertionError','AttributeError','BaseException','BlockingIOError','BrokenPipeError','BufferError','BytesWarning','ChildProcessError','ConnectionAbortedError','ConnectionError','ConnectionRefusedError','ConnectionResetError','DeprecationWarning','EOFError','Ellipsis','EnvironmentError','Exception','False','FileExistsError','FileNotFoundError','FloatingPointError','FutureWarning','GeneratorExit','IOError','ImportError','ImportWarning','IndentationError','IndexError','InterruptedError','IsADirectoryError','KeyError','KeyboardInterrupt','LookupError','MemoryError','NameError','None','NotADirectoryError','NotImplemented','NotImplementedError','OSError','OverflowError','PendingDeprecationWarning','PermissionError','ProcessLookupError','RecursionError','ReferenceError','ResourceWarning','RuntimeError','RuntimeWarning','StopAsyncIteration','StopIteration','SyntaxError','SyntaxWarning','SystemError','SystemExit','TabError','TimeoutError','True','TypeError','UnboundLocalError','UnicodeDecodeError','UnicodeEncodeError','UnicodeError','UnicodeTranslateError','UnicodeWarning','UserWarning','ValueError','Warning','ZeroDivisionError','','_build_class__','__debug__','__doc_',

Page 40: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

'_import__','__loader__','__name_','_package__','__spec__','abs','all','any','ascii','bin','bool','bytearray','bytes','callable','chr','classmethod','compile','complex','copyright','credits','delattr','dict','dir','divmod','enumerate','eval','exec','exit','filter','float','format','frozenset','getattr','globals','hasattr','hash','help','hex','id','input','int','isinstance','issubclass','iter','len','license','list','locals','map','max','memoryview','min','next','object','oct','open','ord','pow','print','property','quit','range','repr','reversed','round','set','setattr','slice','sorted','staticmethod','str','sum','super','tuple','type','vars','zip']

TIP

Herearea fewbuiltins thatwouldbe temptingvariablenamesotherwise:dict,id,list,min,max,open,range,str,sum,andtype.

Summary

InPython, everything is anobject.Objectshold state,which is alsocalled thevalue.Tokeeptrackofobjectsyouusevariables.Pythonvariablesarelikecattletags, they are attached to the object and have a name. But the object has theimportantdata,thevalueandtypeofdata.This chapter alsodiscussed rebindingof variables.Python allowsyou todo

this,butyoushouldbecarefulnottochangethetypeofthevariable,asthatcanbeconfusingtoreadersof thesaidcode.Finally, thechapterdiscussednamingconventionsforPythonvariables.

Exercises

1. Create a variable,pi, that points to an approximation for the value of π.Create a variable, r, for the radius of a circle that has a value of 10.

Page 41: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Calculatetheareaofthecircle(πtimestheradiussquared).Youcandomultiplicationwith*andyoucansquarenumbersusing**.Forexample,3**2is9.

2. Createavariable,b,thatpointstothebaseofarectanglewithavalueof10.Createavariable,h,thatpointstotheheightofarectanglewithavalueof2.Calculatetheperimeter.Changethebaseto6andcalculatetheperimeteragain.

8-https://www.python.org/dev/peps/pep-0008/

Page 42: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

MoreaboutObjects

THIS CHAPTERWILLDIVE INTOOBJECTSA LITTLE BITMORE. YOUWILL COVER THREEimportantpropertiesofobjects:

identitytypevalue

Identity

Identity at its lowest level refers to an object’s location in the computer’smemory.Pythonhasabuiltinfunctioncalledidthattellsyoutheidentityofanobject:

>>>name="Matt">>>id(name)140310794682416

When you type this, the identity of the string "Matt" will appear as140310794682416 (which refers to a location in theRAMof your computer).Thiswillgenerallyvaryfromcomputertocomputerandforeachtimeyoustarttheshell,buttheidofanobjectisconsistentacrossthelifetimeofaprogram.It is possible for a single cow to have two tags on its ears and it is also

possible for two variables to refer to the same object. If you want anothervariable—first—toalsorefertothesameobjectreferredtobyname,youcoulddothefollowing:

>>>first=name

Page 43: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustrateswhathappenswhenyoubindavariabletoanexistingvariable.Theybothpointtothesameobject.Notethatthisdoesnotcopythevariable!Alsonotethattheobjecthasavalue,

"Matt",atype,andanid.

ThistellsPythontogivethefirstvariablethesameidasname.Runningidoneitherofthetwovariableswillreturnthesameid:

>>>id(first)140310794682416>>>id(name)140310794682416

Whatisidentityusedfor?Actuallynotmuch.WhenyouprograminPython,youtypicallyarenotconcernedwithlow-leveldetailssuchaswheretheobjectislivingintheRAMofthecomputer.Butidentityisusedtoillustratewhenobjectsarecreatedand if theyaremutable. It isalsoused indirectly fordoing identitycheckswithis.Theisoperatorchecksforidentityequalityandvalidateswhetherornottwo

variablespointtothesameobject:

>>>firstisnameTrue

If you print eitherfirst orname at theREPL, itwill print the same valuebecausetheyarebothpointingtotheexactsameobject:

>>>print(first)Matt>>>print(name)

Page 44: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>print(name)Matt

IfIhadacattletag,Icouldtakeitoffofonecowandattachittoanother.Justlikeacattletag,youcantakeavariableandpointittoanewobject.Icanmakenamepointtoanewobject.Youwillseethattheidentityofnamehaschanged.Butfirstisstillthesame:

>>>name='Fred'>>>id(name)140310794682434>>>id(first)140310794682416

Type

Another property of an object is its type.Common types are strings, integers,floats, andbooleans.There aremanyotherkindsof types, andyoucan createyourownaswell.Thetypeofanobjectreferstotheclassofanobject.Aclassdefinesthestateofdataanobjectholds,andthemethodsoractionsthat itcanperform.Pythonallowsyoutoeasilyviewthetypeofanobjectwiththebuiltinfunction,type:

>>>type(name)<class'str'>

Thetypefunctiontellsyouthatthevariablenamepointstoastring(str).ThetablebelowshowsthetypesforvariousobjectsinPython.

OBJECT TYPE

String str

Integer int

Floatingpoint float

List list

Dictionary dict

Tuple tuple

function function

User-definedclass(subclassobject) type

Page 45: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Instanceofclass(subclassofclass) class

Builtinfunction builtin_functionormethod

type type

Duetoduck-typing,thetypefunctionisnotusedtoofrequently.Ratherthancheckifanobject isofacertaintypethatprovidesanoperation,normallyyoutryanddothatoperation.Sometimesthoughyouhavedataandneedtoconvertittoanothertype.This

iscommonwhenreadingdatafromstandardin.Typicallyitwouldcomeinasastring,andyoumightwanttochangeit intoanumber.Pythonprovidesbuiltinclasses,str,int,float,list,dict,andtuplethatconvert(orcoerce)totheappropriatetypeifneeded:

>>>str(0)'0'>>>tuple([1,2])(1,2)>>>list('abc')['a','b','c']

NOTE

Duck typing comes from a saying used in the 18th century to refer to amechanicalduck.MuchliketheTuringTest,thesayingwent:

Ifitlookslikeaduck,walkslikeaduckandquackslikeaduck,thenit’saduck

ButIpreferthesceneinMontyPythonandtheHolyGrail,wherealadyisdeterminedtobeawitchbecausesheweighsasmuchasaduck.(Ifthisis confusing go watch the movie, I find it enjoyable). The idea is thatbecauseshehadcharacteristics(herweight)thatwerethesameasaduck’s,shecouldbeconsideredawitch.

Page 46: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Pythontakesasimilarapproach.Ifyouwanttoloopoveranobject,youputitinaforloop.Youdon'tcheckfirsttoseeifitisalistorasubclassofa list,youjust loopover it. Ifyouwant touseaplusoperation,youdon'tcheck to see if the object is a number, or string (or another type thatsupports addition). If theoperation fails, that’s ok, it is an indication thatyouarenotprovidingthecorrecttype.Ifyouarefamiliarwithobject-orientedprogramming,ducktypingeases

the requirement for subclassing.Rather than inheritingmultipleclasses totake advantage of behaviors they provide, you need to implement theprotocols (usuallybydefiningamethodor two).Forexample, tocreateaclassthatadds,youneedtoimplementa.__add__method.Anyclasscandefinethatmethodandrespondtotheplusoperation.

Mutability

Another interesting property of an object is itsmutability. Many objects aremutablewhileothersare immutable.Mutableobjectscanchangetheirvalueinplace,inotherwords,youcanaltertheirstate,buttheiridentitystaysthesame.Objectsthatareimmutabledonotallowyoutochangetheirvalue.Instead,youcan change their variable reference to a new object, but this will change theidentityofthevariableaswell.In Python, dictionaries and lists aremutable types. Strings, tuples, integers,

and floats are immutable types. Here is an example demonstrating that theidentity of a variable holding an integerwill change if you change the value.First,youwillassignanintegertothevariableageandinspecttheid:

>>>age=1000>>>id(age)140310794682416

Noticethatifyouchangethevalueoftheinteger,itwillhaveadifferentid:

>>>age=age+1>>>id(age)140310793921824

Page 47: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

140310793921824

Thisillustratesthatwhenyoutrytochangeaninteger,youwillnecessarilycreateanewinteger.Integersareimmutable,andyoucan'tchangetheirvalue.

Hereisanexampleofchangingalist.Youwillstartwithanemptylist,andexaminetheid.Notethatevenafteryouaddanitemtothelist,theidentityof

Page 48: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

thelistisunchanged,henceitismutable.First,youwillcreatealistandlookattheid:

>>>names=[]>>>id(name)140310794682432

Now,addastringintothelist.Thereareafewthingstonote.Thereturnvalueofthe.appendmethoddidn'tshowanything(ie, it isnotreturninganewlist).Butifyouinspectthenamesvariable,youwillseethatthenewnameisinthere.Also,theidofthelistisstillthesame.Youhavemutatedthelist:

>>>names.append("Fred")>>>names['Fred']>>>id(name)140310794682432

Page 49: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratesthatwhenyouappendanobjectintoalist,youchangethevalueofthelist.Thelistismutated.Youcanaddandremoveitemsfromit,buttheidoftheliststaysthesame.

Mutableobjects shouldnot beused forkeys indictionaries and canpresentproblemswhenusedasdefaultparametersforfunctions.

UsingIDLE

Page 50: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

At thispoint, itwouldbegood to try thisout in IDLE(oryour favoriteeditorthathasREPLintegration).BecauseIDLEcomeswithaREPL,youcouldtypeinthepreviouscodeandinspectitfromthere.Butyoucanalsowritecode,runit, and then inspect it from theREPL.To try it, openanew file, and type thefollowingcodeintoit:

name="Matt"first=nameage=1000print(id(age))age=age+1print(id(age))names=[]print(id(names))names.append("Fred")print(id(names))

Savethisasafile,callitiden.py.Thenrunthefile.InIDLE,youneedtohitF5todothis. In theREPL,youshouldseefournumbersprintedout.Thefirsttwo shouldbe different, illustrating that an integer is immutable.The last twonumbersare thesame.Theyare thesamebecauseeven thoughthe list,names,wasmutated,theidisstillthesame.Thisbyitselfisnothingparticularlynovel.Theinterestingpartnowisthat ifyoutypedir() intheREPL,itwillshow

youthevariables.Youwillseethattheglobalvariablesfromiden.pyarenowavailable.

Page 51: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

ThisillustratesrunningcodeandtheninspectingitfromtheREPLinIDLE.IfyoudonotuseIDLE,figureouthowtodothisfromyoureditor.

FromtheREPLinIDLEyouhaveaccesstoalltheglobalvariables.Youcaninspect name or names. You can even call functions or methods likenames.append("George").Theabilitytoinspectwhatjustrangivesyouthechancetoquicklyinspectthe

code,andtrythingsout.ItisnotuncommonforexperiencedPythondeveloperstowritecodeintheREPL,pasteitintoafile,re-runthefile,writemorecodeintheREPL,andcontinuewritingcodeinthismanner.

Summary

InPython,everythingisanobject.Objectshavethreeproperties:

AType-Indicateswhattheclassisfortheobject.AValue-Thedatathattheobjectholds.Whenyoutestifanobjectisequaltoanotherobject(with==),youarecheckingagainstthevalue.An Id - A unique id for the object. In the Python version found atwww.python.org, this is essentially the location inmemory of the object,

Page 52: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

whichwillbeauniquevalue.Whenyoucheckwhether twoobjectshavethesameidentity(withis),youarecheckingwhethertheidisthesame.

Youalsoexaminedhowmutableobjects,suchaslists,canchangetheirvalue,whileimmutableobjects,likenumbersorstrings,cannotbechanged.

Exercises

1. Create a variable that points to a floating point number. Examine the id,type,andvalueofthatnumber.Updatethevariablebyadding20toit.Re-examinetheid,type,andvalue.Didtheidchange?Didthevaluechange?

2. Createavariablepointingtoanemptylist.Examinetheid,type,andvalueofthelist.Appendthenumber300tothelist.Re-examinetheid,type,andvalue.Didtheidchange?Didthevaluechange?

Page 53: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Numbers

THISCHAPTERWILLDISCUSSMANIPULATINGNUMBERSWITHPYTHON.INTEGERS(WHOLE

numberslike-1,5,or2000)andFloatingPoints(thecomputer’sapproximationofrealnumberslike.333,0.5or-1000.234)areavailableinPythonandprovideeasy numerical manipulation. Out of the box, Python provides support foraddition,subtraction,multiplication,division,power,modulo,andmore!Unlikeotherlanguages,inPython,everythingisanobject,includingnumbers.

Integersareofclassint:

>>>type(1)<class'int'>

Floatingpointnumbersareofclassfloat:

>>>type(2.0)<class'float'>

Everything has a level of precision. It’s up to the user to determine if it issufficientfortheircalculations.Python’sfloatsarerepresentedinternallyusingabinaryrepresentation(aspertheIEEE754standardforfloatingpointnumbers).Floats have a certain amount of precision and rounding errors are possible. Infact, one should expect rounding errors. (If you need more precision, thedecimalmoduleprovidesamoreprecisealbeitslowerimplementation).As aquick exampleof precision, examinewhat happenswhenyouperform

thisapparentlysimplesubtractionoperation:

>>>print(1.01-.99)0.020000000000000018

TIP

Page 54: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Ifyouareinterestedinunderstandingmoreaboutfloatsandhowcomputersrepresentthem,Wikipedia9hasmoreinformationonthesubject.

Addition

ThePythonREPLcanbeusedas a simple calculator. If youwant to add twointegers,typeintheexpression:

>>>2+68

NOTE

Themathexampleabovedidnotbindtheresulttoavariable.Forasimplecalculationprintingouttheresult totheterminalmaybesufficient.Ifyouneedtheresultafterthefact,thePythoninterpreterstoresthelastresultinavariablenamed_:

>>>2+68>>>result=_>>>result8

Notethataddingtwointegerstogetherresultsinaninteger.Likewise,youcanalsoaddtwofloatstogether:

>>>.4+.010.41000000000000003

This example illustrates once again that care is neededwhen using floatingpointnumbers,asyoucanloseprecision(therealresultwouldbe0.41).Whathappenswhenyouaddanintegerandafloat?

>>>6+.26.2

Page 55: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Pythondecidedthatbecauseyouareaddinganintegerandafloat,youneedfloatingpoint arithmetic. In this case,Python converts orcoerces,6 to a floatbehindthescenes,beforeaddingitto.2.Pythonhasgivenyoutheanswerbackasafloat.

NOTE

Ifyouhaveanoperation involving twonumerics,coerciongenerallydoestherightthing.Foroperationsinvolvinganintegerandafloat,theintegeriscoercedtoafloat.

NOTE

Coercion between strings and numerics does not occur with mostmathematicaloperations.Twoexceptionsarethestringformattingoperator,andthemultiplicationoperator.Whenyouuse%withastringontheleftside(theleftoperand)andany

object (including numbers) on the right side (the right operand), Pythonperformstheformattingoperator:

>>>print('num:%s'%2)num:2

Iftheleftoperandisastringandyouusethemultiplicationoperator,*,Pythonperformsrepetition:

>>>'Python!'*2'Python!Python!'>>>'4'*2'44'

NOTE

Page 56: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Explicit conversion can be donewith theint andfloat built-in classes.(Althoughtheselooklikefunctionstheyarereallyclasses):

>>>int(2.3)2>>>float(3)3.0

Subtraction

Subtraction is similar to addition. Subtraction of two integers or two floatsreturnsanintegerorafloatrespectively.Formixednumerictypes,theoperandsarecoercedbeforeperformingsubtraction:

>>>2-6-4>>>.25-0.20.04999999999999999>>>6-.25.8

Multiplication

Inmanyprogramminglanguages,the*(asterisk)isusedformultiplication.Youcanprobablyguesswhatisgoingtohappenwhenyoumultiplytwointegers:

>>>6*212

Ifyouhavebeenfollowingcarefully,youwillalsoknowwhathappenswhenyoumultiplytwofloats:

>>>.25*12.03.0

Andifyoumixthetypesoftheproductyouendupwithafloatasaresult:

>>>4*.31.2

Page 57: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Notethatthefloatresultintheseexamplesappearscorrect,thoughyoushouldbecareful,duetofloatingpointprecisionissues,nottoassumethatyouwouldalwaysbesolucky.

Division

InPython(likemanylanguages),the/(slash)symbolisusedfordivision:

>>>12/43.0

Python3alsoaddressedwhatmanyconsideredtobeawartinpriorversionsofPython.Theresultofdividingtwointegersisafloat:

>>>3/40.75

Previously,Pythonperformedintegerdivision.Ifyouwantthatbehavior,youcan use the// operator.What integer does Python use? The floor of the realresult—taketheanswerandrounddown:

>>>3//40

Modulo

The modulo operator (%) calculates the modulus. This is the same as theremainderofadivisionoperationwhentheoperatorsarepositive.Thisisusefulfordeterminingwhetheranumberisoddoreven(orwhetheryouhaveiteratedover1000items):

#remainderof4dividedby3>>>4%31>>>3%2#oddif1isresult1>>>4%2#evenif0isresult0

TIP

Page 58: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TIP

Be careful with themodulo operator and negative numbers.Modulo canbehavedifferently,dependingonwhichoperandisnegative.Itmakessensethatifyouarecountingdown,themoduloshouldcycleatsomeinterval:

>>>3%30>>>2%32>>>1%31>>>0%30

What should-1%3 be?Sinceyouare countingdown it should cycleoverto2again:

>>>-1%32

Butwhenyouswitchthesignofthedenominator,thebehaviorbecomesweird:

>>>-1%-3-1

Pythonguarantees that the signof themodulo result is the sameas thedenominator(orzero).Tofurtherconfuseyou:

>>>1%-3-2

Thetakeawayhereis thatyouprobablydonotwanttodomodulowithnegativenumbersonthedenominatorunlessyouaresurethatiswhatyouneed.

Power

Pythonalsogivesyouthepoweroperatorbyusing**(doubleasterisks).Ifyouwantedtosquare4(4isthebase,2istheexponent),thefollowingcodewilldo

Page 59: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

it:

>>>4**216

Exponential growth tends to let numbers get large pretty quickly. Considerraising10tothe100thpower:

>>>10**10010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Programsneedtouseacertainamountofmemorytostoreintegers.Becauseintegers are usually smaller numbers,Pythonoptimizes for them, to notwastememory.Underthecovers,itcancoercesystemintegerstolongintegerstostorelargernumbers.Python3doesthisautomaticallyforyou.Ananalogymightbeascale.Ifyouarealwaysweighingsmallamounts,you

mightwantasmallscale.Ifyoudealinsand,youwillprobablywanttoputthesandinabagtomakeiteasiertohandle.Youwillhaveabunchofsmallbagsthatyouwilluse.Butifyouoccasionallyneedtoweighlargeritemsthatdonotfiton thesmall scale,youneed topulloutabiggerscale,andabiggerbag. Itwouldbeawastetousethebiggerbagandscaleformanyofthesmalleritems.Similarly,Pythontriestooptimizestoragespaceforintegerstowardssmaller

sizes.When Python does not have enoughmemory (a small bag) to fit largerintegers in, itcoerces the integer intoa long integer.This isactuallydesirablebecause,insomeenvironments,yourunintoanoverflowerrorhere,wheretheprogramdies(orPac-Manrefusestogooverlevel255—sinceitstoredthelevelcounterinan8-bitnumber).

NOTE

Python includes the operator module which provides functions forcommonmathematicaloperations.Whenusingmoreadvancedfeaturesof

Page 60: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Python such as lambda functions or list comprehensions, this modulecomesinhandy:

>>>importoperator>>>operator.add(2,4)#sameas2+46

Orderofoperations

Whenyouareperformingmath,youdonotapplyalltheoperationsfromlefttoright.Youdothemultiplicationanddivisionbeforetheadditionandsubtraction.Computersworkthesameway.Ifyouwanttoperformaddition(orsubtraction)first,useparenthesestoindicatetheorderofoperations:

>>>4+2310>>>(4+2)318

Asillustratedintheexample,anythinginparenthesesisevaluatedfirst.

Otheroperations

The help section from the REPL is pretty useful. There is a topic calledNUMBERMETHODSthatexplainshowallofthenumberoperationswork.

Summary

Python has built-in support for the basic mathematical operations. Addition,subtraction,multiplication,anddivisionareallincluded.Inaddition,thepowerandmodulus operations are available. If you need to control which order theoperationsoccur,wrapparenthesesaroundtheoperationthatyouwanttohappenfirst.Ifyouneedasimplecalculator, rather thanopeningacalculatorapplication,

givePythonatry.Itshouldbemorethancapableformosttasks.

Exercises

Page 61: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

1. Youslept for6.2,7,8,5,6.5,7.1,and8.5hours thisweek.Calculate theaveragenumberofhoursslept.

2. Is297divisibleby3?3. Whatis2raisedtothetenthpower?4. Wikipediadefinesleapyearsas:

Everyyear that is exactlydivisibleby four isa leapyear, except foryears that are exactly divisibleby100, but these centurial yearsareleapyearsiftheyareexactlydivisibleby400.Forexample,theyears1700,1800,and1900arenotleapyears,buttheyears1600and2000are.—https://en.wikipedia.org/wiki/Leap_year

WritePythoncode todetermine if 1800,1900, 1903,2000, and2002areleapyears.

9-https://en.wikipedia.org/wiki/Floating_point

Page 62: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Strings

STRINGSAREIMMUTABLEOBJECTSTHATHOLDCHARACTERDATA.ASTRINGCOULDHOLDasinglecharacter,aword,alineofwords,aparagraph,multipleparagraphs,orevenzerocharacters.Python denotes strings bywrapping themwith ' (single quotes), " (double

quotes),"""(tripledoubles)or'''(triplesingles).Herearesomeexamples:

>>>character='a'>>>name='Matt'>>>with_quote="Iain'tgonna">>>longer="""Thisstringhas...multiplelines...init""">>>latin='''Lorumipsum...dolor'''>>>escaped='Iain\'tgonna'>>>zero_chars=''>>>unicode_snake="Ilove\N{SNAKE}"

Noticethatthestringsalwaysstartandendwiththesamestyleofquote.Asillustrated in the with_quote example you can put single quotes inside of adouble-quoted string—andvice versa. Furthermore, if you need to include thesametypeofquotewithinyourstring,youcanescapethequotebyprecedingitwitha\ (backslash).Whenyouprintoutanescapedcharacterthebackslashisignored.

NOTE

Attentive readersmaywonder how to include a backslash in a string.Toincludeabackslashinanormalstring,youmustescapethebackslashwith...youguessedit,anotherbackslash:

>>>backslash='\\'

Page 63: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>backslash='\\'>>>print(backslash)\

NOTE

HerearethecommonwaystoescapecharactersinPython:

ESCAPESEQUENCE OUTPUT

\\ Backslash

\' Singlequote

\" Doublequote

\b ASCIIBackspace

\n Newline

\t Tab

\u12af Unicode16bit

\U12af89bc Unicode32bit

\N{SNAKE} Unicodecharacter

\o84 Octalcharacter

\xFF Hexcharacter

TIP

Ifyoudonotwanttouseanescapesequence,youcanusearawstringbypreceding thestringwithanr.Rawstringsarenormallyused twoplaces.Theyareusedinregularexpressions,wherethebackslashisalsousedasanescapecharacter.Youcanuseregularexpressionstomatchcharacters(suchas phone numbers, names, etc) from text. The re module in the Pythonstandard libraryprovides support for regular expressions.Raw strings arealsousedinWindowspathswherethebackslashisadelimiter.

Page 64: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Raw strings interpret the character content literally (ie. there is noescaping).Thefollowingillustratesthedifferencebetweenrawandnormalstrings:

>>>slash_t=r'\tText\\'>>>print(slash_t)\tText\\>>>normal='\tText\\'>>>print(normal)Text\

Pythonalsohasatriplequotingmechanismfordefiningstrings.Triplequotesare useful for creating strings containing paragraphs ormultiple lines. Triple-quoted strings are also commonly used in docstrings. Docstrings will bediscussedinthechapteronfunctions.Belowisanexampleofamulti-linetriple-quotedstring:

>>>paragraph="""Loremipsumdolor...sitamet,consecteturadipisicing...elit,seddoeiusmodtemporincididunt...utlaboreetdoloremagnaaliqua.Ut...enimadminimveniam,quisnostrud...exercitationullamcolaborisnisiut...aliquipexeacommodoconsequat.Duis...auteiruredolorinreprehenderitin...voluptatevelitessecillumdoloreeu...fugiatnullapariatur.Excepteursint...occaecatcupidatatnonproident,sunt...inculpaquiofficiadeseruntmollit...animidestlaborum."""

Anicebenefitofusingtriple-quotedstringsisthatyoucanembedsingleanddoublequotesinsideitwithoutescapingthem:

>>>"""Thisstringhasdouble"andsingle...quotes'insideofit"""'Thisstringhasdouble"andsingle\nquotes\'insideofit'

Page 65: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Unlesstheybuttuptotheendofthestring,thenyouwillneedtoescapethefinalquote:

>>>"""Hesaid,"Hello""""File"<stdin>",line1"""Hesaid,"Hello""""^SyntaxError:EOLwhilescanningstringliteral>>>"""Hesaid,"Hello\""""'Hesaid,"Hello"'

FormattingStrings

Storing strings in variables is nice, but being able to compose stringsof otherstringsandmanipulatethemisalsonecessary.Onewaytoachievethisistousestringformatting.InPython3,thepreferredwaytoformatstringsistousethe.formatmethod

ofstrings.Below,youtellPythontoreplace{}(aplaceholder)withthecontentsofnameorthestringMatt:

>>>name='Matt'>>>print('Hello{}'.format(name))HelloMatt

Anotherusefulpropertyof formatting is thatyoucanalso formatnon-stringobjects,suchasnumbers:

>>>print('I:{}R:{}S:{}'.format(1,2.5,'foo'))I:1R:2.5S:foo

Formatstringsyntax

Formatstringshaveaspecialsyntaxforreplacementfields.Ifanobjectispassedinto the format string, attributes can be looked up using .attribute_namesyntax.Thereisalsosupportforpullingindex-ableitemsoutbyusing[index]as well. The Python documentation refers to these as field names. The fieldnamescanbeempty,anameofakeywordargument,anumberofapositionalargument,orindexofalistordictionary(insquarebrackets):

>>>'Name:{}'.format('Paul')

Page 66: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>'Name:{}'.format('Paul')'Name:Paul'>>>'Name:{name}'.format(name='John')'Name:John'>>>'Name:{[name]}'.format({'name':'George'})'Name:George'

The curly braces ({ and}) can also contain an integer inside of them. Theinteger refers to the zerobasedpositionof the argumentpassed into.format.Below is an example of using the numbers of positional arguments in theplaceholders. The first argument to .format, 'Paul', is at position 0, thesecond,'George',isposition1,and'John'isat2:

>>>'Last:{2}First:{0}'.format('Paul','George',...'John')'Last:JohnFirst:Paul'

There is a whole language for formatting strings. If you insert a colonfollowing the fieldname, you canprovide further formatting information.Theformatisbelow.Anythinginsquarebracketsisoptional:

:[[fill]align][sign][#][0][width][grouping_option][.precision][type]

Thefollowingtablesliststhefieldsandtheirmeaning.

FIELD MEANING

fill Characterusedtofillinalign(defaultisspace)

align Alightoutput<(leftalign),>(rightalign),^(centeralign),or=(putpaddingaftersign)

sign Fornumbers+(showsignonbothpositiveandnegativenumbers,-(default,onlyonnegative),orspace(leadingspaceforpositive,signonnegative)

# Prefixintegers.0b(binary),0o(octal),or0x(hex)

0 Enablezeropadding

width Minimumfieldwidth

grouping_option Numberseparator,(usecommaforthousandsseparator),_(Useunderscoreforthousandsseparator)

.precision Forfloats(digitsafterperiod(floats),fornon-numerics(maxlength)

typeNumbertypeors(stringformatdefault)seeIntegerandFloatcharts

Page 67: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

type

Thetablesbelowliststhevariousoptionsyouhaveforformattingintegerandfloatingpointnumbers.

INTEGERTYPES MEANING

b binary

c character-converttoUnicodecharacter

d decimal(default)

n decimalwithlocale-specificseparators

o octal

x hex(lower-case)

X hex(upper-case)

FLOATTYPES MEANING

e/E Exponent.Lower/upper-casee

f Fixedpoint

g/G General.Fixedwithexponentforlarge,andsmallnumbers(gdefault)

n gwithlocale-specificseparators

% Percentage(multipliesby100)

Someformatexamples

Hereareafewexamplesofusing.format.Toformatastringinthecenterof12characterssurroundedby*,use thecodebelow.* is the fillcharacter,^ is thealignfield,and12isthewidthfield:

>>>"Name:{:*^12}".format("Ringo")'Name:***Ringo****'

Next,youformatapercentageusingawidthof10,onedecimalplace,andthesignbeforethewidthpadding.=isthealignfield,+ensuresthatthereisalwaysasign(negativeorpositive),10.1arethewidthandprecisionfields,and%isthefloattype,whichconvertsthenumbertoapercentage:

>>>"Percent:{:=+10.1%}".format(-44/100)'Percent:-44.0%'

Page 68: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

'Percent:-44.0%'

Belowareabinaryandahexconversion.Theintegertypefieldissettobandxrespectively:

>>>"Binary:{:b}".format(12)'Binary:1100'>>>"Hex:{:x}".format(12)'Hex:c'

NOTE

The.formatmethodonastringprovidesanalternativeforthe%operatorwhich issimilar toC’sprintf.The%operator isstillavailableandsomeuserspreferitasitrequireslesstypingforsimplestatementsandbecauseitissimilartoC.%s,%d,and%xarereplacedbytheirstring,integer,andhexvaluesrespectively.Herearesomeexamples:

>>>"Num:%dHex:%x"%(12,13)'Num:12Hex:d'>>>"%s%s"%('hello','world')'helloworld'

TIP

A great resource for formatting is in the built-in help documentation,availableintheREPL.Type:

>>>help()

Whichputsyouinthehelpmode,andgivesyouahelp>prompt.Thentype:

help>FORMATTING

Youcanscrollthroughhereandfindmanyexamples.Abarereturnfromthehelp>promptwillreturnyoutothenormalprompt.

Page 69: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Anotherresourceisfoundathttps://pyformat.info/.Thiswebsitecontainsmanyformattingexampleswithboth.formatandtheolder%operator.Thereisalsoanentryinhelpforstrings,locatedunderSTRINGS.

F-Strings

Python 3.6 introduced a new type of string, called f-string. If you precede astringwith anf, it will allow you to include code inside of the placeholders.Hereisabasicexample:

>>>name='matt'>>>f'Mynameis{name}''Mynameismatt'

Pythonwilllookintheplaceholderandevaluatethecodethere.Notethattheplaceholdercancontainfunctioncalls,methodcalls,oranyotherarbitrarycode:

>>>f'Mynameis{name.capitalize()}''MynameisMatt'

Youcanalsoprovideformatstringsfollowingacolon:

>>>f'Squarerootoftwo:{2**.5:5.3f}''Squarerootoftwo:1.414'

Summary

In this chapter, strings were introduced. Strings can be defined with variousdelimiters. Unlike other languages, which may distinguish between a stringdefined with " and one defined with ', Python makes no distinction. Triple-quotedstrings,however,mayspanmultiplelines.We also looked at the .format method and gave examples of formatting

strings.Finally,thechapterintroducedanewfeatureinPython3.6,f-strings.

Exercises

1. Create a variable, name, pointing to your name. Create another variable,age,holdinganintegervalueforyourage.Printoutastringformattedwith

Page 70: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

bothvalues.IfyournamewasFredandagewas23itwouldprint:

Fredis23

2. Createavariable,paragraph,thathasthefollowingcontent:

"Python is a great language!", said Fred. "I don't ever rememberhavingthismuchfunbefore."

3. Gotohttps://unicode.organdfindthesymbolomegaintheGreekcharactercodechart.Create a string thatholds theomegacharacter, usingboth theUnicodecodepoint(\uform)andUnicodename(\Nform).Thecodepointis the hex number in the chart, the name is the bolded capital namefollowing the code point. For example, the theta character has the codepointof03f4andanameofGREEKCAPITALTHETASYMBOL.

4. Make a variable, item, that points to a string, "car". Make a variable,cost, that points to 13499.99. Print out a line that has item in a left-justified area of 10 characters, and cost in a right-justified area of 10characters with 2 decimal places and commas in the thousands place. Itshouldlooklikethis(withoutthequotes):

'car13,499.99'

Page 71: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

dir,help,andpdb

YOUHAVEONLYTOUCHEDTHESURFACEOFSTRINGS,BUTYOUNEEDTOTAKEABREAKtodiscuss twoimportantfunctionsandonelibrarythatcomewithPython.Thefirstfunctionisdir,whichillustrateshowpowerfulandusefultheREPLis.Thedir functionreturnstheattributesofanobject. IfyouhadaPythoninterpreteropen and wanted to knowwhat the attributes of a string are, you can do thefollowing:

>>>dir('Matt')['__add__','__class__','__contains__','__delattr__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__getitem__','__getnewargs__','__gt__','__hash__','__init__','__iter__','__le__','__len__','__lt__','__mod__','__mul__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__rmod__','__rmul__','__setattr__','__sizeof__','__str__','__subclasshook__','capitalize','casefold','center','count','encode','endswith','expandtabs','find','format','format_map','index','isalnum','isalpha','isdecimal','isdigit','isidentifier','islower','isnumeric','isprintable','isspace','istitle','isupper','join','ljust','lower','lstrip','maketrans','partition','replace','rfind','rindex','rjust','rpartition','rsplit','rstrip','split','splitlines','startswith','strip','swapcase','title','translate','upper','zfill']

dirlistsalltheattributesoftheobjectpassedintoit.Sinceyoupassedinthestring'Matt'todir,thefunctiondisplaystheattributesofastring.Thishandyfeature of Python illustrates its “batteries included” philosophy. Python givesyouaneasymechanismtodiscovertheattributesofanyobject.Otherlanguages

Page 72: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

might require special websites, documentation or IDEs to access similarfunctionality.But in Python, because you have theREPL, you can get at thisinformationquicklyandeasily.Theattributelistisinalphabeticalorder,andyoucannormallyignorethefirst

couple of attributes startingwith__. Later on, youwill see attributes such ascapitalize(whichisamethodthatcapitalizesastring),format(whichaswasillustrated previously, allows for formatting of strings), or lower (which is amethod used to ensure the string is lowercase). These attributes happen to bemethods,which are functions that are attached to objects.To call, or invoke afunction, you place a period after the object, then the method name, thenparentheses.Thethreemethodsareinvokedbelow:

>>>print('matt'.capitalize())Matt>>>print('Hi{}'.format('there'))Hithere>>>print('YIKES'.lower())yikes

Dundermethods

Youmightbewonderingwhatalltheattributesstartingwith__are.Peoplecallthemspecialmethods,magicmethods,ordundermethodssincetheystart(andend)withdoubleunderscores(DoubleUNDERscores).“Dunderadd”isonewaytosay__add__,“theaddmagicmethod”isanother.Specialmethodsdeterminewhathappensunderthecoverswhenoperationsareperformedonanobject.Forexample, when you use the + or % operator on a string, the .__add__ or.__mod__methodisinvokedrespectively.Beginner Pythonistas can usually ignore dunder methods. When you start

implementingyourownclassesandwantthemtoreacttooperationssuchas+or%,youcandefinethem.

Page 73: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TIP

In thehelp()documentation isanentry,SPECIALMETHODS, thatdescribesthesemethods.AnotherplacewherethesearedescribedisonthePythonwebsite.Goto

Documentation, Language Reference, Data Model. It is tucked away inthere.

help

helpisanotherbuiltinfunctionthatisusefulincombinationwiththeREPL.Thebook previouslymentioned invokinghelp(),without any arguments, to bringuphelpdocumentation.Thehelpfunctionalsoprovidesdocumentationforamethod,module,class,

orfunctionifyoupasstheminasanargument.Forexample,ifyouarecuriouswhat the attribute upper on a string does, the following gives you thedocumentation:

>>>help('somestring'.upper)Helponbuiltinfunctionupper:upper(...)methodofbuiltins.strinstanceS.upper()->strReturnacopyofSconvertedtouppercase.

The help function, combined with the REPL, allows you to read up ondocumentationwithouthavingtogotoabrowser,orevenhaveinternetaccess.If you were stranded on a desert island, you should be able to learn Python,providedyouhadacomputerwithPythoninstalledandapowersource.

pdb

Pythonalso includesadebugger to step throughcode. It is found inamodulenamedpdb.ThislibraryismodeledafterthegdblibraryforC.TodropintothedebuggeratanypointinaPythonprogram,insertthecode:

importpdb;pdb.set_trace()

Page 74: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

importpdb;pdb.set_trace()

These are two statements here, but I typically type them in a single lineseparated by a semicolon—that way I can easily remove them with a singlekeystrokefrommyeditorwhenIamdonedebugging.ThisisalsoabouttheonlyplaceIuseasemicoloninPythoncode(twostatementsinasingleline).Whenthislineisexecuted,itwillpresenta(pdb)prompt,whichissimilarto

theREPL.Codecanbeevaluatedatthispromptandyoucaninspectobjectsandvariablesaswell.Also,breakpointscanbesetforfurtherinspection.Belowisatablelistingusefulpdbcommands:

COMMAND PURPOSEh,help Listthecommandsavailable

n,next Executethenextline

c,cont,continue Continueexecutionuntilabreakpointishit

w,where,bt Printastacktraceshowingwhereexecutionis

u,up Popupalevelinthestack

d,down Pushdownalevelinthestack

l,list Listsourcecodearoundcurrentline

NOTE

InProgrammingPearls,JonBentleystates:

WhenIhavetodebugalittlealgorithmdeepinsideabigprogram,Isometimesusedebuggingtools... though,printstatementsareusuallyfastertoimplementandmoreeffectivethansophisticateddebuggers.

I've heard Guido van Rossum, the creator of Python, voice the sameopinion:heprefersprintdebugging.Printdebuggingiseasy,simplyinsertprint functions to provide clarity as to what is going on. This is oftensufficient to figure out a problem. Make sure to remove these debug

Page 75: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

statementsorchangethemtologgingstatementsbeforereleasingthecode.Ifmoreexplorationisrequired,youcanalwaysusethepdbmodule.

Summary

Python provides many tools to make your life easier. If you learn to use theREPL,youcantakeadvantageofthem.Thedirfunctionwillhelpyouseewhatthe attributesof anobject are.Then,youcanuse thehelp function to inspectthoseattributesfordocumentation.Thischapteralsointroducedthepdbmodule.Thismoduleallowsyoutostep

throughcode,whichcanbeusefulfordebugging.

Exercises

1. OpenaREPL,andcreateavariable,name,withyourname in it.List theattributesofthestring.Printoutthehelpdocumentationforthe.findand.titlemethods.

2. Open a REPL, and create a variable, age, with your age in it. List theattributes of the integer. Print out the help documentation for the.numeratormethod.

Page 76: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

StringsandMethods

INTHEPREVIOUSCHAPTERYOULEARNEDABOUTTHEBUILT-IN DIRFUNCTIONANDSAWsomemethods you can call on string objects. Because strings are immutable,thesemethodsdonotmutatethestring,butratherreturnanewstringoranewresult. Strings allow you create a new version that is capitalized, return aformattedstring,orcreatealowercasestring,aswellasmanyotheractions.Youdothisbycallingmethods.Methodsarefunctionsthatarecalledonaninstanceofatype.Whatdoesthis

mean? The string type allows you to call a method (another term for call isinvoke)byplacinga.(period)andthemethodnamedirectlyafterthevariablename holding the data (or the data itself), followed by parentheses withargumentsinsideofthem.

NOTE

Inthisbook,Iplaceaperiodinfrontofmethods.Thisismeanttoremindyouthatyouneedtohaveanobjectbeforethemethod.Iwillmentionthe.capitalize method, rather than saying capitalize. The invocationlookslikethisonthetextobject:

text.capitalize()

This is in contrast to a function, likehelp,whichyou invokeby itself(thereisnoobjectorperiodbeforeit):

help()

Page 77: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Illustrationofcallingamethodonastring.Themethoddoesnotchangethestringbecauseitisimmutable.Rather,themethodreturnsanewstring.

Hereisanexampleofcallingthe.capitalizemethodonavariablepointingtoastringandastringliteral.Notethatthisdoesnotchangetheobjectonwhichit is called. Because a string is immutable, the result of themethod is a newobjectwiththecapitalizedvalue:

Page 78: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>name='matt'#invokedonvariable>>>correct=name.capitalize()>>>print(correct)Matt

Notethatnamedoesnotchange:

>>>print(name)matt

Note,the.capitalizemethoddoesnothavetobecalledonavariable.Youcaninvokethemethoddirectlyonastringliteral:

>>>print('fred'.capitalize())Fred

In Python,methods and functions are first-class objects.Aswas previouslymentioned,everythingisanobject.Iftheparenthesesareleftoff,Pythonwillnotthrowanerror,itwillonlyshowareferencetoamethod,whichisanobject:

>>>print('fred'.capitalize)<built-inmethodcapitalizeofstrobjectat0x7ff648617508>

Having first-class objects enablesmore advanced features like closures anddecorators(thesearediscussedinmyintermediatePythonbook).

NOTE

Do integersand floatshavemethods?Yes,again,everything inPython isandobjectandobjectshavemethods.Thisiseasytoverifybyinvokingdironaninteger(oravariableholdinganinteger):

>>>dir(4)['__abs__','__add__','__and__','__class__',...'__subclasshook__','__truediv__','__trunc__','__xor__','conjugate','denominator','imag','numerator','real']

Page 79: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Invokingamethodonanumberissomewhattrickyduetotheuseofthe. to denote calling a method. Because . is common in floats, it wouldconfusePythonif.werealsousedtocallmethodsonnumbers.Forexample, the.conjugatemethodreturns thecomplexconjugateof

aninteger.Butifyoutrytoinvokeitonaninteger,youwillgetanerror:

>>>5.conjugate()Traceback(mostrecentcalllast):...5.conjugate()^SyntaxError:invalidsyntax

Onesolutiontothisistowrapthenumberwithparentheses:

>>>(5).conjugate()5

Anotheroptionwouldbetoassignavariableto5andinvokethemethodonthevariable:

>>>five=5>>>five.conjugate()5

However,inpractice,itisfairlyraretocallmethodsonnumbers.

Commonstringmethods

Hereareafewstringmethodsthatarecommonlyusedorfoundinthewild.Feelfreetoexploreothersusingdirandhelp(ortheonlinedocumentation).

endswith

If you have a variable holding a filename, you might want to check theextension.Thisiseasywith.endswith:

>>>xl='Oct2000.xls'>>>xl.endswith('.xls')True>>>xl.endswith('.xlsx')False

Page 80: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

NOTE

Noticethatyouhadtopassinaparameter (orargument),'xls', intothemethod.Methods have a signature, which is a funkyway of saying thattheyneedtobecalledwiththecorrectnumber(andtype)ofparameters.Forthe.endswithmethod,itmakessensethatifyouwanttoknowifastringendswithanotherstringyouhavetotellPythonwhichendingyouwanttocheckfor.Thisisdonebypassingtheendstringtothemethod.

TIP

Again, it isusuallyeasytofindout thissortof informationviahelp.Thedocumentationshouldtellyouwhatparametersarerequiredaswellasanyoptionalparameters.Hereisthehelpforendswith:

>>>help(xl.endswith)Helponbuilt-infunctionendswith:endswith(...)S.endswith(suffix[,start[,end]])->boolReturnTrueifSendswiththespecifiedsuffix,Falseotherwise.Withoptionalstart,testSbeginningatthatposition.Withoptionalend,stopcomparingSatthatposition.suffixcanalsobeatupleofstringstotry.

Noticetheline:

S.endswith(suffix[,start[,end]])->bool

TheSrepresentsthestring(orinstance)youareinvokingthemethodon,in thiscase, thexlvariable..endswith is themethodname.Betweentheparentheses,( and), are theparameters.suffix is arequired parameter,the.endswithmethodwillcomplainifyoudonotprovideit:

>>>xl.endswith()Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>

Page 81: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

File"<stdin>",line1,in<module>TypeError:endswith()takesatleast1argument(0given)

The parameters between the square brackets [ and ] are optionalparameters.Inthiscase,startandendallowyoutoonlycheckaportionof the string. If you wanted to check if the characters starting at 0 andendingat3endswithOctyoucoulddothefollowing:

>>>xl.endswith('Oct',0,3)True

Stringsalsohavea.startswithmethod,sothecorrectwaytocheckifastringstartswith'Oct'is:

>>>xl.startswith('Oct')True

find

The.findmethodallowsyou tofindsubstrings insideotherstrings. It returnstheindex(offsetstartingat0)ofthematchedsubstring.Ifnosubstringisfounditreturns-1:

>>>word='grateful'#0isg,1isr,2isa>>>word.find('ate')2>>>word.find('great')-1

format

formatallowsforeasycreationofnewstringsbycombiningexistingvariables.Thechapteronstringsdiscussedthismethod:

>>>print('name:{},age:{}'.\...format('Matt',10))name:Matt,age:10

NOTE

Page 82: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

NOTE

In the above example, the print function is spread across two lines. Byplacinga\followinga.youindicatetoPythonthatyouwanttocontinueonthenextline.Ifyouhaveopenedaleftparenthesis,(,youcanalsoplacetheargumentsonmultiplelineswithouta\:

>>>print("word"....find('ord'))1>>>print("word".find(...'ord'))1

Tohelpmake thecodemore readable, indent thecontinued lines.Notethat indenting with four spaces serves to indicate to anyone reading thecodethatthesecondlineisacontinuationofapreviousstatement:

>>>print("word".\...find('ord'))1>>>print("word".find(...'ord'))1

Whyspreadcodethatcouldresideinasinglelineacrossmultiplelines?Wherethiscomesintoplayinmostcodeisdealingwithcodestandardsthatexpect lines to be less than 80 characters in length. If a method takesmultiplearguments, itmaybehardtofollowthe80character limit.(NotethatPythonitselfdoesnotcareaboutlinelength,butreadersofyourcodemight). It is not uncommon to see a separate line for each argument to amethod:

>>>print('{}{}{}{}{}'.format(...'hello',...'to',...'you',...'and',...'you'...))hellotoyouandyou

Page 83: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

join

Oftentimes you have a list (lists are discussed later in the book) of items andneedtoinsertsomethingbetweenthem.The.joinmethodcreatesanewstringfromasequencebyinsertingastringbetweeneverymemberofthelist:

>>>','.join(['1','2','3'])'1,2,3'

TIP

For most Python interpreters, using .join is faster than repeatedconcatenationusingthe+operator.Theaboveidiomiscommon.

lower

The.lowermethodreturnsacopyofthestringconvertedtolowercase.Theisoften useful for validating if the input matches a string. For example, someprogramscapitalizefileextensions,whileothersdonot.IfyouwantedtoknowifafilenamehadTXTortxtasanextension,youcoulddothefollowing:

>>>fname='readme.txt'>>>fname.endswith('txt')orfname.endswith('TXT')True

AmorePythonicversionwouldread:

>>>fname.lower().endswith('txt')True

startswith

The.startswithmethodisanalogousto.endswithexceptthatitchecksthatastringstartswithanotherstring:

>>>'Book'.startswith('B')True>>>'Book'.startswith('b')False

Page 84: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

strip

The .strip method returns a new string that removes preceding and trailingwhitespace (spaces, tabs, newlines). This may come in handy if you have tonormalizedataorparseinputfromauser(ortheweb):

>>>'hellothere'.strip()'hellothere'

Notethatthreespacesatthefrontofthestringwereremovedaswerethetwoat the end. But the two spaces between thewordswere left intact. If you areinterestedinremovingonlytheleadingwhitespaceorrightmostwhitespace,themethodslstripandrstriprespectivelywillperformthoseduties.

upper

The.uppermethodisanalogousto.lower.Itreturnsacopyofthestringwithalloftheletterscapitalized:

>>>'yell'.upper()'YELL'

Othermethods

Thereareotherstringmethods,buttheyareusedlessoften.Feelfreetoexplorethembyreadingthedocumentationandtryingthemout.Theappendixprovidesalistofthem.

NOTE

The STRINGMETHODS entry in the help section from the REPL containsdocumentationforallofthestringmethodsaswellassomeexamples.

Summary

This chapter talked about methods. Methods are always called by putting anobject and a period before themethod name.You also looked at some of themore common methods of strings. One thing to remember is that a string is

Page 85: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

immutable. If youwant to change a string’s value, you need to create a newstring.

Exercises

1. Createastring,school,withthenameofyourelementaryschool.Examinethemethodsthatareavailableonthatstring.Usethehelpfunctiontoviewtheirdocumentation.

2. Create a string, country, with the value 'usa'. Create a new string,correct_country, that has the value in uppercase, by using a stringmethod.

3. Createastring,filename,thathasthevalue'hello.py'.Checkandseeifthefilenameendswith'.java'.Findtheindexlocationof'py'.Seeifitstartswith'world'.

4. Open a REPL. Enter the help documentation and scan through theSTRINGMETHODSentry.

Page 86: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Comments,Booleans,andNone

THISCHAPTERWILLINTRODUCECOMMENTS,BOOLEANS,ANDNONE.COMMENTSHAVETHEpotentialtomakeyourcodemorereadable.ThebooleanandNonetypesareverycommonthroughoutPythoncode.

Comments

CommentsarenotatypepersebecausetheyareignoredbyPython.Commentsserve as reminders to the programmer. There are various takes on comments,theirpurpose,andtheirutility.Thereisacontinuumfromthosewhoareagainstanyandallcomments,tothosewhocommentalmosteverylineofcode,aswellas those who are in between. If you are contributing to a project, try to beconsistent with their commenting scheme. A basic rule of thumb is that acomment should explain thewhy rather than the how (code alone should besufficientforthehow).TocreateacommentinPython,startalinewitha#.Anythingthatfollowsthe

hashisignored:

>>>#ThislineisignoredbyPython

Youcanalsocommentattheendofaline:

>>>num=3.14#PI

TIP

Arogueuseofcomments is to temporarilydisablecodeduringediting.Ifyoureditorsupportsthis,itissometimeseasiertocommentoutcoderatherthanremoveitcompletely.Butthebestpracticeistoremovecommented-outcodebeforesharingthecodewithothers.

Page 87: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Otherlanguagessupportmulti-linecomments,butPythondoesnot.Theonlywaytocommentmultiplelinesistostarteverylinewith#.

TIP

You may be tempted to comment out multiple lines of code by makingthoselinesatriple-quotedstring.Thisisuglyandconfusing.Trynottodothis.

Booleans

Booleansrepresentthevaluesfortrueandfalse.Youhavealreadyseentheminpreviouscodeexamples,suchastheresultof.startswith:

>>>'bar'.startswith('b')True

Youcanalsoassignthosevaluestovariables:

>>>a=True>>>b=False

NOTE

TheactualnameofthebooleanclassinPythonisbool,notboolean:

>>>type(True)<class'bool'>

Itcanbeusefultoconvertothertypestobooleans.InPython,theboolclasscandothat.Convertingfromonetypetoanotheriscalledcasting.However,thisis usually unnecessary due to the implicit casting Python performs whenconditionals are evaluated. The conditional statement will do this casting foryou.

Page 88: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

InPythonparlance, it is common tohearofobjectsbehavingas“truthy”or“falsey”—that means that non-boolean types can implicitly behave as thoughtheywerebooleans. Ifyouareunsurewhat thebehaviormightbe,pass in thetypetotheboolclassforanexplicitconversion(orcast).For strings, an empty string is “falsey”, while non-empty values coerce to

True:

>>>bool('')False>>>bool('0')#Thestringcontaining0True

Since a non-empty string behaves as truthy, you can testwhether the stringhascontent.Inthecodebelownamehasbeenset,butimaginethatitcamefromuserinput:

>>>name='Paul'>>>ifname:...print("Thenameis{}".format(name))...else:...print("Nameismissing")ThenameisPaul

Youdon'thavetotestifthenamehasalength.Sodon'tdothis:

>>>iflen(name)>0:...print("Thenameis{}".format(name))

Also,youdon'tneedtodothis:

>>>ifbool(name):...print("Thenameis{}".format(name))

becausePythonwillevaluatethecontentsoftheifstatement,andcoercetoabooleanforyou.BecauseastringisTruewhenithascontentyouonlyneed:

>>>ifname:...print("Thenameis{}".format(name))

NOTE

Page 89: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thebuiltintypes,int,float,str,andbool,areclasses.Eventhoughtheircapitalization(lowercase)makesitlookasiftheywerefunctions,theyareclasses.Invokinghelp(str)willconfirmthis:

>>>help(str)Helponclassstrinmodulebuiltins:classstr(object)|str(object='')->str|str(bytes_or_buffer[,encoding[,errors]])->str|

This is one of those slight inconsistencies with Python. User-definedclasses typically follow PEP8, which suggests camel cased naming ofclasses.

For numbers, zero coerces to False while other numbers have “truthy”behavior:

>>>bool(0)False>>>bool(4)True

Whileexplicitcastingviatheboolfunctionisavailable,itisusuallyoverkill,because variables are implicitly coerced to booleanswhen used in conditionalstatements. For example, container types, such as lists and dictionaries, whenempty,behaveas“falsey”.Ontheflipside,whentheyarepopulatedtheyactas“truthy”.

TIP

Becarefulwhenparsingcontentthatyouwanttoturnintobooleans.Stringsthat are non-empty evaluate toTrue.One example of a string thatmightbiteyouisthestring'False'whichevaluatestoTrue:

>>>bool('False')True

Page 90: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Hereisatableoftruthyandfalseyvalues:

TRUTHY FALSEYTrue False

Mostobjects None

1 0

3.2 0.0

[1,2] [](emptylist)

{'a':1,'b':2} {}(emptydict)

'string' ""(emptystring)

'False'

'0'

TIP

Do not test boolean values to check if they are equal to True. Do notexplicitlycastexpressionstobooleanresults.Ifyouhaveavariable,done,containingaboolean,thisissufficient:

ifdone:#dosomething

Whilethisisoverkill:

ifdone==True:#dosomething

Asisthis:

ifbool(done):#dosomething

Similarly, if you have a list and need to distinguish between an emptyandnon-emptylist,thisissufficient:

members=[]ifmembers:

Page 91: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

#dosomethingifmembers#havevalueselse:#memberisempty

Likewise, this test is superfluous. It is not necessary to determine thetruthinessofalistbyitslength:

iflen(members)>0:#dosomethingifmembers#havevalueselse:#memberisempty

NOTE

If youwish to define the implicit truthiness for user-defined objects, the.__bool__methodspecifiesthisbehavior.ItcanreturnTrue,orFalse.Ifthismagicmethod is not defined, the.__len__method is checked for anon-zerovalue.Ifneithermethodisdefined,anobjectdefaultstoTrue:

>>>classNope:...def__bool__(self):...returnFalse>>>n=Nope()>>>bool(n)False

Ifthisisconfusing,feelfreetocomebacktothisexampleafterreadingaboutclasses.

None

None isaninstanceofNoneType.Otherlanguageshavesimilarconstructssuchasnil,NULL orundefined.Variables can be assigned toNone to indicate thattheyarewaitingtoholdarealvalue.NonecoercestoFalseinabooleancontext:

>>>bool(None)False

Page 92: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

NOTE

A Python function defaults to returning None if no return statement isspecified:

>>>defhello():...print("hi")>>>result=hello()hi>>>print(result)None

NOTE

None isasingleton (PythononlyhasonecopyofNone in the interpreter).Theidforthisvaluewillalwaysbethesame:

>>>a=None>>>id(a)140575303591440>>>b=None>>>id(b)140575303591440

AsanyvariablecontainingNoneisthesameobjectasanyothervariablecontaining None. You typically use is to check for identity with thesevariablesratherthanusing==tocheckforequality:

>>>aisbTrue>>>aisnotbFalse

isisfasterthan==andconnotestotheprogrammerthatidentityisbeingcomparedratherthanthevalue.Youcanputtheisexpressioninanifstatement:

>>>ifaisNone:...print("Aisnotset!")Aisnotset!

Page 93: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

SinceNoneevaluatestoFalseinabooleancontextyoucouldalsodothefollowing:

>>>ifnota:...print("Aisnotset!")Aisnotset!

But,youshouldbecarefulasothervaluesalsoevaluatetoFalse,suchas0,[],or''(emptystring).CheckingagainstNoneisexplicit.

Summary

In this chapter, you learned about comments inPython.Comments are startedwith a hash, and any content following the hash until the end of the line isignored.Therearenomulti-linecomments.Thechapter alsodiscussedTrue,False, andbooleancoercion.Mostvalues

areTrueinabooleancontext(whenusedinanifstatement).TheFalsevaluesarezero,None,andemptysequences.Finally, the None object was mentioned. It is a singleton that is used to

indicatethatyouhaveavariablethatmaybeassignedavalueinthefuture.Itisalsotheresultofafunctionthatdoesnotexplicitlyreturnavalue.

Exercises

1. Create a variable,age, set to your age.Create another variable,old, thatuses a condition to testwhether you are older than 18.The value ofoldshouldbeTrueorFalse.

2. Create a variable, name, set to your name. Create another variable,second_half,thattestswhetherthenamewouldbeclassifiedinthesecondhalfofthealphabet?Whatdoyouneedtocompareitto?

3. Createalist,names,withthenamesofpeopleinaclass.Writecodetoprint'The class is empty!' or 'Class has enrollments.', based onwhethertherearevaluesinnames.(Seethetipinthischapterfordetails).

Page 94: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

4. Createavariable,car,settoNone.Writecodetoprint'Taxiforyou!',or'Youhaveacar!',basedonwhetherornotcarisset(Noneisnotthenameofacar).

Page 95: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

ConditionalsandWhitespace

IN THIS CHAPTER, YOUWILL LEARNMORE ABOUTMAKING COMPARISONS IN PYTHON.Most code needs tomake decisions aboutwhich path to execute, so youwilllookathowthisisdone.Inadditiontothebooleanvalues,TrueandFalse,inPython,youcanalsouse

expressionstogetbooleanvalues.Ifyouhavetwonumbers,youmightwanttocompare them to check if they are greater than or less than each other. Theoperators,>and<,dothisrespectively:

>>>5>9False

Hereisatableofcomparisonoperationstocreatebooleanvalues:

OPERATOR MEANING

> Greaterthan

< Lessthan

>= Greaterthanorequalto

<= Lessthanorequalto

== Equalto

!= Notequalto

is Identicalobject

isnot Notidenticalobject

Theseoperationsworkonmosttypes.Ifyoucreateacustomclassthatdefinestheappropriatemagicmethods,yourclasscanusethemaswell:

>>>name='Matt'>>>name=='Matt'True

Page 96: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>name!='Fred'True>>>1>3False

NOTE

The“richcomparison”magicmethods,__gt__,__lt__,__ge__,__le__,__eq__, and __ne__ correspond to >, <, >=, <=, ==, and != respectively.Defining all of these canbe somewhat tedious and repetitive. For classeswhere these comparisons are commonly used, thefunctools.total_ordering class decorator gives you all of thecomparison functionality as long as you define __eq__ and __le__. Thedecorator will automatically derive the remainder of the comparisonmethods.Otherwise,allsixmethodsshouldbeimplemented:

>>>importfunctools>>>@functools.total_ordering...classAbs(object):...def__init__(self,num):...self.num=abs(num)...def__eq__(self,other):...returnself.num==abs(other)...def__lt__(self,other):...returnself.num<abs(other)>>>five=Abs(-5)>>>four=Abs(-4)>>>five>four#notusinglessthan!True

Decoratorsareconsideredanintermediatesubjectandarenotcoveredinthisbeginningbook.

TIP

Theisandisnotstatementsareforcomparingidentity.Whentestingforidentity—if twoobjects are the same actual objectwith the sameid (not

Page 97: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

justthesamevalue)—useisorisnot.SinceNoneisasingletonandonlyhasoneidentity,isandisnotareusedwithNone:

>>>ifnameisNone:...#initializename

Combiningconditionals

Conditionalexpressionsarecombinedusingbooleanlogic.Thislogicconsistsoftheand,or,andnotoperators.

BOOLEANOPERATOR MEANING

xandy BothxandymustevaluatetoTruefortrueresult

xory IfxoryisTrue,resultistrue

notx Negatethevalueofx(TruebecomesFalseandviceversa)

Belowisasimpleexampleforsettingagradebasedonascoreusingandtotestwhetherthescoreisbetweentwonumbers:

>>>score=91>>>ifscore>90andscore<=100:...grade='A'

NOTE

Pythonallowsyoutodotheaboveexampleusingarangecomparisonlikethis:

>>>if90<score<=100:...grade='A'

Either style works, but range comparisons are not common in otherlanguages.

Hereisanexampleforcheckingifagivennameisamemberofaband:

>>>name='Paul'>>>beatle=False

Page 98: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>beatle=False>>>ifname=='George'or\...name=='Ringo'or\...name=='John'or\...name=='Paul':...beatle=True...else:...beatle=False

NOTE

In theaboveexample the\at theendof"'George'or\" indicates thatthestatementwillbecontinuedonthenextline.Like most programming languages, Python allows you to wrap

conditional statements in parentheses. Because they are not required inPython,mostdevelopersleavethemoutunlesstheyareneededforoperatorprecedence.Butanothersubtletyofusingparenthesesisthattheyserveasahinttotheinterpreterwhenastatementisstillopenandwillbecontinuedonthenextline,hencethe\isnotneededinthatcase:

>>>name='Paul'>>>beatle=False>>>if(name=='George'or...name=='Ringo'or...name=='John'or...name=='Paul'):...beatle=True...else:...beatle=False

TIP

An idiomaticPythonversionof checkingmembership is listedbelow.Tocheck if a value is found across a variety of values, you can throw thevaluesinasetandusetheinoperator:

>>>beatles={'George','Ringo','John','Paul'}>>>beatle=nameinbeatles

Page 99: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Alaterchapterwilldiscusssetsfurther.

Hereisanexampleofusingthenotkeywordinaconditionalstatement:

>>>last_name='unknown'>>>ifname=='Paul'andnotbeatle:...last_name='Revere'

ifstatements

Booleans(TrueandFalse)areoftenusedinconditionalstatements.Conditionalstatementsareinstructionsthatsay“ifthisstatementistrue,performablockofcode, otherwise execute some other code.” Branching statements are usedfrequently in Python. Sometimes, the “if statement” will check values thatcontainbooleans,othertimesitwillcheckexpressionsthatevaluatetobooleans.Anothercommoncheckisforimplicitcoercionto“truthy”or“falsey”values:

>>>debug=True>>>ifdebug:#checkingaboolean...print("Debugging")Debugging

elsestatements

Anelsestatementcanbeusedincombinationwithanifstatement.ThebodyoftheelsestatementwillexecuteonlyiftheifstatementevaluatestoFalse.Hereisanexampleofcombininganelsestatementwithanifstatement.Theschoolbelowappearstohavegradeinflation:

>>>score=87>>>ifscore>=90:...grade='A'...else:...grade='B'

Notethattheexpression,score>=90,isevaluatedbyPythonandturnsintoaFalse. Because the “if statement”was false, the statements under the elseblockareexecuted,andthegradevariableissetto'B'.

Morechoices

Page 100: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

The previous example does not work for most schools. You can add moreintermediatestepsifneededusingtheelifkeyword.elifisanabbreviationfor“elseif”.Belowisacompletegradingscheme:

>>>score=87>>>ifscore>=90:...grade='A'...elifscore>=80:...grade='B'...elifscore>=70:...grade='C'...elifscore>=60:...grade='D'...else:...grade='F'

Theif,elif,andelsestatementsaboveeachhavetheirownblock.PythonwillstartfromthetoptryingtofindastatementthatevaluatestoTrue,whenitdoes,itrunstheblockandthencontinuesexecutingatthecodefollowingalloftheelifandelseblocks.IfnoneoftheiforelifstatementsareTrue,itrunstheblockfortheelsestatement.

NOTE

The if statement can have zero or more elif statements. The elsestatementisoptional.Ifitexists,therecanonlybeone.

Whitespace

A peculiarity you may have noticed is the colon (:) following the booleanexpressionintheifstatement.Thelinesimmediatelyaftertheifstatementwereindentedbyfourspaces.TheindentedlinesaretheblockofcodethatisexecutedwhentheifexpressionevaluatestoTrue.Inotherlanguages,anifstatementmightlooklikethis:

if(score>=90){grade='A';}

Page 101: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Inmanyoftheselanguages,thecurlybraces,{and},denotetheboundariesof theifblock.Anycodebetween thesebraces isexecutedwhen the score isgreaterthanorequalto90.Python,unlikethoseotherlanguages,usestwothingstodenoteblocks:

acolon(:)indentation

Ifyouhaveprogrammedinotherlanguages,itiseasytolearnthewhitespacerules inPython.Allyouhave todo is replace the left curlybracket ({)withacolon(:)andindentconsistentlyuntiltheendoftheblock.

TIP

Whatisconsistent indentation?Normallyeither tabsorspacesareusedtoindentcode.ThePythoninterpreteronlycaresaboutconsistencyonaper-filebasis. It ispossible tohaveaprojectwithmultiple files thateachusedifferentindentationschemes,butthiswouldbesilly.InPython,usingfourspacesisthepreferredwaytoindentcode.Thisis

described inPEP8. Ifyoumix tabsandspaces in thesamefile,youwilleventuallyrunintoproblems.Although spaces are the preferred mechanism, if you are working on

code that already uses tabs, it is better to be consistent. In that case,continueusingtabswiththecode.Thepython3executablewillcomplainwithaTabErrorwhenyoumix

tabsandspaces.

Summary

This chapter discussed theif statement. This statement can be used to createarbitrarily complex conditionswhen combining expressionswithand,or, andnot.

Page 102: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Blocks, indentation, and whitespace were also discussed. Sometimes whenpeople encounter Python, the required whitespace rules may seem like anuisance. I've runacross suchpeople inmy trainings.Whenasked if andwhytheyindentcodeinotherlanguages,theyreply“Ofcourse,itmakescodemorereadable”.InPython,youemphasizereadability,andenforcingwhitespacetendstoaidinthat.

Exercises

1. Write an if statement to determinewhether a variable holding ayear is aleapyear.(SeetheNumberschapterexercisesfortherulesforleapyears).

2. Writeanifstatementtodeterminewhetheravariableholdinganintegerisodd.

3. Writeanifstatement.Lookattheindentedblockandcheckifyoureditorindented with tabs or spaces. If it is indented with tabs, configure youreditor to indentwith spaces. Some editors show tabs differently, if yoursdoesnotdistinguishbetweentabsandspaces,aneasywaytocheckif thespacing is a tab is to cursor over it. If the cursor jumps four or eightcharacters,thenitinsertedatabcharacter.

Page 103: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Containers:Lists,Tuples,andSets

MANY OF THE TYPES DISCUSSED SO FAR HAVE BEEN SCALARS,WHICH HOLD A SINGLEvalue.Integers,floats,andbooleansareallscalarvalues.Containersholdmultipleobjects(scalartypesorevenothercontainers).This

chapterwilldiscusssomeofthesetypes—lists,tuples,andsets.

Lists

Lists,asthenameimplies,areusedtoholdalistofobjects.InPython,alistmayholdanytypeofitemandmaymixitemtype.Thoughinpractice,youonlystorea single item type in a list.Anotherway to thinkof a list is that theygive anorder to a sequence of items.They are amutable type,meaning you can add,remove,andalterthecontentsofthem.Therearetwowaystocreateemptylists,oneistoinvokethelistclass,andtheotheristousethesquarebracketliteralsyntax—[and]:

>>>names=list()>>>other_names=[]

Ifyouwanttohaveprepopulatedlists,youcanprovidethevaluesinbetweenthesquarebrackets,usingtheliteralsyntax:

>>>other_names=['Fred','Charles']

NOTE

The list class can also create prepopulated lists, but it is somewhatredundantbecauseyouhavetopassalistintoit:

>>>other_names=list(['Fred','Charles'])

Page 104: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Typically,thisclassisusedtocoerceothersequencetypesintoalist.Forexample,astringisasequenceofcharacters.Ifyoupassastringintolist,yougetbackalistoftheindividualcharacters:

>>>list('Matt')['M','a','t','t']

Lists,likeothertypes,havemethodsthatyoucancallonthem(usedir([])toseeacompletelistofthem).Forexample,toadditemstotheendofalist,usethe.appendmethod:

>>>names.append('Matt')>>>names.append('Fred')>>>print(names)['Matt','Fred']

Rememberthatlistsaremutable.Pythondoesnotreturnanewlistwhenyouappendtoalist.Noticethatthecallto.appenddidnotreturnalist(theREPLdidn'tprintanythingout).RatheritreturnsNoneandupdatesthelistinplace.(InPython,thedefaultreturnvalueisNoneforafunctionoramethod.Thereisnowaytohaveamethodthatdoesn'treturnanything).

Sequenceindices

AlistisoneofthesequencetypesinPython.Sequencesholdorderedcollectionsof objects. To work effectively with sequences, it is important to understandwhatanindexis.Everyiteminalisthasanassociatedindex,whichdescribesitslocationinthelist.Forexample,theingredientsinpotatochipsarepotatoes,oil,andsalt,andtheyarenormallylistedinthatorder.Potatoesarefirstinthelist,oilissecond,andsaltisthird.Inmanyprogramminglanguages,thefirstiteminasequenceisatindex0,the

second item is at index1, the thirdat index2, and soon.Countingbeginningwithzeroiscalledzero-basedindexing.

Page 105: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Youcanaccessan item ina listusing thebracketnotationand the indexofsaiditem:

>>>names[0]'Matt'>>>names[1]'Fred'

Listinsertion

Toinsertanitematacertain index,usethe.insertmethod.Calling.insertwillshiftanyitemsfollowingthatindextotheright:

>>>names.insert(0,'George')>>>print(names)['George','Matt','Fred']

Thesyntaxforreplacementatanindexisthebracketnotation:

>>>names[1]='Henry'>>>print(names)['George','Henry','Fred']

Toappenditemstotheendofalistusethe.appendmethod:

>>>names.append('Paul')>>>print(names)['George','Henry','Fred','Paul']

NOTE

CPython’s underlying implementation of a list is actually an array ofpointers. This provides quick random access to indices. Also, appendingand removing at the end of a list is quick (O(1)), while inserting andremoving from themiddle of a list is slower (O(n)). If you find yourselfinserting and popping from the front of a list, collections.deque is abetterdatastructuretouse.

Listdeletion

Page 106: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Toremoveanitem,usethe.removemethod:

>>>names.remove('Paul')>>>print(names)['George','Henry','Fred']

Youcanalsodeletebyindexusingthebracketnotation:

>>>delnames[1]>>>print(names)['George','Fred']

Sortinglists

Acommonoperationonlistsissorting.The.sortmethodordersthevaluesinthelist.Thismethodsortsthelistinplace.Itdoesnotreturnanew,sortedcopyofthelist,ratheritupdatesthelistwiththeitemsreordered:

>>>names.sort()>>>print(names)['Fred','George']

Page 107: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratessortingalistwiththe.sortmethod.Notethatthelistissortedin-place.Theresultofcallingthe.sortmethodisthelistismutated,andthemethodreturnsNone.

If the previous order of the list was important, you canmake a copy of itbefore sorting. A more general option for sorting sequences is the sortedfunction. Thesorted functionworkswith any sequence. It returns a new listthatisordered:

Page 108: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>old=[5,3,-2,1]>>>nums_sorted=sorted(old)>>>print(nums_sorted)[-2,1,3,5]>>>print(old)[5,3,-2,1]

Thisillustratessortingalistbyusingthesortedfunction.Notethatthelistisnotmodified,ratheranewlistiscreated.Also,notethatPythonreusedtheitemsofthelist.Itdidnotcreatenewitems.

Page 109: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Finalstepsshowingthatthevariableassignmentisusedtocreateavariablepointingtothenewlist.Notethatthesortedfunctionworkswithanysequence,notonlylists.

Becarefulaboutwhatyousort.Pythonwantsyoutobeexplicit.InPython3,whenyoutry tosorta list thatcontainsheterogeneous types,youmightgetanerror:

>>>things=[2,'abc','Zebra','1']>>>things.sort()Traceback(mostrecentcalllast):...TypeError:unorderabletypes:str()<int()

Boththe.sortmethodandsortedfunctionallowarbitrarycontrolofsortingbypassing ina function for thekeyparameter.Thekeyparametercanbeanycallable(function,class,method)thattakesasingleitemandreturnssomethingthatcanbecompared.

Page 110: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Inthisexample,bypassinginstrasthekeyparameter,everyiteminthelistissortedasifitwereastring:

>>>things.sort(key=str)>>>print(things)['1',2,'Zebra','abc']

Usefullisthints

As usual, there are othermethods found on lists. Do not hesitate to open thePythoninterpreterandtypeinafewexamples.Rememberthatdirandhelpareyourfriends.

TIP

rangeisabuilt-infunctionthatconstructsintegersequences.Thefollowingwillcreatethenumberszerothroughfour:

>>>nums=range(5)>>>numsrange(5)

Python3tendstobelazy.Notethatrangedoesnotmaterializethelist,butrathergivesyouaniterablethatwillreturnthosenumberswheniteratedover. By passing the result into list you can see the numbers it wouldgenerate:

>>>list(nums)[0,1,2,3,4]

Notice that range does not include 5 in its sequence. Many Pythonfunctionsdealingwithfinalindicesmean“uptobutnotincluding”.(Slicesareanotherexampleofthisyouwillseelater).If you need to start at a non-zero number, range will accept two

parameters.Whentherearetwoparameters,thefirstisthestartingnumber(includingitself),andthesecondisthe“uptobutnotincluding”number:

#numbersfrom2to5>>>nums2=range(2,6)>>>nums2

Page 111: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>nums2range(2,6)

range also has an optional third parameter—stride. A stride of one(which is the default)means the next number in the sequence thatrangereturns shouldbeonemore than theprevious.A strideof2would returneveryothernumber.Below isanexample that returnsonlyevennumbersbeloweleven:

>>>even=range(0,11,2)>>>evenrange(0,11,2)>>>list(even)[0,2,4,6,8,10]

NOTE

The“uptobutnotincluding”constructismoreformallyknownasthehalf-openintervalconvention.Itiscommonlyusedwhendefiningsequencesofnaturalnumbers.Thisconstructhasafewniceproperties:

ThedifferencebetweentheendandstartisthelengthwhendealingwithasequenceofconsecutivenumbersTwosubsequencescanbesplicedtogethercleanlywithoutoverlap

Pythonadoptsthishalf-openintervalidiomwidely.Hereisanexample:

>>>a=range(0,5)>>>b=range(5,10)>>>both=list(a)+list(b)>>>len(both)#10-010>>>both[0,1,2,3,4,5,6,7,8,9]

Ifyouaredealingwithnumericsequencesyoumightwanttofollowsuit,especiallywhendefiningAPIs.

Page 112: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Famous computer scientist, EdsgerDijkstra, posited on the reasons forusingzero-based indexing,andwhy it is thecorrectchoice. 10Heendsbysaying:

Many programming languages have been designed without dueattentiontothisdetail.

Luckily,Pythonisnotoneofthoselanguages.

Tuples

Tuples(commonlypronouncedaseither“two”-plesor“tuh”-ples)areimmutablesequences.Youshouldthinkofthemasorderedrecords.Onceyoucreatethem,you cannot change them. To create a tuple using the literal syntax, useparenthesesaroundthemembersandcommasinbetween.Thereisalsoatupleclassthatyoucanusetoconstructanewtuplefromanexistingsequence:

>>>row=('George','Guitar')>>>row('George','Guitar')>>>row2=('Paul','Bass')>>>row2('Paul','Bass')

You can create tuples with zero or one items in them. Though in practice,because tuples hold record type data, this isn't super common. There are twoways to create an empty tuple, using either the tuple function or the literalsyntax:

>>>empty=tuple()>>>empty()>>>empty=()>>>empty()

Page 113: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Herearethreewaystocreateatuplewithoneiteminit:

>>>one=tuple([1])>>>one(1,)>>>one=(1,)>>>one(1,)>>>one=1,>>>one(1,)

NOTE

Parentheses are used for denoting the calling of functions or methods inPython.Theyarealsousedtospecifyoperatorprecedence.Inaddition,theymaybeusedintuplecreation.Thisoverloadingofparenthesescanleadtoconfusion.Here is thesimple rule, if there isone item in theparentheses,then Python treats the parentheses as normal parentheses (for operatorprecedence),suchasthosethatyoumightusewhenwriting(2+3)*8.Iftherearemultipleitemsseparatedbycommas,thenPythontreatsthemasatuple:

>>>d=(3)>>>type(d)<class'int'>

In the above example, d might look like a tuple with parentheses butPythonclaims it isan integer.For tupleswithonlyone item,youneed toputacomma(,)followingtheitem—orusethetupleclasswithasingleitemlist:

>>>e=(3,)>>>type(e)<class'tuple'>

Page 114: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Herearethreewaystocreateatuplewithmorethanoneitem.Typically,youwouldusethelastonetobePythonic.Becauseithasparenthesesitiseasiertoseethatitisatuple:

>>>p=tuple(['Steph','Curry','Guard'])>>>p('Steph','Curry','Guard')>>>p='Steph','Curry','Guard'>>>p('Steph','Curry','Guard')>>>p=('Steph','Curry','Guard')>>>p('Steph','Curry','Guard')

Becausetuplesareimmutableyoucannotappendtothem:

>>>p.append('GoldenState')Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>AttributeError:'tuple'objecthasnoattribute'append'

NOTE

Whythedistinctionbetweentuplesandlists?Whynotuselistssincetheyappeartobeasuper-setoftuples?Themaindifferencebetweentheobjectsismutability.Becausetuplesare

immutable, theyareable toserveaskeys indictionaries.Tuplesareoftenused to represent a record of data such as the row of a database query,whichmaycontainheterogeneous typesofobjects.Perhapsa tuplewouldcontainaname,address,andage:

>>>person=('Matt','123North456East',24)

Tuplesareusedforreturningmultipleitemsfromafunction.Tuplesalsoserveasahinttothedeveloperthatthistypeisnotmeanttobemodified.Tuplesalsouse lessmemory than lists. Ifyouhavesequences thatyou

arenotmutating,considerusingtuplestoconservememory.

Page 115: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Sets

AnothercontainertypefoundinPythonisaset.Asetisanunorderedcollectionthatcannotcontainduplicates.Likea tuple, itcanbeinstantiatedwitha listoranythingyoucaniterateover.Unlikealistoratuple,asetdoesnotcareaboutorder. Sets are particularly useful for two things, removing duplicates andcheckingmembership.Becausethelookupmechanismisbasedontheoptimizedhash function found in dictionaries, a lookup operation takes very little time,evenonlargesets.

NOTE

Becausesetsmustbeabletocomputeahashvalueforeachitemintheset,sets can only contain items that are hashable. A hash is a semi-uniquenumberforagivenobject.Ifanobjectishashable,itwillalwaysgeneratethesamehashnumber.InPython,mutable itemsarenothashable.Thismeans thatyoucannot

hasha list ordictionary.Tohashyourownuser-createdclasses,youwillneedtoimplement__hash__and__eq__.

Sets can be specified by passing in a sequence into the set class (anothercoercionclassthatappearsasafunction):

>>>digits=[0,1,1,2,3,4,5,6,...7,8,9]>>>digit_set=set(digits)#removeextra1

Theycanalsobecreatedwithaliteralsyntaxusing{and}:

>>>digit_set={0,1,1,2,3,4,5,6,...7,8,9}

As was mentioned, a set is great for removing duplicates. When a set iscreatedfromasequence,anyduplicatesareremoved.Theextra1wasremoved

Page 116: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

fromdigit_set:

>>>digit_set{0,1,2,3,4,5,6,7,8,9}

Tocheckformembership,youusetheinoperation:

>>>9indigit_setTrue>>>42indigit_setFalse

NOTE

ThereisacontainsprotocolinPython.Ifaclass(setorlist,oruser-definedclass) implements the __contains__ method (or the iteration protocol),you can use in with to check for membership. Due to how sets areimplemented, membership tests against them can be much quicker thantestsagainstalist.

Below,asetcalledoddiscreated.Thissetwillaidinthefollowingexamples:

>>>odd={1,3,5,7,9}

Setsprovidesetoperations,suchasunion(|),intersection(&),difference(-),andxor(^).Thedifference(-)operatorremovesitemsinonesetfromanother:

>>>odd={1,3,5,7,9}#difference>>>even=digit_set-odd>>>even{0,8,2,4,6}

Noticethattheorderoftheresultissomewhatarbitraryatacasualglance.Iftheorderisimportant,asetisnotthedatatypeyoushoulduse.

Page 117: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Theintersection(&)operation(youcanthinkofitastheareawheretworoadsintersect)returnstheitemsfoundinbothsets:

>>>prime=set([2,3,5,7])#thoseinboth>>>prime_even=prime&even>>>prime_even{2}

Theunion(|)operationreturnsasetcomposedofalltheitemsfrombothsets,withduplicatesremoved:

>>>numbers=odd|even>>>print(numbers){0,1,2,3,4,5,6,7,8,9}

Xor(^)isanoperationthatreturnsasetofitemsthatonlyarefoundinonesetortheother,butnotboth:

>>>first_five=set([0,1,2,3,4])>>>two_to_six=set([2,3,4,5,6])>>>in_one=first_five^two_to_six>>>print(in_one){0,1,5,6}

TIP

Why use a set instead of a list? Remember that sets are optimized formembership and removing duplicates. If you find yourself performingunionsordifferencesamonglists,lookintousingasetinstead.Setsarealsomuchquickerfortestingmembership.Theinoperatorruns

faster forsets than lists.However, thisspeedcomesatacost.Setsdonotkeeptheelementsinanyparticularorder,whereaslistsandtuplesdo.Iftheorderisimportantforyou,useadatastructurethatrememberstheorder.

Summary

Page 118: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thischapterdiscussedafewofthebuilt-incontainertypes.Yousawlists,whichareorderedsequences thataremutable.Remember thata listmethoddoesnotreturn a new list, but typicallywill change the list in place.Listswill supportinsertinganyitem,butyoutypicallyputitemsofthesametypeinalist.Youalsosawtuples.Tuplesarealsoorderedlikelists,unlikelists,however,

tuplesdonotsupportmutation.Inpractice,youusethemtorepresentarecordofdata,likearowretrievedfromadatabase.Whentheyarerepresentingrecords,theymightholddifferenttypesofobjects.Finally,setswereintroduced.Setsaremutable,buttheyareunordered.They

are used to removeduplicates and checkmembership.Because of the hashingmechanism theyuse, these setoperations are fast andefficient.But it requiresthattheitemsinthesetarehashable.

Exercises

1. Createalist.Appendthenamesofyourcolleaguesandfriendstoit.Hastheidofthelistchanged?Sortthelist.Whatisthefirstiteminthelist?Whatistheseconditeminthelist?

2. Create a tuple with your first name, last name, and age. Create a list,people, and append your tuple to it. Make more tuples with thecorresponding information fromyour friends and append them to the list.Sort the list. When you learn about functions, you can use the keyparametertosortbyanyfieldinthetuple,firstname,lastname,orage.

3. Createalistofthenamesofthefirstnamesyourfriends.Createalistwiththetoptencommonnames.Usesetoperationstoseeifanyofyourfriendshavecommonnames.

4. GotoProjectGutenberg 11andfindapageoftextfromShakespeare.Pasteitintoatriple-quotedstring.CreateanotherstringwithaparagraphoftextfromRalphWaldoEmerson.Usethestring's.splitmethodtogetalistofwordsfromeach.Usingsetoperationsfindthecommonwordsandwordsuniquetobothauthors.

Page 119: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

5. Tuplesandlistsaresimilarbuthavedifferentbehavior.Usesetoperationstofindtheattributesofalistobjectthatarenotinatupleobject.

10-https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html11-https://www.gutenberg.org/

Page 120: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Iteration

ACOMMON IDIOMWHENDEALINGWITHSEQUENCES ISTOLOOPOVERTHECONTENTSOFthesequence.Youmightwanttofilteroutoneoftheitems,applyafunctiontoit, or print it out. Thefor loop is oneway to do this.Here is an example ofprintingoutthestringsinalist:

>>>forletterin['c','a','t']:...print(letter)cat>>>print(letter)t

NOTE

Notice that a for loop construct contains a colon (:) followed by theindentedcode.(Theindentedcodeistheblockoftheforloop).

Page 121: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustrateshowaforloopcreatesavariable.Anewvariable,letter,iscreated.Atfirst,itpointsto'c',whichisprinted.Thentheloopcontinuesandthevariablepointsto'a'.

Page 122: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Theforloopcontinueswiththefinalloop.After't'isprinted,theloopexits.Atthispoint,thelistliteralisgarbagecollected.Becausetheonlythingpointingto'c'and'a'wasthelist,thosearealsogarbagecollected.However,thelettervariableisstillpointingto't'.Pythondoesn'tcleanupthis

variable,ithangsaroundaftertheforloopisdone.

Duringaforloop,Pythonmakesanewvariable,letter,thatholdstheitemof iteration.Note that thevalueofletter isnot the indexposition,but ratherthestring.ThisvariableisnotcleanedupbyPythonaftertheforloopisdone.

Loopingwithanindex

InlanguageslikeC,whenyouloopoverasequence,youdonot loopover theitemsinthesequence,ratheryouloopovertheindices.Usingthoseindicesyou

Page 123: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

canpullouttheitemsatthoseindexvalues.HereisonewaytodothatinPythonusingthebuilt-infunctionsrangeandlen:

>>>animals=["cat","dog","bird"]>>>forindexinrange(len(animals)):...print(index,animals[index])0cat1dog2bird

Theabovecodeisacodesmell.ItindicatesthatyouarenotusingPythonasyoushould.Usually,thereasonforiteratingoverasequenceistogetaccesstothe items in thesequence,not the indices.Butoccasionallyyouwillalsoneedtheindexpositionoftheitem.Pythonprovidesthebuilt-inenumeratefunctionthat makes the combination of range and len unnecessary. The enumeratefunctionreturnsatupleof(index,item)foreveryiteminthesequence:

>>>animals=["cat","dog","bird"]>>>forindex,valueinenumerate(animals):...print(index,value)0cat1dog2bird

Because the tuple returns a pair of index and value, you can use tupleunpackingtocreatetwovariables,indexandvaluedirectlyintheforloop.Youneed to put a commabetween the variable names.As long as the tuple is thesamelengthasthenumberofvariablesyouincludeintheforloop,Pythonwillhappilycreatethemforus.

Breakingoutofaloop

Youmayneedtostopprocessingaloopearly,withoutgoingovereveryitemintheloop.Thebreakkeywordwilljumpoutofthenearestloopyouarein.Belowisaprogramthataddsnumbersuntilitcomestothefirstnegativeone.Itusesthebreakstatementtostopprocessingwhenitcomesacrossanegativenumber:

>>>numbers=[3,5,9,-1,3,1]>>>result=0>>>foriteminnumbers:...ifitem<0:

Page 124: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

...ifitem<0:

...break

...result+=item>>>print(result)17

NOTE

Theline:

result+=item

useswhatiscalledaugmentedassignment.Itissimilartowriting:

result=result+item

Augmentedassignment isslightlyquickeras the lookupfor theresultvariableonlyoccursonce.Anotheraddedbenefitisthatitiseasiertotype.

NOTE

Theifblockinsidetheforblockisindentedeightspaces.Blockscanbenested,andeachlevelneedstobeindentedconsistently.

Skippingoveritemsinaloop

Anothercommonloopingidiomistoskipoveritems.Ifthebodyoftheforlooptakesawhiletoexecute,butyouonlyneedtoexecuteitforcertainitemsinthesequence,thecontinuekeywordcomesinhandy.ThecontinuestatementtellsPythontodisregardprocessingofthecurrentitemintheforloopand“continue”fromthetopoftheforblockwiththenextvalueintheloop.Hereisanexampleofsummingallpositivenumbers:

>>>numbers=[3,5,9,-1,3,1]>>>result=0>>>foriteminnumbers:...ifitem<0:...continue...result=result+item

Page 125: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

...result=result+item>>>print(result)21

Theinstatementcanbeusedformembership

Youhaveusedtheinstatementinaforloop.InPython,theinstatementcanalsobeusedtocheckformembership.Ifyouwanttoknowifalistcontainsanitem,youcanusetheinstatementtocheckthat:

>>>animals=["cat","dog","bird"]>>>'bird'inanimalsTrue

Ifyouwanttheindexlocation,usethe.indexmethod:

>>>animals.index('bird')2

Removingitemsfromlistsduringiteration

Itwasmentionedpreviouslythatlistsaremutable.Becausetheyaremutableyoucanaddorremoveitemsfromthem.Also,listsaresequences,soyoucanloopoverthem.Donotmutatethelistatthesametimethatyouareloopingoverit.For example, if you wanted to filter a list of names so it only contained

'John'or'Paul',thiswouldbethewrongwaytodoit:

>>>names=['John','Paul','George',...'Ringo']>>>fornameinnames:...ifnamenotin['John','Paul']:...names.remove(name)>>>print(names)['John','Paul','Ringo']

Whathappened?Pythonassumesthatlistswillnotbemodifiedwhiletheyarebeingiteratedover.Whentheloopgotto'George',itremovedthenamefromthelist.InternallyPythontrackstheindexlocationoftheforloop.Atthatpointthereareonlythreeitemsinthelist,'John','Paul',and'Ringo'.Buttheforloopinternallythinksitisonindexlocation3(thefourthitem),andthereisnofourthitemsotheloopstops,leaving'Ringo'in.

Page 126: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Therearetwoalternativestotheabovecontructofremovingitemsfromalistduring iteration. The first is to collect the items to be removed during a passthroughthelist.In a subsequent loop, iterate over only the items that need to be deleted

(names_to_remove),andremovethemfromtheoriginallist(names):

>>>names=['John','Paul','George',...'Ringo']>>>names_to_remove=[]>>>fornameinnames:...ifnamenotin['John','Paul']:...names_to_remove.append(name)>>>fornameinnames_to_remove:...names.remove(name)>>>print(names)['John','Paul']

Anotheroptionistoiterateoveracopyofthelist.Thiscanbedonerelativelypainlessly using the[:] slice copy construct that is covered in the chapter onslicing:

>>>names=['John','Paul','George',...'Ringo']>>>fornameinnames[:]:#copyofnames...ifnamenotin['John','Paul']:...names.remove(name)>>>print(names)['John','Paul']

elseclauses

A for loop can also have an else clause. Any code in an else block willexecuteiftheforloopdidnothitabreakstatement.Belowissamplecodethatchecksifnumbersinalooparepositive:

>>>positive=False>>>fornuminitems:...ifnum<0:...break...else:...positive=True

Page 127: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

...positive=True

Note thatcontinue statements do not have any effect onwhether an elseblockisexecuted.Theelse statement is somewhat oddly named. For afor loop, it indicates

thatthewholesequencewasprocessed.Atypicaluseofanelsestatementinaforloopistoindicatethatanitemwasnotfound.

whileloops

Pythonwill letyou loopoverablockofcodewhileaconditionholds.This iscalledawhileloopandyouusethewhilestatementtocreateait.Awhileloopis followed by an expression that evaluates to True or False. Then, a colonfollows it. Remember what follows a colon (:) in Python? Yes, an indentedblock of code. This block of code will continue to repeat as long as theexpressionevaluatestoTrue.Thisallowsyoutoeasilycreateaninfiniteloop.You usually try to avoid infinite loops because they cause your program to

"hang", forever caught in the processing of a loop with no way out. Oneexception to this isaserver, that loopsforever,continuing toprocess requests.Another exception seen in more advanced Python is an infinite generator. Ageneratorbehaveslikealazylistandonlycreatesvalueswhenyouloopoverit.Ifyouarefamiliarwithstreamprocessing,youcouldthinkofitasastream.(Idon'tcovergeneratorsinthisbook,butdoinmymoreadvancedbook.)Typically,ifyouhaveanobjectthatsupportsiteration,youuseaforloopto

iterateovertheitems.Youusewhileloopswhenyoudon'thaveeasyaccesstoaniterableobject.Acommonexampleiscountingdown:

>>>n=3>>>whilen>0:...print(n)...n=n-1321

Page 128: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Youcanalsousethebreakstatementtoexitawhileloop:

>>>n=3>>>whileTrue:...print(n)...n=n-1...ifn==0:...break

Summary

Thischapterdiscussedusing thefor loop to iterateoverasequence.Yousawthatyoucanloopoverlists.Youcanalsoloopoverstrings,tuples,dictionaries,andotherdatastructures.Infact,youcandefineyourownclassesthatrespondtotheforstatement,byimplementingthe.__iter__method.Afor loop creates a variable during iteration. This variable is not garbage

collected after the for loop, it sticks around. If your for loop is inside of afunction,thevariablewillbegarbagecollectedwhenthefunctionexits.Theenumeratefunctionwasintroduced.Thisfunctionreturnsasequenceof

tuplesofindex,itempairsforthesequencepassedintoit.Ifyouneedtogettheindexlocationaswellastheitemofiteration,useenumerate.Finally, you saw how to break out of loops, continue to the next item of

iteration, and use else statements. These constructs enable you to adeptlyconfigureyourloopinglogic.

Exercises

1. Createalistwiththenamesoffriendsandcolleagues.Calculatetheaveragelengthofthenames.

2. Createalistwiththenamesoffriendsandcolleagues.SearchforthenameJohn using a for loop. Print not found if you didn't find it. (Hint: useelse).

3. Createalistoftuplesoffirstname,lastname,andageforyourfriendsandcolleagues. If youdon't know the age,put inNone.Calculate the average

Page 129: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

age,skippingoveranyNonevalues.Printouteachname,followedbyoldoryoungiftheyareaboveorbelowtheaverageage.

Page 130: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Dictionaries

DICTIONARIESAREAHIGHLYOPTIMIZEDBUILT-INTYPEINPYTHON.You can compare a Python dictionary to anEnglish dictionary.AnEnglish

dictionaryhaswordsanddefinitions.Thepurposeofadictionaryistoallowfastlookupofthewordinordertofindthedefinition.Youcanquicklylookupanyword by doing a binary search (open up the dictionary to the midpoint, anddeterminewhichhalfthewordisin,andrepeat).APython dictionary also haswords and definitions, but you call them keys

andvaluesrespectively.Thepurposeofadictionaryistoprovidefastlookupofthekeys.Youcanquicklylookforakeyandpulloutthevalueassociatedwithit.LikeanEnglishdictionary,whereitwouldtakealongtimetodeterminethewordfromadefinition(ifyoudidn'tknowthewordbeforehand),lookingupthevalueisslow.InPython3.6,thereisafeaturethatisnewfordictionaries.Thekeysarenow

sortedbyinsertionorder. IfyouarewritingPythoncodethatneeds toworkinpriorversions,youwillneedtorememberthatpriorto3.6,keyshadanarbitraryorder(thatallowedPythontodoquicklookupsbutwasn'tparticularlyusefultoendusers).

Dictionaryassignment

Dictionaries provide a link from a key to a value. (Other languages call themhashes,hashmaps,maps,orassociativearrays).Supposeyouwanted to storeinformationaboutanindividual.Yousawhowyoucoulduseatupletorepresentarecord.Adictionaryisanothermechanism.Becausedictionariesarebuiltinto

Page 131: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Python, you can use a literal syntax to create one. This one has first and lastnames:

>>>info={'first':'Pete','last':'Best'}

NOTE

Analternatewaytocreateadictionaryiswiththebuilt-indictclass.Ifyoupassalistoftuplepairsintotheclass,itwillreturnadictionary:

>>>info=dict([('first','Pete'),...('last','Best')])

Youcanalsousenamedparameterswhenyoucalldict:

>>>info=dict(first='Pete',last='Best')

Ifyouusenamedparameters,theymustbevalidPythonvariablenames,andtheywillbeconvertedtostrings.

Youcanuseindexoperationstoinsertvaluesintothedictionary:

>>>info['age']=20>>>info['occupation']='Drummer'

Page 132: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratesthecreationofadictionary.Inthiscase,youuseanexistingvariableforthevalue.Notethatthedictionarydoesnotcopythevariable,butitpointstoit(increasingthereferencecount).

In the above example, the keys are 'first', 'last', 'age', and'occupation'.Forexample,'age' is thekey thatmaps to the integer20, thevalue.Youcanquicklylookupthevaluefor'age'byperformingalookupwithanindexoperation:

>>>info['age']20

On the flip side, finding what the key is that has the value 20 is a slowoperation. It would be like giving someone a definition from an EnglishDictionaryandaskingwhatwordhasthatdefinition.The above example illustrates the literal syntax for creating an initially

populateddictionary. It also showshow the squarebrackets (indexoperations)areusedtoinsertitemsintoadictionaryandpullthemout.Anindexoperation

Page 133: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

associates a key with a value when used in combination with the assignmentoperator(=).Whentheindexoperationhasnoassignment,itlooksupthevalueforagivenkey.

Retrievingvaluesfromadictionary

As you have seen, the square bracket literal syntax can pull a value out of adictionarywhenyouusethebracketswithoutassignment:

>>>info['age']20

Be careful though, if you try to access a key that does not exist in thedictionary,Pythonwillthrowanexception:

>>>info['Band']Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>KeyError:'Band'

BecausePython likes tobe explicit and fail fast, raising an exception is thedesired behavior. You know that the 'Band' key is not in the dictionary. Itwouldbebad ifPythondecided toreturnanarbitraryvalueforakey thatwasnot in thedictionary.Doingsocouldallowerrors topropagate further inyourprogramandmaskalogicerror.

Theinoperator

Pythonprovidesanoperator,in,thatallowsyoutoquicklycheckifakeyisinadictionary:

>>>'Band'ininfoFalse>>>'first'ininfoTrue

As you have seen, in also works with sequences. You can use the instatementwithalist,set,orstringtocheckformembership:

>>>5in[1,3,6]False

Page 134: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>'t'in{'a','e','i'}False>>>'P'in'Paul'True

NOTE

Python 3 removed the .has_key method, which provided the samefunctionalityastheinstatement,butisspecifictoadictionary.Hoorayforstepsforwardtowardsconsistency!

Theinstatementwillworkwithmostcontainers.Inaddition,youcandefineyourownclassesthatrespondtothisstatement.Yourobjectneedstodefinethe.__contains__orbeiterable.

Dictionaryshortcuts

The .get method of a dictionary will retrieve a value for a key. .get alsoacceptsanoptionalparametertoprovideadefaultvalueifthekeyisnotfound.Ifyouwantedthegenretodefaultto'Rock',youcoulddothefollowing:

>>>genre=info.get('Genre','Rock')>>>genre'Rock'

TIP

The.getmethod of dictionaries is oneway to get around theKeyErrorthrownwhentryingtousethebracketnotationtopulloutakeynotfoundinthedictionary.It is fine touse thismethodbecauseyou arebeing explicit aboutwhat

willhappenwhen thekey ismissing.Youshouldprefer to fail fastwhenyouaren'tbeingspecificaboutthefailingcase.

setdefault

Page 135: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

A useful, but somewhat confusingly named, method of dictionaries is the.setdefaultmethod.Themethodhasthesamesignatureas.getandinitiallybehaveslikeit,returningadefaultvalueifthekeydoesnotexist.Inadditiontothat,italsosetsthevalueofthekeytothedefaultvalueifthekeyisnotfound.Because.setdefaultreturnsavalue,ifyouinitializeittoamutabletype,suchasadictorlist,youcanmutatetheresultinplace.

.setdefaultcanbeusedtoprovideanaccumulatororcounterforakey.Forexample, if youwanted to count the number of people with same name, youcoulddothefollowing:

>>>names=['Ringo','Paul','John',...'Ringo']>>>count={}>>>fornameinnames:...count.setdefault(name,0)...count[name]+=1

Withoutthe.setdefaultmethod,abitmorecodeisrequired:

>>>names=['Ringo','Paul','John',...'Ringo']>>>count={}>>>fornameinnames:...ifnamenotincount:...count[name]=1...else:...count[name]+=1>>>count['Ringo']2

TIP

Performingthesecountingtypesofoperationswassocommonthatlaterthecollections.Counter class was added to the Python standard library.Thisclasscanperformtheaboveoperationsmuchmoresuccinctly:

>>>importcollections>>>count=collections.Counter(['Ringo','Paul',...'John','Ringo'])>>>countCounter({'Ringo':2,'Paul':1,'John':1})

Page 136: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Counter({'Ringo':2,'Paul':1,'John':1})>>>count['Ringo']2>>>count['Fred']0

Here is a somewhat contrived example illustrating mutating the result of.setdefault.Assumeyouwanttohaveadictionarymappinganametobandsthat theyplayed in. If apersonnamedPaul is in twobands, the result shouldmapPaultoalistcontainingbothofthosebands:

>>>band1_names=['John','George',...'Paul','Ringo']>>>band2_names=['Paul']>>>names_to_bands={}>>>fornameinband1_names:...names_to_bands.setdefault(name,...[]).append('Beatles')>>>fornameinband2_names:...names_to_bands.setdefault(name,...[]).append('Wings')>>>print(names_to_bands['Paul'])['Beatles','Wings']

Tobelaborthepoint,withoutsetdefaultthiscodewouldbeabitlonger:

>>>band1_names=['John','George',...'Paul','Ringo']>>>band2_names=['Paul']>>>names_to_bands={}>>>fornameinband1_names:...ifnamenotinnames_to_bands:...names_to_bands[name]=[]...names_to_bands[name].\...append('Beatles')>>>fornameinband2_names:...ifnamenotinnames_to_bands:...names_to_bands[name]=[]...names_to_bands[name].\...append('Wings')>>>print(names_to_bands['Paul'])['Beatles','Wings']

TIP

Page 137: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

The collections module from the Python standard library includes ahandyclass—defaultdict.Thisclassbehaveslikeadictionarybutitalsoallows for setting thedefaultvalueofakey toanarbitrary factory. If thedefaultfactoryisnotNone,itisinitializedandinsertedasavalueanytimeakeyismissing.Thepreviousexamplere-writtenwithdefaultdictisthefollowing:

>>>fromcollectionsimportdefaultdict>>>names_to_bands=defaultdict(list)>>>fornameinband1_names:...names_to_bands[name].\...append('Beatles')>>>fornameinband2_names:...names_to_bands[name].\...append('Wings')>>>print(names_to_bands['Paul'])['Beatles','Wings']

Usingdefaultdictisslightlymorereadablethanusingsetdefault.

Deletingkeys

Another common operation on dictionaries is the removal of keys and theircorresponding values. To remove an item from a dictionary, use the delstatement:

#remove'Ringo'fromdictionary>>>delnames_to_bands['Ringo']

TIP

Python will prevent you from adding to or removing from a dictionarywhileyouareloopingoverit.PythonwillthrowaRuntimeError:

>>>data={'name':'Matt'}>>>forkeyindata:...deldata[key]Traceback(mostrecentcalllast):...RuntimeError:dictionarychangedsizeduringiteration

Page 138: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Dictionaryiteration

Dictionariesalsosupportiterationusingtheforstatement.Bydefault,whenyouiterateoveradictionary,yougetbackthekeys:

>>>data={'Adam':2,'Zeek':5,'Fred':3}>>>fornameindata:...print(name)AdamZeekFred

NOTE

Thedictionaryhasamethod—.keys—thatwillalso listout thekeysofadictionary. In Python 3, the.keysmethod returns a view. The view is awindowintothecurrentkeysfoundinthedictionary.Youcaniterateoverit, like a list. But, unlike a list, it is not a copy of the keys. If you laterremoveakeyfromthedictionary,theviewwillreflectthatchange.Alistwouldnot.

Toiterateoverthevaluesofadictionary,iterateoverthe.valuesmethod:

>>>forvalueindata.values():...print(value)253

Theresultof.valuesisalsoaview.Itreflectsthecurrentstateofthevaluesfoundinadictionary.Toretrievebothkeyandvalueduringiteration,usethe.itemsmethod,which

returnsaview:

>>>forkey,valueindata.items():...print(key,value)Adam2Zeek5

Page 139: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Zeek5Fred3

Ifyoumaterializetheviewintoalist,youwillseethatthelistisasequenceof(key,value)tuples—thesamethingthatdictacceptstocreateadictionary:

>>>list(data.items())[('Adam',2),('Zeek',5),('Fred',3)]

TIP

Remember that a dictionary is ordered based on key insertion order. If adifferentorderisdesired,youwillneedtosortthesequenceofiteration.The built-in function sorted will return a new sorted list, given a

sequence:

>>>fornameinsorted(data.keys()):...print(name)AdamFredZeek

Thesortedfunctionhasanoptionalargument,reverse,tofliptheorderoftheoutput:

>>>fornameinsorted(data.keys(),...reverse=True):...print(name)ZeekFredAdam

NOTE

Itispossibletohavekeysofdifferenttypes.Theonlyrequirementforakeyis that it behashable. For example, a list isn't hashable because you canmutate it, andPython can't generate a consistent hashvalue for it. If youusedalistasakeyandthenmutatedthatkey,shouldthedictionaryreturn

Page 140: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

thevaluebasedontheoldlist,orthenewone,orboth?Pythonrefusestoguesshereandmakesyouusekeysthatdon'tchange.Itwouldbepossibletoinsertitemsintoadictionaryusingbothintegers

andstringsaskeys:

>>>weird={1:'first',...'1':'anotherfirst'}

Typically,youdon'tmixkeytypes,becauseitisconfusingtoreadersofthe code and alsomakes sorting keys harder. Python 3won't sortmixedtypelistswithoutakey functiontellingPythonexplicitlyhowtocomparedifferent types. This is one of those areas where Python gives you theabilitytodosomething,butthatdoesn'tmeanyoushould.InthewordsofPythoncoredeveloperRaymondHettinger:

Many"CanIdoxinPython"questionsequateto"CanIstopacaron train tracks when no trains are coming?" Yes you can, No youshouldn't—@raymondh

Summary

Thischapterdiscussedthedictionary.ThisdatastructureisimportantbecauseitisabuildingblockinPython.Classes,namespaces,andmodulesinPythonareallimplementedusingadictionaryunderthecovers.Dictionariesprovidequick lookupor insertion for akey.Youcanalsodoa

lookupbyvalue,butitisslow.Ifyoufindyourselfdoingthisoperationoften,itisacodesmellthatyoushoulduseadifferentdatastructure.Yousawhowtomutateadictionary.Youcaninsertandremovekeysfroma

dictionary. You can also check a dictionary for membership using the instatement.You looked at some fancier constructs, using .setdefault to insert and

Page 141: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

return values in one operation. You saw that Python includes specializeddictionaryclasses,Counteranddefaultdictinthecollectionsmodule.Because dictionaries aremutable, you can delete keys from them using the

del statement.You can also iterate over the keys of a dictionary using aforloop.RememberthatPython3.6introducedorderingtothedictionary.Thekeysare

orderedbyinsertionorder,notalphabeticornumericorder.

Exercises

1. Createadictionary,info,thatholdsyourfirstname,lastname,andage.2. Createanemptydictionary,phone,thatwillholddetailsaboutyourphone.

Addthescreensize,memory,OS,brand,etc.tothedictionary.3. Write a paragraph in a triple-quoted string. Use the .split method to

createalistofwords.Createadictionarytoholdthecountforeverywordintheparagraph.

4. CounthowmanytimeseachwordisusedinaparagraphoftextfromRalphWaldoEmerson.

5. Writecodethatwillprintouttheanagrams(wordsthatusethesameletters)fromaparagraphoftext.

6. ThePageRankalgorithmwasusedtocreatetheGooglesearchengine.Thealgorithmgivesascoretoeachpagebasedonincominglinks.Ittakesoneinput:alistofpagesthatlinktootherpages.Eachpageinitiallygetsascoresetto1.Thenmultipleiterationsofthealgorithmarerun,typicallyten.Foreachiteration:

Apagetransfersitsscoredividedbythenumberofoutgoinglinkstoeachpagethatitlinksto.Thescoretransferredismultipliedbyadampingfactor,typicallysetto.85.

Page 142: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Writesomecodetorun10iterationsofthisalgorithmonalistoftuplesofsourceanddestinationlinks,ie:

links=[('a','b'),('a','c'),('b','c')]

Page 143: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Functions

WE HAVE COME A LONGWAYWITHOUT DISCUSSING FUNCTIONS,WHICH ARE A BASICbuildingblockofPythonprograms.Functionsarediscreteunitsofcode,isolatedinto theirownblock.Youhaveactuallybeenusingbuiltin functionsalong theway such as dir, help, (and the classes that behave like coercion functions—float,int,dict,list,andbool).

Afunctionislikeabox.Itcantakeinputandreturnoutput.Itcanbepassedaroundandreused.

Oneway to thinkofa function isasablackbox thatyoucansend input to(though input is not required). The black box then performs a series ofoperations and returns output (it implicitly returns None if the function endswithoutreturnbeingcalled).Anadvantageofafunctionisthatitenablescodereuse.Onceafunctionisdefined,youcancallitmultipletimes.Ifyouhavecodethatyourepeatedlyruninyourprogram,ratherthancopyingandpastingit,youcanput it ina functiononce, thencall that functionmultiple times.Thisgivesyoulesscodetoreasonabout,makingyourprogramseasiertounderstand.Itisalsoeasier to changecode (or fixbugs) later asyouonlyhave todo it inoneplace.

Page 144: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Hereisasimpleexampleofafunction.Thisfunction,namedadd_2,takesanumberasinput,adds2tothatvalue,andreturnstheresult:

>>>defadd_2(num):...'''...return2morethannum...'''...result=num+2...returnresult

Whatarethedifferentcomponentsofafunction?Thiswholegroupofcodeisknownasa functiondefinition.First,youseethedefstatement,whichisshortfordefine(i.e.defineafunction).Followingdefisarequiredspace(onespaceisfine)andthenthefunctionname—add_2.Thisisthenamethatisusedtoinvokethe function. Synonyms for invoke include call, execute, or run the function.WhenPythoncreatesafunction,itwillcreateanewvariable,usingthenameofthefunction.

Thisillustratesthecreationofafunction.NotethatPythoncreatesanewfunctionobject,thenpointsavariabletoitusingthenameofthefunction.Usethedirfunctiononthefunctionnametosee

theattributesofthenewlycreatedfunction.

Followingthefunctionnameisaleftparenthesisfollowedbynumandarightparenthesis. The names between the parentheses (there can be an arbitrary

Page 145: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

number of names, in this case, there is only one), are the input parameters.Thesearetheobjectsthatyoupassintoafunction.Aftertheparenthesescomesacolon(:).WheneveryouseeacoloninPython,

you should immediately think the colon is followed by an indented block—similar to the body of the for loops shown previously. Everything that isindentedisthebodyofthefunction.Itisalsocalledablockofcode.Thebodyofafunctioniswherethelogiclives.Youmightrecognizethefirst

3linesofindentedcodeasatriple-quotedstring.Thisisnotacomment,thoughitappearstohavecomment-liketext.Itisastring.Pythonallowsyoutoplaceastringimmediatelyafterthe:, thisstringiscalledadocstring.Adocstringisastring used solely for documentation. It should describe the block of codefollowingit.Thedocstringdoesnotaffectthelogicinthefunction.

TIP

Thehelp functionhasbeenemphasizedthroughthisbook.It is importantto note that the help function gets its content from the docstring of theobject passed into it. If you call help on add_2, you should see thefollowing(providedyouactuallytypedouttheadd_2codeabove):

>>>help(add_2)Helponfunctionadd_2inmodule__main__:add_2()return2morethannum(END)

Providing docstrings can be useful to you as a reminder of what yourcode does. If they are accurate, the docstrings are invaluable to anyonetryingtouseyourcode.

Followingthedocstring(notethatadocstringisoptional),comesthelogicofthe function. The result is calculated. Finally, the function uses a return

Page 146: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

statementtoindicatethatithasoutput.Areturnstatementisnotnecessary,andifitismissingafunctionwillreturnNonebydefault.Furthermore,youcanusemorethanonereturnstatement,andtheydonotevenhavetobeattheendofthefunction.Forexample,aconditionalblockmaycontainareturnstatementinsideofanifblockandanotherinanelseblock.Torecap,themainpartsofafunctionare:

thedefkeywordafunctionnamefunctionparametersbetweenparenthesesacolon(:)indentation

docstringlogicreturnstatement

Creatingfunctionsiseasy.Theyallowyoutoreusecode,whichmakesyourcodeshorterandeasiertounderstand.Theyareusefultoremoveglobalstatebykeeping short-lived variables inside of the function body. Use functions toimproveyourcode.

Invokingfunctions

Whenyoucallorexecuteafunction,youareinvokingafunction.InPython,youinvokefunctionsbyaddingparenthesesfollowingthefunctionname.Thiscodeinvokesthenewlydefinedfunctionadd_2:

>>>add_2(3)5

To invoke a function, list its name followed by a left parenthesis, the inputparameters,andarightparenthesis.Thenumberofparametersshouldmatchthenumber of parameters in the function declaration. Notice that the REPL

Page 147: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

implicitly prints the result—the integer 5. The result is what the returnstatementpassesback.Youcanpassinwhateverobjectyouwanttotheadd_2function.However,if

that object doesn't support additionof a number, youwill get an exception. Ifyoupassastringin,youwillseeaTypeError:

>>>add_2('hello')Traceback(mostrecentcalllast):...TypeError:mustbestr,notint

Scope

Python looks for variables in various places.You call these places scopes (ornamespaces). When looking for a variable (remember that functions are alsovariablesinPython,asareclasses,modules,andmore),Pythonwilllookinthefollowinglocations,inthisorder:

Localscope-Variablesthataredefinedinsideoffunctions.Globalscope-Variablesthataredefinedatthegloballevel.Builtinscope-VariablesthatarepredefinedinPython.

Inthefollowingcodeisafunctionthatwill lookupvariables ineachof thethreescopes:

>>>x=2#Global>>>defscope_demo():...y=4#Localtoscope_demo...print("Local:{}".format(y))...print("Global:{}".format(x))...print("Builtin:{}".format(dir))>>>scope_demo()Local:4Global:2Builtin:<builtinfunctiondir>

Note that after scope_demo is invoked, the local variable y is garbagecollectedandnolongeravailableintheglobalscope:

>>>y

Page 148: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>yTraceback(mostrecentcalllast):...NameError:name'y'isnotdefined

Variablesdefinedinsideofafunctionormethodwillbelocal.Ingeneral,youshouldtrytoavoidglobalvariables.Theymakeithardertoreasonaboutcode.Globalvariablesarecommoninbooks,blogs,anddocumentationbecauseusingthem requireswriting less code, and allows you to focus on conceptswithoutthembeingwrappedinafunction.Usingfunctionsandclassesaresomeofthetoolsthathelpyouremoveglobalvariables,makeyourcodemoremodular,andeasiertounderstand.

NOTE

Pythonwillallowyoutooverridevariablesintheglobalandbuiltinscope.Atthegloballevel,youcoulddefineyourownvariablecalleddir.Atthatpoint, the builtin function, dir, is shadowed by the global variable. Youcouldalsodothiswithinafunction,andcreatealocalvariablethatshadowsaglobalorbuiltin:

>>>defdir(x):...print("Dircalled")>>>dir('')Dircalled

Youcanuse thedelstatement todeletevariables in the localorglobalscope. In practice though, you don't see this, as it is better to avoidshadowingbuiltinsinthefirstplace:

>>>deldir>>>dir('')['__add__','__class__','__contains__',...]

HINT

Page 149: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Youcanusethelocalsandglobalsfunctionstolistthesescopes.Thesereturndictionarieswiththeircurrentscopeinthem:

>>>deffoo():...x=1...print(locals())>>>foo(){'x':1}

The __builtins__ variable lists the builtin names. If you access its__dict__ attribute, it will give you a dictionary similar to globals andlocals.

Multipleparameters

Functions can have many parameters. Below is a function that takes twoparametersandreturnstheirsum:

>>>defadd_two_nums(a,b):...returna+b

NotethatPythonisadynamiclanguageandyoudon'tspecifythetypesoftheparameters.Thisfunctioncanaddtwointegers:

>>>add_two_nums(4,6)10

Itcanalsoaddfloats:

>>>add_two_nums(4.0,6.0)10.0

Stringstoo:

>>>add_two_nums('4','6')'46'

Notethatthestringsuse+toperformstringconcatenation(joiningtwostringstogether).However,ifyoutrytoaddastringandanumber,Pythonwillcomplain:

Page 150: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>add_two_nums('4',6)Traceback(mostrecentcalllast):...TypeError:Can'tconvert'int'objecttostrimplicitly

This is an instancewherePythonwantsyou tobemore explicit aboutwhatoperationisdesired,andit isn'tgoingtoguessforyou.Ifyouwantedtoaddastringtypetoanumber,youmightwanttoconvertthemtonumbersfirst(usingfloatorint).Likewise,itmightbeusefultoconvertfromnumberstostringsifconcatenationisthedesiredoperation.Pythondoesnotimplicitlychoosewhichoperation to perform. Rather, it throws an error which should force theprogrammertoresolvetheambiguity.

Defaultparameters

One cool feature of Python functions is default parameters. Like the nameimplies,defaultparametersallowyoutospecifythedefaultvaluesforfunctionparameters.Thedefault parameters are thenoptional, thoughyoucanoverridethemifyouneedto.Thefollowingfunctionissimilartoadd_two_nums,butwilldefaulttoadding

3ifthesecondnumberisnotprovided:

>>>defadd_n(num,n=3):..."""defaultto...adding3"""...returnnum+n>>>add_n(2)5>>>add_n(15,-5)10

Tocreate adefault value for aparameter, follow theparameternameby anequalsign(=)andthechosenvalue.

NOTE

Default parameters must be declared after non-default parameters.Otherwise,PythonwillgiveyouaSyntaxError:

Page 151: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>defadd_n(num=3,n):...returnnum+nTraceback(mostrecentcalllast):...SyntaxError:non-defaultargumentfollowsdefaultargument

Because default parameters are optional, Python forces you to declarerequired parameters before optional ones. The above codewouldn'tworkwith an invocation like add_n(4) because the required parameter ismissing.

TIP

Donotusemutabletypes(lists,dictionaries)fordefaultparametersunlessyou know what you are doing. Because of the way Python works, thedefaultparametersarecreatedonlyonce—atfunctiondefinitiontime,notatfunctionexecutiontime.Ifyouuseamutabledefaultvalue,youwillendupreusing the same instance of the default parameter during each functioninvocation:

>>>defto_list(value,default=[]):...default.append(value)...returndefault>>>to_list(4)[4]>>>to_list('hello')[4,'hello']

Thefactthatdefaultparametersareinstantiatedatthetimethefunctioniscreatedisconsideredawartbymany.Thisisbecausethebehaviorcanbesurprising. The workaround is to push the creation of the default valuesfromfunctiondefinitiontime(whichonlyoccursonce)tofunctionruntime(whichwillcreateanewvalueeverytimethefunctionisexecuted).Change the mutable default parameters so that they default to None.

Then,createaninstanceofthedesiredmutabletypewithinthebodyofthe

Page 152: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

functionifthedefaultisNone:

>>>defto_list2(value,default=None):...ifdefaultisNone:...default=[]...default.append(value)...returndefault>>>to_list2(4)[4]>>>to_list2('hello')['hello']

Thefollowingcode:

...ifdefaultisNone:

...default=[]

Canalsobewrittenasasinglelineusingaconditionalexpression:

...default=defaultifdefaultisnotNoneelse[]

Namingconventionsforfunctions

Function naming conventions are similar to variable naming conventions (andare also found in the PEP 8 document). This is called snake case, which isclaimedtobeeasiertoread.Functionnamesshould:

belowercasehave_an_underscore_between_wordsnotstartwithnumbersnotoverridebuiltinsnotbeakeyword

LanguagessuchasJavahaveadopted thecamelcasenamingconvention. Inthat style youmight have a variable namedsectionList or amethod namedhasTimeOverlap. In Python, you would typically name these section_listandhas_time_overlaprespectively.WhilePythoncodeshouldfollowthePEP

Page 153: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

8conventions, there isalsoanallowanceinPEP8forconsistency.If thecodeyouareworkingonhasadifferentstyleofnamingconvention,followsuitandbe consistent with the existing code. Indeed, the unittest module in thestandardlibrarystillhasJavastyleconventions(becauseitwasoriginallyaportfromtheJavalibraryjunit).

Summary

Functionsallowyoutoencapsulatechangeandsideeffectswithintheirbody.Inthischapter,youlearnedthatfunctionscantake inputandreturnoutput.Therecan bemultiple input parameters, and you can also provide default values forthem.Remember thatPython isbasedonobjects,andwhenyoucreatea function,

youalsocreateavariablewiththefunctionnamethatpointstoit.Functionscanalsohaveadocstringwhichisastringwrittenimmediatelyafter

the declaration. These strings are used to present documentation when thefunctionispassedintothehelpfunction.

Exercises

1. Write a function, is_odd, that takes an integer and returns True if thenumberisoddandFalseifthenumberisnotodd.

2. Write a function,is_prime, that takes an integer and returnsTrue if thenumberisprimeandFalseifthenumberisnotprime.

3. Write a binary search function. It should take a sorted sequence and theitem it is looking for. It should return the index of the item if found. Itshouldreturn-1iftheitemisnotfound.

4. Write a function that takes camel cased strings (i.e. ThisIsCamelCased),and converts them to snake case (i.e. this_is_camel_cased). Modify thefunction by adding an argument, separator, so it will also convert tokebabcase(i.e.this-is-camel-case)aswell.

Page 154: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

IndexingandSlicing

PYTHONPROVIDESTWOCONSTRUCTSTOPULLDATAOUTOFSEQUENCE-LIKETYPES(LISTS,tuples,andevenstrings).Thesearetheindexingandslicingconstructs.Indexingallowsyoutoaccesssingleitemsoutofasequence,whileslicingallowsyoutopulloutasubsequencefromasequence.

Indexing

You have seen indexingwith lists. For example, if you have a list containingpets,youcanpulloutanimalsbyindex:

>>>my_pets=["dog","cat","bird"]>>>my_pets[0]'dog'

TIP

RememberthatinPythonindicesstartat0.Ifyouwanttopulloutthefirstitemyoureferenceitby0,not1.Thisiscalledzero-basedindexing.

Page 155: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratespositiveandnegativeindexpositions.

Python has a cool feature where you can reference items using negativeindices. -1 refers to the last item, -2 the second to last item, etc. This iscommonlyusedtopulloffthelastiteminalist:

>>>my_pets[-1]'bird'

Guido van Rossum, the creator of Python, tweeted to explain how tounderstandnegativeindexvalues:

[The]properwaytothinkof[negativeindexing]istoreinterpreta[-X]asa[len(a)-X]

—@gvanrossum

Youcanalsoperformanindexoperationonatupleorastring:

>>>('Fred',23,'Senior')[1]23>>>'Fred'[0]'F'

Sometypes,suchassets,don'tsupportindexoperations.Ifyouwanttodefineyour own class that supports index operations, you should implement the.__getitem__method.

Page 156: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Slicingsublists

Inadditiontoacceptinganintegertopulloutasingleitem,aslicemaybeusedtopulloutasubsequence.Aslicemaycontain thestart index,anoptionalendindex,andanoptionalstride,allseparatedbyacolon.Hereisaslicethatpullsoutthefirsttwoitemsofalist:

>>>my_pets=["dog","cat","bird"]#alist>>>print(my_pets[0:2])['dog','cat']

Remember thatPythonuses thehalf-open interval convention.The listgoesup tobutdoesnot include theend index.Asmentionedpreviously, therangefunctionalsobehavessimilarlywithitssecondparameter.

Thisillustratesslicingoffthefirstfourcharactersofastring.Threeoptionsareshown.Thelastoptionisthepreferredway.Youdon'tneedthezeroindexsinceitisthedefault.Usingnegative

indicesisjustsilly.Slicingoffthefinalthreecharactersisshownaswell.Again,thefinalexampleistheidiomaticwaytodoit.Thefirsttwoassumethestringhasalengthofeight,whilethefinalcode

willworkwithanystringthathasatleastthreecharacters.

Whenyouslicewithacolon(:),thefirstindexisoptional.Ifthefirstindexismissing, the slice defaults to starting from the first itemof the list (the zerothitem):

>>>print(my_pets[:2])

Page 157: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>print(my_pets[:2])['dog','cat']

Youcanalsousenegativeindiceswhenslicing.Anegativeindexcanbeusedinthestartlocationorendinglocation.Theindex-1representsthelastitem.Ifyousliceuptothelastitem,youwillgeteverythingbutthatitem:

>>>my_pets[0:-1]['dog','cat']>>>my_pets[:-1]#defaultsto0['dog','cat']>>>my_pets[0:-2]['dog']

Thefinalindexisalsooptional.Ifthefinalindexismissing,theslicedefaultstotheendofthelist:

>>>my_pets[1:]['cat','bird']>>>my_pets[-2:]['cat','bird']

Finally, you can default both the start and end indices. If both indices aremissing,theslicereturnedwillrunfromthestarttotheend(whichwillcontainacopyofthelist).ThisisaconstructyoucanusetoquicklycopylistsinPython:

>>>print(my_pets[:])['dog','cat','bird']

Stridingslices

Slices also take a stride following the starting andending indices.Thedefaultvalueforanunspecifiedstrideis1.Astrideof1meanstakeeveryitemfromasequence between the indices.A stride of2would take every second item.Astrideof3wouldtakeeverythirditem:

>>>my_pets=["dog","cat","bird"]>>>dog_and_bird=my_pets[0:3:2]>>>print(dog_and_bird)['dog','bird']>>>zero_three_six=[0,1,2,3,4,5,6][::3]>>>print(zero_three_six)[0,3,6]

Page 158: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

[0,3,6]

NOTE

Again,therangefunctionhasasimilarthirdparameterthatspecifiesstride:

>>>list(range(0,7,3))[0,3,6]

Stridescanbenegative.Astrideof-1meansthatyoumovebackwardrighttoleft.Touseanegativestride,youshouldmakethestartslicegreaterthantheendslice.Theexceptionis ifyouleaveout thestartandendindices,astrideof-1willreversethesequence:

>>>my_pets[0:2:-1][]>>>my_pets[2:0:-1]['bird','cat']>>>print([1,2,3,4][::-1])[4,3,2,1]

Thenexttimeyouareinajobinterviewandtheyaskyoutoreverseastring,youcandoitinasingleline:

>>>'emerih'[::-1]'hireme'

Ofcourse, theywillprobablywantyoutodoit inC.Just tell themthatyouwanttoprograminPython!

Summary

Youuseindexingoperationstopullsinglevaluesoutofsequences.Thismakesiteasytogetacharacterfromastring,oranitemfromalistortuple.Ifyouwantsubsequences,youcanuse theslicingconstruct.Slicingfollows

thehalf-openintervalandgivesyouthesequenceuptobutnotincludingthelastindex.Ifyouprovideanoptionalstride,youcanskipelementsinaslice.Pythonhasanice feature thatallowsyou tousenegativevalues to indexor

Page 159: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

slicerelativetotheendofthesequence.Thisletsyoudoyouroperationsrelativetothelengthofthesequence,andyoudon'thavetoworryaboutcalculatingthelengthofsequenceandsubtractingfromthat.

Exercises

1. Create a variable with your name stored as a string. Use indexingoperations to pull out the first character. Pull out the last character.Willyourcodetopulloutthelastcharacterworkonanameofarbitrarylength?

2. Createavariable,filename.Assumingthat ithasathreeletterextension,and using slice operations, find the extension. For README.txt, theextension should betxt.Write code using slice operations thatwill givethe name without the extension. Does your code work on filenames ofarbitrarylength?

3. Createa function,is_palindrome, todetermine if a suppliedword is thesameifthelettersarereversed.

Page 160: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

FileInputandOutput

READING AND WRITING FILES IS COMMON IN PROGRAMMING. PYTHON MAKES THESEoperationseasy.Youcanreadbothtextandbinaryfiles.Youalsohaveachoiceof readinga fileby thenumberofbytes, lines,oreven thewhole fileatonce.Therearesimilaroptionsavailableforwritingfiles.

Openingfiles

The Python function, open, returns a file object. This function has multipleoptionalparameters:

open(filename,mode='r',buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)

HINT

Windows paths use \ as a separator, which can be problematic. Pythonstringsalsouse\asanescapecharacter.Ifyouhadadirectorynamed"test"andwrote"C:\test",Pythonwouldtreat\tasatabcharacter.TheremedyforthisistouserawstringstorepresentWindowspaths.Put

anrinfrontofthestring:

r"C:\test"

Youtypicallyareonlyconcernedwiththefirst twoorthreeparameters.Thefirst parameter, the filename, is required. The second parameter is the mode,whichdeterminesifyouarereadingorwritingafileandifthefileisatextfileorbinaryfile.Therearevariousmodes.

Filemodes

Page 161: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

FilemodesMODE MEANING

'r' Readtextfile(default)

'w' Writetextfile(overwritesifexists)

'x' Writetextfile,throwFileExistsErrorifexists.

'a' Appendtotextfile(writetoend)

'rb' Readbinaryfile

'wb' Writebinary(overwrite)

'w+b' Openbinaryfileforreadingandwriting

'xb' Writebinaryfile,throwFileExistsErrorifexists.

'ab' Appendtobinaryfile(writetoend)

Fordetailson therestof theoptions to theopen function,pass it intohelp.Thisfunctionhasverydetaileddocumentation.Ifyouaredealingwith text files, typicallyyouwilluse'r' as themode to

readafile,and'w'towriteafile.Hereyouopenthefiletmpa.txtforwriting.Pythonwillcreatethatfile,oroverwriteitifitalreadyexists:

>>>a_file=open('tmpa.txt','w')

Thefileobject,returnedfromtheopencall,hasvariousmethodstoallowforreadingandwriting.Thischapterdiscusses themostcommonlyusedmethods.To read the fulldocumentationona fileobjectpass it to thehelp function. Itwilllistallofthemethodsanddescribewhattheydo.

NOTE

/tmpiswhereUnixsystemsplacetemporaryfiles.IfyouareonWindows,youcaninspecttheTempvariablebytyping:

c:\>ECHO%Temp%

Thevalueisusually:

C:\Users\<username>\AppData\Local\Temp

Page 162: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Readingtextfiles

Pythonprovidesmultiplewaystoreaddatafromfiles.Ifyouopenafileintextmode(thedefault),youreadstringsfromthefileoryouwritestringstoit.Ifyouopenafile inbinarymode(usinga'rb' forreadingor'wb' forwriting),youwillreadandwritebytestrings.Ifyouwanttoreadasinglelinefromanexistingtextfile,usethe.readline

method. Ifyoudon't specifyamode,Pythonwilldefault to readinga text file(modeofr):

>>>passwd_file=open('etcpasswd')>>>passwd_file.readline()'root:x:0:0:root:/root:/bin/bash'

Becareful,ifyouopenafileforreadingthatdoesnotexist,Pythonwillthrowanerror:

>>>fin=open('bad_file')Traceback(mostrecentcalllast):...IOError:[Errno2]Nosuchfileordirectory:'bad_file'

TIP

Theopenfunctionreturnsafileobjectinstance.Thisobjecthasmethodstoreadandwritedata.Commonvariablenames for fileobjects arefin (file input),fout (file

output),fp (filepointer,usedforeither inputoroutput)ornamessuchaspasswd_file.Names likefin andfout are useful because they indicatewhetherthefileisusedforreadingorwritingrespectively.

Asillustratedabove,the.readlinemethodwillreturnonelineofafile.Youcan call it repeatedly to retrieve every line or use the .readlinesmethod toreturnalistcontainingallthelines.Toreadallthecontentsofafileintoonestringusethe.readmethod:

Page 163: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>passwd_file=open('etcpasswd')>>>print(passwd_file.read())root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/bin/falsedaemon:x:2:2:daemon:/sbin:/bin/falseadm:x:3:4:adm:/var/adm:/bin/false

Youshouldalwayscloseyourfileswhenyouaredonewiththembycalling.close:

>>>passwd_file.close()

Closingyourfilesiseasy.Abitlateryouwilldigintowhyyoushouldmakesureyouclosethem.

Readingbinaryfiles

Toreadabinaryfile,passin'rb'(readbinary)asthemode.Whenyoureadabinaryfileyouwillnotgetstrings,butbytestrings.Don'tworry,astheinterfaceforbytestringsisverysimilartostrings.HerearethefirsteightbytesofaPNGfile.Toreadeightbytes,youwillpass8tothe.readmethod:

>>>bfin=open('img/dict.png','rb')>>>bfin.read(8)b'\x89PNG\r\n\x1a\n'

Noticethebinfrontofthestring,specifyingthatthisisabytestring.Youcanalso use .readline on binary files and it will read until it gets to a b'\n'.Binarystringsversusnormalstringswillbediscussedinalaterchapter.

Iterationwithfiles

Iterationoversequenceswasdiscussedpreviously.InPython,itiseasytoiterateover the lines ina file.Whendealingwitha text file,youcan iterateover the.readlinesmethodtogetalineatatime:

>>>fin=open('etcpasswd')>>>forlineinfin.readlines():...print(line)

Page 164: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

However, because .readlines returns a list, Python will need to read thewhole file tocreate that list, and thatcouldbeproblematic.Say the filewasalarge logfile, itcouldpossiblyconsumeallofyourmemorytoread it.Pythonhasatrickupitssleevethough.Pythonallowsyoutoloopoverthefileinstanceitselftoiterateoverthelinesofthefile.Whenyouiteratedirectlyoverthefile,Pythonislazy,andonlyreadsthelinesoftextasneeded:

>>>fin=open('etcpasswd')>>>forlineinfin:...print(line)

How can you iterate directly over the file instance? Python has a dundermethod, .__iter__, that defines what the behavior is for looping over aninstance.Itjustsohappensthatforthefileclass,the.__iter__methoditeratesoverthelinesinthefile.The.readlinesmethodshouldbe reservedforwhenyouaresure thatyou

can hold the file inmemory and you need to access the linesmultiple times.Otherwise,directlyiteratingoverthefileispreferred.

Writingfiles

Towrite toa file,youmust firstopen the file inwritemode. Ifmode is set to'w',thefileisopenedforwritingtextdata:

>>>fout=open('tmpnames.txt','w')>>>fout.write('George')

The above method will try to overwrite the file tmpnames.txt if it exists,otherwise,thefilewillbecreated.Ifyoudon'thavepermissiontoaccessthefile,a Permission Error will be thrown. If the path is bad, you will see aFileNotFoundError.Twomethodsusedtoplacedatainafileare.writeand.writelines.The

.write method takes a string as a parameter and writes it to the file. The

.writelinesmethodtakesasequencecontainingstringdataandwritesittothefile.

Page 165: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

NOTE

Toincludenewlinesinyourfile,youneedtoexplicitlypassthemtothefilemethods.OnUnix platforms, strings passed into.write should endwith\n. Likewise, each of the strings in the sequence that is passed into to.writelinesshouldendin\n.OnWindows,thenewlinestringis\r\n.Toprograminacrossplatformmanner,thelinesepstringfoundinthe

osmoduledefinesthecorrectnewlinestringfortheplatform:

>>>importos>>>os.linesep#Unixplatform'\n'

TIP

Ifyouaretryingthisoutontheinterpreterrightnow,youmaynoticethatthe tmpnames.txt file is empty even though you told Python to writeGeorgeinit.Whatisgoingon?File output is buffered by the operating system. In order to optimize

writestothestoragemedia,theoperatingsystemwillonlywritedataafteracertain thresholdhasbeenpassed.OnLinuxsystems, this isnormally4Kbytes.Toforcewritingthedata,youcancallthe.flushmethod,whichflushes

thependingdatatothestoragemedia.Amoreheavy-handedmechanism,toensurethatdataiswritten,istocall

the.closemethod.This informsPython thatyouaredonewriting to thefile:

>>>fout2=open('tmpnames2.txt',...'w')>>>fout2.write('John\n')>>>fout2.close()

Closingfiles

Page 166: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Closingfiles

Asmentioned previously, calling.closewillwrite the file buffers out to thestoragemedia.ThebestpracticeinPythonistoalwaysclosefilesafteryouaredonewiththem(whetherforwritingorreading).Hereareafewreasonswhyyoushouldexplicitlycloseyourfiles:

If youhave a file in a global variable, itwill never be closedwhile yourprogramisexecuting.cPython will automatically close your files for you if they are garbagecollected.OtherPythonimplementationsmaynot.Unlessyoucall.flushyouwon'tknowwhenyourdataiswritten.Youroperatingsystemprobablyhasalimitofopenfilesperprocess.Someoperatingsystemswon'tletyoudeleteanopenfile.

Pythonusuallytakescareofgarbagecollectionforyouandyoudon'thavetoworry about cleaning up objects. Opening and closing files are exceptions.Pythonwillautomaticallyclosethefileforyouwhenthefileobjectgoesoutofscope. But this is a case where you shouldn't rely on garbage collection. Beexplicitandcleanupafteryourself.Makesureyoucloseyourfiles!Python 2.5 introduced thewith statement.Thewith statement is usedwith

context managers to enforce conditions that occur before and after a block isexecuted.Theopen functionalso servesasacontextmanager toensure that afileisopenedbeforetheblockisenteredandthatitisclosedwhentheblockisexited.Belowisanexample:

>>>withopen('tmpnames3.txt','w')asfout3:...fout3.write('Ringo\n')

Thisistheequivalentof:

>>>fout3=open('tmpnames3.txt','w')>>>fout3.write('Ringo\n')>>>fout3.close()

Page 167: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Noticethatthewithlineendswithacolon.WhenalineendswithacoloninPython,youalwaysindentthecodethatfollows.Theindentedcontentfollowinga colon is called a block or the body of the context manager. In the aboveexample, theblockconsistsofwritingRingo toafile.Thentheblockfinishes.Youcan't reallysee it in theaboveexample,butyouknowawithblockendswhen the code is dedented. At this point, the context manager kicks in andexecutestheexitlogic.TheexitlogicforthefilecontextmanagertellsPythontoautomaticallyclosethefileforyouwhentheblockisfinished.

TIP

Usethewithconstructforreadingandwritingfiles.Itisagoodpracticetoclosefiles,andifyouusethewithstatementwhenusingfiles,youdonothavetoworryaboutclosingthem.Thewithstatementautomaticallyclosesthefileforyou.

Designingaroundfiles

You have seen how to use functions to organize and compartmentalizecomplicated programs. One benefit to using functions is that you can re-usethosefunctionsthroughoutyourcode.Hereisatipfororganizingfunctionsthatdealwithfiles.Assume that you want to write code that takes a filename and creates a

sequenceof the lines from the filewith the line number inserted before everyline. At first thought it might seem that you want the API (applicationprogramminginterface)foryourfunctionstoacceptthefilenameofthefilethatyouwanttomodify,likethis:

>>>defadd_numbers(filename):...results=[]...withopen(filename)asfin:...fornum,lineinenumerate(fin):...results.append(...'{0}-{1}'.format(num,line))...returnresults

Page 168: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

...returnresults

This codewill work okay. Butwhatwill happenwhen you are required toinsertlinenumbersinfrontoflinesfromasourceotherthanafile?Ifyouwantto test the code, now you have access to the file system. One solution is torefactortheadd_numbersfunctionsothatitwillonlyopenthefileinacontextmanager,andthencallanotherfunction,add_nums_to_seq.Thisnewfunctioncontainslogicthatoperatesonasequenceratherthandependingonafilename.Since a file behaves as a sequence of strings, you preserve the originalfunctionality:

>>>defadd_numbers(filename):...withopen(filename)asfin:...returnadd_nums_to_seq(fin)>>>defadd_nums_to_seq(seq):...results=[]...fornum,lineinenumerate(seq):...results.append(...'{0}-{1}'.format(num,line))...returnresults

Nowyouhave amore general function,add_nums_to_seq, that is easier totest and reuse, because instead of depending on a filename, it depends on asequence.Youcanpassinalistofstrings,orcreateafakefiletopassintoit.

HINT

Thereareother typesthatalsoimplement thefile-likeinterface(readandwrite).Anytimeyoufindyourselfcodingwithafilename,askyourselfifyoumaywanttoapplythelogictoothersequence-likethings.Ifso,usethepreviousexampleof refactoring the functions toobtaincode that ismucheasiertoreuseandtest.

Summary

Page 169: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Python provides a single function to interact with both text and binary files,open.Byspecifyingthemode,youcantellPythonwhetheryouwanttoreadorwritetothefile.Whenyouaredealingwithtextfiles,youreadandwritestrings.Whenyouaredealingwithbinaryfiles,youreadandwritebytestrings.Makesureyoucloseyourfiles.Usingthewithstatementistheidiomaticway

todothis.Finally,makesureyourfunctionsdealwithsequencesofdatainsteadoffilenamesasthismakesyourcodemoregenerallyuseful.

Exercises

1. Write a function towrite a comma separated value (CSV) file. It shouldacceptafilenameandalistoftuplesasparameters.Thetuplesshouldhaveaname,address,andage.Thefileshouldcreateaheaderrowfollowedbyarowforeachtuple.Ifthefollowinglistoftupleswaspassedin:

[('George','4312AbbeyRoad',22),('John','54LoveAve',21)]

itshouldwritethefollowinginthefile:

name,address,ageGeorge,4312AbbeyRoad,22John,54LoveAve,21

2. WriteafunctionthatreadsaCSVfile.Itshouldreturnalistofdictionaries,using the first row as key names, and each subsequent row as values forthosekeys.Forthedatainthepreviousexampleitwouldreturn:

[{'name':'George','address':'4312AbbeyRoad','age':22},{'name':'John','address':'54LoveAve','age':21}]

Page 170: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Unicode

WE'VESEENSTRINGSALLOVERTHEPLACE,BUTWEHAVEN'TREALLYTALKEDABOUTONEof the biggest changes that came in Python 3,Unicode strings! Python 2 hadsupportforUnicodestrings,butyouneededtoexplicitlycreatethem.Thisisnolongerthecase,everythingisUnicode.

Background

What is Unicode? It is a standard for representing glyphs (the characters thatcreatemostwritten language,aswellassymbolsandemoji).Thestandardcanbe found on the Unicode website 12, and is frequently updated. The standardconsists of various documents or charts that map code points (hexadecimalnumberssuchas0048or1F600)toglyphs(suchasHorᛡ),andnames(LATINCAPITALH andGRINNING FACE). The code points and names are unique,thoughmanyglyphsmaylookverysimilar.

Page 171: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustrateshowtoreadcodechartsfoundatunicode.org.Thechartshavetableslistingglyphsbytheirhexcodepoints.Followingthattableisanothertablewiththecodepoint,glyph,andname.

Youcanuseaglyph,thename,orthecodepoint.Ifthecodepointhasmorethan4digits,youneedtousecapitalUandleftpadwith0untilyouhave8digits.Ifithas4orlessdigits,youneedtousea

lowercaseuandleftpadwith0untilyouhave4digits.AlsoshownisanexampledecodingtheUTF-8bytestringtothecorrespondingglyph.

Here is a condensed history. As computers became prevalent, differentprovidershaddifferentschemestomapbinarydatatostringdata.Oneencoding,ASCII,woulduse7bitsofdatatomapto128symbolsandcontrolcodes.ThatworksfineinaLatincharacter-centricenvironmentsuchasEnglish.Having128different glyphs would provide enough space for lowercase characters,uppercasecharacters,digits,andcommonpunctuation.

Page 172: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Assupportfornon-Englishlanguagesbecamemorecommon,ASCIIwasnotsufficient.WindowssystemsthroughWindows98supportedanencodingcalledWindows-1252, that had support for various accented characters, and symbolssuchastheEurosign.Allof theseencodingschemesprovidedaone-to-onemappingofbytes toa

character.InordertosupportChinese,Korean,andJapanesescripts,manymorethan 128 symbolswere needed.Using four bytes provided support for over 4billioncharacters.Butthisencodingcameatacost.ForthemajorityofpeopleusingonlyASCII-centriccharacters,requiringthosecharacterstobeencodedinfourtimesasmuchdataseemedlikeacolossalwasteofmemory.Acompromisethatprovidedboththeabilitytosupportallcharactersbutnot

wastememory,wastostopencodingcharacterstoasequenceofbits.Rather,thecharacters were abstracted. Each character instead mapped to a unique codepoint(thathasahexvalueandauniquename).Variousencodingsthenmappedthesecodepointstobitencodings.Unicodemapsfromcharactertoacodepoint—it is not the encoding. For different contexts, an alternate encoding mightprovidebettercharacteristics.One encoding, UTF-32, uses four bytes to store the character information.

This representation is easy for low-level programmers to use as indexingoperationsaretrivial.ButitusesfourtimestheamountofmemoryasASCIItoencodeaLatinsequenceofletters.Thenotionofvariablewidthencodingsalsohelpedalleviatememorywaste.

UTF-8isonesuchencoding.Itusesbetweenoneandfourbytestorepresentacharacter.Inaddition,UTF-8isbackwardcompatiblewithASCII.UTF-8isthemost common encoding on theweb, and is a great choice for encoding sincemanyapplicationsandoperatingsystemsknowhowtodealwithit.

TIP

Page 173: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

You can find out what the preferred encoding is on your machine byrunningthefollowingcode.Hereismineona2015Mac:

>>>importlocale>>>locale.getpreferredencoding(False)'UTF-8'

Let’sbeclear.UTF-8isanencodingofbytesforUnicodecodepoints.TosaythatUTF-8isUnicodeissloppyatbestandconnotesalackofunderstandingofcharacter encodings at worst. In fact, the name is derived from UnicodeTransformationFormat-8-bit,ie.itisaformatforUnicode.Let’s look at an example. The character named, SUPERSCRIPT TWO, is

definedintheUnicodestandardascodepointU+00b2.Ithasaglyph(awrittenrepresentation) of ². ASCII has no way to represent this character.Windows-1252does,itisencodedasthehexbyteb2(whichhappenstobethesameasthecodepoint, note that this is not guaranteed). InUTF-8 it is encoded asc2b2.Likewise,UTF-16encodesitasfffeb200.TherearemultipleencodingsforthisUnicodecodepoint.

BasicstepsinPython

You can createUnicode strings in Python. In fact, you have been doing it allalong. Remember in Python 3, strings are Unicode strings. But you probablywanttocreateastringthathasanon-ASCIIcharacter.Belowiscodetomakeastringthathasxsquared(x²)init.Ifyoucanfindtheglyphyouwanttouse,youcancopythatcharacterinintoyourcode:

>>>result='x²'

Thisworksingeneral.Thoughyoumightrunintoproblemsifyourfontdoesnotsupportsaidglyph.Thenyouwillgetwhatissometimescalledtofubecauseit lookseither likeanemptyboxoradiamondwithaquestionmark.Another

Page 174: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

way to include non-ASCII characters is to use the hex Unicode code pointfollowing\u:

>>>result2='x\u00b2'

Notethatthisstringisthesameasthepreviousstring:

>>>result==result2True

Finally,youcanusethenameofthecodepointinsideofthecurlybracesin\N{}:

>>>result3='x\N{SUPERSCRIPTTWO}'

Allofthesework.TheyallreturnthesameUnicodestring:

>>>print(result,result2,result3)x²x²x²

Thethirdoptionisalittleverboseandrequiresalittlemoretyping.Butifyoudon'tspeaknativeUnicodeorhavefontsupport,itisperhapsthemostreadable.

TIP

The Python help documentation has an entry forUnicode. Type help(),then UNICODE. It actually doesn't discuss Unicode that much, rather thedifferentwaystocreatePythonstrings.

Encoding

PerhapsoneofthekeystogrokkingUnicodeinPythonistounderstandthatyouencodeaUnicodestringtoabytestring.Youneverencodeabytestring.YoudecodeabytestringtoaUnicodestring.Likewise,youneverdecodeaUnicodestring. Another way of looking at encoding and decoding is that encodingtransforms a human-readable or meaningful representation into an abstractrepresentation meant for storage (Unicode to bytes or letter to bytes), and

Page 175: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

decoding transforms that abstract representation back to a human readable ormeaningfulrepresentation.

Imageillustratestheencoding(inthiscaseusingUTF-8)ofaUnicodestringintoitsbyterepresentation,andthenthedecodingofthesamebytestringbackintoUnicode(alsousingUTF-8).Notethatyoushouldbeexplicitwhendecodingasthereareotherencodingsthatifused,might

produceerroneousdataormojibake(charactertransformation).

Given a Unicode string, you can call the .encode method to see therepresentationinvariousencodings.Let’sstartoffwithUTF-8:

>>>x_sq='x\u00b2'>>>x_sq.encode('utf-8')b'x\xc2\xb2'

IfPythondoesnotsupportanencoding,itwillthrowaUnicodeEncodeError.ThismeansthattheUnicodecodepointsarenotsupportedinthatencoding.Forexample,ASCII,doesnothavesupportforthesquaredcharacter:

>>>x_sq.encode('ascii')Traceback(mostrecentcalllast):...UnicodeEncodeError:'ascii'codeccan'tencodecharacter'\xb2'inposition1:ordinalnotinrange(128)

If you use Python long enough, you will probably encounter this error. Itmeansthatthespecifiedencodingdoesnothavetheabilitytorepresentallofthe

Page 176: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

characters. If you are certain that youwant to force Python to this encoding,therearea fewdifferentoptionsyoucanprovide to theerrorsparameter.ToignorecharactersPythoncan'tencode,useerrors='ignore':

>>>x_sq.encode('ascii',errors='ignore')b'x'

Ifyouspecifyerrors='replace',Pythonwillinsertaquestionmarkfortheunsupportedbytes:

>>>x_sq.encode('ascii',errors='replace')b'x?'

NOTE

TheencodingsmodulehasamappingofaliasesofencodingsthatPythonsupports.Thereare99encodingsinPython3.6.MostmodernapplicationstrytostayinUTF-8,butifyouneedsupportforotherencodings,thereisagoodchancethatPythonhassupportforit.Thismapping is found inencodings.aliases.aliases.Alternatively,

thedocumentationonthemoduleatthePythonwebsite13hasatableoftheencodings.

Herearesomeotherpossibleencodingsforthisstring:

>>>x_sq.encode('cp1026')#Turkishb'\xa7\xea'>>>x_sq.encode('cp949')#Koreanb'x\xa9\xf7'>>>x_sq.encode('shift_jis_2004')#Japaneseb'x\x85K'

ThoughPythonsupportsmanyencodings,theirusageisbecomingmorerare.Typically they are used for legacy applications. Today, most applications useUTF-8.

Decoding

Page 177: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

DecodinghasaspecificmeaninginPython.ItmeanstotakeasequenceofbytesandcreateaUnicodestringfromthem.InPython,youneverencodebytes,youdecodethem(infactthereisno.encodemethodonbytes).Ifyoucanrememberthatrule,itcansaveabitoffrustrationwhendealingwithnon-ASCIIcharacters.Let’sassumethatyouhavetheUTF-8bytesequenceforx²:

>>>utf8_bytes=b'x\xc2\xb2'

Whenyouaredealingwithcharacterdata representedasbytes,youwant toget it into aUnicode string as soon as possible. Typically, youwill only dealwithstringsinyourapplicationandusebytesasaserializationmechanism(i.e.whenpersistingtofilesorsendingoverthenetwork).Ifyoureceivedthesebytessomehowand the frameworkor library that youwere usingdid not convert itintoastringforyou,youcoulddothefollowing:

>>>text=utf8_bytes.decode('utf-8')>>>text'x²'

Anotherthingtonoteisthatingeneral,youcannotdivinewhatasequenceofbyteswasencodedas.YouknowthatthesequenceinthecodelistedisUTF-8because you just created it, but if unidentified bytes were sent to you fromanothersourcethenitcouldcertainlybeanotherencoding.

NOTE

Youneedtobetoldtheencoding.Otherwise,youmighttrytodecodewiththewrongencodingandhavebaddata.When thishappens, themiscodedstring is calledmojibake. This is a Japanese word that means charactermutation,butmojibakesoundscooler.Herearesomeexamplesoferroneousdecoding:

>>>b'x\xc2\xb2'.decode('cp1026')#Turkish'ÌB¥'

>>>b'x\xc2\xb2'.decode('cp949')#Korean'x'

Page 178: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>b'x\xc2\xb2'.decode('shift_jis_2004')#Japanese'xツイ'

Butsomeencodingsdon'tsupportallbytesequences.Ifyoudecodewiththewrong encoding, sometimes insteadof gettingbaddata, youget an exception.Forexample,ASCII,doesnotsupportthisbytesequence:

>>>b'x\xc2\xb2'.decode('ascii')Traceback(mostrecentcalllast):...UnicodeDecodeError:'ascii'codeccan'tdecodebyte0xc2inposition1:ordinalnotinrange(128)

AUnicodeDecodeErrormeansthatyouweretryingtoconvertabytestringto a Unicode string and the encoding did not have support to create Unicodestrings forallof thebytes.Typically, thismeans thatyouareusing thewrongencoding.Forbestresults,trytodetermineandusethecorrectencoding.If you really don't know the encoding, you can pass the errors='ignore'

parameter,butthenyouarelosingdata.Thisshouldonlybeusedasalastresort:

>>>b'x\xc2\xb2'.decode('ascii',errors='ignore')'x'

Unicodeandfiles

When you read a text file, Pythonwill give youUnicode strings. By default,Python will use the default encoding(locale.getpreferredencoding(False)).Ifyouwanttoencodeatextfileinanotherencoding,youcanpassthatinformationwiththeencodingparametertotheopenfunction.Likewise, you can specify the encoding when you open a file for writing.

Remember,youshouldtreatencodingsasaserializationformat(usedtotransferinformationovertheinternetorstorethedatainafile).Herearetwoexamplesofwriting to a file.With the first file no encoding is defined, and it therefore

Page 179: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

defaults toUTF-8 (per the system's default encoding). In the second example,CP949(Korean)issetastheencodingparameter:

>>>withopen('tmpsq.utf8','w')asfout:...fout.write('x²')

>>>withopen('tmpsq.cp949','w',encoding='cp949')asfout:...fout.write('x²')

From theUNIX terminal, lookat the files.You see that theyhavedifferentcontents,becausetheyareusingdifferentencodings:

$hexdumptmpsq.utf8000000078c2b20000003

$hexdumptmpsq.cp949000000078a9f70000003

Youcanreadthedataback:

>>>data=open('tmpsq.utf8').read()>>>data'x²'

Remember,thatinPython,explicitisbetterthanimplicit.Whendealingwithencodings, you need to be specific. Python on a UTF-8 system will try anddecodefromUTF-8whenyoureadafile.ThisisfineifthefileisencodedwithUTF-8,butifitisnot,youwilleithergetmojibake,oranerror:

>>>data=open('tmpsq.cp949').read()Traceback(mostrecentcalllast):...UnicodeDecodeError:'utf-8'codeccan'tdecodebyte0xa9inposition1:invalidstartbyte

IfyouareexplicitandtellPythonthatthisfilewasencodedwiththeCP949encoding,youwillgetthecorrectdatafromthisfile:

>>>data=open('tmpsq.cp949',encoding='cp949').read()>>>data'x²'

Page 180: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Ifyouaredealingwithtextfilesthatcontainnon-ASCIIcharacters,makesureyouspecifytheirencoding.

Summary

Unicode is a mapping of code points to glyphs. In Python, strings can holdUnicode glyphs. You can encode the Unicode string to a byte string usingvariousencodings.YouneverdecodePythonstrings.Whenyoureadatextfile,youcanspecifytheencodingtomakesurethatyou

getaUnicodestringcontainingthecorrectcharacters.Whenyouwritetextfiles,youcanusetheencodingparametertodeclaretheencodingtouse.UTF-8isthemostpopularencodingthesedays.Unlessyouhaveareasonto

useanotherencoding,youshoulddefaulttousingUTF-8.

Exercises

1. Go to http://unicode.org and download a chart that has code points on it.Chooseanon-ASCIIcharacterandwritePythoncodetoprintthecharacterbyboththecodepointandname.

2. There are various Unicode characters that appear to be upside downversions of ASCII characters. Find a mapping of these characters (theyshouldbeasearchaway).Writeafunction that takesastringwithASCIIcharacters,andreturnstheupsidedownversionofthatstring.

3. Writetheupsidedownversionofyournametoafile.Whataresomeofthepossibleencodingsthatsupportyourname?Whataresomeencodingsthatdon't?

4. Smart quotes (or curly quotes) are not supported with ASCII. Write afunctionthattakesanASCIIstringasinputandreturnsastringwherethedouble quotes are replaced with smart quotes. For example, the stringPythoncomeswith"batteriesincluded",shouldbecomePythoncomeswith“batteries included” (if you look closely, you will see that with smartquotes,theleftquotescurvedifferentlythantherightquotes).

Page 181: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

5. Writea function that takes textwitholdschoolemojis in it (:),:P,etc.).Using the emoji chart 14, add code to your function that replaces the textemojis,withUnicodeversionsfoundinthechart.

12-https://unicode.org13-https://docs.python.org/3/library/codecs.html14-http://unicode.org/emoji/charts/full-emoji-list.html

Page 182: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Classes

STRINGS,DICTIONARIES, FILES,AND INTEGERSAREALLOBJECTS.EVEN FUNCTIONSAREobjects. InPython, almost everything is anobject.There are someexceptions,keywords(suchasin)arenotobjects.Also,variablenamesarenotobjects,buttheydopointtothem.Thischapterwilldelvedeeperintowhatanobjectreallyis.Object is a somewhat ambiguous term. One definition of “Object-Oriented

Programming” is using structures to group together data (state) and methods(functionstoalterstate).Manyobject-orientedlanguagessuchasC++,Java,andPythonuseclasses todefinewhat stateanobject canholdand themethods toalter that state. Whereas classes are the definition of the state and methods,instancesareoccurrencesofsaidclasses.Generallywhenpeoplesayobjecttheymeananinstanceofaclass.InPython,str is thenameof the classused to store strings.Thestr class

definesthemethodsofstrings.Youcancreateaninstanceofthestrclass,b,byusingPython’sliteralstring

syntax:

>>>b="I'mastring">>>b"I'mastring"

Therearemanytermsthatyouwillseethrownabouttotalkaboutb.Youmayhear,“bisastring”,“bisanobject”,“bisaninstanceofastring”.Thelatterisperhapsthemostspecific.But,bisnotastringclass.

Page 183: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratesastringobject.Allobjectshavetypes,whicharereallyjusttheclassoftheobject.Inthiscasetheclassisstr.

Page 184: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratesanupdatedversionofastringobject.Typehasbeenchangedto__class__,becausewhenyouinspecttheobject,the__class__attributepointstotheclassoftheobject.Notethatthisclasshasvariousmethods,thisimageonlyshowscapitalize,buttherearemanymore.Methodsare

alsoobjects,asshownintheimage.

NOTE

Thestr classcanalsobeused tocreate strings,but isnormallyused forcasting. Strings are built into the language, so it is overkill to pass in astringliteralintothestrclass.Youwouldn'tsay:

>>>c=str("I'mastring")

Page 185: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Because Python automatically creates a string when you put quotesaroundcharacters.ThetermliteralmeansthatthisisaspecialsyntaxbuiltintoPythontocreatestrings.Ontheflipside,ifyouhaveanumberthatyouwanttoconverttoastring,

youcouldcallstr:

>>>num=42>>>answer=str(num)>>>answer'42'

It is said that Python comes with “batteries included”—it has libraries andclassespredefinedforyouruse.Theseclassestendtobegeneric.Youcandefineyour own classes that deal specifically with your problem domain. You cancreatecustomizedobjectsthatcontainstate,andaswellaslogictochangethatstate.

Planningforaclass

First of all, classes are not always needed in Python. You should give somethoughttowhetheryouneedtodefineaclassorwhetherafunction(orgroupoffunctions) would be sufficient. Classes might be useful to provide aprogrammatic representation of something that is a physical object, or aconceptual object. Something that is a description such as speed, temperature,average,orcolorarenotgoodcandidatesforclasses.Onceyouhavedecided thatyouwant tomodel somethingwitha class, ask

yourselfthefollowingquestions:

Doesithaveaname?Whatarethepropertiesthatishas?Arethesepropertiesconstantbetweeninstancesoftheclass?ie:

Whichofthesepropertiesarecommontotheclass?

Page 186: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Whichofthesepropertiesareuniquetoeachmember?

Whatactionsdoesitdo?

Here’saconcreteexample.Assumethatyouworkforaskiresortandwanttomodelhowpeopleusethechairlifts.Onewaytodosowouldbetocreateaclassthatdefinesachaironachairlift.Achairlift,ifyouarenotfamiliarwithit,isacontraption that has many chairs. These chairs are like a bench that multipleskiersmaysiton.Skiersqueueupatthebottomofahilltoboardthechairs,thenunboardoncethechairhasliftedthemtothetopofthehill.Obviously,youwillneedtoabstractyourmodeltosomedegree.Youarenot

goingtomodeleverylow-levelpropertyofachair.Forexample,youdon'tcarewhether a chair ismade of steel or aluminum or wood for calculating usage.Thatmightmatterforotherpeople.Doesthisthingyouwanttomodelhaveaname?Yes,chair.Afewproperties

ofthechairincludechairnumber,capacity,whetherithasasafetybar,andifithaspaddedseats.Todive ina littledeeper, capacitycanbebrokendown intomaximum capacity and current occupants. Maximum capacity should stayconstant,whereasoccupantscanchangeatapointintime.Achairisinvolvedwithafewactions.Someactionsincludeaddingpeopleat

thebottomofthehillandremovingpeoplewhentheyreachthetopofthehill.Another actionmight be the position of the safety bar. You are going handleloadingandunloadingbutignorebarpositionforyourmodel.

Definingaclass

HereisaPythonclasstorepresentachaironachairlift.Belowisasimpleclassdefinition.Thecommentsarenumberedfordiscussionfollowingthecode:

>>>classChair:#1...'''AChaironachairlift'''#2...max_occupants=4#3......def__init__(self,id):#4...self.id=id#5...self.count=0

Page 187: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

...self.count=0

...

...defload(self,number):#6

...self.count+=number

...

...defunload(self,number):#7

...self.count-=number

TheclassstatementinPythondefinesaclass.Youneedtogiveitaname(1),followed by a colon.Remember that in Python, you indent following a colon(unless it is a slice). Note, that you indented consistently below the classdefinition.Alsonotethatthenameoftheclasswascapitalized.

NOTE

Classnamesareactuallycamelcased.BecauseChairisasingleword,youmightnothavenoticed.Unlikefunctionswherewordsare joined togetherwith underscores, in camel casing, you capitalize the first letter of eachword and then shove them together.Normally class names are nouns. InPython, they cannot start with numbers. The following are examples ofclassnames,bothgoodandbad:

Kitten#good

jaguar#bad-startswithlowercase

SnowLeopard#good-camelcase

White_Tiger#bad-hasunderscores

9Lives#bad-startswithanumber

SeePEP8forfurtherinsightintoclassnaming.Note that many of the builtin types do not follow this rule: str, int,

float,etc.

Immediatelyfollowingthedeclarationoftheclass,youcaninsertadocstring(2). This is just a string. Note that if it is a triple-quoted string, it may span

Page 188: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

multiple lines. Docstrings are optional, but they are useful to readers of yourcode,andalsoappearwhenyouusethehelpfunctiontoinspectyourcodeintheREPL.Usethemjudiciouslyanditwillpaygreatdividends.Inside the indentedbodyof the class, you can createclass attributes (3).A

classattributeisusedtoholdstatethatissharedamongallinstancesofaclass.In this example, any chair that you create will have a maximum of fouroccupants.(Skierscall thesetypesofchairliftsquads).Thereareadvantagestocreatingclassattributes.Becausetheclassissettingthisnumber,youdon'thavetorepeatyourselfandsetthevalueeachtimeyoucreateachair.Ontheflipside,youhavehardcodedyourchair toonlysupportfourseatsonit.Later,youwillseehowtooverridetheclassattribute.Next you see adef statement (4). It looks like you are defining a function

insideoftheclassbody.Andyouare,exceptwhenyoudefineafunctiondirectlyinsideofaclassbody,youcall itamethod.Because thismethodhasaspecialname,__init__,youcallitaconstructor.Ithastwoparameters,selfandid.Mostmethodshaveselfasthefirstparameter.Youcaninterpretselfasbeingtheinstanceoftheclass.

Page 189: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustrateswhathappenswhenyoudefineaclass.Pythonwillcreateanewtypeforyou.Anyclassattributesormethodswillbestoredasattributesofthenewclass.Instanceattributes(idand

count)arenotfoundintheclassastheywillbedefinedontheinstances.

Aconstructoriscalledwhenyoucreateaninstanceofaclass.Ifyouconsideraclasstobeafactorythatprovidesatemplateorblueprintforinstances,thentheconstructoriswhatinitializesthestatefortheinstances.Theconstructortakesaninstanceasinput(theselfparameter),andupdatesitinsidethemethod.Pythontakescareofpassingaroundtheinstanceforus.Thiscanbeconfusingandwillbediscussedmorelater.

Page 190: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Inside the body of the constructor (5) (it is indented because it follows acolon), you attach two attributes that will be unique to the instance, id andcount. On most chairlifts, each chair on the chairlift has a unique numberpaintedon the chair.Theid represents this number.Also, a chairmayhold anumberofskiers—youstorethisinthecountattributeandinitializeit tozero.Note, that theconstructordoesnotreturnanything,butrather itupdatesvaluesthatareuniquetotheinstance.

NOTE

RememberthatidisabuiltinfunctioninPython,butyoucanalsousethatasanattributenameinaclass.Youwillstillhaveaccesstotheidfunction.Everytimeyouwanttoaccesstheidattributeyouwilldoalookupontheinstance.Iftheinstancewasnamedchair,youwouldgettheidbycallingchair.id.So,thisisnotshadowingthebuiltinfunctionandisok.

You can tell that the constructor logic is finished when you see that theindentation level has stepped back out. You see another method defined (6),load.Thismethodrepresentsanactionthataninstanceoftheclasscanperform.In this case, a chair may load passengers onto it, and this method tells theinstancewhat todowhen thathappens.Again,self (the instance), is the firstparameter to the method. The second parameter, number, is the number ofpeople that get on the chair.Remember that a chair on a chairlift can usuallyholdmorethanoneperson,andinthiscase,yousaidthatyourchairmayholdupto fourpeople.Whenskiersboard thechairyouwouldwant tocall theload`methodon the chair, and insideof thebodyof thatmethod,update thecountattributeontheinstance.Likewise,thereisacorrespondingmethod,unload(7),thatshouldbecalled

whenskiersdismountatthetopofthehill.

NOTE

Page 191: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

NOTE

Don't be intimidated bymethods.You have already seenmanymethods,such as the .capitalize method defined on a string. Methods arefunctionsthatareattachedtoaclass.Insteadofcallingthemethodbyitself,youneedtocallitonaninstanceoftheclass:

>>>'matt'.capitalize()'Matt'

Insummary,creatingaclassiseasy.Youdefinetheattributesyouwant.Theattributesthatareconstantareputinsidetheclassdefinition.Theattributesthatareuniquetoaninstanceareputintheconstructor.Youcanalsodefinemethodsthat contain actions that modify the instance of the class. After the class isdefined,Pythonwillcreateavariablewith thenameof theclass thatpoints totheclass:

>>>Chair<class'__main__.Chair'>

Youcaninspecttheclasswiththedirfunction.Notethattheclassattributesaredefinedontheclass,andyoucanaccessthemdirectlyontheclass:

>>>dir(Chair)['__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__','load','max_occupants','unload']>>>Chair.max_occupants4

Thefigureinthissectionshowedhowtheattributesandmethodsoftheclassarestored.WecanalsoinspectthemfromtheREPL.BecauseeverythingisanobjectinPython,theywillallhavea__class__attribute:

>>>Chair.__class__<class'type'>>>>Chair.max_occupants.__class__

Page 192: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>Chair.max_occupants.__class__<class'int'>>>>Chair.__init__.__class__<class'function'>>>>Chair.load.__class__<class'function'>>>>Chair.unload.__class__<class'function'>

Themethodsarealsodefinedontheclass,buttheinstanceattributesarenot.Becauseinstanceattributesareuniquetotheinstance,theywillbestoredontheinstance.Ifyouhavedocstringsdefinedonyourclassor itsmethods,youcaninspect

themwithhelp:

>>>help(Chair)HelponclassChairinmodule__main__:classChair(builtins.object)|AChaironachairlift||Methodsdefinedhere:||__init__(self,id)||load(self,number)||unload(self,number)||------------------------------------------------------|Datadescriptorsdefinedhere:||__dict__|dictionaryforinstancevariables(ifdefined)||__weakref__|listofweakreferencestotheobject(ifdefined)||------------------------------------------------------|Dataandotherattributesdefinedhere:||max_occupants=4

Creatinganinstanceofaclass

Page 193: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Nowthatyouhavedefinedaclasstorepresentachair,youcancreateinstancesofchairs.OnewaytothinkoftheChairclassistocompareittoafactory.Thefactorytakesinbareobjectsandchurnsoutchairobjects.To be more specific, this is pretty much what the constructor method,

__init__ does. You'll notice that self is the first parameter, this is the bareobject.Pythonassignsthe__class__attribute(pointingtheChairclass)totheobjectbeforepassingitintotheconstructor.Another analogy that might help understand classes is to consider how

cartoons depict the delivery of babies. The unborn babies live in the cloudssomewhere.Atsomepoint in time,astorkcomesalong,picksupababyfromthe cloud and delivers it to a crib in the parent's house. When you call theconstructor,Pythongoesoutandpicksababyupfromthecloud(getsanobjectforyou).Itdeliversittothehouse,makingitamemberofthefamily(itsetsthe__class__ to Chair or whatever your class is). Once the baby is inside thehouse,youcanmoldher,cutherhair,etc.Rememberthatobjectsstorestateandmutatethestate.Below is code to create chair number 21 in Python.When you invoke the

class(i.e.putparenthesesaftertheclassname),youtellPythonthatyouwanttocalltheconstructor.Unlikesomelanguages,youdon'tneedtosayneworaddthevariable type, you just add parentheses with the constructor parametersfollowingthenameoftheclass:

>>>chair=Chair(21)

Again,tobespecificwithterminology,thechairvariablepointstoanobjector instance. It does not point to a class. The object has a class, Chair. Theinstancehasafewattributes,includingcountandid.

Page 194: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Thisillustratesconstructinganobject.Whentheconstructoriscalled,theproverbialPython"stork"dropsababyobjectasselfintotheconstructor.Thebabyobjecthasthe__class__

attributeset,buttheconstructorisfreetoaltertheinstance,byaddingattributes.Thisobjectwillturnintochair.

Youcanaccessaninstanceattributefromtheinstance,chair:

>>>chair.count0>>>chair.id21

Pythonhasahierarchyforlookingupattributes.First,Pythonwilllookfortheattributeontheinstance.Ifthatfails,Pythonwilltrytofindtheattributeontheclass.Becauseinstancesknowabouttheirclass,Pythonwill looktherenext.If

Page 195: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

that fails Python will raise an AttributeError, an apt error for a missingattribute.Themax_occupants attribute is actually storedon the class, but youcanaccessitfromtheinstance:

>>>chair.max_occupants4

UnderthecoversPythonisdoingthisforyou:

>>>chair.__class__.max_occupants4

Attributelookupisdifferentthatvariablelookup.RecallthatPythonlooksforvariables first in the localscope, thenglobalscope, then thebuiltinscope,andfinally raisesaNameError if itwasunsuccessful.Attribute lookupoccurs firston the instance, then the class, then the parent classes, and will raise aAttributeErroriftheattributewasnotfound.

Callingamethodonaclass

Whenyouhaveaninstanceofaclass,youcancallmethodsonit.Methods—likefunctions—are invoked by adding parentheses with any arguments inside ofthem.Hereyouwillcallthe.loadmethodtoadd3skierstothechair:

>>>chair.load(3)

Here’s a review of the syntax of method invocation. First, you list theinstance,chair,which is followedby aperiod.Aperiodmeans search for anattribute in Python (unless it is following a number literal).When you see aperiodfollowinganinstance,rememberthatPythonisgoingtosearchforwhatfollowstheperiod.First,Pythonwilllookontheinstanceforload.Thisattributewasnotfound

ontheinstance,recallthatonlycountandidweresetontheinstanceinsideoftheconstructor.Buttheinstancehasalinktoitsclass.Soifthesearchfailsonthe instance, Python will look for those attributes on the class. The .loadmethod is definedon theChair class, soPython returns that.Theparentheses

Page 196: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

mean invoke or call the method. You are passing 3 in as a parameter to themethod.Recallthatthedeclarationofloadlookedlikethis:

...defload(self,number):#6

...self.count+=number

In the declaration, therewere twoparameters,self andnumber.But in theinvocation,youonlypassedasingleparameter,3.Whythemismatch?Theselfparameterrepresentstheinstance,whichischairinyourcase.Pythonwillcallthe.loadmethodbyinsertingchairastheselfparameterand3asthenumberparameter.Ineffect,Pythonhandlespassingaroundtheselfparameterforyouautomatically.

NOTE

Whenyoucall:

chair.load(3)

Whathappensunderthecoversissimilartothis:

Chair.load(chair,3)

Youcantrythisouttovalidatethatitworks,butyouwouldn'tdothisinreallifebecauseitishardertoread,andalsorequiresmoretyping.

Examininganinstance

Ifyouhaveaninstanceandwanttoknowwhatitsattributesare,youhaveafewoptions.Youcanlookupthedocumentation(ifitexists).Youcanreadthecodewheretheclasswasdefined.Oryoucanusedirtoexamineitforyou:

>>>dir(chair)['__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__',

Page 197: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

'__subclasshook__','__weakref__','count','id','load','max_occupants','unload']

Recallthatthedirfunctionliststheattributesofanobject.Ifyoulookatthedocumentationfordir,youseethatthedefinitionpreviouslyprovidedfordirisnotquitecorrect.Thedocumentationreads:

returnanalphabetizedlistofnamescomprising(someof)theattributesofthegivenobject,andofattributesreachablefromit.—help(dir)(emphasisadded)

This function shows the attributes that are reachable from an object. Theactual state of the instance is stored in the __dict__ attribute, a dictionarymappingattributenamestovalues:

>>>chair.__dict__{'count':3,'id':21}

So, the instance really only stores count and id, the other attributes areavailable through the class. Where is the class stored? In the __class__attribute:

>>>chair.__class__<class'__main__.Chair'>

Itisimportantthataninstanceknowwhatitsclassisbecausetheclassstoresthemethodsandclassattributes.

Privateandprotected

Some languages have the notion of private attributes or methods. These aremethods that are meant to be implementation details and end users can't callthem.Infact,thelanguagemaypreventaccesstothem.Pythondoesnotmakeanefforttopreventusersfromdoingmuchofanything.

Rather, it takes the attitude that you are an adult and you should takeresponsibilityforyouractions.Ifyouwant toaccesssomething,youcandoit.Butyoushouldbewillingtoaccepttheconsequences.

Page 198: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Python programmers realize that it can be convenient to store state andmethodsthatareimplementationdetails.Tosignifytoendusersthattheyshouldnotaccessthesemembers,youprefixtheirnamewithanunderscore.Hereisaclassthathasahelpermethod,._check,thatisnotmeanttobecalledpublicly:

>>>classCorrectChair:...'''AChaironachairlift'''...max_occupants=4......def__init__(self,id):...self.id=id...self.count=0......defload(self,number):...new_val=self._check(self.count+number)...self.count=new_val......defunload(self,number):...new_val=self._check(self.count-number)...self.count=new_val......defcheck(self,number):...ifnumber<0ornumber>self.maxoccupants:...raiseValueError('Invalidcount:{}'.format(...number))...returnnumber

The._checkmethodisconsideredprivate,onlytheinstanceshouldaccessitinside the class. In the class, the.load and.unloadmethods call the privatemethod.Ifwanted,youcouldcallitfromoutsidetheclass.Butyoushouldn't,asanythingwithanunderscoreshouldbeconsideredanimplementationdetailthatmightnotexistinfutureversionsoftheclass.

Asimpleprogrammodelingflow

Let’susetheclassabovetomodelflowofskiersupahill.Youwillmakesomebasic assumptions, such as every chair has an equal probability of 0 tomax_occupantsridingonit.Itwillturnonthechairlift,loadit,andrunforever.Fourtimesaseconditprintsoutthecurrentstatistics:

importrandomimporttime

Page 199: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

classCorrectChair:'''AChaironachairlift'''max_occupants=4

def__init__(self,id):self.id=idself.count=0

defload(self,number):new_val=self._check(self.count+number)self.count=new_val

defunload(self,number):new_val=self._check(self.count-number)self.count=new_val

defcheck(self,number):ifnumber<0ornumber>self.maxoccupants:raiseValueError('Invalidcount:{}'.format(number))returnnumber

NUM_CHAIRS=100

chairs=[]fornuminrange(1,NUM_CHAIRS+1):chairs.append(CorrectChair(num))

defavg(chairs):total=0forcinchairs:total+=c.countreturntotal/len(chairs)

in_use=[]transported=0whileTrue:#loadingloading=chairs.pop(0)in_use.append(loading)in_use[-1].load(random.randint(0,CorrectChair.max_occupants))

#unloadingiflen(in_use)>NUM_CHAIRS/2:unloading=in_use.pop(0)transported+=unloading.countunloading.unload(unloading.count)chairs.append(unloading)print('LoadingChair{}Count:{}Avg:{:.2}Total:{}'.format

Page 200: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

(loading.id,loading.count,avg(in_use),transported))time.sleep(.25)

Thisprogramwillrunforeverprintingouthowmanypeopleareridingonthechairlift.Itoutputstotheterminal,buttheprintfunctioncouldbereplacedwithcodethatwritesaCSVfileaswell.By changing two numbers, the global NUM_CHAIRS and the class attribute

CorrectChair.max_occupants, you could change how themodel behaves torepresent larger or smaller chairlifts. The call to random.randint could bereplacedwithafunctionthatmorepreciselyrepresentstheusagedistribution.

Summary

Wedoveintoclassesabit inthischapter.Theterminologyaroundclasseswasdiscussed.Youcansayobjectorinstance;theyareinterchangeable.Eachobjecthasaclass.Theclass is likea factory thatdetermineshowits instanceobjectsbehave.An object is created by the constructor method. This method is named

__init__.Youmaydefineothermethodsforclassesaswell.Givesomethoughttocreatingaclass.Whataretheattributes?Iftheattributes

remainconsistentacrosstheobjects,definethemontheclass.Iftheyareuniquetotheobject,setthemintheconstructor.

Exercises

1. Imagineyouaredesigningabankingapplication.Whatwouldacustomerlooklike?Whatattributeswouldshehave?Whatmethodswouldshehave?

2. ImagineyouarecreatingaSuperMariogame.YouneedtodefineaclasstorepresentMario.Whatwoulditlooklike?Ifyouaren'tfamiliarwithSuperMario,useyourownfavoritevideoorboardgametomodelaplayer.

3. Create a class that could represent a tweet. If you aren't familiar withTwitter,Wikipediadescribesitas:

Page 201: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

[...] an online news and social networking service where users postandinteractwithmessages,"tweets",restrictedto140characters.—https://en.wikipedia.org/wiki/Twitter

4. Createaclass thatcouldrepresentahouseholdappliance(toaster,washer,refrigerator,etc.).

Page 202: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

SubclassingaClass

BESIDESGROUPINGSTATEANDACTIONINACOHERENTPLACE,CLASSESALSOENABLERE-use. Ifyoualreadyhaveaclassbutwantone thatbehaves slightlydifferently,onewaytore-usetheexistingclassistosubclassit.Theclassthatyousubclassfrom is called the superclass. (Another common term for superclass isparentclass).Supposethatyouwantedtocreateachairthatcanholdsixpeople.Tocreatea

class representing a six-person chair, Chair6, which is a more specializedversionof aChair, youcancreatea subclass.Subclassesallowyou to inheritmethodsofparentclasses,andoverridemethodsyouwanttochange.HereistheclassChair6,whichisasubclassofCorrectChair:

>>>classChair6(CorrectChair):...max_occupants=6

Page 203: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Illustrationofthe__bases__attributeinasubclass.Thisconnectionbetweenasubclassanditsparentclassesallowsyoutolookupattributesinawell-definedmanner.Iftheinstanceofasubclass

hasanattributedefined,itusesthatattribute.Ifnot,aftersearchingtheinstance,theclass(__class__)oftheinstanceissearched.Failingthat,parentclasses(__bases__)oftheclassare

searched.

Note that you put the parent class,CorrectChair, in parentheses followingthe class name. Notice that Chair6 doesn't define a constructor inside of the

Page 204: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

body,yetyoucanstillcreateinstancesoftheclass:

>>>sixer=Chair6(76)

Illustrationdepictingtheinstantiationofasubclass.Notethattheinstancepointstoitsclassandthattheclasspointstoanyparentclassesusingthe__bases__attribute.

Page 205: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

How does Python create an object, when the class doesn't define theconstructor? Here is what happens: when Python looks for the .__init__method,itwillsearchfor itonChair6 first.SincetheChair6classonlyhasamax_occupantsattribute,Pythonwillnotfindthe.__init__methodthere.But,becauseChair6isasubclassofCorrectChair,ithasa__bases__attributethatliststhebaseclassesinatuple:

>>>Chair6.__bases__(__main__.CorrectChair,)

Pythonwill then search the base classes for the constructor. Itwill find theconstructorinCorrectChairanduseittocreatethenewclass.Thesamelookuphappenswhenyoucall.loadonaninstance.Theinstance

doesn'thaveanattributematchingthemethodname,soPythonlooksattheclassoftheinstance.Chair6doesnothavethe.loadmethodeither,soPythonlooksfor the attribute on the base class, CorrectChair. Here the .load method iscalledwithacountthatistoolarge,leadingtoaValueError:

>>>sixer.load(7)Traceback(mostrecentcalllast):File"/tmp/chair.py",line30,in<module>sixer.load(7)File"/tmp/chair.py",line13,inloadnew_val=self._check(self.count+number)File"/tmp/chair.py",line23,in_checknumber))ValueError:Invalidcount:7

Pythonfindsthemethodonthebaseclass,butthecalltothe._checkmethodraisesaValueError.

Countingstalls

Asemi-commonoccurrenceisthataskierfailstomountthechaircorrectly.Inthat case, a chairlift operatorwill slowdownor stop the chairlift to assist theskier.YoucanusePythontocreateanewclassthatwillbeabletoaccountforthenumberoftimesastallhappens.

Page 206: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Assumethatyouwanttocallafunctioneverytime.load iscalled,andthisfunctionwillreturnabooleanindicatingwhetherastalloccurred.Thefunctiontakesasparametersthenumberofskiersandthechairobject.Below is a class that accepts anis_stalled function in the constructor. It

willcall this functionevery time.load is invoked todetermine if thechairlifthasstalled:

>>>classStallChair(CorrectChair):...def__init__(self,id,is_stalled):...super().__init__(id)...self.is_stalled=is_stalled...self.stalls=0......defload(self,number):...ifself.is_stalled(number,self):...self.stalls+=1...super().load(number)

Tocreateaninstanceofthisclass,youmustprovideanis_stalledfunction.Hereisasimplefunctionthatstallstenpercentofthetime:

>>>importrandom>>>deften_percent(number,chair):..."""ReturnTrue10%oftime"""...returnrandom.random()<.1

Now you can create an instance using the ten_percent function as youris_stalledparameter:

>>>stall42=StallChair(42,ten_percent)

Page 207: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Afigureshowingthecodeforcreatingasubclasswithcustommethods.Notethatyouusesuper()tocallthemethodontheparentclass.Thisillustrateswhatobjectsarecreatedwhenyoucreatea

classthatisasubclass.

super

RememberthatStallChairdefinesitsown.__init__method,whichiscalledwhentheinstanceiscreated.Notethatthefirstlineintheconstructoris:

Page 208: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

super().__init__(id)

Whensuper is called insideof amethod, it givesyouaccess to the correctparentclass.ThislineintheconstructorallowsyoutoinvoketheCorrectChairconstructor.Rather than repeat the logicof setting theid andcount attribute,you can reuse the logic from the parent class. Because StallChair hasadditionalattributesitwantstosetontheinstance,youcandothatfollowingthecalltotheparentconstructor.Notethatthe.loadmethodalsohasacalltosuper:

defload(self,number):ifself.is_stalled(number,self):self.stalls+=1super().load(number)

In the .load method, you call your is_stalled function to determinewhether the chair was stalled. Then you dispatch back to the original .loadfunctionalityfoundinCorrectChairbyusingsuper.Havinggeneralcodeappearinoneplace(thebaseclass)eliminatesbugsand

repeatingcode.

NOTE

There are two cases where super really comes in handy. One is forresolving method resolution order (MRO) in classes that have multipleparents.superwillguaranteethatthisorderisconsistent.Theotheriswhenyouchangethebaseclass,super is intelligentaboutdeterminingwhothenewbaseis.Thisaidsincodemaintainability.

Summary

Thischapterdiscussedsubclasses,whicharenewspecializedclassesthatreusecodefromtheirbaseclass(alsoreferredtoassuperclassorparentclass).Foranymethod that you don't implement in a subclass, Python will reuse the parent

Page 209: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

class' functionality. You can choose to implement a method to overridecompletely, or you can call out tosuper.When you callsuper, it gives youaccesstotheparentclasssoyoucanreuseanyfunctionalityfoundthere.

Exercises

1. Createaclasstorepresentacat.Whatcanacatdo?Whatarethepropertiesof a cat? Create a subclass of a cat for a tiger. How does it behavedifferently?

2. In the previous chapter, you created a class to representMario from theSuperMarioBrothersvideogame.Inlatereditionsofthegame,thereweredifferent characters that you could play. They all had the same basicfunctionality 15 but differed in skill. Create a base class for the character,thenimplementfoursubclasses.OneforMario,Luigi,Toad,andPrincessToadstool.

NAME MARIO LUIGI TOAD PRINCESSTOADSTOOL

Speed 4 3 5 2

Jump 4 5 2 3

Power 4 3 5 2

SpecialSkill Floatjump

15-https://www.mariowiki.com/Super_Mario_Bros._2#Playable_characters

Page 210: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Exceptions

ACOMPUTERMAYBETOLDTOPERFORMANACTIONTHATITCANNOTDO.READINGFILESthatdonotexistordividingbyzeroaretwoexamples.Pythonallowsyoutodealwith such exceptions when they occur. In these cases, Python throws anexceptionorraisesanexception.Normallywhen an exception occurs, Pythonwill halt and print out a stack

traceexplainingwheretheproblemoccurred.Thisstacktraceisusefulinthatittellsyouthelineandfileoftheerror:

>>>3/0Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>ZeroDivisionError:divisionbyzero

The above states that in line 1 of the file<stdin> (this is the name of theinterpreter“file”)therewasadividebyzeroerror.Whenyouexecuteaprogramwithanexception,thestacktracewillindicatethefilenameandlinenumberofwheretheproblemoccurred.Thisexamplefromtheinterpreterisn'tparticularlyhelpfulasthereisonlyasinglelineofcode.Butinbiggerprogramsyoucouldhave deeply nested stack traces due to functions calling other functions andmethods:If you had the following in a file and a tried to run it, you would see a

traceback:

deferr():1/0defstart():returnmiddle()defmiddle():returnmore()

Page 211: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

returnmore()defmore():err()start()

Hereisthestacktrace:

Traceback(mostrecentcalllast):File"/tmp/err.py",line13,in<module>start()File"/tmp/err.py",line5,instartreturnmiddle()File"/tmp/err.py",line8,inmiddlereturnmore()File"/tmp/err.py",line11,inmoreerr()File"/tmp/err.py",line2,inerr1/0ZeroDivisionError:divisionbyzero

Tracebacksareeasiesttoreadwhenyoustartfromthebottom,findtheerror,and see where it occurred. As you move up the traceback, you are in effectlookingupthecallchain.Thiscanhelpyoupinpointwhat isgoingoninyourprogram.

Lookbeforeyouleap

Suppose you have a program that performs division. Depending on how it iscoded,itmaybepossiblethatittriestodividebyzeroatsomepoint.Therearetwo styles for dealing with exceptions that programmers commonly use. Thefirstislookbeforeyouleap(LBYL).Theideaistocheckforexceptionalcasesbefore performing an action. In this case, the program would examine thedenominatorvalueanddetermineifitiszeroornot.Ifitisnotzero,theprogramcouldperformthedivision,otherwise,itcouldskipit.InPython,lookbeforeyouleapcanbeimplementedwithifstatements:

>>>numerator=10>>>divisor=0>>>ifdivisor!=0:...result=numerator/divisor...else:...result=None

Page 212: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

...result=None

NOTE

Lookbeforeyouleapisnotalwaysaguaranteeofsuccess.Ifyoucheckthatafileexistsbeforeyouopenit(lookingbeforeleaping),thatdoesnotmeanthatthefilewillstillbearoundlater.Inmulti-threadedenvironments,thisisknownasaracecondition.

NOTE

None is used to represent the undefined state. This is a common idiomthroughoutPythondom.Becarefulthough,trynottoinvokemethodsonavariablethatisassignedtoNone,asthatwillraiseanexception.

Easiertoaskforforgiveness

Another option for dealing with exceptions is known as easier to ask forforgiveness than permission (EAFP). The idea here is to always perform theoperationinsideofatryblock.Iftheoperationfails,theexceptionwillbecaughtbytheexceptionblock.The try...except construct provides a mechanism for Python to catch

exceptionalcases:

>>>numerator=10>>>divisor=0>>>try:...result=numerator/divisor...exceptZeroDivisionErrorase:...result=None

Notice that the try construct creates a block following the try statement(because there is a colon and indentation). Inside of the try block are thestatements that might throw exceptions. If the statements actually throw an

Page 213: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

exception, Python looks for an except block that catches that exception (or aparentclassofit).Inthecodeabove,theexceptblockstatesthatitwillcatchanexceptionthatis

an instance (or subclass) of the ZeroDivisionError class. When the statedexceptionisthrowninthetryblock,theexceptblockisexecutedandresultissettoNone.Notethatline:

exceptZeroDivisionErrorase:

has as e: on the end. This part is optional. If it is included then e (orwhatever you choose as a valid variable name)will point to an instance of aZeroDivisionError exception. You can inspect the exception as they oftenhavemoredetails.Theevariablepointstotheactiveexception.Ifyouleave"ase"off theendoftheexceptstatement,youwillstillhaveanactiveexception,butyouwon'tbeabletoaccesstheinstanceofit.

TIP

Trytolimitthescopeofthetryblock.Insteadofincludingallthecodeinafunction insideatryblock, includeonly the line thatwillpossibly throwtheerror.

Because the look before you leap style of handling is not guaranteed toprevent errors, in general, most Python developers favor the easier to ask forforgiveness style of exception handling. Here are some rules of thumb forexceptionhandling:

Gracefully handle errors you know how to handle and can reasonablyexpect.Do not silence exceptions that you cannot handle or do not reasonablyexpect.

Page 214: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Useaglobalexceptionhandlertogracefullyhandleunexpectederrors.

TIP

If you were making a server type application that needs to run withoutstopping, here is one way to do it. The functions process_input andlog_errordon'texistbutserveasplaceholders:

while1:try:result=process_input()exceptExceptionase:log_error(e)

Multipleexceptioncases

If there aremultiple exceptions that your code needs to be aware of, you canchainalistofexceptstatementstogether:

try:some_function()exceptZeroDivisionErrorase:#handlespecificexceptExceptionase:#handleothers

Inthiscase,whensome_functionthrowsanexception,theinterpreterchecksfirstifitisaZeroDivisionError(orasubclassofit).Ifthatisnotthecase,itchecks if the exception is a subclass ofException.Once anexcept block isentered,Pythonnolongerchecksthesubsequentblocks.Ifanexceptionisnothandledbythechain,codesomewhereupthestackmust

dealwiththeexception.Iftheexceptionisunhandled,Pythonwillstoprunningandwillprintthestacktrace.An example of dealing with multiple exceptions is found in the standard

library.Theargparsemodulefromthestandardlibraryprovidesaneasywaytoparsecommandlineoptions.Itallowsyoutospecifyatypeforcertainoptions,

Page 215: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

suchas integersor files (theoptionsall come inas strings). In the.getvaluemethodthereareexamplesofmultipleexceptclauses.Basedonthetypeoftheexceptionthatoccursadifferenterrormessageisprovided:

defgetvalue(self,action,arg_string):

type_func=self._registry_get('type',action.type,action.type)ifnotcallable(type_func):msg=('%risnotcallable')raiseArgumentError(action,msg%typefunc)

#convertthevaluetotheappropriatetypetry:result=type_func(arg_string)

#ArgumentTypeErrorsindicateerrorsexceptArgumentTypeError:name=getattr(action.type,'__name__',repr(action.type))msg=str(_sys.exc_info()[1])raiseArgumentError(action,msg)

#TypeErrorsorValueErrorsalsoindicateerrorsexcept(TypeError,ValueError):name=getattr(action.type,'__name__',repr(action.type))args={'type':name,'value':arg_string}msg=_('invalid%(type)svalue:%(value)r')raiseArgumentError(action,msg%args)

#returntheconvertedvaluereturnresult

NOTE

This code example also shows that a single except statement can catchmorethanoneexceptiontypeifyouprovideatupleofexceptionclasses:

except(TypeError,ValueError):

NOTE

This example also shows an older style of string formatting using the %operator.Thelines:

Page 216: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

msg=_('invalid%(type)svalue:%(value)r')raiseArgumentError(action,msg%args)

wouldbewritteninamoremodernstyleas:

msg=_('invalid{type!s}value:{value!r}')raiseArgumentError(action,msg.format(**args))

finallyclause

Anotherclauseforerrorhandlingisthefinallyclause.Thisstatementisusedto place code that will always execute, regardless of whether an exceptionhappens or not. If the try block succeeds, then the finally block will beexecuted.Thefinallyalwaysexecutes.Iftheexceptionishandled,thefinallyblock

will execute after the handling. If the exception is not handled, the finallyblockwillexecuteandthentheexceptionwillbere-raised:

try:some_function()exceptExceptionase:#handleerrorsfinally:#cleanup

Usually, thepurposeof thefinally clause is tocleanupexternal resources,suchasfiles,networkconnections,ordatabases.Theseresourcesshouldbefreedregardlessofwhetheranoperationwassuccessfulornot.Anexamplefromthetimeitmodulefoundinthestandardlibrarymightaid

in seeing the utility of the finally statement. The timeit module allowsdeveloperstorunabenchmarkontheircode.Oneofthethingsthatitdoeswhilerunning the benchmark is tell the Python garbage collector to disable itselfduringtherun.But,youwanttoensurethatgarbagecollectionisworkingafterthebenchmarkisdoneregardlessofwhethertherunworkedorerroredout.Hereisthemethod,timeitthatdispatchestorunthebenchmark.Itchecksif

thegarbagecollectorwasenabled,thenturnsoffthegarbagecollector,runsthe

Page 217: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

timing code, and finally, re-enables garbage collection if it was previouslyenabled:

deftimeit(self,number=default_number):"""Time'number'executionsofthemainstatement.Tobeprecise,thisexecutesthesetupstatementonce,andthenreturnsthetimeittakestoexecutethemainstatementanumberoftimes,asafloatmeasuredinseconds.Theargumentisthenumberoftimesthroughtheloop,defaultingtoonemillion.Themainstatement,thesetupstatementandthetimerfunctiontobeusedarepassedtotheconstructor."""it=itertools.repeat(None,number)gcold=gc.isenabled()gc.disable()try:timing=self.inner(it,self.timer)finally:ifgcold:gc.enable()returntiming

Itispossiblethatthecalltoself.innerwillthrowanexception,butbecausethestandardlibraryusesfinally,garbagecollectionwillalwaysbeturnedbackonregardless(ifthegcoldbooleanistrue).

NOTE

This book doesn't address contextmanagers, but to prepare you for yourfutureasaPythonexpert,hereisahint.Thetry/finallycombinationisacode smell in Python. Seasoned Python programmers will use a contextmanager in these cases. Put this on your list of things to study after youhavemasteredbasicPython.

elseclause

Theoptionalelse clause inatry statement isexecutedwhennoexception israised. Itmust followanyexcept statementsandexecutesbefore thefinallyblock.Hereisasimpleexample:

Page 218: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>try:...print('hi')...exceptExceptionase:...print('Error')...else:...print('Success')...finally:...print('atlast')hiSuccessatlast

Here is an example from the heapq module found in the in the standardlibrary.According to thecomments, there isashortcut ifyouwant theget thesmallestvaluesandyouaskformorevaluesthanthesizeoftheheap.However,ifyoutrytogetthesizeoftheheapandgetanerror,thecodecallspass.Thisignores the error and continues on with the slower way of getting the smallitems.Iftherewasnoerror,youcanfollowtheelsestatementandtakethefastpathifnisgreaterthanthesizeoftheheap:

defnsmallest(n,iterable,key=None):#Coderemovedhere....#Whenn>=size,it'sfastertousesorted()try:size=len(iterable)except(TypeError,AttributeError)ase:passelse:ifn>=size:returnsorted(iterable,key=key)[:n]#Coderemovedhere....Tryslowerway

Raisingexceptions

In addition to catching exceptions,Python also allowsyou to raise exceptions(orthrowthem).RememberthattheZenofPythonwantsyoutobeexplicitandrefusethetemptationtoguess.Ifinvalidinputispassedintoyourfunctionandyou know that youwill not be able to handle it, youmay raise an exception.

Page 219: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

ExceptionsaresubclassesoftheBaseExceptionclass,andareraisedusingtheraisestatement:

raiseBaseException('Programfailed')

Normally youwill not raise the genericBaseException class butwill raisesubclassesthatarepredefined,ordefinedbyyou.Anothercommonwayofusing theraise statement is touse itallby itself.

Recallthatwhenyouareinsideofanexceptstatement,youhavewhatiscalledanactiveexception. If that is thecase,youcanuseabareraise statement.Abare raise statement allows you to deal with the exception, but re-raise theoriginalexception.Ifyoutrytouse:

except(TypeError,AttributeError)ase:log('Hitanexception')raisee

You will succeed in raising the original exception, but the stack trace willstate that the original exceptionnowoccurred in the linewithraisee ratherthanwheretheexceptionfirstoccurred.Youhavetwooptionstodealwiththis.Thefirst isabare ``raise`` statement.Thesecond isusingexceptionchaining,describedlater.Here is an example from theconfigparsermodule in the standard library.

ThismodulehandlesreadingandcreatingINIfiles.AnINIfileisusuallyusedfor configurationandwaspopularbefore JSONandYAMLwerearound.The.read_dictmethodwill try toread theconfigurationfromadictionary. If theinstanceisinstrictmode,itwillraiseanerrorifyoutrytoaddthesamesectionmorethanonce.Ifyouarenotinstrictmode,themethodallowsduplicatekeys;the last one wins. Here is a portion of the method showing the bare raisemethod:

defread_dict(self,dictionary,source='<dict>'):elements_added=set()forsection,keysindictionary.items():section=str(section)try:self.add_section(section)

Page 220: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

self.add_section(section)except(DuplicateSectionError,ValueError):ifself._strictandsectioninelements_added:raiseelements_added.add(section)#coderemovedfromhere....

Whenaduplicateisaddedinstrictmode,thestacktracewillshowtheerrorinthe.add_sectionmethod,becausethatiswhereitoccurred.

Wrappingexceptions

Python3hasintroducedanotherfeaturesimilartoabareraisein“PEP3134–ExceptionChaining andEmbeddedTracebacks”When handling an exception,another exceptionmay occur in the handling code. In this case, it is useful toknowaboutbothexceptions.Here is somebasic code.The function,divide_work,might haveproblems

dividingbyzero.Youcancatchthaterrorandlogthatitoccurred.Supposethatyour log function is calling out to a cloud-based service that is down (you'llsimulatethatbyhavinglograiseanexception):

>>>deflog(msg):...raiseSystemError("Loggingnotup")>>>defdivide_work(x,y):...try:...returnx/y...exceptZeroDivisionErrorasex:...log("Systemisdown")

When you call divide_work with 5 and 0 as input, Pythonwill show twoerrors, the ZeroDivisionError, and the SystemError. It will showSystemErrorlastbecauseithappenedlast:

>>>divide_work(5,0)Traceback(mostrecentcalllast):File"begpy.py",line3,individe_workreturnx/yZeroDivisionError:divisionbyzeroDuringhandlingoftheaboveexception,anotherexceptionoccurred:Traceback(mostrecentcalllast):

Page 221: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Traceback(mostrecentcalllast):File"begpy.py",line1,in<module>divide_work(5,0)File"begpy.py",line5,individe_worklog("Systemisdown")File"begpy.py",line2,inlograiseSystemError("Loggingnotup")SystemError:Loggingnotup

Suppose your cloud logging service is now working (the log function nolonger throws an error). If you want to change the type of theZeroDivisionError in divide_work to ArithmeticError, you can use asyntaxdescribedinPEP3134.Youcanusetheraise...fromsyntax:

>>>deflog(msg):...print(msg)>>>defdivide_work(x,y):...try:...returnx/y...exceptZeroDivisionErrorasex:...log("Systemisdown")...raiseArithmeticError()fromex

Youwill see twoexceptionsnow: theoriginalZeroDivisionError and theArithmeticErrorwhichisnolongershadowedbyZeroDivisionError:

>>>divide_work(3,0)Traceback(mostrecentcalllast):File"begpy.py",line3,individe_workreturnx/yZeroDivisionError:divisionbyzeroTheaboveexceptionwasthedirectcauseofthefollowingexception:Traceback(mostrecentcalllast):File"begpy.py",line1,in<module>divide_work(3,0)File"begpy.py",line6,individe_workraiseArithmeticError()fromexArithmeticError

Ifyouwanttosuppresstheoriginalexception,theZeroDivisionError,youcan use the following code. This is described in “PEP 0409 – Suppressingexceptioncontext”:

Page 222: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>defdivide_work(x,y):...try:...returnx/y...exceptZeroDivisionErrorasex:...log("Systemisdown")...raiseArithmeticError()fromNone

Nowyouonlyseetheoutermosterror,ArithmeticError:

>>>divide_work(3,0)Traceback(mostrecentcalllast):File"begpy.py",line1,in<module>divide_work(3,0)File"begpy.py",line6,individe_workraiseArithmeticError()fromNoneArithmeticError

Definingyourownexceptions

Pythonhasmanybuilt-inexceptionsdefinedintheexceptionsmodule.Ifyourerror correspondswellwith the existing exceptions, you can re-use them.Thefollowingliststheclasshierarchyforthebuilt-inexceptions:

BaseExceptionSystemExitKeyboardInterruptGeneratorExitExceptionStopIterationArithmeticErrorFloatingPointErrorOverflowErrorZeroDivisionErrorAssertionErrorAttributeErrorBufferErrorEnvironmentErrorIOErrorOSErrorEOFErrorImportErrorLookupErrorIndexErrorKeyErrorMemoryErrorNameErrorUnboundLocalErrorReferenceErrorRuntimeError

Page 223: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

RuntimeErrorNotImplementedErrorSyntaxErrorIndentationErrorTabErrorSystemErrorTypeErrorValueErrorUnicodeErrorUnicodeDecodeErrorUnicodeEncodeErrorUnicodeTranslateErrorWarningDeprecationWarningPendingDeprecationWarningRuntimeWarningSyntaxWarningUserWarningFutureWarningImportWarningUnicodeWarningBytesWarning

Whendefiningyourownexception,youshouldsubclassfromExceptionorbelow. The reason for this is that other subclasses of BaseException are notnecessarily“exceptions”.Forexample,ifyoucaughtKeyboardInterrupt,youwouldn’t be able to stop the process with control-C. If you caughtGeneratorExit,generatorswouldstopworking.Hereisanexceptionfordefiningthataprogramismissinginformation:

>>>classDataError(Exception):...def__init__(self,missing):...self.missing=missing

Usingyourcustomexceptioniseasy:

>>>if'important_data'notinconfig:...raiseDataError('important_datamissing')

Summary

This chapter introduced strategies fordealingwithexceptions. InLookBeforeYouLeap,youmakesuretheenvironmentwillnotthrowanerrorbeforetryingsomething.InEasiertoAskforForgivenessthanPermission,youwrapanycode

Page 224: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

thatyouknowmightthrowanerrorwithatry/catchblock.YoushouldfavorthelatterstyleofprogramminginPython.Thevariousmechanismsforcatchingerrors,raisingthem,andre-raisingthem

werediscussed.Finally,thechaptershowedhowyoucouldsubclassanexistingexceptiontocreateyourown.

Exercises

1. Writeaprogramthatservesasabasiccalculator.Itasksfortwonumbers,thenitasksforanoperator.Gracefullydealwithinputthatdoesn'tcleanlyconverttonumbers.Dealwithdivisionbyzeroerrors.

2. Writeaprogramthatinsertslinenumbersinfrontthelinesofafile.Accepta filenamebeing passed in on the command line. Import thesysmoduleandreadthefilenamefromthesys.argvlist.Gracefullydealwithabogusfilebeingpassedin.

Page 225: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

ImportingLibraries

THEPREVIOUSCHAPTERSHAVECOVEREDTHEBASICCONSTRUCTSFORPYTHON. INTHISchapter,you'lllearnaboutimportingcode.Manylanguageshavetheconceptoflibraries or reusable chunks of code. Python comes with a whole swath oflibraries,commonlyreferredtoas“batteriesincluded”.Youneedtoknowhowtousethebatteriesthatarefoundintheselibraries.To use a library, you have to load the code from that library into your

namespace.Thenamespaceholdsthefunctions,classes,andvariablesyouhaveaccessto.Ifyouwanttocalculatethesineofanangleyouwillneedtodefineafunction thatdoes thator loadapreexistingfunction.Thebuilt-inmath libraryhas asin function that calculates the sineof an angle expressed in radians. Italsohasavariablethatdefinesavalueforpi:

>>>frommathimportsin,pi>>>sin(pi/2)1.0

The above code loads the math module. But it doesn't put math in yournamespace.Ratheritcreatesavariablethatpointstothesinfunctionfromthemathmodule.Italsocreatesavariablethatpointstothepivariablefoundinthemathmodule.Ifyouinspectyourcurrentnamespaceusingthedirfunctionyoucanconfirmthis:

>>>'sin'indir()True

Multiplewaystoimport

Inthepreviousexample,youimportedasinglefunctionfromalibrary.Itisalsopossibletoloadthelibraryintoyournamespaceandreferenceallofitsclasses,

Page 226: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

functions,andvariables.Toimportthemathmoduleintoyournamespacetype:

>>>importmath

Thisillustratesimportingamodule.Notethatthiscodecreatesanewvariable,math,thatpointstoamodule.Themodulehasvariousattributesthatyoucanaccessusingaperiod.

In the above, you imported the math library. This created a new variable,math,thatpointstothemodule.Themodulehasvariousattributes.Youcanusethedirfunctiontolisttheattributes:

>>>dir(math)['__doc__','__file__','__loader__','__name__','__package__','__spec__','acos','acosh','asin','asinh','atan','atan2','atanh','ceil','copysign','cos','cosh','degrees','e','erf','erfc','exp','expm1','fabs','factorial','floor','fmod','frexp','fsum','gamma','gcd','hypot','inf','isclose','isfinite','isinf','isnan','ldexp','lgamma','log','log10','log1p','log2','modf','nan','pi','pow','radians','sin','sinh','sqrt','tan','tanh','trunc']

Page 227: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Mostoftheseattributesarefunctions.Ifyouwanttocallthetanfunction,youcan'tinvokeit,becausetanisn'tinyournamespace,onlymathis.But,youcando a lookup on the math variable using the period (.) operator. The periodoperatorwilllookupattributesonanobject.BecauseeverythinginPythonisanobject,youcanusetheperiodtolookupthetanattributeonthemathobject:

>>>math.tan(0)0.0

Ifyouwanttoreadtheassociateddocumentationforthetanfunction,youcanenlistthehelpfunctionforaid:

>>>help(math.tan)Helponbuilt-infunctiontaninmodulemath:tan(...)tan(x)Returnthetangentofx(measuredinradians).

TIP

When would you import a function using from versus the importstatement? If you are only using a couple attributes from a library, youmightwant touse thefrom style import. It ispossible tospecifymultiplecomma-delimitedattributesinthefromconstruct:

>>>frommathimportsin,cos,tan>>>cos(0)1.0

Howeverifyouneedtoaccessmostofthelibrary,itrequireslesstypingtoimportthelibraryusingtheimportstatement.Itisalsoahinttoanyonereading your code (including you), as to where the function (or class orvariable)camefrom.

NOTE

Page 228: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Ifyouneedtoimportmultipleattributesfromalibrary,youmightneedtospanmultiple lines. If you continue importing functions on the next line,youwillrunintoanerror:

>>>frommathimportsin,...cosTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>SyntaxError:trailingcommanotallowedwithoutsurroundingparentheses

Youwillneed touseabackslash, to indicate that the linecontinuesonthenextline:

>>>frommathimportsin,\...cos

Otherwise, you can specify multiple imports with parentheses. Openparentheses(orbraces,orbrackets)indicatethatthestatementcontinuesonthenextline:

>>>frommathimport(sin,...cos)

ThislatterformismoreidiomaticPython.

Conflictingimportnames

Ifyouwereworkingonaprogramthatperformstrigonometricoperations,youmightalreadyhaveafunctionnamedsin.Whatifyoualsowanttousethesinfunctionfromthemath library?Oneoptionistoimportmath, thenmath.sinwouldreferencethelibraryandsinwouldreferenceyourfunction.Pythonhasanotheroptiontoo.Youcanredefinethenameofwhatyouwant

toimportusingtheaskeyword:

>>>frommathimportsinasother_sin>>>other_sin(0)0.0

Page 229: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Now, other_sin is a reference to the sin found in math and you maycontinueusingyoursinwithouthavingtorefactoryourcode.The as keyword construct also works on import statements. If you had a

variable(orafunction) thatconflictedwith themathnameinyournamespace,thefollowingwouldbeonewaytogetaroundit:

>>>importmathasother_math>>>other_math.sin(0)0.0

TIP

The as keyword can also be used to eliminate typing. If your favoritelibraryhasoverly longandverbosenamesyoucaneasilyshortentheminyour code. Users of the Numpy 16 library have adopted the standard ofreducingkeystrokesbyusingatwo-letteracronym:

>>>importnumpyasnp

ThePandas17libraryhasadoptedasimilarstandard:

>>>importpandasaspd

Starimports

Pythonalsoallowsyoutoclobberyournamespacewithwhatareknownasstarimports:

>>>frommathimport*>>>asin(0)0.0

Noticethattheabovecodecallsthearcsinefunction,whichwasnotdefined.Thelinewhereasinisinvokedisthefirstreferencetoasininthecode.Whathappened?Whenyousayfrommathimport*,thatisastarimport,andittellsPython to throweverything from themath library (classdefinitions, functions,

Page 230: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

andvariables) into thelocalnamespace.While thismightappearhandyatfirstglance,itisquitedangerous.Star imports make debugging harder because it is not explicit where code

comes from. Even worse are star imports frommultiple libraries. Subsequentlibraryimportsmightoverridesomethingdefinedinanearlierlibrary.Assuch,starimportsarediscouragedandfrownedupon.

TIP

Donotusestarimports!Thepossibleexceptionstothisrulearewhenyouarewritingyourown

testingcode,ormessingaroundin theREPL.Libraryauthorsdothisasashortcuttoimportingeverythingfromthelibrarythattheywanttotest.Andthisoftenendsupinthedocumentation.Donotbetemptedbecauseyouseeitinother’scode,tousestarimportsinyourcode.RemembertheZenofPython:

Explicitisbetterthanimplicit

Nestedlibraries

SomePythonpackageshaveanestednamespace.Forexample,theXMLlibrarythatcomeswithPythonhassupportforminidomandetree.Bothlibrariesliveunderthexmlparentpackage:

>>>fromxml.dom.minidomimport\...parseString>>>dom=parseString(...'<xml><foo/></xml>')>>>fromxml.etree.ElementTreeimport\...XML>>>elem=XML('<xml><foo/></xml>')

Page 231: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Noticethatthefromconstructallowsimportingonlythefunctionsandclassesneeded.Using theimportconstruct (withoutfrom)wouldrequiremore typing(butalsoallowaccesstoeverythingfromthepackage):

>>>importxml.dom.minidom>>>dom=xml.dom.minidom.parseString(...'<xml><foo/></xml>')>>>importxml.etree.ElementTree>>>elem=xml.etree.ElementTree.XML(...'<xml><foo/></xml>')

Importorganization

According toPEP8, import statements shouldbe locatedat the topof the filefollowingthemoduledocstring.Thereshouldbeoneimportperlineandimportsshouldbegroupedby:

Standardlibraryimports3rdpartyimportsLocalpackageimports

Anexamplemodulemighthavethefollowingatthestart:

#!/usr/bin/envpython3"""ThismoduleconvertsrecordsintoJSONandshovesthemintoadatabase"""importjson#standardlibsimportsysimportpsycopg2#3rdpartylibimportrecordconverter#locallibrary...

TIP

Itisusefultoorganizethegroupedimportsalphabetically.

Page 232: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TIP

Itcanbeusefultopostponesomeimportsto:

Avoid circular imports. A circular import is where modulesmutuallyimportoneanother.Ifyouarenotable(orwilling)torefactorto remove the circular import, it is possible to place the importstatement within the function or method containing the code thatinvokesit.Avoidimportingmodulesthatarenotavailableonsomesystems.Avoidimportinglargemodulesthatyoumaynotuse.

Summary

ThischapterdiscussedimportinglibrariesinPython.Pythonhasalargestandardlibrary 18, andyouwill need to import those libraries to use them.Throughoutthisbook, ithasemphasized that everything is anobject, andyouoftencreatevariables thatpoint to thoseobjects.Whenyou import amodule,youcreate avariablethatpointstoamoduleobject.Anythingwithinthemodule’snamespacecanbeaccessedusingthelookupoperation(.).Youcanalso selectively importpartsoutof themodule’snamespace,using

thefromstatement.Ifyouwanttorenamewhatyouareimporting,youcanuseanasstatementtochangewhatthevariablenamewillbe.

Exercises

1. Find a package in the Python standard library for dealing with JSON.Importthelibrarymoduleandinspecttheattributesofthemodule.Usethehelp function to learn more about how to use the module. Serialize adictionarymapping'name'toyournameand'age'toyourage,toaJSONstring.DeserializetheJSONbackintoPython.

Page 233: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

2. FindapackageinthePythonstandardlibraryforlistingdirectorycontents.Using that package, write a function that accepts a directory name. Thefunctionshouldgetallthefilesinthatdirectoryandprintoutareportofthecountoffilesbyextensiontype.

16-numpy.scipy.org17-pandas.pydata.org18-https://docs.python.org/3/library/index.html

Page 234: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Libraries:PackagesandModules

THEPREVIOUSCHAPTERDISCUSSEDHOWTOIMPORTLIBRARIES.THISCHAPTERWILLDIVEa little deeper into what constitutes a library. There are two requirements forimportingalibrary:

1. Thelibrarymustbeamoduleorapackage2. The library must exist in the PYTHONPATH environment variable or

sys.pathPythonvariable.

Modules

Modules arePython files that end in.py, andhaveaname that is importable.PEP 8 states that module filenames should be short and in lowercase.Underscoresmaybeusedforreadability.

Packages

ApackageinPythonisadirectorythatcontainsafilenamed__init__.py.Thefile named __init__.py can have any implementation it pleases or it can beempty. In addition, the directorymay contain an arbitrary number ofmodulesandsubpackages.Whenwritingcode,shouldyoupreferamoduleorapackage?Iusuallystart

simpleanduseamodule.WhenIneedtobreakcoherentpartsoutintotheirownmodules,thenIrefactorintomodulesinapackage.Here isanexample fromthedirectory layoutof thepopularSQLAlchemy 19

project(anObjectRelationalMapperfordatabases).

sqlalchemy/__init__.pyengine/__init__.py

Page 235: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

__init__.pybase.pyschema.py

PEP8statesthatdirectorynamesforpackagesshouldbeshortandlowercase.Underscoresshouldnotbeused.

Importingpackages

To import a package, use the import statement with the package name (thedirectoryname):

>>>importsqlalchemy

This will import the sqlalchemy/__init__.py file into the currentnamespaceifthepackageisfoundinPYTHONPATHorsys.path.If you wanted to use the Column and ForeignKey classes found in the

schema.pymodule,eitherofthecodesnippetsbelowwouldwork.Thefirstputssqlalchemy.schema in your namespace, while the latter only puts schema inyournamespace:

>>>importsqlalchemy.schema>>>col=sqlalchemy.schema.Column()>>>fk=sqlalchemy.schema.ForeignKey()

or:

>>>fromsqlalchemyimportschema>>>col=schema.Column()>>>fk=schema.ForeignKey()

Alternatively,toaccessonlytheColumnclass,importthatclassinoneofthefollowingtwoways:

>>>importsqlalchemy.schema.Column>>>col=sqlalchemy.schema.Column()

or:

>>>fromsqlalchemy.schemaimportColumn>>>col=Column()

PYTHONPATH

Page 236: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

PYTHONPATH is an environment variable listing non-standard directories thatPythonlooksformodulesorpackagesin.Thisvariableisusuallyempty.Itisnotnecessary to changePYTHONPATH unless you are developing code andwant touselibrariesthathavenotbeeninstalled.

TIP

LeavePYTHONPATHemptyunlessyouhaveagoodreasontochangeit.Thissectionillustrateswhatcanhappenifyouchangeit.Thiscanbeconfusingtoothers tryingtodebugyourcodewhoforget thatPYTHONPATHhasbeenchanged.

If you had some code in hometest/a/plot.py, but were working out ofhometest/b/, using PYTHONPATH allows access to that code. Otherwise, ifplot.py was not installed using system or Python tools, trying to import itwouldraiseanImportError:

>>>importplotTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>ImportError:Nomodulenamedplot

IfyoustartPythonbysettingthePYTHONPATH,itindicatestoPythonwheretolookforlibraries:

$PYTHONPATH=hometest/apython3Python3.6.0(default,Dec242016,08:01:42)>>>importplot>>>plot.histogram()...

TIP

Python packages can be installed via package managers, WindowsexecutablesorPythonspecifictoolssuchaspip20.

Page 237: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

sys.path

The sys module has an attribute, path, that lists the directories that Pythonsearchesforlibraries.Ifyouinspectsys.path,youwillseeallthelocationsthatarescanned:

>>>importsys>>>sys.path

['','usrlib/python35.zip','usrlib/python3.6','usrlib/python3.6/plat-darwin','usrlib/python3.6/lib-dynload','usrlocal/lib/python3.6/site-packages']

TIP

Ifyouseeerrorslike:

ImportError:Nomodulenamedplot

Look at the sys.path variable to see if it has the directory holdingfoo.py (if it isamodule). Ifplot isapackage, then theplot/directoryshouldbelocatedinoneofthepathsinsys.path:

>>>importplotTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>ImportError:Nomodulenamedplot>>>sys.path.append('hometest/a')>>>importplot>>>plot.histogram()

Alternatively,youcansetPYTHONPATHtopointtothatdirectoryfromthecommandusedtoinvokePython.Again, typically you don't manually set sys.path or PYTHONPATH,

normally you install libraries, and the installer puts them in the correctlocation.

TIP

Page 238: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TIP

Ifyouwant toknowthelocationof thelibraryonthefilesystem,youcaninspectthe__file__attribute:

>>>importjson>>>json.__file__'usrlib/python3.6/json/__init__.py'

ThisonlyworkswithlibrariesimplementedinPython.ThesysmoduleisnotimplementedinPython,sothisfails:

>>>importsys>>>sys.__file__Traceback(mostrecentcalllast):...AttributeError:module'sys'hasnoattribute'__file__'

Summary

This chapter discussed modules and packages. A module is a Python file. Apackageisadirectorythathasafilenamed__init__.pyinit.Apackagemayalsocontainothermodulesandpackages.ThereisalistofpathsthatdetermineswherePythonlookstoimportlibraries.

This list is stored insys.path.Youcan inspect it to seewherePython looks.You can also update its value via the PYTHONPATH environment variable, ormutate the list directly. But typically, you don't set this variable to installpackages,youusesomethinglikepiptoinstallpackages.

Exercises

1. Create a module, begin.py, that has a function named prime in it. Theprime function should take a number and return a boolean indicatingwhetherthenumberisaprimenumber(divisibleonlyby1anditself).Gotoanotherdirectory,launchPython,andrun:

frombeginimportprime

Page 239: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

It should fail. Update the sys.path variable, so that you can import thefunctionfromthemodule.Then,setPYTHONPATHtogetittoload.

2. Create a package,utils. In the__init__.py file, place theprime codefrom the previous exercise. Go to a different directory in the terminal,launchPython,andrun:

fromutilsimportprime

It should fail. Update the sys.path variable, so that you can import thefunctionfromthepackage.Then,setPYTHONPATHtogetittoload.

19-https://www.sqlalchemy.org/20-https://pip.pypa.io/

Page 240: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

ACompleteExample

THISCHAPTERCOVERSHOWTOLAYOUTCODEWITHINASCRIPT.ITINCLUDESTHESOURCEforasimplified implementationof theUnixcommandcat.Thecatcommandreadsfilenamesfromthecommand lineandprints theircontents to thescreen.Therearevariousoptionstodothingslikeaddlinenumbering.ThisscriptwillillustratehowthecodeislaidoutinatypicalPythonfile.

cat.py

BelowarethecontentsofthePythonimplementationoftheUnixcommandcat.Itonlyincludesanoptionforaddinglinenumbers(--number),butnoneoftheothercatoptions.Youcanputthisinafilenamedcat.py:

#!usrbin/envpython3

r"""Asimpleimplementationoftheunix``cat``command.Itonlyimplementsthe``--number``option.ItisusefulforillustratingfilelayoutandbestpracticesinPython.

Thisisatriplequoteddocstringforthewholemodule(thisfile).Ifyouimportthismodulesomewhereelseandrun``help(cat)``,youwillseethis.

Thisdocstringalsocontainsa``doctest``whichservesasanexampleofprogrammaticallyusingthecode.Italsofunctionsasadoctest.The``doctest``modulecanexecutethisdocstringandvalidateitbycheckinganyoutput.

>>>importio>>>fin=io.StringIO(\...'hello\nworld\n')>>>fout=io.StringIO()>>>cat=Catter([fin],...show_numbers=True)

Page 241: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

>>>cat.run(fout)>>>print(fout.getvalue())1hello2world

"""

importargparseimportloggingimportsys

__version__='0.0.1'

logging.basicConfig(level=logging.DEBUG)

classCatter(object):"""Aclasstoconcatenatefilestostandardout

Thisisaclassdocstring,``help(cat.Catter)``wouldshowthis."""

def__init__(self,files,show_numbers=False):self.files=filesself.show_numbers=show_numbers

defrun(self,fout):#use6spacesfornumbersandrightalignfmt='{0:>6}{1}'forfininself.files:logging.debug('catting{0}'.format(fin))forcount,lineinenumerate(fin,1):ifself.show_numbers:fout.write(fmt.format(count,line))else:fout.write(line)

defmain(args):"""Logictorunacatwitharguments

Page 242: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

"""parser=argparse.ArgumentParser(description='ConcatenateFILE(s),or''standardinput,tostandardoutput')parser.add_argument('--version',action='version',version=__version__)parser.add_argument('-n','--number',action='store_true',help='numberalloutputlines')parser.add_argument('files',nargs='*',type=argparse.FileType('r'),default=[sys.stdin],metavar='FILE')parser.add_argument('--run-tests',action='store_true',help='runmoduletests')args=parser.parse_args(args)

ifargs.run_tests:importdoctestdoctest.testmod()else:cat=Catter(args.files,args.number)cat.run(sys.stdout)logging.debug('donecatting')

if__name__=='__main__':main(sys.argv[1:])

Ifyoudon'tfeelliketypinginthiscode,youcangrabacopyhere21.

Whatdoesthiscodedo?

This codewill echo the contents of a file (optionallywith line numbers) to aterminalonWindowsandUnixsystems:

$python3cat.py-nREADME.md1#IllustratedPy323Ifyouhavequestionsorconcerns,clickonIssuesabove.

Ifyou run thiscodewith-h itwillprintout thehelpdocumentation for thecommandlinearguments:

$python3cat.py-husage:cat.py[-h][--version][-n][--run-tests][FILE[FILE...]]ConcatenateFILE(s),orstandardinput,tostandardoutput

Page 243: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

positionalarguments:FILEoptionalarguments:-h,--helpshowthishelpmessageandexit--versionshowprogram'sversionnumberandexit-n,--numbernumberalloutputlines--run-testsrunmoduletests

Thecommandlineparsingfunctionalityisimplementedinthemainfunctionand provided by the argparse module found in the standard library. Theargparsemodulehandlescommandlineargumentparsing.If youwant to knowwhat theargparsemodule does, you can lookup the

documentationontheweboryoucanusethehelpfunction.ThebasicideaofthemoduleisthatyoucreateaninstanceoftheArgumentParserclassandcall.add_argumentforeachcommandlineoption.Youprovidethecommandlineswitches,tellitwhatkindofactiontodo(thedefaultstoresthevaluefollowingtheswitch),andprovidehelpdocumentation.Afteryouhaveaddedarguments,youcallthe.parse_argsmethodonthecommandlinearguments(wegetthatfrom sys.argv). The result of .parse_args is an object that has attributesattached to it based on the option names. In this case, therewill be a.filesattributeanda.numberattribute.

NOTE

YoucanalsousetheREPLtoinspectthismoduleandanydocumentationthatitshipswith.Rememberthehelpfunction?Youcanpassamoduletoitanditwillprintoutthemoduleleveldocstring.Ifyouwantedtolookatthesourcecodeforthismodule,youcandothat

too. Remember the dir function? It lists attributes of an object. If youinspecttheargparsemodule,youseethatithasa__file__attribute.Thispointstothelocationonyourcomputerwherethefileis:

>>>importargparse>>>argparse.__file__'usrlocal/Cellar/python3/3.6.0/Frameworks/

Page 244: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Python.framework/Versions/3.6/lib/python3.6/argparse.py'

BecauseitiswritteninPython(somemodulesarewritteninC),youcaninspectthesource.Atthispoint,youshouldbeabletoreadthemoduleandunderstandwhatitistryingtodo.

Afterparsingthearguments,youcreateaninstanceoftheCatterclassthatisdefinedinthecode,andcallthe.runmethodonit.Thisexamplemightseemalittleoverwhelming,butyouhavecoveredallof

thesyntaxthatitillustratesoverthecourseofthebook.Therestofthischapterwilldiscussthelayoutandotheraspectsofthiscode.

Commonlayout

Here are the commoncomponents found in aPythonmodule and theorder inwhichtheyarefound:

#!usrbin/envpython3(shebang)(usedifmodulealsoservesasascript.)moduledocstringimportsmetadata/globalsloggingimplementationif__name__=='__main__':(usedifmodulealsoservesasascript.)argparse

NOTE

The above list is a recommendation. Most of those items can be in anarbitraryorder.Andnoteveryfilewillhavealltheseitems.Forinstancenoteveryfileneedstobeexecutableasashellscript.Youarefreetoorganizefileshowyouplease,butyoudosoatyourown

peril. Users of your code will likely complain (or submit patches). As a

Page 245: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

readerofcode,youwillappreciatecodethatfollowstherecommendation,sinceitwillbequicklydiscoverable.

Shebang

The first line in a file (that is also used as a script) is the shebang line(#!usrbin/env python3). On Unix operating systems, this line is parsed todeterminehowtoexecutethescript.Thus,thislineisonlyincludedinfilesthataremeanttobeexecutableasscripts.Itshouldsaypython3,aspythonreferstoPythonversion2onmostsystems.

NOTE

TheWindowsplatformignorestheshebangline.Sothisissafetoinclude.IndeedyouwillfinditinlibrariesthatarealsopopularonWindows.

NOTE

RatherthanhardcodingaspecificpathtoaPythonexecutable,usrbin/envselectsthefirstpython3executablefoundontheuser’sPATH.Toolssuchasvenv22willmodifyyourPATHtouseacustompython3executableandwillworkwiththisconvention.

TIP

OnUnixsystems,ifthedirectorycontainingthefileispresentintheuser’sPATH environment variable, and the file is executable, then the file namealoneissufficientforexecutionfromashell.Type:

$chmod+x<path/to/file.py>

tomakeitexecutable.

Page 246: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Docstring

Amodulemay have amodule-level docstring at the top of the file. It shouldfollowtheshebanglinebutprecedeanyotherPythoncode.Adocstringservesasan overview of themodule and should contain a basic summary of the code.Also,itmaycontainexamplesofusingthemodule.

TIP

Python includes a library, doctest that can verify examples from aninteractive interpreter. Using docstrings that contain REPL code snippetscanservebothasdocumentationandsimplesanitytestsforyourlibrary.cat.py includesdoctestcodeat theendof itsdocstring.Whencat.py

runswith--run-tests,thedoctestlibrarywillcheckanydocstringsandvalidatethecodefoundinthem.Thiswasincludedforillustrationpurposesonly.Normallyanon-developerenduserwouldnotseeoptionsforrunningtestsinascript,thoughyoucouldincludedoctestsinthedocstrings.Inthiscase, the --run-tests option is included as an example of using thedoctestmodule.

Imports

ImportsareusuallyincludedatthetopofPythonmodules.Theimportlinesarenormallygroupedbylocationofthelibrary.First,listanylibrariesfoundinthePythonstandard library.Next list third-party libraries.Finally, list the librariesthat are local to the current code. Such organization allows end users of yourcodetoquicklyseeimports,requirements,andwherethecodeiscomingfrom.

Metadataandglobals

If you have legitimate module-level global variables, define them after theimports.Thismakes it easy to scan amodule and quickly determinewhat the

Page 247: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

globalsare.Globalvariablesaredefinedatthemodule-levelandareaccessiblethroughout

that module. Because Python allows any variable to be modified, globalvariables are potential sources of bugs. In addition, it is easier to understandcodewhenvariables are defined andmodified onlywithin the function scope.Thenyoucanbesureofwhatdatayouhaveandwhoischangingit.Ifyouhavemultipleplaceswhereaglobalvariableisbeingmodified(especiallyifitisinadifferentmodule)youaresettingyourselfupforalongdebuggingsession.One legitimate use for globals is to emulate constants found in other

programminglanguages.Aconstantvariableisavariablewhosevaluedoesnotchange. Python doesn't support variables that don't change, but you can use aconventiontoindicatetotheuserthattheyshouldtreatavariableasread-only.PEP 8 states that global constants should have names that are the same asvariablesexcept theyshouldbecapitalized.Forexample, ifyouwanted tousethegoldenratioyoucoulddefineitlikethis:

>>>GOLDEN_RATIO=1.618

If thiscodewasdefined inamodule, thecapitalizationservesasahint thatyoushouldnotrebindthisvariable.

NOTE

By defining constants as globals, and using well thought-out variablenames,youcanavoidaproblemfoundinprogramming—magicnumbers.Amagicnumberisanumbersittingincodeoraformulathatisnotstoredin a variable. That in itself is bad enough, especiallywhen someone elsestartsreadingyourcode.Another problem with magic numbers is that the same value tends to

propagatethroughthecodeovertime.Thisisn’taproblemuntilyouwanttochange thatvalue.Doyoudoa searchand replace?What if themagicnumberactuallyrepresentstwodifferentvalues,i.e.thenumberofsidesof

Page 248: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

a triangle and number of dimensions? In that case, a global search andreplacewillintroducebugs.Thesolutiontoboththeseproblems(contextandrepetition)istoputthe

value in a named variable. Having them in a variable gives context andnamingaroundthenumber.Italsoallowsyoutoeasilychangethevalueinoneplace.

Inadditiontoglobalvariables,therearealsometadatavariablesfoundatthatlevel.Metadatavariablesholdinformationaboutthemodule,suchasauthorandversion. Normally metadata variables are specified using “dunder” variablessuchas__author__.For example, PEP 396 recommends that the module version should be

specifiedinastring,__version__,attheglobalmodulelevel.

NOTE

It is a good idea to define a version for your library if you intend onreleasingittothewild.PEP396suggestsbestpracticesforhowtodeclareversionstrings.

Othercommonmetadatavariablesincludeauthor,license,date,andcontact.Ifthesewerespecifiedincodetheymightlooklikethis:

__author__='MattHarrison'__date__='Jan1,2017'__contact__='matt_harrison<at>someplace.com'__version__='0.1.1'

Logging

Onemorevariable that isoftendeclaredat theglobal level is the logger for amodule. The Python standard library includes thelogging library that allowsyoutoreportdifferentlevelsofinformationinwell-definedformats.

Page 249: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Multiple classes or functions in the same module will likely need to loginformation. It is common to perform logger initialization once at the globallevelandthenreusetheloggerhandlethatyougetbackthroughoutthemodule.

Otherglobals

You should not use a global variable when local a variable will suffice. ThecommonglobalsfoundinPythoncodearemetadata,constants,andlogging.Itisnotuncommontoseeglobalsscatteredaboutinsamplecode.Donotfall

tothetemptationtocopythiscode.Placeitintoafunctionoraclass.Thiswillpaydividendsinthefuturewhenyouarerefactoringordebuggingyourcode.

Implementation

Followinganyglobalandloggingsetupcomestheactualmeatofthecode—theimplementation.Functionsandclasseswillbeasubstantialportionofthiscode.TheCatterclasswouldbeconsideredthecorelogicofthemodule.

Testing

Normally,bonafidetestcodeisseparatedfromtheimplementationcode.Pythonallows a small exception to this. Python docstrings can be defined atmodule,function, class, and method levels. Within docstrings, you can place PythonREPL snippets illustrating how to use the function, class, or module. Thesesnippets, if well crafted and thought-out, can be effective in documentingcommonusageofthemodule.Another nice feature of doctest is validation of documentation. If your

snippetsonceworked,butnowtheyfail,eitheryourcodehaschangedoryoursnippets are wrong. You can easily find this out before end users startcomplainingtoyou.

TIP

doctest code can be in a stand-alone text file.To execute arbitrary filesusingdoctest,usethetestfilefunction:

importdoctest

Page 250: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

importdoctestdoctest.testfile('module_docs.txt')

NOTE

Inadditiontodoctest,thePythonstandardlibraryincludestheunittestmodule that implements the common xUnit style methodology—setup,assert and teardown. There are pro’s and con’s to both doctest andunittest styles of testing. doctest tends to bemore difficult to debug,while unittest contains boilerplate code that is regarded as too Java-esque.Itispossibletocombinebothtoachievewelldocumentedandwelltestedcode.

if__name__=='__main__':

Ifyourfileismeanttoberunasascript,youwillfindthissnippetatthebottomofyourscript:

if__name__=='__main__':sys.exit(main(sys.argv[1:])or0)

Tounderstandthestatement,youshouldunderstandthe__name__variable.

__name__

Pythondefinesthemodulelevelvariable__name__foranymoduleyouimport,oranyfileyouexecute.Normally__name__’svalueisthenameofthemodule:

>>>importsys>>>sys.__name__'sys'>>>importxml.sax>>>xml.sax.__name__'xml.sax'

There isanexception to this rule.Whenamodule isexecuted (i.e.python3some_module.py),thenthevalueof__name__isthestring"__main__".Ineffect,thevalueof__name__indicateswhetherafileisbeingloadedasa

Page 251: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

library,orrunasascript.

NOTE

It is easy to illustrate__name__.Create a file,some_module.py,with thefollowingcontents:

print("The__name__is:{0}".format(__name__))

NowrunaREPLandimportthismodule:

>>>importsome_moduleThe__name__is:some_module

Nowexecutethemodule:

$python3some_module.pyThe__name__is:__main__

It isacommonidiomthroughoutPythondomtoplaceachecksimilar to thefollowingatthebottomofamodulethatcouldalsoserveasascript.Thischeckwilldeterminewhetherthefileisbeingexecutedorimported:

if__name__=='__main__':#executesys.exit(main(sys.argv[1:])or0)

This simple statementwill run themain functionwhen the file is executed.Conversely,ifthefileisusedasamodule,mainwillnotberunautomatically.Itcallssys.exitwiththereturnvalueofmain(or0ifmaindoesnotreturnanexitcode)tobehaveasagoodcitizenintheUnixworld.Themain function takes thecommand lineoptionsasparameters.sys.argv

holds the command line options. It also containspython3 at the front, so youneedtoslicesys.argvtoignorethat,beforeyoupasstheoptionsintomain.

TIP

Page 252: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Somepeopleplacetheexecutionlogic(thecodeinsidethemainfunction)directlyundertheif__name__=='__main__':test.Reasonstokeepthelogicinsideafunctioninclude:

ThemainfunctioncanbecalledbyothersThemainfunctioncanbetestedeasilywithdifferentargumentsReducetheamountofcodeexecutingatthegloballevel

Summary

Inthischapter,youdissectedPythoncodeinascript.Thechapterdiscussedbestpracticesandcommoncodingconventions.By layingout your code as described in this chapter, youwill be following

bestpracticesforPythoncode.This layoutwillalsoaidothersneedingtoreadyourcode.

Exercises

1. Copy the cat.py code. Get it working on your computer. This isn't justbusy work. Much of the time when you are programming, you aren'tcreating something from scratch, but rather are reusing code that othershavewritten.

2. Write a script,convert.py, thatwill convert a file fromoneencoding toanother.Acceptthefollowingcommandlineoptions:

AninputfilenameAninputencoding(defaulttoutf-8)AnoutputencodingAnoptionforhandlingerrors(ignore/raise)

21-https://github.com/mattharrison/IllustratedPy3/

Page 253: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

22-https://docs.python.org/3/library/venv.html

Page 254: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

OntoBiggerandBetter

AT THIS POINTYOU SHOULDHAVEA PRETTYGOODUNDERSTANDINGOFHOW PYTHONprograms work. You should feel comfortable using the Python REPL andexploringclassesusingdirandhelp.Whatcomesnext?Thatisuptoyou.Youshouldnowhavetheprerequisites

tousePythontocreatewebsites,GUIprograms,ornumericalapplications.One huge benefit of Python is the various communities associatedwith the

different areas of programming. There are local user groups, newsgroups,mailing lists and social networks for many aspects of Python. Most of thesegroups are welcoming to new programmers and willing to share theirknowledge.Donot be afraid to try something new,Pythonmakes it easy andmostlikelythereareotherswhohavesimilarinterests.

Page 255: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

FileNavigation

IFYOUARENOTFAMILIARWITHFILENAVIGATIONFROMATERMINAL,HERE ISABASICintroduction. First, you need to open a terminal. A terminal is one of thosewindowsyouseeon themovieswherehackers type ina lotof text.Youdon'thavetouseonetoprogram,butbeingabletonavigateandruncommandsfromtheterminalisausefulskilltohave.

MacandUnix

On Mac, type command-space to bring up Spotlight, then type terminal tolaunchtheterminalapplicationincludedonMacs.On Linux systems, launching a terminal depends on your desktop

environment.Forexample,onUbuntusystemsyoucanhitthekeyboardshortcutctr-alt-T.Aminimalterminalfoundinmostsystemsiscalledxterm.Thereareafewcommandstoknow:

cd-Changedirectorychangestoadifferentdirectory.Typing:

$cd~/Documents

willchange to theDocumentsdirectoryfound inyourhomefolder (~ isashortcut for home, which is Users<username> on Mac andhome<username>onLinux.pwd-Printworkingdirectorywilllistthecurrentdirectorythatyouarein.ls-Listdirectorywilllistthecontentsofthecurrentdirectory.

If you had a Python script located at~/work/intro-to-py/hello.py, youcouldtypethefollowingtorunit:

$cd~/work/intro-to-py

Page 256: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

$cd~/work/intro-to-py$python3hello.py

Windows

OnWindows, typeWin-R to bring up the "RunWindow" interface, then typecmdtolaunchthecommandprompt.Thereareafewcommandstoknow:

cd-Changedirectorychangestoadifferentdirectory.Typing:

c:>cdC:\Users

willchangetotheC:\Usersdirectory.echo%CD%-Willlistthecurrentdirectorythatyouarein.dir-Listdirectorywilllistthecontentsofthecurrentdirectory.

If you had a Python script located at C:\Users\matt\intro-to-

py\hello.py,youcouldtypethefollowingtorunit:

C:>cdC:\Users\matt\intro-to-pyC:\Users\matt\intro-to-py>pythonhello.py

Page 257: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

UsefulLinks

HEREARESOMEUSEFULPYTHONLINKS:

https://python.org/-Pythonhomepagehttps://github.com/mattharrison/Tiny-Python-3.6-Notebook - Python 3.6referencehttp://docutils.sourceforge.net/ - reStructuredText - lightweight markuplanguageforPythondocumentationhttps://pyformat.info-Usefulstringformattingreferencehttps://pypi.python.org/pypi-PythonPackageIndex-3rdpartypackageshttps://www.python.org/dev/peps/pep-0008/-PEP8-Codingconventionshttps://www.anaconda.com/download/ - Anaconda - Alternate Pythoninstallerwithmany3rdpartypackagesincludedhttps://www.djangoproject.com/-Django-Popularwebframeworkhttp://scikit-learn.org/-MachinelearningwithPythonhttps://www.tensorflow.org/-DeeplearningwithPythonhttps://www.reddit.com/r/Python/-NewsforPython

Page 258: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

AbouttheAuthor

MATT HARRISON HAS BEEN USING PYTHON SINCE 2000. HE RUNS METASNAKE, APythonandDataScienceconsultancyandcorporatetrainingshop.Inthepast,hehas worked across the domains of search, build management and testing,businessintelligence,andstorage.He has presented and taught tutorials at conferences such as Strata, SciPy,

SCALE,PyCON,andOSCONaswellas localuserconferences.Thestructureand content of this book is based on first-hand experience teaching Python tomanyindividuals.He blogs at hairysun.com and occasionally tweets useful Python related

informationat@__mharrison__.

AbouttheTechnicalEditors

Roger A. Davidson is currently the Dean of Mathematics at American RiverCollege in Sacramento,CA.His doctorate is in aerospace engineering, but he

Page 259: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

also holds degrees in computer science, electrical engineering and systemsengineeringinadditiontoarecentgraduatecertificateindatascience(wherehiscurrentloveofPythonbegan).DuringhiscareerthusfarRogerhasworkedforNASA, Fortune 50 companies, startups, and community colleges. He ispassionate about education, science (not just the data kind), wild blackberrycobblerandguidingdiverseteamstosolvebigproblems.AndrewMcLaughlin isaprogrammeranddesigner,asysadminbyday,and

familymanbynight.Withalovefordetail,he'sbeenbuildingthingsforthewebsince1998.AgraduatewithhonorsfromGeorgeFoxUniversity,Andrewhasadegree in Management and Information Systems. In his free time he enjoyshikingwithhiswifeand twokids,andoccasionallyworking inhiswoodshop.Hehasalltenfingers.Followhimontwitter:@amclaughlin

Page 260: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

AlsoAvailable

BeginningPythonProgramming

TreadingonPython:BeginningPythonProgramming 23byMattHarrisonisthecompletebook to teachyouPythonfast.Designed toupyourPythongamebycoveringthebasics:

InterpreterUsageTypesSequencesDictionaries

Page 261: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

FunctionsIndexingandSlicingFileInputandOutputClassesExceptionsImportingLibrariesTestingAndmore…

Reviews

Matt Harrison gets it, admits there are undeniable flaws and schisms inPython, and guides you through it in short and to the point examples. IboughtbothKindleandpaperbackeditionstoalwayshaveatthereadyforcontinuingtolearntocodeinPython.—S.Oakland

ThisbookwasagreatintrotoPythonfundamentals,andwasveryeasytoread.IespeciallylikedallthetipsandsuggestionsscatteredthroughouttohelpthereaderprogramPythonically:)—W.Dennis

Youdon'tneed1600pagestolearnPythonLast timeIwasusingPythonwhenLutz'sbookLearningPythonhadonly300pages.Forwhateverreasons, Ihave toreturn toPythonrightnow. Ihavediscoveredthatthesamebooktodayhas1600pages.Fortunately, I discoveredHarrison's books. I purchasedall of them,bothKindleandpaper.JustfewdayslaterIwasontrack.Harrison'spresentationisjustright.Shortandclear.Thereisno50pagesabouttheZenandphilosophyofusingif-then-elseconstruct.Justfacts.

Page 262: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

—A.Customer

TreadingonPython:Vol2:IntermediatePython

Treading on Python: Vol 2: Intermediate Python 24 by Matt Harrison is thecomplete book on intermediate Python.Designed to up your Python game bycovering:

FunctionalProgrammingLambdaExpressionsListComprehensionsGeneratorComprehensionsIteratorsGeneratorsClosures

Page 263: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

DecoratorsAndmore…

Reviews

Complete!All youmust knowaboutPythonDecorators: theory, practice,standarddecorators.Allwritteninaclearanddirectwayandveryaffordableprice.NicetoreadinKindle.—F.DeArruda(Brazil)

Thisisaverywellwrittenpiecethatdelivers.Nofluffandrighttothepoint,Mattdescribeshowfunctionsandmethodsareconstructed,thendescribesthevaluethatdecoratorsoffer.…Highlyrecommended,evenifyoualreadyknowdecorators,asthisisaverygoodexampleofhowtoexplainthissyntaxillusiontoothersinawaytheycangrasp.—JBabbington

DecoratorsexplainedthewaytheySHOULDbeexplained…Thereisanoldsayingtotheeffectthat“Everystickhastwoends,onebywhich itmay be picked up, and one bywhich itmay not.” I believe thatmostexplanationsofdecorators failbecause theypickup thestickby thewrongend.What I like about Matt Harrison’s e-book “Guide to: Learning PythonDecorators”isthatitisstructuredinthewaythatIthinkanintroductiontodecoratorsshouldbestructured.Itpicksupthestickbytheproperend…Whichisjustasitshouldbe.—S.Ferg

Page 264: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

This bookwill clear up your confusions about functions even before youstart toreadaboutdecorationatall. Inaddition togettingstraightaboutscope,you'llfinallygetclarityaboutthedifferencebetweenargumentsandparameters, positional parameters, named parameters, etc. The authorconcedesthatthisintroductorymaterialissomethingthatsomereaderswillfind“pedantic,”butreportsthatmanypeoplefindithelpful.He’sbeingtoomodest. The distinctions he draws are essential to moving yourprogrammingskillsbeyonddoingaprettygoodimitationtorealfluency.—R.Careago

Page 265: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

EbookFormatting:KF8,Mobi&EPUB

EbookFormatting:KF8,Mobi&EPUBbyMattHarrisonisthecompletebookon formatting for all Kindle and EPUB devices. A good deal of the eBooksfound in online stores today have problematic formatting.Ebook Formatting:KF8,Mobi&EPUBismeanttobeanaidinresolvingthoseissues.Customershate poorly formattedbooks.Read through the reviewsonAmazon andyou'llfindmany examples. This doesn't just happen to self-published books. BookscomingoutofbigPublishingHousesoftensuffersimilar issues. In therush toput out a book, one of the most important aspects affecting readability isignored.Thisbookscoversallaspectsofebookformattingonthemostpopulardevices

(Kindle,iPad,AndroidTablets,NookandKobo):

Covers

Page 266: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

TitlePagesImagesCenteringstuffBoxmodelsupportTextStylesHeadingsPagebreaksTablesBlockquotesFirstsentencestylingNon-ASCIIcharactersFootnotesSidebarsMediaQueriesEmbeddedFontsJavascriptandmore…

23-http://hairysun.com/books/tread/24-http://hairysun.com/books/treadvol2/

Page 267: Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Onemorething

THANKYOUFORBUYINGANDREADINGTHISBOOK.If you have found this book helpful, I have a big favor to ask. As a self-

published author, I don't have a big Publishing House with lots of marketingpowerpushingmybook.Ialsotrytopricemybookssothattheyaremuchmoreaffordable.Ifyouenjoyed thisbook, Ihope thatyouwould takeamoment to leavean

honest reviewonAmazon.Ashortcommentonhowthebookhelpedyouandwhatyour learnedmakesahugedifference.Aquickreviewisuseful tootherswhomightbeinterestedinthebook.Thanksagain!Writeareviewhere.