Escolar Documentos
Profissional Documentos
Cultura Documentos
Python
JOSELUISROBERTOASUNCION,
GERALDBRITTON
SecondEdition(May2015)
This work is licensed under a
Creative Commons Attribution-NoDerivatives 4.0 International License
.
Trademarks
IBM,the IBMlogo, and ibm.com are trademarks or registeredtrademarksofInternational BusinessMachines Corp.,
registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other
companies. A current list of IBM trademarks is available on the Web at
Copyright and trademark information at
www.ibm.com/legal/copytrade.shtml .
Java and all Javabased trademarks are trademarks of SunMicrosystems,Inc.in theUnitedStates,other countries,
orboth.
MicrosoftandWindowsaretrademarksofMicrosoftCorporationintheUnitedStates,othercountries,orboth.
LinuxisaregisteredtrademarkofLinusTorvaldsintheUnitedStates,othercountries,orboth.
UNIXisaregisteredtrademarkofTheOpenGroupintheUnitedStatesandothercountries.
Othercompany,product,orservicenamesmaybetrademarksorservicemarksofothers.
TableofContents
Chapter1QuickStart
1.1HelloWorld!
1.2InstallingandsettingupPython
1.3DataScientistWorkbench
1.11Summary
Chapter2:Fundamentals
2.2Documentation
2.2.1Comments
2.2.2Docstrings
2.3BasicSyntax
2.3.1AssignmentStatements
2.3.3OtherArithmeticOperators:
2.3.4ConditionalExecution
2.3.5Compoundarithmeticexpressions
2.3.6CompoundLogicalExpressions
2.3.7Expressionchaining
2.3.8EverythinghasaBooleanValue:
2.3.9SpecialOperations:
2.3.10Repetition
2.4ExercisesforChapter2
Chapter3Functions
3.1TheBigPicture
3.2TheBuiltinFunctions
3.2.1ExamplesofBuiltinFunctions
3.2.1FileOperations
3.2.2ListsandTuples
3.2.2.2Builtinmethodsforusewithlistsandtuples
3.2.2.3Comprehensions
3.2.3FormattingOutput
3.3TheStandardLibrary
3.3.1Themathmodule
3.3.2TheOSModule
3.3.3ThePlatformModule
3.3.4Thesysmodule
3.4UserDefinedFunctions
3.4.1Basics
3.4.2GeneratorsandGeneratorExpressions
3.4.3Closures
3.4.4Decorators
3.4.5CoroutinesandConsumers
3.5LambdaExpressions
3.6Exercises
Chapter4Sequences,MappingsandCollections
4.1Sequences
4.2Morefunwithstrings
4.2.1Multilinestrings
4.2.2OtherStringMethods
4.2.3Moreonlists
4.2.4Updatinganddeletinglistitems
4.2.5Operatorsandmethodsforlistsandtuples
4.3Sets
4.3.1IntroductiontoPythonSets
4.3.2Setoperations
4.3.3SetTesting
4.3.4Setsasrelations
4.3.5SetMethods
4.3.6ImmutableSets
4.4Dictionaries
4.4.1Buildingdictionaries
4.4.2Buildingdictionarieswithlistcomprehensions
4.4.2ModifyingDictionaryEntries
4.4.3DictionariesasKeyedRelations
4.4.4IteratingOveraDictionary
4.4.5DictionaryMethods
4.4.6UsingDictionariestoCategorizeandCount
4.4.7Usingdefaultdict
4.5NamedTuples
4.6DoubleendedQueues
4.7Exercises
Chapter5Modules
5.1TheBigPicture
5.2Introduction
5.3Defintion
5.4ImportingModules
5.5ExecutingModulesasscripts
5.6Thedir()function
5.7Packages
5.7.1Importingmodulesfrompackages
5.7.2Modulesreferencingfromothermodules
5.8Howdoestheinterpretergoaboutlookingforyourfiles?
Chapter6ObjectOrientedProgramming
6.1TheBigPicture
6.2ObjectOrientedProgrammingversusProceduralProgramming
6.3Classes
6.3CreatinganObject
6.4Attributes
6.5Behaviours
6.6Inheritance
6.6.1ExtendingCreatedClasses
6.7Exercises
Chapter7DatabaseConnectivity
7.1TheBigPicture
7.2Prerequisites
7.3Settingup
7.4UsingIBMDB2withPython
7.5ConnectionObjects
7.6CursorObjects
7.7PerformingSQLqueries
7.7.1SELECT
7.7.2INSERT
7.8Exercises
AppendixASolutionstothereviewquestions
Chapter2
Chapter3
Chapter4
Chapter6
Chapter7
Websites
Books
Preface
Keepingyourskills currentintoday's world isbecoming increasinglychallenging. There are too manynew
technologies being developed, and little time to learn them all. The Big DataUniversity Book Series has
been developed to minimize the time and effort required to learn many of these new technologies. The
booksthat are part of thisseries have correspondingfree onlinecourses inBigDataUniversity.com,soyou
canlearnusingjustthebook,justtheonlinecourse,orboth!
ThisbookisintendedforanyonewhoworkswithorintendstodevelopPythonapplicationssuchas
applicationdevelopers,consultants,softwarearchitects,datascientists,instructorsandstudents.Itisa
goodreferenceaswellfordevops,systemadministratorsandproductmanagers.
This book was created by the community a community consisting of university professors, students, and
professionals (including IBM employees). The online version of this book isreleasedto the community at
nocharge.Numerousmembersofthecommunityfromaround the worldhaveparticipatedindevelopingthis
book, which will also be translated to several languages by the community. If you would like to provide
feedback, contribute new material, improve existing material, or help with translating thisbooktoanother
language, please send an email of your planned contribution to admin@bigdatauniversity.com with the
subjectGettingStartedwithPythonbookfeedback.
If you are interested in Python becauseyouwant to become a datascientist, orwork with dataanalytics,
makesuretoreviewbigdatauniversity.com,whichhasalargenumberoffreecoursesonthesesubjects.
Abouttheauthors
JoseLuisRobertoAsuncion
Jose isa code qualityfreak. Heplays barbie with objectsby dressingthem upwithdesignpatterns.Heisa
PHPdeveloperby day. Onedayhe wouldlike tofocus workingmorewithJavaandPythonratherthanwith
PHP.Drophimalineattwitter.com/jeunito
GeraldBritton
Gerald Britton is currently a database developer withTD Bankand anopensourcecontributor to various
Pythonbased projects, includingGrampsand OpenLP. Geraldhasbeenactiveindatabase development
for four decadesand has worked both inNorthAmericaandoverseas helping companiesandcharitieswith
their database needs across a variety of platforms, including Linux, Windows and OS/390. Heis alsoa
strong advocatefor the open source software developmentmodel with a dedicationto findingbetter,faster
andcheaperwaysofhandlingdifficultproblems.
Contributors
Thefollowingpeopleedited,reviewed,providedcontent,andcontributedsignificantlytothisbook.
Chapter1QuickStart
1
Welcome to Python! This book aims to get you started on learning Python as quickly as possible. No
previous programmingexperience isassumed. We willshowyoua basic Pythonprogram andthenwewill
getyoustartedoncreatingyourown!
1.1HelloWorld!
LetscreateourfirstPythonprogram.Listing1.1hasthePythoncode.
"""ThisismyfirstprograminPythonYAY!"""
print"Hello,World!"
Listing1.1TheHelloWorld!program
The output of the program,asyoumayhaveguessedisHello,World!Thefirstlinein thelistingissimplya
comment.
To runtheprogramoninteractivemode,start acommandprompt(onWindows,ifyouhavePython installed
already)orterminal(onLinux/MacOS)andtype:
>>>print"Hello,World!"
Python is very simple. Ithasbeendesigned so thatthecode is easytoreadand isasunderstandable as
everydayEnglish.
1.2InstallingandsettingupPython
The first steptowork withPythonistodownloadandinstall itforyour platform.Ifyou'reusingLinux orMac,
Python is already installed on your system. For example, on Linux, you can verify Python isinstalledby
openingaterminalwindow,typingpythonandpressingenter.Ifcorrectlyinstalled,outputsimilartotheone
shownin Figure1.1
shouldappear.
Figure1.1VerifyingifPythonhasbeeninstalledonLinux
ForWindowsusers,followthesestepstogetPythonupandrunningonyourcomputer:
1. Download the Python interpreter from http://www.python.org/downloads/ and choose the installer
that fits with your operating system. Install the latest release of version 2.7. (As of this writing,
version2.7.9iscurrent).ThisisshowninFigure1.2.
Note
:Forthepurposesofthisintroduction,wearenotusingPython3.0.Asalanguage,Python3.0has
severalattractivefeaturesandenhancements.However,forthewidestcompatibilitywiththemany
commercialandopensourcelibrariesthatareavailable,wewillstickwithPython2.7.
Figure1.2DownloadingPython
Figure1.3InstallingPythonforallusers?
Figure1.4SelectDestinationDirectory
Figure1.5CustomizePython
BesuretoenabletheoptionAddpython.exetoPath"
Figure1.6InstallingPython
python
3.Testtheinstallationbyopeningacommandpromptandtyping: .(Youmayneedto
logoutandlogbackintoWindowsagainforthechangetothePathenvironmentvariableto
takeeffect.)WhenyoureachthePythonprompt,type
print" Helloworld!"
andhittheEnterkey.
1.3DataScientistWorkbench(
datascientistworkbench.com
)
AlthoughyoucancertainlygetstartedwithPythononitsown,youmayfindyourselfwanting
extrafeaturestohelpyousaveyourscripts,organizeyourprojects,anddisplayyouroutputall
inthesameenvironment.Fortunately,therestheDataScientistWorkbench(DSWB)at
https://datascientistworkbench.com .PoweredbyiPython,acommandshellforinteractive
computing,DSWBletsyouwrite,runandsavePythoncode,andevendisplaygraphicswithin
eachdocumentornotebook.DSWBishostedonIBMscloud,allowingyoutoaccessyour
Pythonnotebooksfromanycomputer.Theinterfaceiscustomizable,andletsyouorganizeyour
projectsanddatafileswithease.Bestofall,likePython,itsfree!
TofollowalongthePythoncodeinthistextbook,youcanusePythononitsown,butwe
recommendtakingalookintoDSWBifyouplanonworkingwithPythoninthefuture.Theyhave
someexcellenttutorialstohelpgetyoustartedusingDSWB.
1.11Summary
ItisveryeasytogetstartedwithPython.Onmanysystems(includingLinuxandOSX)the
languageispreinstalled.ForWindowsusers,theinstallationisquickandpainless!
Chapter2:Fundamentals
2
Pythonwasdesignedwithseveralspecificgoalsinmind:
Simpleimplementation(GuidovanRossumwrotetheoriginalversionentirelyonhisown)
Veryhighlevellanguage
Crossplatformportability(writeonce,runanywhere)
Automaticmemorymanagement
Everythingisanobject
Smallnumberofpowerfuldatatypes
Readabilityandexpressivepower
Easytolearnandremember
Predictability
Safety(bugsinaPythonprogramdonotcrashtheinterpreter)
ExtensibilitywithClanguagemodules
Thosegoalshavebeenachievedandmaintainedthroughoutitsmorethantwentyyearshistory.Todaythere
aremanycontributorswhocontinuetorefineandextendthelanguage.
In this chapter, we will look at some of the fundamental things needed to become an effective Python
programmer. Let's dive in and andputPython to work. Thatmeansyouneedtoknowalittlesyntax.We'll
startoffwithafewbasics,butbeforeallelse,let'sbesurewedo one thingright:documentation!
2.2Documentation
Virtually all professional programmers would agree that a program without proper documentation is
incomplete, regardless of the language. Somelanguagesare quiteverbose(e.g. COBOL, whichclaimsto
be "selfdocumenting" to a degree but still can be used to develop inscrutable programs.) Others are
extremely terse (perhaps APL is the best example). Nomatterwhatlanguageisusedtowriteit,aprogram
without documentation will very likely defy understanding and maintenance. Python is no exception
fortunatelyit provides amplefacilitiestoembed documentationwithin each program. Aswegoalong, we'll
showyouhowtodothatand"practicewhatwepreach"aswell.
2.2.1Comments
The most basictype ofdocumentationisaninlinecomment.InPython,acommentbeginswitha#symbol
(variouslycalled anumbersignor a hashmarkor symbol,dependingon where you live) and finisheswith
theendoftheline.Thisisanexampleofacomment:
#Thisisacomment
A comment can start anywhere on a line, and take place even after other Python commands. Many
comment lines in a row can be used to introduce the method or purpose of a larger block of code that
follows. Getin the habit of using both sortsof comments a lot!You'llthank yourself later,when yougo
back to your programandcan'trememberwhy you did whatyoudidorthewayyoudidit.Ifsomeoneelse
"inherits"yourprogram,thatpersonwillbeespeciallythankful.
2.2.2Docstrings
Adocstring(shortfordocumentationstring)isusedtodocumentthepurpose,inputargumentsandreturn
argumentsofafunction,classormethod.Itbeginsandendswiththreedoublequotationmarks.Lines
betweenthebeginningandenddonotneedthequotationmarks.Thisisanexampleofadocstring:
"""
Thisisanexampleofadocstring
"""
We'llstarttousetheseinearnestwhenwebegintoworkonuserdefinedfunctionsinChapter3.
2.3BasicSyntax
InthissectionwewilllookatthebuildingblocksofaPythonprogramtheelementsyouwillneedtobegin
towriterealprograms.We'llalsobeneedingafewtypesofdata.Fornow,we'llstickwithjustthree:
Integers
o Anintegerisjust,well,aninteger!42,forexample.
Floatingpointnumbers
o Afloatingpointnumberusuallyhasadecimalpoint,like3.14159
Strings
o Astringisasequenceofcharactersenclosedinquotationseithersingle,double,
triplesingleortripledouble.e.g.Hello,world,'''Icanusetripleopeningandclosing
quotations.''',"""Pythonisfun!""".IfyouarecomingfromalanguagelikeCyoumaybe
usedtousingdoublequotationsforstringsandsinglequotationsforcharacters.Thatis
actuallyagoodconventionandaonethatwewilltrytostickwith.
2.3.1AssignmentStatements
Most programminglanguageshavesomesortofanassignmentstatement.Thatisa command specific to
the language thatsaysthat some variablename can be usedtorepresent some constant or expression
(which may involve other variablenames).Forexample, inmathematics,we can assigntheproduct of two
ormorenumbersorvariablestoavariablename:
(1)
y
Ifweassignthevalue2tothevariable:
(2)
$python
Python2.7.9(default,Dec102014,12:24:55)
Type"help","copyright","credits"or"license"formoreinformation.
>>>
The ">>>" is the interpreter prompt and this iswhere you can begin enteringPython statements.Wecan
enter equations (2) and (1) directly, except that the multiplication symbol in Python (as in many other
languages)istheasterisk(*):
>>>y=2#setytotheinteger2
>>>x=2*y#compute2timesthevariabley
>>>
The equals sign (=) is recognized by Python as the assignment operator. Thatis,when the equals sign
appearsbetween two operands, the meaning is to assignthevalue ofthesecondoperandtothe firstone.
So, inthefirststatement, the value2isassignedtothevariable yinthesecondstatement the valueofthe
expression 2 * y x
is assigned to the variable . (This isprobablyagoodtime to point out that,inPython,
x
and y
in this exampledo not receive the values 2 and4,respectively,butratherreferences orpointersto
storage locationswhere 2 and4 are stored.Thisis a subtle but important distinction between Pythonand
someoftheotherlanguageswithwhichyoumaybefamiliar.)
Before we go further, let's get one thing out of the way: identifiers. An identifier is a name you give to
something, like avariable.Sointheabove example,"x"isanidentifier.InPython,youcanmakeidentifiers
fromanysequence of letters, numbersand underscores("_")exceptthatthefirstcharacter must
bealetter
or underscore. Try to make your identifiers say something aboutwhat theyareidentifying.Forexample,
"day"isbetterthan"i"ifyou'retalkingaboutadayoftheweekormonth.
Noticethat, aseach statement is entered,Pythonrespondswitha newprompt,whichmeansthatitisready
for input again. Notice also that we used spaces to separate the variable names, numbers, the
multiplication symbol and the "equals" sign. Spacing like this is not required in Python but is heartily
encouraged. Thereis evenaspecialdocument,(calledPython EnhancementProposalnumber8,or simply
PEP8) that goes into greatdetailaboutwhatgoodPythonstyleisandisnot.Inthisbook,wewill attemptto
follow the guidelines of PEP8 and other styleguides.We want you to developgoodhabits from the very
start!
2.3.2CheckingResults
Sofar,sogood.Atthispointwehavetocheckwhetherourmathworkedandifxreallygotthevalue4.To
x
verifythis,simplytypethevariablenameandhitenter:
>>>x
4
>>>
x
Pythondisplaysthecurrentvalueofthevariableontheterminal.Noticethat,ininteractivemode,itisnot
necessarytousetheprintcommandforthis,thoughthatworksjustaswell:
>>>printx
4
>>>
2.3.3OtherArithmeticOperators:
There are other ways to perform various arithmetic operations in Python. For starters, here is a table
showingthePythonoperatorsthatcorrespondtobasicarithmeticoperations:
Mathematical
PythonEquivalent Example Result Operation
Operator
xy 21 1 Subtraction
2/1 2 Integerdivision
x/y
3.0/2 1.5 Realdivision
x//y
3//2 1 Integerdivision
The different types of division in this table demands an explanation. Python recognizes two types of
division:integerandreal.Withintegerdivision,boththedividendand the divisoraretreatedasintegersand
the resultis also an integer.That means that,whenthequotientisnotaninteger, itisrounded
downtothe
closest integer.With real division, the dividend and divisoraretreated asreal numbersandthequotientis
alsoa realnumberwithoutrounding.The//(doubleslash)operatorexplicitlyspecifies thatyouwantinteger
Forexample:
>>>2/3
0
>>>2.0/3
0.66666666666666663
>>>
2.3.4ConditionalExecution
>>>x=2
>>>y=3
>>>ify!=0:
...printx/y#onlyattemptdivisionifthedivisorisnonzero
...else:
...print"Ican'tdividebyzero!"
...
0
>>>
This codesnippetdemonstrates the use of the ifstatement. You begin with the word"if",and followitwith
some condition ("y != 0"in this example), and further follow that with a colon. The operator "!=" is the
Python equivalentof theoperator from mathematics. The use of the colon in thiscontextisaconsistent
patternin Pythonandaonethatwillbeencounteredmanytimes.Inthiscontext,itimpliesthat,"Onlydothe
next sectionof codeif the condition aboveistrue."Inthis case, thenextsectionofcodeistheline"printx /
y". Notice that this line is indented four spaces from the if statement that precedes it. Indentation is
required here and indicates that all the indented linesarepart ofa suiteof Pythoncode thatis dependent
upontheifstatement. The use of fourspacesforindentation isoneof the style guidelinesinPEP8,which
weare following. Notice alsothat theindentation givesavisualcluethattheprintstatementissubordinate
totheifstatement.
TheelsestatementtellsPythonwhattodointhecasewhereyis,infact,zero.(Noticethattheelse
statementisfollowedbyacolonandthatthenextlineisindentedfourspaces.)Let'strythesameexample
withysettozero:
>>>x=2
>>>y=0
>>>ify!=0:
...printx/y#onlyattemptdivisionifthedivisorisnonzero
...else:
...print"Ican'tdividebyzero!"
...
Ican'tdividebyzero!
>>>
Pythondidexactlywhatitwastoldittodo.Itavoidedthedivisionbyzero
andinformedusofitaswell.
Therearemanysituationswhereasimple"eitheror"suchastheaboveexampleisnotuptothejob.
Supposeyouwantedtoprintadifferentphrasedependingonthedayoftheweek.Let'sassumeyouare
givenavariable,day_number,thatisanintegerfrom1to7where1meansMonday,2meansTuesday,...
and7meansSunday.Todothis,wewillusetheelifstatement:
>>>day_number=4#Let'stryThursday!
>>>ifday_number==1:
...print"Monday'schildisfairofface"
...elifday_number==2:
...print"Tuesday'schildisfullofgrace"
...elifday_number==3:
...print"Wednesday'schildisfullofwoe"
...elifday_number==4:
...print"Thursday'schildhasfartogo"
...elifday_number==5:
...print"Friday'schildislovingandgiving"
...elifday_number==6:
...print"Saturday'schildworkshardforaliving"
...elifday_number==7:
...print"ButthechildbornontheSabbathDay"
...print"Isfairandwiseandgoodandgay"
...else:
...print"Thereareonlysevendaysinaweek!"
...
Thursday'schildhasfartogo
>>>
Theelifstatementgivesyouaconvenientwaytolineupvariousconditionssothattheyappearvisuallyasa
unit.Somelanguagesprovideasimilarfunctionthrougha"switch"or"case"statement"elif"isusedin
Pythontodoasimilarthing.
2.3.4OtherConditionalOperators
Pythonincludesafullsuiteofconditionaloperators.ThefollowingtableshowsPythonoperatorsandthe
correspondingmathematicaloperations:
Mathematics
PythonEquivalent Example Result Operation
Operator
Note that there are two operators that can be used to test the "not equal to" condition. This is a
convenience providedby Python for programmers familiar with other languages (includingSQL).You can
choosewhicheveroneyouprefer,but beconsistent!
2.3.5Compoundarithmeticexpressions
Sofar,we'veonlylookedatverysimpleexpressions.Thingsarenotalwayssosimple!Whatifyouwere
workingonquadraticequations?Forexample,thegeneralequationforaparabolawithaverticalaxisis:
(3)
Pythonallowsyoutobuildacompoundexpressionfromsimplerones,sothetranslationofthisequationinto
Pythonisnotdifficult:
y=a*x**2+b*x+c#Computetheyaxiscoordinateofaquadraticequation
(GoaheadandtrythisinaninteractivePythonsessionusingyourownvaluesfora,b,candx.)
BylookingatthePythonstatementmoreclosely,youmaywonderhowit"knows"thatyouwantittodothe
exponentiationfirst,thenthemultiplicationandfollowthatwithaddition.Afteralltheresultswouldbequite
different(andwrong!)ifthecomputationproceededstrictlyfromlefttorightorfromrighttoleft(Provethisto
yourselfwithvaluesyouchoosefora,b,candx!)Pythonsolvesthisbyobeyingasystemof
precedence formathematicaloperations.Forthearithmeticoperatorswehaveseensofar,operationsare
doneaccordingtothistable,withthetoprowhavingthehighestprecedenceandthebottomrowhavingthe
lowest.
Operator Description
(expression) parentheses
** exponentiation
multiplication,
*
,
/
,
//
,
%division,
modulus
addition,
+
,
subtraction
positive,
+x
,
x
negative
Noticethatthistableintroducesoperatorsthatwehavenotseenbefore:positive(+x)andnegative(x).
Thesearecalled unaryoperatorssincetheyonlyaffectonevariable.Notealsothatwhitespaceisneither
requirednorrecommendedbetweenaunaryoperatoranditstargetso,forexample:
+a*b
iscorrectbut:
+a*b
isnotrecommended(andhardertoreadintheopinionoftheauthors!)
WhatifyouactuallyneedtooverridePython'sbuiltinprecedenceofoperations?Youcandothatbyusing
parentheses.Expressionsinsideparenthesesarealwayscalculatedfirst,fromtheinmostparenthesized
expressiontotheoutermost.Wecouldforcethe(incorrect!)lefttorightevaluationofequation(3)using
parentheses,likethis:
#Useparenthesestoforcestrictlefttorightevaluation
y=(((a*x)**2+b)*x)+c
This is saying: Multiply a by x, then square the resultthen addb andmultiplythenewresult by x finally,
addc.Asanexercise,howwouldyouuseparenthesestoforcerighttoleftevaluationofequation(3)?
2.3.6CompoundLogicalExpressions
We've seen the way to build compound arithmetical expressions. Now what if we need to test for some
combination ofconditions?Forexample, let'ssay thatyouwanttoplaytenniswithafriend,but you will only
do that ifthetemperatureis greater than80 degrees (Fahrenheit)andthereismorethan 70% sunshine.If
wehavetwoPythonvariables,tempandsunshine,wecoulddoitlikethis:
iftemp>80andsunshine>70:
...
Here wehavetwo conditions("temp > 80" and"sunshine > 70") joined by the keyword "and". The suiteof
statements (represented by the ellipsis, "...") following the "if" statement willnotbe executedunless both
conditionsaretrue.Ifyouarealittlemoreflexibleandwillaccepteithercondition,youcouldwrite:
iftemp>80orsunshine>70:
...
ifnot(temp<80)andnot(sunshine<70):
...
Beautifulisbetterthanugly.
Following these two rules, we can see thatthe firstcompoundexpression isthe better one. Now thatwe
have three new operators, weneedto putthem inour precedence table so that weknowwhat to expect.
Thenewprecedencetablelookslikethis:
Operator Description
(expression) parentheses
** exponentiation
multiplication,
*
,
/
,
//
,
% division,
modulus
addition,
+
,
subtraction
positive,
+x
,
x
negative
<
,
<=
,
==
,
!=
,
<>
,
>
,
>= comparisons
not BooleanNOT
and BooleanAND
or BooleanOR
if...else Conditionalexpression
Note:Wewillcontinuethediscussionofconditionalexpressionfurtherinthischapter.
2.3.7Expressionchaining
iffred<0andfred==nancy:
butPythonhasashorthandexpressionthatwilldothesamething:
if0<fred==nancy:
ifa<b==c<=d>=e:
arevalid!Theadvantagesarethreefold:
shortcircuiting
The last advantage is the result of Python's strategy. Basically, Python will onlyevaluate
what it needs to in order to proceed, savingextra work andavoiding possibleerrors. For example, ifthe
variables"buffalo"and"bill"arenotdefined,thefollowingstatementwillworkjustfine:
>>>if1>2<buffalo<bill:
...print"shouldn'tgethere"
...
>>>
2.3.8EverythinghasaBooleanValue:
In Python, everything every variable, number, function, collection, sequence, ... (some of which you
haven't evenseenasyet),hasa boolean value. Thatmeansthat you can put anything inaconditionalto
see if it is True or False. As mentioned before, everythingin Python isalsoa pointer. Thisincludesthe
integer"1"whichisapointertoastoragelocationthatholdstheinteger..Whenyouwrite:
ifvar :
you are essentially asking Python to look at whatever "var" pointsto (an operation called dereferencing)
anddetermine the Boolean value of that. If "var"happenstopoint toa number,PythonconsidersitFalseif
the number is equal to zero and true otherwise."var"couldrefer toeitheroftheBoolean constantsTrueor
False(whicharealsokeywordsthatyoucanuse),inwhichcasethevalueisreturneddirectly.
Often, "var" will refer to some other type of Python object, or None. We capitalize "None"herebecause
None is aspecial Pythonconstantthat isuniquefor the lifetime of the programinwhichitisreferredto.If
var pointsto None,itisconsideredFalse inaBooleansense.Thoughwehaven'tdiscussed themyet,itisa
good time to note that empty collections and sequences are considered False and a nonempty other
collectionorsequenceisconsideredTrue.
2.3.9SpecialOperations:
There are a few special operations that should be mentioned at this point. First up, we will discuss the
augmented assignment statements. An augmented assignment is a shorthand way ofmodifying avalue
referred to by some variable. For example, a common programming operation is to increment (or
decrement)acounterbyone.
Typicallythisisdonelikethis:
x=x+1
butIcanuseanaugmentedassignmentstatementtoshortenthisto:
x+=1
ifa:#setcbasedonwhetheraisTrueorFalse
c=a
else:
c=b
Thisisacommonpatternfoundinmanyprograms.InPython,thiscanbeshortenedto:
c=aandb
Note: In Python, we use the word "binding" to describe the operation of identifying avariable with some
value. Thus, in the example above, "c" is bound to whatever "a" or "b" are bound to,respectively. The
binding operation is accomplished by using pointers to particular storage locations that is, memory
addresses.
Similartotheaboveexample:
c=aandb
>>>0and2<3
0
>>>(0and2)<3
True
In the first statement, following the rules of precedence,"2< 3" is evaluatedfirst the result isTrue.That
means thatthenext expression to be evaluatedis "0 andTrue".Followingtherulesjustgiven,0evaluates
to False, so 0 is returned. In the second statement,we force the Boolean operation to be evaluatedfirst
using parentheses. "0and2"evaluateto2followingtherulesjust given."0<3"evaluatesto True,whichis
what Pythonreturns! Asanexercise,changethe"and"to"or" intheexamplesaboveandconvinceyourself
thatPythonreallybehavesasdescribedinthissection.
The last special operation that we will look at in this section is the conditional expression.A conditional
expressionisonethatusesif...elsetoreturnasinglevalue.Forexample:
a=1ifbelse2#Setatoeither1ortwodependingonb
Thisisthesameasthelonger:
ifb:#Setatoeither1ortwodependingonb
a=1
else:
a=2
>>>1+2ifFalseelse4
4
>>>1+(2ifFalseelse4)
5
2.3.10Repetition
Hereisanexampleofasimpleforloopinaction:
>>>foriin1,2,3:
...printi
...
1
2
3
>>>
All this loop does istoprintthe numbers1, 2and 3 insuccession.Nevertheless,it demonstratesthe key
elementsofaforloop.Noticethatthegeneralsyntaxis:
for<identifier>in<things>:
<suite>
The keyword "for" is a variable name that is to be used in theloop.Next comes the keyword"in" which
gives you a hint that something elseshouldfollow.Finallywehavethethingsthat theidentifierwillbeused
toreference. This can bea simplelistsuch asinthe example oran identifier thatreferstosomethingthat
can be iteratedover.Lastly comes theallimportant colon.Afterthefor statement comes the bodyofthe
loop the suiteof instructions that areexecuted aspartof theforloop.Inthisexample,thereisonlyone
instruction:
printi
whichisindented4spacesfromtheforstatementthatprecedesitfollowingtheguidelinesofPEP8.
Forloopscanbenestedandfrequentlymustbeinordertoperformusefulwork.Forexample:
>>>fordayin"Mon","Tue","Wed":
...forletterinday:
...printletter
...
M
o
n
T
u
e
W
e
d
>>>
Nowlet'stakealookatasimplewhileloop:
>>>n=5
>>>f=1
>>>whilen>0:
...f=f*n
...n=1
...
>>>f
120
>>>
What is this loop doing? It is computing n! (n factorial) which isthe productof all theintegersup to and
includingagiveninteger.Thegeneralsyntaxis:
while<condition>:
<suite>
>>>foriin1,2,3,4,5:
...ifi%2:#Ifimod2isnotzero,gogetthenextnumber
...continue
...printi
...
2
4
>>>
WhatifyouonlywanttoprintsomelettersofthestringWednesday?
>>>forletterin"Wednesday":
...ifletter=="s":
...break
...printletter
...
W
e
d
n
e
>>>
Notice how the break statement causes the loop to stop before it processes all of the letters in
"Wednesday". As another example, suppose you wantto take in some number andprint out thenumbers
betweenitand100:
>>>number=105
>>>whileTrue:
...printnumber
...ifnumber>=100:#Ifwe'vereached100,stopnow
...break
...number=1
...
105
104
103
102
101
100
>>>
2.4ExercisesforChapter2
1. Eachof the following Python statements has oneor more errors. Correcttheerrorsand test your
correctionsinaninteractivePythonsession:
a.
y=2x3#Multiply2by3andassigntheresulttothevariabley
b.
if4=2/2:#Checkif4isequalto2/2
print"4=2/2!"
c.
forxin123:#printthefirstthreepositiveintegersonthree
lines
printx
d.
x=4ifb#assign4toxifbisTrue,otherwiseleaveitalone
e.
whileTrue:
x=1
ifx:continue
2. Fibonaccinumbersaredefinedwiththisfunction:
withseedvalues:
Write a Python program fragmentthat computestheFibonacci number foragiven number n,and
thenprintstheresult.
3. Itispossibletoapproximatethesineofanyrandomvaluex(inradians)usingthisTaylorseries:
Write a Python program fragmentthat performsthiscalculationtosixterms (ofwhichthefirstthree
aregiven)andcompareyourresultstothepublishedsinetables.
4. Write a Pythonprogramfragmentthat,whengivenamonth oftheyearasanintegerbetween1and
12, printsoutthe month name, the number of daysinthemonth (assumeFebruaryalwayshas 28
days)andalsothenameofthebirthstoneassignedtothemonth.
Chapter3Functions
3
3.1TheBigPicture
3.2TheBuiltinFunctions
>>>function(arguments)
3.2.1ExamplesofBuiltinFunctions
Let'stryoutafewbuiltinfunctionstoseewhattheydo:
>>>abs(1)#Absolutevalue
1
>>>bin(3)#Converttobinary
'0b11'
>>>chr(97)#Converttocharacter(inverseoford())
'a'
>>>hex(26)#Converttohexadecimal
'0x1a'
>>>int('26')#Convertastringtoaninteger
26
>>>len("HelloWorld")#Returnthelengthoftheargument
11
>>>max(1,2)#Maximumofarguments
2
>>>min('a','b','c')#Minimumofarguments,whichdon'thavetobenumbers!
'a'
>>>oct(35)#Converttooctal
'043'
>>>ord('a')#Converttoaninteger(inverseorchr())
97
>>>str(44)#Converttoastring
'44'
>>>bool(1)#ReturnTrueorFalseaccordingtoBooleanevaluation
True
Currently, there are nearly 150 builtin functions in Python. Refer to the official documentation for a
complete,uptodatelist ofbuiltinfunctions.Thereisonebuiltinfunctionthatisarguablythemostusefulof
all:help(x).TrythesestatementsinaninteractivePythonsession:
help(help)
help(int)
help(max)
help(bool)
help('+')
orjust:
help#Startinteractivehelp
3.2.1FileOperations
>>>myfile=open("my.txt",'w')
That'sallittakes!Nowthefile"my.txt"isopenforwriting.Let'sfillitupwithsomedata:
>>>i=0
>>>whilei<5:
...myfile.writelines("Linenumber"+str(i))
...i+=1
...
>>>myfile.close()
What is going on here? Well, when the open() function was called, it returned a reference to a file
object.Likeallobjectsin Python (even basic objects like integers and strings), ithas"methods"associated
with it that you use to manipulate the object. Under the covers, methods are actually functions that are
designedto work with a particulartype of object. Inthisexample,weusedtwomethodsthat arepartofthe
fileobject (thereareseveralothers).Inthe whileloop,weusedthewritemethodtowritefive linestothefile
wejustopened.(We used the str()builtinfunction to convertthe loop countertoastring.)Whentheloop
finished(thatis,whentheloopcounterbecameequalto5),weusedtheclose()methodtoclosethefile.
Diditwork?Well,let'sreaditandsee:
>>>myfile=open('my.txt','r')
>>>whileTrue:
...line=myfile.readline()
...ifline=='':
...break
...printline
...
Linenumber0
Linenumber1
Linenumber2
Linenumber3
Linenumber4
>>>myfile.close()
>>>
Thereisanother,somewhatmoreconvenientwaytoreadthelinesfromourfile.Wecandoitlikethis:
>>>myfile=open('my.txt','r')
>>>forlineinmyfile:
...printline
...
Linenumber0
Linenumber1
Linenumber2
Linenumber3
Linenumber4
>>>myfile.close()
>>>
>>>forletterin"word":
...printletter
...
w
o
r
d
>>>
3.2.2ListsandTuples
Lists (and their stuffy, readonly cousins, tuples) are pervasive in Python. Youwouldbe hardpressed to
find any serious Python programthat does notuselistsin somefashion. Definingasimple list ortuple is
easytodo:
>>>mylist=["this","is","my","list"]
>>>mytuple=("this","is","a","tuple")
The brackets (for lists)or parentheses(for tuples) are requiredhereand tell Pythonto builda list ortuple
andreturnareferencetoit.Themaindifference between a list anda tuple isthat atupleis immutable
that is, it may not bechangedonceit iscreated.WhatcanI dowitha list? Well,forstarters,I can loop
overtheitemsinalistlikethis:
>>>foriteminmylist:
...printitem
...
this
is
my
list
>>>
Single items in the list can also be referred tobynumber. The first itemis 0, the second 1 andsoon.To
specify whichitem wewant,we puttheitemnumberinbrackets (thecharacters[and]). Wecanalsocount
fromthe end, using negative numbers,so 1 is the lastitem,2 isthepenultimate itemandsoon.Hereis
onewaytoprintoutthecontentsofmylistbackwards:
>>>i=1
>>>whilei>=4:
...printmylist[i]
...i=1
...
list
a
is
this
>>>
slicing
Itisalsopossibletotakepiecesoutofthelist,usinganotationcalled .Forexample:
>>>printmylist[1:3]
['is','a']
>>>
k
mylist[i:j]is a slice that selects all items with index i <= k < j.
such that Thus, "list" is not included in
mylist[1:3].
3.2.2.2Builtinmethodsforusewithlistsandtuples
>>>all([0,1,2])#ReturnsTrueifalllistitemsevaluatetoTrue
False
>>>any([0,1,2])#ReturnsTrueifanylistitemevaluatestoTrue
True
>>>len([0,1,2])#Returnsthenumberofitemsinthelist
3
>>>min([0,1,2])#Returnsthesmallestiteminthelist
0
>>>max([0,1,2])#Returnsthelargestiteminthelist
2
>>>sum([0,1,2])#Addsupalltheitemsinthelist
3
>>>range(5)#Returnsalistofintegersfrom0to4
[0,1,2,3,4]
>>>map(str,range(5))#Returnsalistofintegersconvertedtostrings
['0','1','2','3','4']
>>>filter(bool,range(5))#Returnsalistofonlythoseitemsthatevaluate
toTrue
[1,2,3,4]
>>>
3.2.2.3Comprehensions
Python offers a concise way to build lists and other objects using comprehensions . Basically, Python is
able to understand aspecial kind ofa forloop withinalist ortupledefinition(andothers,includingsetsand
dictionaries) andbuild a list ortupleaccordingtotheresultsreturnedbytheloop.For example,ifIwanteda
listcomprisedofthesquaresofthefirst100integers,Icouldusealistcomprehensiontodoit:
>>>[i**2foriinrange(100)]
[0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,...,9801]
>>>
Note:
Wetruncatedthedisplaytomakeitfitcomfortablyinthisdocument.
The list comprehension says, "Foreachinteger from 0to99,insert anitem intothe listequaltothesquare
ofthat integer." To see just how powerful thissyntax is, consider the way to dothesamethingwith other
tools.Perhapsitwouldlooksomethinglikethis:
>>>squares=[]
>>>foriinrange(100):
...squares.append(i**2)
...
>>>
>>>[(i,j)foriinrange(5)forjinrange(2)]
[(0,0),(0,1),(1,0),(1,1),(2,0),(2,1),(3,0),(3,1),(4,0),(4,
1)]
>>>
Itispossibletonestcomprehensions.Hereweusedthisfacilitytoconstructalistconsistingoftuples.
>>>[(i,j)foriinrange(5)forjinrange(2)ifi+j<3]
[(0,0),(0,1),(1,0),(1,1),(2,0)]
>>>
We can add conditions on the comprehension to limit what is included. There is no limit on what the
conditionscanentail,providedthattheyaresyntacticallyvalid.
>>>tuple([i,j]foriinrange(5)forjinrange(2)if(i+j)%3)
([0,1],[1,0],[1,1],[2,0],[3,1],[4,0],[4,1])
3.2.3FormattingOutput
Sooner or later, you will want to exert some control over the appearance of the output of yourprogram.
Perhaps youwill needtowrite atabularreportandensurethatthecolumnslineupproperly.Perhapsyour
outputwillbetheinputtoanotherprogramthatrequiresaparticular format.Perhapsyousimplywanttoadd
sometextaroundtheresultsofyourcalculations.Youcandoafairbitwiththehumbleprintstatement:
>>>print"Thesquareof",2,"is",2**2
Thesquareof2is4
First let us see if we can use the format() function to solve the problem of alignment mentioned int the
precedingparagraph.Wecandothis:
>>>foriinrange(2,12,2):#range()willmakealiststarting at2,endingat
11andincrementingby2
...print"Thesquareof",format(i,">3d"),"is",format(i**2,">3d")
...
Thesquareof2is4
Thesquareof4is16
Thesquareof6is36
Thesquareof8is64
Thesquareof10is100
>>>
Noticehowthenumbers in the outputare rightaligned?This is whatthe format() function did for us.The
first argument given is the value we want to format (the "what"). The second argument is the format
specification (the"how").Thespecification iswritten in a specialminilanguagethat isderivedfromsimilar
output formattingfacilities foundinC andother languages. A format specifieris a string (thusenclosed in
quotation marks, as in the example above) that is constructed from 0 or more elements in the following
order:
[[fill]align][sign][#][0][width][.precision][type]
where:
Option Meaning
A fill character, which can be any character other than '}'. If a fillcharacteris specified,
fill
thenthenextcharactermustbeoneofthealignmentoptions.
Option Meaning
'<' Leftaligned(default)
align '>' Rightaligned(asinourexample)
'=' Putpaddingafterthesign,ifany,butbeforethefirstdigit.
'^' Centeraligned
Option Meaning
'+' Useasignforbothpositiveandnegativenumbers.
sign '' Onlyuseasignfornegativenumbers.(Thisisthedefaultbehaviour.)
Use a leading space on positive numbers and a minus sign on
space
negativenumbers
Onlyforintegersinbinary,octalorhexadecimaloutput.Prefixestheoutputby '0b', 'O0', or
#
'0x'respectively
0 Padtheoutputwithazero.
width Minimumfieldwidth.Ifnotspecified,thenthefieldwidthisdeterminedbythecontent
Number of digits to be displayed after the decimal point, for floating pointnumbers.Not
precision
validforintegers.Fornonnumbers,itindicatesthemaximumfieldwidth.
Option Meaning
's' Stringformat.Thisisthedefaultforstringvaluesandmaybeomitted
type
'b' Binary.Formatsanumberinbase2
'd' Decimal.Formatsanumberinbase10
'o' Octal.Formatsanumberinbase8
Hexadecimal.Formatsanumberinbase16,usinglowercaseletters
'x'
forthedigitsabove9
Hexadecimal. Formats a number in base 16, using uppercase
'X'
lettersforthedigitsabove9
Number. This is the same as'd' but inserts separatorsaccording to
'n'
thelocale.
'e' Exponentnotation.Uses'e'toindicatetheexponent.
'E' Exponentnotation.Uses'E'toindicatetheexponent.
'f'
or
Fixedpoint
'F'
General format. Prints in either fixed point or scientific format
'g'
or dependingon the thevalueandthespecifiedfieldwidth.Lowercase
'G' 'g' uses lowercase 'e' for scientific notation. Upper case 'G' uses
uppercase'E'forscientificnotation.
Percentage. Multiplies by 100, displays in fixed ('f') format and
'%'
appendsapercentsign.
>>>foriinrange(2,12,2):#range()willmakealiststarting at2,endingat
11andincrementingby2
...print"Thesquareof{0:>3d}is{1:>3d}".format(i,i**2)
...
Thesquareof2is4
Thesquareof4is16
Thesquareof6is36
Thesquareof8is64
Thesquareof10is100
>>>
Let us look at the differences in the print statement. First, there isjust onestring, which embedssome
formatting instructions. This is followed by a period ('.') and the format function call, with arguments
corresponding to the values we want to format and insert into the string for printing. Let's dissect the
formattinginstructions. Aformatstringcontains"replacementfields"surroundedbybraces(the characters{
and}).Anything not insidebracesis copied asistotheoutput. (Ifyouneed abraceintheoutput,include
theminpairs:{{and}}.)
Insidethebraces,thereplacementfieldisbuiltupasfollows:
field[!conversion][:format]
where "field" is either a field nameor number. Our exampleuses numbers, which simply means that the
value for a field isthecorrespondingargumentsupplied totheformatmethod,countingfromzero.Thefield
name may also, optionally, include a subscript forlists andtuples, keysformappingobjects (discussed in
Chapter 4)andattributesforclassinstances(discussedinChapter6)."conversion"isforspecialcasesand
normally not required it may either be "r" or "s". (See the official documentation for more details.) The
"format" is the format specificationwe justdiscussed.Herearesome alternatewaysto printthelinesinour
example,showingsomeofthewaysyoucanspecifythefield:
print"Thesquareof{0[0]:>3d}is{0[1]:>3d}".format([i,i**2])
3.3TheStandardLibrary
3.3.1Themathmodule
If we want to use the math module, we need to tell Python to go and get it. We do that using the
importstatement.OpenupaninteractivePythonsessionandtype:
>>>importmath#Importthemathmodule
Nowthatwehaveimportedthemathmodule,wecanusethesinfunction:
>>>math.sin(1)
0.8414709848078965
This statementsays,"Lookup the functioncalled'sin' in the module 'math',then call that functionwiththe
value '1' andreturntheresults." Thatis exactlywhathappened.(Ifyouareskeptical,goahead andlookup
the value of sine(1) in a table of sines.) The math moduleprovides 18 trigonometricfunctions, six power
andlogarithm functions,12 functions from number theory andtwoimportantconstants.Trythesefunctions
onyourcomputer:
3.3.2TheOSModule
The OS module contains a number of functions that can be used to query the operating system for
information about the running process (where Python is running),to manipulate files,toissue commands
andformanyother,osspecific purposes. We will cover just afewexamplesthatencourageyouto consult
the official documentation for a complete list of available functions and howtousethem. Letusstart by
importingthemodule:
>>>importos
Now,let'strysomesimplequeries:
>>>os.access('my.txt',os.F_OK)#Seeifwecanaccessafile
True
>>>os.rename('my.txt','your.txt')#Renamethefile
>>>os.access('my.txt',os.F_OK)#Seeifwecanstillaccessthefile
False
>>>os.getenv('HOME')#RetrievetheenvironmentvariableHOME
'/home/user1'
>>>os.getcwd()#Findthecurrentworkingdirectory
'/home/user1'
>>>temp_file=os.tmpfile()#Openatemporaryfileforwriting
>>>os.system('unamea')#Issueasystemcommand
Linuxubuntu2.6.3120generic#58UbuntuSMPFriMar1205:23:09UTC2010i686
GNU/Linux
Trythesefunctionsonyourowncomputer(someareplatformspecific):
Functionnameandarguments Purpose
Returnsthenameofthecurrently
os.getlogin()
loggedinuser.
Createadirectorywiththesupplied
os.mkdir(path)
pathname.
Removeadirectorywiththespecified
os.rmdir(path)
pathname.
os.chdir(path) Changethecurrentworkingdirectory.
Returnalistofthenamesofthefilesin
os.listdir(path)
thespecifiedpath.
3.3.3ThePlatformModule
>>>importplatform
>>>platform.architecture()
('32bit','ELF')
>>>platform.machine()
'i686'
>>>platform.node()
'ubuntu'
>>>platform.platform()
'Linux2.6.3120generici686withUbuntu9.10karmic'
>>>platform.python_version()
'2.6.4'
>>>platform.system()
'Linux'
>>>platform.uname()
('Linux','ubuntu','2.6.3120generic','#58UbuntuSMPFriMar1205:23:09
UTC2010','i686','')
>>>
3.3.4Thesysmodule
This module provides access to some Python interpreter variables and to certain functions that are
closelyaligned with the interpreter's operation. Here area few examplesfromtheavailable 70+ functions
andvariables:
$pythonia=1b=2c="foo"
Python2.6.4(r264:75706,Dec72009,18:45:15)
[GCC4.4.1]onlinux2
Type"help","copyright","credits"or"license"formoreinformation.
>>>importsys
>>>sys.argv#Listofcommandlinearguments
['','a=1','b=2','c=foo']
>>>sys.maxint#Largestsupportedinteger
2147483647
>>>sys.maxsize#Largestobjectsize
2147483647
>>>sys.platform#Platformwe'rerunningon
'linux2'
>>>sys.version#VersionofPython(comparetoplatform.python_version())
'2.6.4(r264:75706,Dec72009,18:45:15)\n[GCC4.4.1]'
Tryeachoftheseonyoursystemandobservetheresults.Someotherfunctionstotry:
Function Purpose
sys.builtin_module_ Tuple of the names of the modules compiled with your
names versionofPython
sys.copyright Pythoncopyrightstatement
sys.getwindowsversi
Windowsonly:versioninformation
on()
sys.modules Dictionarymappingmodulenamestoloadedmodules
sys.path Listofpathstosearchformodules
sys.winver VersionnumberusedforregistrykeysonWindows
3.4UserDefinedFunctions
3.4.1Basics
deffunction_name(arg1,arg2,...,keyword_arg1=default,keyword_arg2=default):
"""
documentationstringdescribingthepurposeofthefunction,
whatitsinputargumentsareandwhatitreturns
"""
#bodyoffunction
returnreturned_data
Let us look at each of these pieces in turn. Every function definition begins with the word "def",that is
followed by the name of the function. Quoting from PEP8, "Function names should be lowercase, with
wordsseparatedbyunderscoresasnecessarytoimprovereadability."
After the function name, with nointervening whitespace, comes a list of the argumentsthat yourfunction
will use,enclosedinparentheses.Firstcomethepositionalargument names, then the keywordargument
nameswithdefaultvalues.Notethatyoucannotminglethepositionalandkeywordarguments.
Nowthatweunderstandthebasicformat,let'swriteasimplefunctionthatcomputesaFibonaccinumber:
>>>deffibonacci(n):
..."""
...Computesthen'thFibonaccinumber
...
...Inputargument:naninteger
...Returns:then'thFibonaccinumber
..."""
...
...ifn==0:
...return0
...elifn==1:
...return1
...else:
...returnfibonacci(n1)+fibonacci(n2)
...
Copy this function definition (stripping out the '>>> ' and '... 'fromthe beginning of the lines) and try this
function inan interactive Pythonsession. It shouldreturntheresult foranyFibonacci number uptoabout
1000, though itwillgetslower as the numbersgetbigger.To understand why, wehave tofirstlookat the
last line of the function. The "return"statement calls the fibonacci() function twice. This is called
recursion and is aquitecommonapproachforsolvingcertainrepetitiveproblems. However,it isnotagood
approach for this problem, since the overheadofusingrecursion makesthe runningtimestretch out asthe
input numbersincrease withnoendinsight!Actually,there willbeastoppingpoint.Python has abuiltin
limit for how deeprecursive calls may go. You can access that depth using the function
sys.getrecursionlimit().
>>>importsys
>>>sys.getrecursionlimit()
1000
>>>
In this case, the limit is 1000, which means that it should be impossible to ask for fibonacci(1002).
Practically, you would notwant to,since it may takehours to computethis way!SeeExercise 3.5.1 for a
constanttimeapproachtothisproblem.Meanwhile,let'sseeifwecandoitwithoutrecursioninlineartime:
>>>deffibonacci(n):
..."""
...Computesthen'thFibonaccinumberinlineartime.
...
...Inputargument:naninteger
...Returns:then'thFibonaccinumber
..."""
...
...ifn==0:
...return0
...fc=fn=1
...for_inxrange(2,n):
...fn,fc=fn+fc,fn
...returnfn
fc=fn=1
fn,fc=fn+fc,fn
Thereis one otherthingwe shoulddo with our function. We need to check ourinput argument tobesure
that it is valid. It needs to be a nonnegative integer. To check this, we can use the builtin function
isinstance()likethis:
isinstance(n,int)#ReturnTrueifnisaninteger
Usingthis,beforewebeginanycalculations,wewilladdthefollowingtesttoourfunction:
ifnotisinstance(n,int)orn<0:
raiseValueError,"Argumentmustbeaninteger>=0"
defvar_func(*args,**kwargs):
<suite>
This function takes in an unknown number of positional arguments followed by an unknown number of
keywordarguments.Let'sseethisinaction:
>>>deffunc(*args,**kwargs):
...print"Args:",args
...print"Keywordargs:",kwargs
...
>>>
>>>func(1,2,3,a=4,b=5,c=6)
Args:(1,2,3)
Keywordargs:{'a':4,'c':6,'b':5}
>>>func()
Args:()
Keywordargs:{}
3.4.2GeneratorsandGeneratorExpressions
Let'sseehowthismightworkwithourFibonaccifunction:
>>>deffibonacci_generator(n=0):
..."""
...YieldsFibonaccinumbersfrom0ton
...
...Inputargument:naninteger,thehighestFibonaccinumbertobe
generated
...Yields:Fibonaccinumbersfrom0ton,inclusive
..."""
...
...ifnotisinstance(n,int)orn<0:
...raiseValueError,"Argumentmustbeaninteger>=0"
...
...yield0
...ifn==0:
...return
...yield1
...fc=fn=1
...for_inxrange(2,n):
...fn,fc=fn+fc,fn
...yieldfn
Now,let'susethisgenerator:
>>>fib_nums=fibonacci_generator(10)
>>>forfinfib_nums:
...printf
...
0
1
2
3
5
8
13
21
34
55
>>>
What is going on here? First of all, let us see how we changed our fibonacci() function into our new
fibonacci_generator() function. For starters, we added a default value for n, so that we can call our
generatorwithoutanyarguments andgetthe firstFibonaccinumber. Next, weadded a yield statementto
sendthefirstFibonaccinumber, 0,backtothecaller.Then,assumingthat thecallerwantsmoreresults,we
added a secondyieldstatement to send the second Fibonacci number,1. Finally, in the bodyof theloop,
everytime wecalculate a new number,weusetheyieldstatementto sendthenextFibonaccinumberback
tothecaller. At compile time, when Python sees ayieldstatementinafunction,itmarksthatfunctionasa
generator. At execution time, when a yield statement is encountered, the result of the yieldstatementis
sent back to the caller andexecution issuspended.Thenext time the caller calls,thefunction continues
until it hits anotheryieldstatement, and so on, until no moreyieldstatements are encountered and the
functionexits.
Whenweuseourgenerator,thefirststatementis:
>>>fib_nums=fibonacci_generator(10)
Python also supports a sortof inline generator, called a generator expression . It is useful for simple
generators that can be written as a single expression. For example, suppose you wanted to produce
squaresofintegers.Ageneratorexpressionlikethiswoulddothetrick:
>>>importsys
>>>sys.maxint
9223372036854775807
>>>squares=(i**2foriinxrange(sys.maxint))#Generatorexpression
yieldingsquares
>>>forsinsquares:
...prints
...ifs>100:
...squares.close()
...
0
1
4
9
16
25
Thisexamplealsoshowsthewaytoimportasinglefunctionfromamodule.
3.4.3Closures
pow(...)
pow(x,y[,z])>number
Withtwoarguments,equivalenttox**y.Withthreearguments,
equivalentto(x**y)%z,butmaybemoreefficient(e.g.forlongs).
Now, suppose you wanted to use the threeargument form, but for your application, the lastargument is
always3. Itwouldbenicenotto havetoenter3everytimeyoucallthis function.Aclosurewouldallowyou
closing
do to this, by the value for z so that you didn't have to write it again and again. Such aclosure
wouldlooklike:
>>>defpow3(x,y):
...returnpow(x,y,3)
...
Oncedefined,wecanuseournewfunction:
>>>pow3(3,4)
0
>>>pow3(5,4)
1
>>>pow3(5,7)
2
Let'slookatanexampleofaclosurewithauserdefinedfunction:
>>>deff(x):
...defg(y):
...returnx>y
...returng
...
>>>lt5=f(5)
>>>lt5(4)
True
>>>lt5(6)
False
>>>
>>>fromfunctoolsimportpartial
>>>base2=partial(int,base=2)
>>>base2('101010')#Convertstringinbase2toaninteger
42
>>>
The partial function works with any function that has keyword arguments. If you want to
close (that is,
freeze or lockin) positional arguments, theymustbe done in the orderinwhich theyoccur inthefunction
definition.Forexample:
>>>pow4=partial(pow,4)#Functiontoraise4toanypower
>>>pow4(2)#Compute4tothepowerof2(4squared)
16
>>>
Naturally,youcanusepartialwithuserdefinedfunctionsaswellaslibraryfunctions.
3.4.4Decorators
>>>defdecorator(f):
...def_f(x):
...print"I'minf,calling",f,"withargument",x
...returnf(x)
...return_f
...
>>>@decorator
...defg(x):
...print"I'mingwithargument",x
...
>>>g(42)
I'minf,calling<functiongat0x033D7970>withargument2
I'mingwithargument42
Having defined the decorator function, weuseit in the definition of our nextfunction.Toto that,weusea
special statement that begins withan '@'then continueswiththe name ofthedecoratorfunction. Ineffect,
we'reputtingicing onthecake! Finally,we defineour realfunction. However, notice whathappens when
wecall the realfunction. First, wegettheline printedfromthedecoratorfunction,thenthelineprintedfrom
therealfunction.Thisisthedecoratorinaction.
Let's take a look at a more complicated example. This is also a great opportunity to introduce Python's
exceptionhandling facilities. Say that you have a series of functions that read from a database. Each
function takes inthename of the databaseand executessomespecialreadoperation. Askeletonofsuch
afunctionmightlooklikethis:
defdbread1(dbname):
"""
Doreadtype1fromdatabasedbname
"""
data=dbname.read(...)#Callthedatabasereadfunction
returndata
defcatch_errors(func):
def_try(dbname):
try:
returnfunc(dbname)
exceptDBERR1,msg:
print"Databaseerror1:",msg
raise
exceptDBERR2,msg:
print"Databaseerror2:",msg
raise
except:
print"Unknowndatabaseerroroccurred"
raise
else:
#Databasefunctioncompletednormally
finally:
#Performanyneededcleanup
return_try
The inner function, _try(), wraps the calltothe databasefunction inatry...except structure.First,theactual
function call func(dbname) is attempted. Then, if either DBERR1or DBERR2occurs,theexceptclauses
matching those two exceptions report on the error. If an unknown exception is encountered, the third
exceptclause catches it (so it is the default error handler). If nothing goes wrong, the code in the
elseclause is executed.No matterwhat happens,thecodeinthefinally clauseisexecutedattheend(any
cleanupcodeshouldgohere).
Now thatwe have our decorator ready, wecanuseit to wrap any ofourdatabasefunctions andknow that
theerrorswillbecaughtandhandled.Wejusthavetowritethemlikethis:
@catch_errors
defdbread1(dbname):
...
@catch_errors
defdbread2(dbname):
...
.
.
.
In case you're wondering, it is perfectly legal to stack decorators, which means this would be valid
(assumingyouhavepreviouslydefinedthedecoratorfunctions):
@happy_birthday
@icing
@top_layer
@filling
@bottom_layer
defplate(shape):
...
3.4.5CoroutinesandConsumers
>>>defco_routine(path):
...f=open(path,'w')
...try:
...whileTrue:
...data=yield#yieldexpression
...f.write(data+'\n')
...exceptGeneratorExit:
...f.close()
...
>>>f=co_routine("new.file")
>>>f.send(None)
>>>f.send('a')
>>>f.send('b')
>>>f.send('c')
>>>f.close()
>>>
>>>nf=open("new.file")
>>>forlineinnf:
...printline,
...
a
b
c
>>>nf.close()
(Admittedly, this coroutine does not do anything special. It just writes lines to a file specified when itis
called. This could have been done withoutanything fancy,butitshouldservetoshowhowcoroutineswork
asdataconsumersandwillhopefullyinspireyoutofindmore(andbetter!)usesforthisapproach.)
The coroutine startsoff likeanyother function,declaring its nameandsingleargument.Thenitopensthe
file to be written. Next, it enters a try...except construct, which begins with a whileloop. The loop is
designed to run forever, or until an exception is raised. The single except statement looks for one
exception:GeneratorExit.
The nextthree lines send three piecesof datatothecoroutine, which completestheyield expressionand
assigns the resulttothevariable data, which isthen written to the file.Finally, the statement f.close()tells
the coroutine to stop, just like it would for a generator. Internally, it raises theexceptionGeneratorExit,
whichiscaughtbyourexceptclause.Theexceptclausejustclosesthefileandthecoroutineends.
3.5LambdaExpressions
Lambdaexpressionsareawayofcreatinganonymousfunctions.Heresasimpleone:
>>>lambdax:x*x
Ifyouguessedthatthatsimplysquaresagivennumber,youdbecorrect.Infact,wecantake
thissimpleexpressionandassignittosomevariable:
>>>square=lambdax:x*x
>>>defsquare(x):
returnx*x
Sowhat?youmayask.Isavealittleontyping,bigdeal!Well,therearegreatusesfor
lambdaexpressions.Forexample,somefunctionstakefunctionsasarguments.Rememberthe
partial() function?However,usingalambdawithapartialisnoeasierthandefiningthe
functioninthefirstplace!
>>>mylist.sort(lambdax,y:cmp(y,x))
cmp isabuiltinfunctionthatcomparestwoobjects.Hereweusealambdainplaceofa
previouslydefinedfunctiontoperhapschangethesortorderbasedonsomeruleofourown.
(Intheexample,therulewouldcausethelisttobesortedindescendingorder.)
LambdasalsohavegreatapplicationswhenwritingGUIprogramswherethingshappen
asynchronously.(Thisisalargetopicthatisoutofscopeforthisintroductoryvolume.)
Lambdasareagreattooltohaveinyourkit!
3.6Exercises
1.Fibonaccinumbersinconstanttime
(a)ThestandarddefinitionoftheFibonaccisequenceisrecursive:
It can beshown,however, that thereis a closed (i.e.nonrecursive)formula (Binet's formula, after French
mathematician Jacques Philippe Marie Binet, 17861856) for the sequence that is based on the
"goldenratio."Usingthatformulaanddoingalittlealgebra,itcanbereducedtothis:
where isthegoldenratio:
>>>fromtimeitimportTimer
>>>deffibonacci(n):
..."""
...Computesthen'thFibonaccinumberinlineartime.
...
...Inputargument:naninteger
...Returns:then'thFibonaccinumber
..."""
...
...ifn==0:
...return0
...fc=fn=1
...for_inxrange(2,n):
...fn,fc=fn+fc,fn
...returnfn
...
>>>Timer('fibonacci(10)','from__main__importfibonacci').timeit()
2.3244328498840332
>>>
By default,thetimeit() methodruns the sample code 1,000,000 (yes, one million)timesandreportson the
total time takenin seconds. For this exercise, use thetimeit moduletotime yournewfunctionfrompart(a)
and compare it to the times for the sameFibonacci numbersusing the above function.As the Fibonacci
numbers increase, which implementation(the given oneoryournew "constanttime"version),producesthe
fastestresult?Dotheybothproducethesameresultsforallvaluesofnupto100?Ifnot,whynot?
2.Decoratortohelpsetupacoroutineandautomaticallyadvancetofirstyield.
3.WriteageneratortolistallPythonfilesinthestandardlibrary
Recall that the
sys
module has a
pathattribute thatis a list of all paths thatPython will search to find
modules when processing an import statement. Depending on your operating system, the list may look
somethinglikethis:
>>>importsys
>>>sys.path
['','/usr/lib/python2.6','/usr/lib/python2.6/platlinux2',
'/usr/lib/python2.6/libtk',...]
>>>
Note the list itemthatcontains the path to the beginningof thePython library. (Inthe aboveexample,itis
sys.path[1] ).
In the OS module there is a function named walk that traverses the entire tree under a given starting
directory and returns a tuple for eachone that contains three items:thedirectorypath,thesubdirectories
containedinthatdirectoryandthefilenamescontainedinthatdirectory.
4.ListMaintenance
(a)
Thereis a librarymodule named bisect that can be usedtoperform binarysearches onsortedlists
toquickly find items inthelist.Forexample,ifyou haveaPython listcalledmylist thatisalreadysorted,you
canfindaniteminthelistlikethis:
>>>frombisectimportbisect_left
>>>mylist=['abc','def','ghi','klm','opq','rst','uvw','xyz']
>>>bisect_left(mylist,'klm')
3
>>>mylist[3]
'klm'
>>>
Note that, for larger, sorted lists, bisection is substantially faster than the list method
index()
, which
searchesthelistsequentiallyfromthebeginning.
Write a function that uses bisection. The function must take three arguments: a list, an item and an
operation.Thefirstargumentcanbe any validPython list (make sure thatitis!)thesecondargumentcan
beanyitemthatmightbeinthelistthethirdparameterisanintegercodespecifyinganoperation:
Code Operation
0 Sortthelist.ReturnsNone.
Insert item into list using bisection. Returns True if
1 the new item is already in the list (but inserts a
duplicateanyway),otherwisereturnsFalse.
Remove itemfromlistusingbisection.ReturnsTrue
2
ifitemfound,otherwisereturnsFalse.
Returns True if item is in the list, otherwise return
4
False
Be sure to testyour functionon a wide variety of listsand items and operations, includingempty listsand
nullitems.(NotethatNoneisavalidvalue foralistitembutyouhave todecidewhetheryouwanttoinclude
itornot.)
(b) Write four closures for your function to make the four operationsusablewithout specifyingthe third
argument.
(c) Suppose that your program only operates on a single, large list. Use the partial function to create
closurestocallyournewfunctionsothatyoucanomitthefirstargument.
Chapter4Sequences,MappingsandCollections
4
So far we haveconsidered alimited subset of Pythondata types:integers,floatingpointnumbers, strings
and lists. In this chapter we will look at some of the other main Python data types and some of the
extensions built on top of them. These types fall into the categories of Sequences, Collections and
Mappings.
4.1Sequences
Sequencesareobjectsoverwhichitispossibletoiterate.Thatis,foreverysequencetype,thismustwork:
foriteminsequence:
#dosomethingwithitem
4.2Morefunwithstrings
4.2.1Multilinestrings
So far, we know how to build strings. We simply enclose some charactersin quotation marks. Wealso
learntthattherearefourwaystodothis:
Singlequotationmarks,e.g.'stringinsinglequotationmarks'
Doublequotationmarks,e.g."stringindoublequotationmarks"
Triplesinglequotationmarks,e.g.'''stringintriplesinglequotationmarks'''
Tripledoublequotationmarks,e.g."""stringintripledoublequotationmarks"""
We also learned that tripledouble quotation marks are used to document functions (the docstring).
However the two "triple" forms have a more general purpose: multiline strings. They are very useful.
Suppose you wanted to write three lines to a file. If you usedeither of the firsttwoforms,youmight do
somethinglikethis:
>>>line1="firstline"#Stringforthefirstline
>>>line2="secondline"#Stringforthesecondline
>>>line3="thirdline"#Stringforthethirdline
>>>f=open("/tmp/3lines.txt",'w')#Openafiletowrite
>>>f.write(line1+'\n')#Writefirstline,appendinganewline
>>>f.write(line2+'\n')#Writesecondline,appendinganewline
>>>f.write(line3+'\n')#Writethirdline,appendinganewline
>>>f.close()#Closethefile
>>>
What if you then had to go back and add another threelines?You'd have to alsoaddthree new write()
calls.If youroutputfile grewand grew, then the maintenancewouldbecome boring at least, andlikelybe
errorprone aswell.Wouldn't it be nice ifyoucoulddefine the content in oneplaceand thenwrite itinon
operation?Well,ifyouuseamultilinestring,youcandojustthat:
>>>lines="""firstline
...secondline
...thirdline
..."""
>>>f=open("/tmp/3lines.txt",'w')
>>>f.write(lines)
>>>f.close()
>>>
A multiline string, like the one above, can bedefined in one place and maintainedon its own. The code
that actually writes the data need not change if the multiline string changes. Also, a multiline string
automaticallyaddsnewlinecommandsat theendofeachline,sothatwedonotneedto addthembyhand.
A multiline string can alsobe a handy way towrite datathat requires substitution andcanbe performed
withtheformat()methodfromChapter3:
>>>HTML="""
...<html>
...<head>
...<title>{title}</title>
...</head>
...</body>
...Thisiseasytodoin{lang}
...using{how}.
...</body>
...</html>
..."""
>>>f=open("/tmp/multi.html",'w')
>>>f.write(
...HTML.format(title="Funwithstrings",lang="Python",how="multiline
strings")
...)
>>>f.close()
>>>
Here, we have formatted a simple page of HTML, using a multiline string to define a template with
substitutionvariables,thenusingtheformat()methodonitto substituteforthethreevariables.Notethatwe
used all capitals for the identifier for the multiline string constant. This is a convention used in Python
programsfordefiningconstantsandispartofPEP8.
Constantsareusuallydeclaredonamoduleleveland
writteninallcapitalletterswithunderscoresseparating
words.ExamplesincludeMAX_OVERFLOWandTOTAL.
4.2.2OtherStringMethods
Strings have a numberofvery useful methodsthat you can use forquerying and modifyingstrings.Also,
someofthearithmetic operatorstake on newmeaningwithstrings.The table below shows someofthese
andgivetypicalusecasesforthem.Forafulllist,seetheofficialdocumentation.
sub
find(sub[, start[,Returns index of startof inrange
[start, >>>"aaabbcc".find("bc")
end]]) end]
or1ifnotfound 4
Returns a copy of the string translated to >>>"HTML".lower()
lower()
lowercase 'html'
>>>'Guidovan
Splitsthestringat sep and returnsa3tuple
Rossum'.partition('van')
sep
partition( ) with the first part, the separator andthelast
('Guido','van','
part.
Rossum')
Splits the string using sepas a separator >>>sys.path[1].split('/')
sep
split([ [,
maxspl
and returns a list of words. Limits the split ['','usr','lib',
it
]])
maxsplit
by . 'python2.6']
Returns anew stringwith leadingandtrailing >>>"toowide
[chars]
strip( ) characters removed. chars defaults to a ".strip()
space 'toowide'
4.2.3Moreonlists
BackinChapter3weintroducedlistsandtuples.Thereismuchmoretosayabouttheseusefuldatatypes!
4.2.4Updatinganddeletinglistitems
It'seasytoupdateanddeleteitemsinalist:
>>>delmylist[1]#removetheseconditemfromthelist
>>>mylist[1]="was"#changethevalueoftheseconditemto"was"
>>>delmylist[:]#emptythelist
4.2.5Operatorsandmethodsforlistsandtuples
Pythonlistsandtuplescomewithseveralusefulmethods,whichwelisthere:
>>>[1,2,3]+[4,5,6]
+ Additemsfromanotherlist
[1,2,3,4,5,6]
>>>['foo']*3
* Duplicatelistitems
['foo','foo','foo']
append(x) Additemxtotheendofthelist mylist.append("example")
Since tuples are immutable, the only methods available are count() andindex().Both operators are
available for tuples.Inaddition,since itis immutable, anewtuplewillbe created, rather than changing the
currentone.
4.3Sets
4.3.1IntroductiontoPythonSets
Sets in Python are used to implement the mathematical concept of a set. That is, they are unordered
collectionsof immutable objects. Sincetheyareunordered,theycannotbeindexed.Howeveritispossible
>>>myset=set([1,2,3,4,5,4,3,2,1])
>>>myset
set([1,2,3,4,5])
>>>myset2={7,8,9} #shorthandsetdefinition
>>>myset2
set([8,9,7])
Noticethat the setcontains only unique objects. The extralistentriesthat wesupplied ([4,3,2,1])werenot
addedtothesetsincetheywerealreadypresent.Alsonoticethatthereisnoordertomembersofaset.
4.3.2Setoperations
>>>myset2={iforiinxrange(4,8)} #useacomprehension
>>>myset
set([1,2,3,4,5])
>>>myset|myset2#Union
set([1,2,3,4,5,6,7])
>>>myset&myset2#Intersection
set([4,5])
>>>mysetmyset2#Difference
set([1,2,3])
>>>myset^myset2#Symmetricdifference
set([1,2,3,6,7])
4.3.3SetTesting
Also available are the typical Boolean set operations for testing set memberships and the (proper)
subset/supersetoperations:
>>>myset
set([1,2,3,4,5])
>>>myset2
set([4,5,6,7])
>>>myset3=set([1,2,3])
>>>1inmyset#Setmembership
True
>>>6inmyset#Setmembership
False
>>>4notinmyset3#Setmembership
True
>>>myset3<myset#Propersubset
True
>>>myset<myset#Propersubset
False
>>>myset3<=myset#Subset
True
>>>myset>myset3#Propersuperset
True
>>>mset>=myset3#Superset
True
>>>myset>=myset2#Superset
False
>>>
Wesummarizetheseoperatorsinthistable:
Python
Setoperation
operator
&
in
notin
<
<=
>
>=
len(x)
4.3.4Setsasrelations
>>>fromrandomimportrandint
>>>R=set(
...(randint(1,10),randint(1,10),randint(1,10))
...for_inrange(100)
...)
>>>R=set()
>>>for_inrange(100):
...R.add(
...(randint(1,10),randint(1,10),randint(1,10))
...)
...
>>>
This approach will generally be slower though, since it has separate calls to the add() method for each
iteration.Usethe
timeit moduletoprovethattoyourself.
Now,let'squeryourrelation"R".Assumethatithastheattributecolumns(A,B,C).
>>>#SELECTA,BFROMRWHEREA=1
>>>fortinset((A,B)for(A,B,C)inRifC==1):printt,
...
(5,4)(10,4)(4,5)(6,1)(3,1)(9,10)(1,5)(8,8) (2,2) (3,7) (1,1)
(6,5)
FormoreexamplesofSQLlikerelations,seethesectiononnamedtuples,below.
4.3.5SetMethods
Likeother builtinobjectsinPython,setshaveanassortmentofmethodsforprocessing,inadditiontothose
thathavebeendiscussed already.Fortheexamples,weassumethatthetwosets,RandS aredefinedas
follows:
>>>R=set([1,2,3])
>>>S=set([4,5,6])
4.3.6ImmutableSets
>>>fromrandomimportrandint
>>>R=frozenset(
...(randint(1,10),randint(1,10),randint(1,10))
...for_inrange(100)
...)
However,youcannotbuildafrozensetusingthealternate,forloopmethod:
>>>R=frozenset()
>>>for_inrange(100):
...R.add(
...(randint(1,10),randint(1,10),randint(1,10))
...)
...
Traceback(mostrecentcalllast):
File"<stdin>",line2,in<module>
AttributeError:'frozenset'objecthasnoattribute'add'
Frozen sets are useful for testing fixed memberships. For example, suppose you had a list of all the
battleships thatwere sunkin WWII.If,atthestart ofyourprogram,youputthese into afrozenset,thenyou
cantestanyshipnametoseethatwasamongthosethathadsunk:
>>>sunken_battleships=frozenset(...)
>>>ifshipnameinsunken_battleships:
>>> print "The battleship {0} was sunk during World War
II".format(shipname)
4.4Dictionaries
4.4.1Buildingdictionaries
>>>number=dict(Bob="2125551212",Ted="2145551212",Carol="4165551212",
Alice="5145551212")
>>>number["Bob"]
'2125551212'
Here, we built a simple dictionary and added four telephone numbers to it. (Your friends may be good
sources of information!). We thenretrieved Bob's telephone number using thestandard look up. Python
alsoprovidesasimplifiedsyntaxfordefiningdictionarieswithstaticvalues:
>>>d={Bob:"2125551212",Ted:"2145551212",Carol:"4165551212",Alice:"5145551212"}
4.4.2Buildingdictionarieswithlistcomprehensions
Here'sanotherdictionarycontainingthefirst100squaresandthatwasbuiltusingacomprehension:
>>>one100squares={k:k**2forkinrange(100)}
>>>one100squares.get(99)
9801
>>>one100squares[100]
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
KeyError:100
>>>one100squares.get(100)
>>>one100squares.get(100,"Keynotindictionary")
'Keynotindictionary'
4.4.2ModifyingDictionaryEntries
Wecaneasilymodifyorremoveentriesinadictionary:
>>>one100squares[100]=100**2#Setuptheentryforonehundredsquared
>>>one100squares[100]
10000
>>>one100squares[100]=100**2.1#Changetheentrytoanillogicalvalue
>>>one100squares[100]
15848.931924611141
>>>one100squares.setdefault(100,100**3)#Trytosetanentryto100cubed
15848.931924611141
>>>one100squares.setdefault(101,101**2)#Trytoset101cubed
10201
>>>
>>>delone100squares[100]#Removeentrywiththekeyequalto100
>>>one100squares[100]
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
KeyError:100
>>>
>>>d=dict((k,k**2)forkinrange(5))
>>>d
{0:0,1:1,2:4,3:9,4:16}
>>>d.update((k,k**3)forkinrange(3,7))
>>>d
{0:0,1:1,2:4,3:27,4:64,5:125,6:216}
>>>
4.4.3DictionariesasKeyedRelations
Dictionary keys and elements do not have to be simple strings and numbers. They can bemany things
(evenotherdictionaries).YoucoulduseadictionarytoemulateakeyedtableinanRDBMS:
>>>fromrandomimportrandint
>>>R=set(
...(randint(1,10),randint(1,10),randint(1,10))
...for_inrange(100)
...)
>>>
>>>keyed_R=dict(
...(A,(A,B,C))
...forA,B,CinR
...ifC==1
...)
>>>keyed_R[10]
(10,4,1)
Here,we'veemulatedatablewiththeattributes(A,B,C)usingAastheprimarykey.
4.4.4IteratingOveraDictionary
>>>d=dict((k,k**2)forkinrange(3))
>>>d
{0:0,1:1,2:4}
>>>forkind:#Iterateoverthekeys(thedefault)
...printk
...
0
1
2
>>>forkind.iterkeys():#Iterateoverthekeys(explicitly)
...printk
...
0
1
2
>>>forvind.itervalues():#Iterateoverthevalues
...printv
...
0
1
4
>>>foriind.iteritems():#Iterateoverthekey/valuepairsastuples
...printi
...
(0,0)
(1,1)
(2,4)
>>>
>>>fork,vind.iteritems():#Iterateoverkey,valuepairs
...printk,v
...
00
11
24
>>>
There is also a method that allows you to extract key/value pairs from adictionary until itis empty. This
methodiscalledpopitem().Hereitisinaction:
>>>whilelen(d):
...printd.popitem()
...
(0,0)
(1,1)
(2,4)
>>>
4.4.5DictionaryMethods
Thefollowingtableliststheoperatorsandmethodsthatcanbeusedondictionaries:
4.4.6UsingDictionariestoCategorizeandCount
One useful application for dictionaries is categorizing and counting. Suppose your programreads movie
data,where each movie is representedbyalist, and where the first elementis the movietitle,thesecond
element isthedirector ofthemovieand the otherelementsincludeotherdata. Supposeyouwanttocount
the number of movies produced by each directory. Using standard dictionary methods, you might do
somethinglikethis:
>>>directors={}
>>>formovieinget_movies():
...ifmovie[1]indirectors:
...directors[movie[1]]+=1
...else:
...directors[movie[1]]=1
Alternatively,youcouldusetheget()methoddescribedabovetosimplifyyourprogram:
>>>directors={}
>>>formovieinget_movies():
...directors[movie[1]]=directors.get(movie[1],0)+1
4.4.7Usingdefaultdict
>>>fromcollectionsimportdefaultdict
>>>directors=defaultdict(int)
>>>formovieinget_movies():
...directors[movie[1]]+=1
Adefaultdictsetsa default data typetobe used to automatically create entries for keys thatarenotinthe
dictionary. Inthisexample,weusedthe datatype int whichmeansthatfor everynewkey,anentrywillbe
added to the dictionary with the key
movies[1] and the value i nt(),which defaultsto 0. Note that the
argumentsupplied to defaultdict must be
callable that is itmustbesomesortoffunction ormethod.
Thatis why you cannot just code
defaultdict(0) , even thoughatfirstglance,thatmightseemtomake
sense. Intheexamplebelow, thefirst time Stephen Spielberg isencountered,an entry will beaddedwith
his name as the key and a data value of 0. However, this happens inside an augmented assignment
statement.Thus,theverynextthingthathappensisthat1isaddedtothe entry.0+1=1 sotheentrynow
hasStephenSpielbergasthekeyand1asthevalue,asshownbelow:
>>>fromcollectionsimportdefaultdict
>>>directors=defaultdict(int)
>>>directors["StephenSpielberg"]+=1
>>>fork,vindirectors.iteritems():
...printk,v
...
StephenSpielberg1
Suppose that, instead of counting movies, you want to make a list of the movie data by director.
defaultdict canhandlethistaskaswell:
>>>fromcollectionsimportdefaultdict
>>>movies_by_director=defaultdict(list)
>>>formovieinget_movies():
...movies_by_director[movie[1]]+=[
...movie[0:0]+movie[2:]
...]
4.5NamedTuples
SELECTA,B,CFROMR
>>>fromcollectionsimportnamedtuple#Getthenamedtupletype
>>>R=namedtuple("R","A,B,C")#Defineanamedtupleforourrelation
>>>conn=connect("database")#Connecttoourdatabase
>>>cursor=conn.cursor()#Getacursor
>>>cursor.execute("SELECTA,B,CfromR")#ExecuteanSQLSELECT
>>>forrowinmap(R._make,cursor.fetchall()):
#Iterateovertherowsthatwegotback
...printR.A,R.B,R.C
#Printtheattributesfromeachrow
>>>movies=[
...["StarWars","GeorgeLucas"],
...["TheMatrix","AndyandLanaWachowski"],
...["CloseEncounters","StephenSpielberg"],
...]
>>>movie=namedtuple("Movies","title,director")
>>>formovinmap(movie._make,movies):
...print"{0:<20}{1:<20}".format(mov.title,mov.director)
...
StarWarsGeorgeLucas
TheMatrixAndyandLanaWachowski
CloseEncountersStephenSpielberg
4.6DoubleendedQueues
>>>fromcollectionsimportdeque#Importthedequedatatype
>>>lifo=deque()#Makeanewdeque
>>>foriinrange(5):#Add5newitems
...lifo.append(i)
...
>>>whilelifo:#Takeoffallitems,LIFO
...printlifo.pop()
...
4
3
2
1
0
Ofcourseyoucanputanythingyoulikeintoa deque:integers,strings,lists,tuples,dictionaries,functions
evenotherdeques!Here'showyoucoulduseadequeforaFIFOqueue:
>>>fifo=deque(iforiinrange(5))#MakeaFIFOdeque
>>>whilefifo:
...print(fifo.popleft())#Takeoffallitems,FIFO
...
0
1
2
3
4
Here,we showthat using the popleft()method removesitems from the left of the queue. Wecanalso
seethata
deque cantakeacomprehension(orotheriterable)asanargument.
The followingtable lists themethods that can be usedwithdeques. Assumethat we have a dequecalled
"deck".
4.7Exercises
1.UsingaDictionarytoCollectObjects
Write a function that examines Python's search path and builds and returnsa dictionarythat collectsthe
pathsby the prefix consisting ofthefirsttwodirectoriesinthepath.Allofthedirectoriesbelowthat,willbein
alistthatisthedataportionofthedictionaryentry.Forexample,ifthesearchpathhadtheseentries:
/foo/bar/fum
/foo/bar/foe
/fum/foo/bar
Yourdictionarywouldlooklike:
{"/foo/bar":["fum","foe"],"/fum/foo":["bar"]}
Be sure to allow for empty strings in the path and for path prefixes with no subdirectories.To test your
function, write a second function that takes the dictionary you build and prints it by each entry in the
dictionary,indentingthesubdirectoriesfourspaces.Withtheaboveexample,youroutputshouldlooklike:
/foo/bar
fum
foe
/fum/foo
bar
2.Usingadictionarylikeakeyedtableinarelationaldatabase
Assumethatyouhavethefollowingdictionarystructureforthemoviedata:
{"titleyear":("director",("star1","star2",...)),...}
Oneentrymightbe:
{"StarWars1977":("GeorgeLucas",("CarrieFisher","MarkHamill","Harrison
Ford"))}
(b) Write a function that accepts the dictionary you built in part (a) and a second argument with the last
name of a star. Print all movies where that star appears in your dictionary. Format the print using
indentationandlabelsforthetitle,year,directorandcast.
3.Usingalistlikeamatrix
A Python list can have lists as entries. That means that it is not difficult to define arrays, since a
twodimensionalarray isno more than a tablewithrows (theouter list) andcolumnsineachrow(theinner
list).
(a)Write a functionthatbuildsanarrayusingsuchatwodimensionallist.Thefunctionshouldtakeasinput
the number of rows and columns for the array and populate the array with random integers in a range
specifiedasthethirdandfourthargumentsofthefunction.Atypicalfunctioncallwouldlooklike:
myarray=build_array(10,10,1,100)
(b) Write a second function that performs matrix multiplication. This function will take in two arrays and
returnthe resultofthecomputation. It must check thatthematrices arefullycompatibleforthe operation.
Usingtheresultfrompart (a), test thisfunction and checkyourresults byhandorbyanyothermeansthat
youlike.
Chapter5Modules
5
5.1TheBigPicture
Withmodulesyoucan!
Besidesthat,modulesareusedto:
Separatecodewithdifferentconcerns
Organizecode
Reusecodemadebysomeoneelse
5.2Introduction
>>>message="hello,world"
>>>defhelloworld():
...printmessage
...
>>>helloworld()
hello,world
>>>
>>>quit()
$python
Python2.6.4rc2(r264rc2:75497,Oct202009,02:55:11)
[GCC4.4.1]onlinux2
Type"help","copyright","credits"or"license"formoreinformation.
>>>helloworld()
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
NameError:name'helloworld'isnotdefined
>>>
5.3Defintion
InPython,
modules
arefilesthatcontainfunctiondefinitions,variablesandstatements.
You can use your favorite text editor to write your modules. These files are saved with a .py extension.
Therearetwowaystousepythonmodules:eitherimportthemorexecutethemasascript.
5.4ImportingModules
Copythefollowingcodeintoatexteditorandsaveasfunctions.py:
>>>deffactorial(num):
...factorial=1
...whilenum>0:
...factorial*=num
...num=1
...returnfactorial
>>>defsquare_sequence(n):
...result=[]
...fornuminrange(1,n+1):
...result.append(num*num)
...returnresult
...
Youcannowmakeuseofthisfunctionevenafteryouquitthepythoninterpreterbutfirst,
you have to make sure thatintheterminal you arein the current directory whereyousaved your
module
youhavetoimportthemoduleintothecurrentsession
Okay,letususethemodulewejustsavedinaninteractivesession:
>>>importfunctions
>>>functions.factorial(3)
Youmayassigntheimportedfunctiontoalocalvariableifyouthink"functions.factorial(...)"istoolong:
>>>fact=functions.factorial
>>>fact(3)
ButwhatifIneedonlythesquare_sequencefunctioninthesessionandnotthefactorialfunction?
Avariationoftheimportstatementallowsyouonlytoimportthesquare_sequencefunction:
>>>fromfunctionsimportsquare_sequence
>>>square_sequence(3)
[1,4,9]
Youcanalsoimportallofthefunctions,denotedbyanasterisk,thiswayifyou'refeelinglazy:
>>>fromfunctionsimport*
>>>factorial(3)
>>>square_sequence(3)
[1,4,9]
>>>
Notehoweverthatthispracticeisfrowneduponbecauseitmakesthecodelessreadable.
Toillustrate,considertheformulagiveninChapter2,
Thefollowingisafunctionthatapproximatesthesineofx:
frommathimportfactorial,pi
defsin(x,t=10):
sign_of_x=1.0ifx>=0else1.0
x=float(abs(x))%(2.0*pi)
s=0.0
foriinrange(1,2*t,2):
sign=1.0if(i1)%4else1.0
s+=sign*x**i/factorial(i)
returnsign_of_x*s
Copyandpastethecodeaboveintoatexteditorandsaveitastrig.py.
Then,importyourmoduleandtestit:
>>>fromtrigimportsin
>>>sin(1)
0.8414709848078965
Notice that the function has a second argument,t whichcontrols the number of termsintheexpansion of
the series. Experiment with different valuesoft andseewhat size of twillcausethefunction to returnthe
samevalues as the functionof thesame nameinthemathlibrary. Also,seeifyoucanrewritethis function
intoaonelinelambdausingacomprehension.
5.5ExecutingModulesasscripts
Earlier,wesaidthatmodulescanberunasascript.Thismeansthatwecancallthefunctionsin(x)inthe
moduleitselfwithagivenparameter.Wecandoawaywiththeimportingitintheinterpreterandenteringthe
parametersourselves.Infact,wearegoingtotakeitastepfurther,wearegoingtomakeourtrigmodule
askinputfromtheuser!
Todothis,weaddthefollowingcodeattheendofourfiletrig.py,
if__name__=="__main__":
x=input('x?')#asksuserforaninputthatgetsassignedtox
print"sin("+str(x)+")="+str(sin(x))
Think of
__main__ as containing the code that we currently want to execute. The interpreter executes
everythingcontainedin__main__.
Toexecutetrig.pyasamodulewefeeditasaparameterwhenwefireuptheinterpreter,
oem@orange~/Desktop/SampleCode$pythontrig.py
x?2
sin(2)=0.909297426826
Makesuretochangetothedirectorywheretrig.pyisbeforerunningthiscommand.
The difference is that in the case above, the trig.py module's name becomes __main__ and not trig,
however,whenweimportitintheinterpretertousesin,asyoucanseebelow:
>>>importtrig
>>>trig.sin(2)
0.90929742682568171
>>>trig.__name__
'trig'
>>>
Infact,the__main__atthatmomentistheinteractiveinterpreter,
>>>__name__
'__main__'
5.6Thedir()function
Considerourtrigmodule,
>>>importtrig
>>>dir(trig)
['__builtins__','__doc__','__file__','__name__','__package__','factorial',
'sin']
Expect each stringto return something when you call them. We've alreadydiscussedthesin and factorial
methodsaswellasthe __name__ attribute.
The
__doc__
attributereturnsnothingbecausewedidn'tcodeinadocstringinthetrigmodule:
>>>trig.__doc__
The
__file__
attributereturnsthenameofthecompiledversionofthemodule:
>>>trig.__file__
'trig.pyc'
>>>numbers=range(1,5)
>>>importtrig
>>>sin_func=trig.sin
>>>sin_func(1)
0.8414709848078965
>>>dir()
['__builtins__','__doc__','__name__','__package__','numbers','sin_func',
'trig']
5.7Packages
Packages
provideawaytoorganizeyourmodules.
chapter
__init__.py
trig/
__init__.py
sin.py
cos.py
factorial_script.py
others/
__init__.py
fact.py
square_sequence.py
The
__init__.py inside each foldermakes Pythonrecognize the folderas a Python package.If afolder
doesn'thavean
__init__.py ,thenPythonsimplyseesitasafolder.
5.7.1Importingmodulesfrompackages
Let's say Iwant to writeaseparate module thattakesan input x andgets the factorialofx.We've already
written the factorialfunction in
fact.pybeforeandso we canreuse that!We can import modules inthe
interpreterorfromanothermodule,
Todosousingamodule,
fromchapter5.others.factimportfactorial
if__name__=='__main__':
x=input('x?')
printfactorial(x)
#youcanalsodoitthisway:importchapter5.others.factbutyouwouldhave
toqualify
#thefunctionaschapter5.others.fact.factorial(x)butthat'swaytoolong
and
#youwouldn'twantthatwouldyou?
Makesurethatthefactorial_script.pyisinsamefolderwhereyourchapter5folderisplaced:
SampleCode/
chapter5/
__init__.py
...
...
others/
factorial_script.py
Runningthescript,
oem@orange~/Desktop/SampleCode$pythonfactorial_script.py
x?3
6
Usingtheinterpreter,
>>>fromchapter5.others.factimportfactorial
>>>factorial(3)
6
orsimilarly,
>>>importchapter5.others.fact
>>>chapter5.others.fact.factorial(3)
6
5.7.2Modulesreferencingfromothermodules
fromfunctionsimportfactorial
defsin(x):
sequence=[1]
foriinrange(2,20):
ifi%2:
sequence.append((1.0ifsequence[1]>0else1.0)
*x**i
/fact(i))
returnsum(sequence)
if__name__=="__main__":
x=input('x?')
print"sin("+str(x)+")="+str(sin(x))
sin.py
Insection5.4oursin.pyandfact.pywereinthesamefolder,
chapter5/
sin.py
functions.py
Thus, our current code won't work because it is trying to import the factorial function from the functions
modulebutitisnotthere.
oem@orange~/Desktop/SampleCode$python
Python2.6.4rc2(r264rc2:75497,Oct202009,02:55:11)
[GCC4.4.1]onlinux2
Type"help","copyright","credits"or"license"formoreinformation.
>>>fromchapter5.trig.sinimportsin
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
File"chapter5/trig/sin.py",line1,in<module>
fromfunctionsimportfactorial
ImportError:Nomodulenamedfunctions
>>>
Tomakeitwork,weneedtoimportthefactorialfunctionfromchapter5.others.fact:
Thismeans
thatinsteadofstartingwith:
fromfunctionsimportfactorial
Wechangethefirstlinetowhatyouseebelow:
fromchapter5.others.factimportfactorial
defsin(x):
sin_x=0
forninrange(1,20):
...
...
Now,ourprogramworksagain!
>>>fromchapter5.trig.sinimportsin
>>>sin(1)
0.8414709848078965
>>>
5.8Howdoestheinterpretergoaboutlookingforyourfiles?
Whether you arecoding from the interpreter or using modules,whenever you import a module,thePython
interpreter first looks inthecurrent directory for thatmodule. If themoduleisnot present, thenitgoesonto
lookateachdirectoryinthelist sys.path .
Toseethelistofdirectoriesinthe
sys.path
:
>>>importsys
>>>sys.path
['','/usr/lib/python2.6','/usr/lib/python2.6/platlinux2',
'/usr/lib/python2.6/libtk','/usr/lib/python2.6/libold',
'/usr/lib/python2.6/libdynload','/usr/lib/python2.6/distpackages',
'/usr/lib/python2.6/distpackages/PIL',
'/usr/lib/python2.6/distpackages/gst0.10','/usr/lib/pymodules/python2.6',
'/usr/lib/python2.6/distpackages/gtk2.0',
'/usr/lib/pymodules/python2.6/gtk2.0',
'/usr/local/lib/python2.6/distpackages']
>>>
Chapter6ObjectOrientedProgramming
6
6.1TheBigPicture
6.2ObjectOrientedProgrammingversusProceduralProgramming
What other reallife entities can you think of? These can probably all be represented in the computer as
objects.
Nowthatwehaveidentifiedanddefinedwhatobjectsare,letustalkaboutattributes.
Attributes define an object. These are what make an object unique. They usually come in a setwhich is
unique tothat object.For example, a dog's attributes can beitsbreedandname.Althougha studenthasa
nameaswell,itdoesn'thaveabreed.
Attributes
areanobject'scharacteristics.
areactionsthatanobjectcanperform
Behaviours .
6.3Classes
A
class
isablueprintofanobject.Itcontainsthetheattributesand/orbehavioursofanobject.
Aclassisnottheobjectitselfbutratherthedesignoftheobject.
Let'sstartmakingastudentobject!Tocodeaclassthemostbasicsyntaxforaclassdefinitionis:
classClassName:
defmethod_name(self,[optionalarguments]):
<statements>
Let'snameourstudentclassStudent:
>>>classStudent:
...pass
ThecodeabovefollowsthebasicsyntaxinFigure6.1forcreatingaclass.
6.3CreatinganObject
Nowwehaveastudentclass.Letusstartbycreatingstudents.
>>>classStudent:
...pass
...
>>>s1=Student()#Createss1asaninstanceofStudent
>>>s2=Student()#Createss2asaninstanceofStudent
Wenowhavetwostudents!Whatwejustdidwasto
instantiate
twoinstancesofclassStudent.
Instantiation
referstocreatinganewobjectthatfollowsthedesignandcharacteristicsofacertainclass.
6.4Attributes
Tomakeitlookmorelikeastudentletusaddsomeattributes:
>>>classStudent:
...pass
...
>>>s3=Student()
>>>s3.name="Jose"
>>>s3.student_number=1234
>>>s3.subjects=["Math","English"]
>>>print"s3studentsname:",s3.name
s3studentsname:Jose
>>>print"s3studentnumber:",s3.student_number
s3studentnumber:1234
>>>print"s3student'ssubjects:",s3.subjects
student'ssubjects:['Math','English']
Initially, our Student class has no attributes. If we were to call s3.name before setting it, thenthat would
causeanAttributeError:
>>>s3.name
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
AttributeError:Studentinstancehasnoattribute'name'
>>>
>>>classStudent:
...def__init__(self,name,student_number,subjects):
...self.name=name
...self.student_number=student_number
...self.subjects=subjects
...
The function __init__(self,...) which takes in the required parameter self. Think of
self as
referring to the new class being created atthat time.In fact,
self
isjusta convention. Youcanusethe
word me or
this,justlikeinJava,torefertothe instance.Notethatwhenwritingthe__init__()method,
"__
"is a double underscore.In theexampleabove, __init__isusedtosetaname,student_numberand
a list of subjects. This automatically gives instances of the class Student the attributes, name,
student_numberandsubjects,whosevaluescanbesetatthetimeofinstantiation.
For example, the code below creates a new instance of class Studentwithname Jose, studentnumber
1234,takingthesubjectsCalculus,andProgramming.
>>>s1=Student(name="Jose",student_number=1234,subjects=["Calculus",
"Programming"])
To makethingseasier,if you know the orderofarguments when creating aninstance,youdo not haveto
writeouteachoftheattributesnames:
>>>s2=Student("Dan",5678,["FineArts","Communication"])
>>>classStudent:
...def__init__(self,name):
...self.__name=name
...
Forexample,tryingtoaccesstheprivatevariable
__name
willresultinanerror:
>>>student_one=Student("Jose")
>>>student_one.__name
Traceback(mostrecentcalllast):
File"<stdin>",line1,in<module>
AttributeError:Studentinstancehasnoattribute'__name'
If you're coming from a staticallytyped background, you might be wondering why there are no private
variablesinPython.ThesimpleansweristhatthisisjustapartofthePython'sprogrammingphilosophy.
Whenan attributeisprefixedthisway(i.e.,withadoubleunderscore__),itdoesnotmeanthatyoucannot
access itatall. Itsimply means that the attribute ispart oftheimplementation detail of say for instance, a
method ora class. There are certainly ways tohack or tosnoop aroundtheprivacy ofa "private" variable
andto accessit.Butthismaymakethingstoocomplicated,so,intheend,itisoften bettertojustkeepallof
theattributes"public".
Justincase you need to know how to access"private"attributes in Python, you will needtoaddamethod
thatretrievesthename:
>>>classStudent:
...def__init__(self,name):
...self.__name=name
...defget_name(self):
...returnself.__name
...
>>>student_one=Student("Jose")
>>>printstudent_one.get_name()
'Jose'
>>>printstudent_one.name
'Jose'
Additionally,youcanincludeasettermethodifyouwanttoallowforthechangingof"private"attributes:
>>>classStudent:
...
...
...defset_name(self,name):
...self.__name=name
>>>student_one=Student("Jose")
>>>printstudent_one.get_name()
Jose
>>>student_one.set_name("Dan")
>>>printstudent_one.get_name()
Dan
6.5Behaviours
Now that we have made our student objects look more studentlike, let's make them
behave more like
students.
We begin by writing functions to reflect Student behaviours. One common way is to assign
functionsdefinedoutsideoftheclassasalocalvariableofthatclass.
>>>defstudy():
...print"studying"
...
>>>a_student.study=study
>>>a_student.study()
studying
Functionscanalsobecodedwhenyoudefineaclass:
>>>classStudent:
...def__init__(self,name,sid,subjects):
...self.name=name
...self.sid=sid
...self.subjects=subjects
...defstudy(self):
...print"studyingnow"
...defask(self,question):
...printquestion
...deflisten(self):
...print"ZZZZZZZZ"
>>>s1=Student("Jose",1234,["Calculus","Programming","Biology"])
>>>s1.listen()
ZZZZZZZ
>>>s1.ask("Whatisthesquarerootof4?")
Whatisthesquarerootof4?
>>>
6.6Inheritance
OneofthemainconceptsinObjectOrientedProgrammingis
inheritance
.
Inheritance
iswaytocreateanewclassfromanexistingclass.
6.6.1ExtendingCreatedClasses
ForexampleifwewanttocreateanewclasscalledCollegeStudent,wecouldcodeitfromscratchlikethis:
>>>classCollegeStudent:
...def__init__(self,name,sid,subjects):
...self.name=name
...self.sid=sid
...self.subjects=subjects
...defstudy(self):
...print"studyingnow"
...defask(self,question):
...printquestion
...deflisten(self):
...print"ZZZZZZZZ"
ThesyntaxforinheritanceinPythongoeslikethis:
classClassName(ParentClassName):
defmethod_name(self,[optionalarguments]):
<statements>
The parent class refers to the class whose code is to be inherited. In ourcase,the
CollegeStudent
class makes use of Student class to define itself. This makes Student the parent class as
CollegeStudent thesubclass.
Usually
subclasses are createdbecause weneedtoputinnewattributesorbehavioursthatmay ormay
not necessarily apply to the parent class. Think of the parent class as a more general type of a class.
Subclassesaremorespecific.
Goingbacktoourexample,
>>>classCollegeStudent(Student):
...def__init__(self,degree,major):
...self.degree=degree
...self.major=major
...
Thesubclass
CollegeStudent
inheritstheparentclass
Student
.Thismeansthat:
>>>classCollegeStudent(Student):
...def__init__(self,degree,major):
...self.degree=degree
...self.major=major
...defcut(self,class):
...print"feelinglazy,won'tgoto%sclass"%class
...defstudy():
...print"sippingcoffeewhilegoingthroughatonofreadings"
study,thatarespecificto
CollegeStudent andnotfoundinitsparentclass,
Student
.
Finally, subclasses can change behaviours that are inherited. This is called overriding a function. For
instance we might want to change how the
study() function is to reflect how a college student really
studies.
>>>classCollegeStudent(Student):
...def__init__(self,degree,major):
...self.degree=degree
...self.major=major
...
...defcut(self,class):
...print"feelinglazy,won'tgoto%sclass"%class
...defstudy(self):
...print"studyingwhilesippingcoffee"
...
>>> college_student = CollegeStudent("Jose",1234,["Calculus","Computer
Programming",])
>>>college_student.study()
studyingwhilesippingcoffee
>>>
6.7Exercises
1.CreateaSectionclasswithasectionid,coursetitle,instructorandstudentsasclassvariables.
2.CreateanInstructorclassthathasanameandlistofsubjectsbeingtaughtasitsclassvariables.
3. All objects in Python inherit from the Object class. Override thatclass'
__contains__ method inthe
Sectionclasssuchthatwecandothis:
>>>section=Section(1,"Algebra",Instructor("Raul"),["Jose","Luis"])
>>>"Jose"insection
True
>>>
>>>section=Section(1,"Algebra",instructor,["Jose","Luis"])
>>>section.add("Roberto")
>>>section.size()
3
5.Allowiteratingoverasection'sstudentssuchas:
>>>forstudentinsection:
...printstudent
Jose
Luis
Roberto
7
Chapter7DatabaseConnectivity
7.1TheBigPicture
The Python DB API provides a common interface to access relational databases like DB2. With this
specification, ourPython programs can accessdifferentdatabasesusingthesamesyntaxwithoutknowing
details of each specific database. It is up to the drivers of each database to handle these detailsfor us.
TherearealotofDB2driversforPython.InthisbookwewillusethedriverprovidedbyIBM.
ThefollowingfigureillustrateshowourPythonprogramsinteractwithrelationaldatabases.
7.2Prerequisites
BeforewecanuseDB2,thereareseveralthingsthatwehavetodo:
Get a copy of IBM DB2ExpressC..Thereare many waystogetDB2 but the easiest isfromthe
websiteat DB2ExpressCDataServer
InstallIBMDB2ExpressC.
Installeasy_install,whichisfoundhere:PythonSetupTools
Using the latter,installtheIBMDBegg,animplementation ofthePythonDBAPI2.0sothatwecan
interfacewithDB2 usingPython.You can downloaditfrom http://code.google.com/p/ibmdb/ (Take
note: Do not download the IBMDB egg forDjangobutrathertheIBMDB egg.Inour casesince
wereusingPython2.6,thefilenamelookssomethinglikeibm_db1.0.3py2.6win32.egg)
7.3Settingup
Go to the command processor. You should see thisscreenonceyouarethere (yourDB2 version maybe
different):
Next,letscreateadatabase:
db2=>createdatabasesample
DB20000ITheCREATEDATABASEcommandcompletedsuccessfully.
Connecttothedatabasewejustmade.
db2=>connecttosample
DatabaseConnectionInformation
Databaseserver =DB2/NT9.7.2
SQLauthorizationID=JOSE
Localdatabasealias=SAMPLE
Letsnowcreateatable:
db2=>createtablestudent(idsmallintnotnull,
last_namevarchar(100),
given_namevarchar(100),
login_namevarchar(100),
year_levelsmallint,
birthdaydate,
home_addressvarchar(100))
DB20000ITheSQLcommandcompletedsuccessfully.
Weneedjustonemoresteptocompleteoursetup.Letspopulateourdatabasewithrows:
db2=>INSERTINTOstudentVALUES(1,'Asuncion','Jose',
'jasuncion',2,'19880408','Manila')
DB20000ITheSQLcommandcompletedsuccessfully.
db2=>INSERTINTOstudentVALUES(1,'Delgado','Dan',
'dcdelgado',4,'19880420','Manila')
DB20000ITheSQLcommandcompletedsuccessfully.
Ifwewantedtopopulateourdatabasewithmanyvaluesatatime,allwehavetodois:
db2=>INSERTINTOstudentVALUES(3,'Duffy','Arthur','aduff',4,
'19890815','Bulacan'),(4,'Watson','Emilie','eawatson',5,'1987315',
'Singapore')
DB20000ITheSQLcommandcompletedsuccessfully.
7.4UsingIBMDB2withPython
Now thatwe are all set up, its timetohit the database!TobeabletouseIBMDB2withPythonwehave to
followsomesimplesteps:
ImporttheDB2moduleandconnecttothedatabase
Getaconnectionobject
Createacursor
PerformSQLqueries
Closethecursorandtheconnection
7.5ConnectionObjects
ThefirststepinaccessingaDB2databaseistoimporttheIBMDB2Pythonmodulethatwehaveinstalled.
>>>importibm_db
Then,weestablishaconnectiontoaparticulardatasource.
>>>ibm_db_conn=ibm_db.connect("sample","yourname","yourpassword")
Theconnect()constructoracceptsthefollowingparameters:
dsndatasourcename,requiredinourexampleourdatasourceisthedatabasewecreated
uidusername,required
pwdpassword,required
Thisissimilartowhenweconnectedtothedatabaseinthecommandlineprocessorinanearliersection:
Afterthatletusretrieveaconnectionobject:
>>>importibm_db_dbi
>>>conn=ibm_db_dbi.Connection(ibm_db_conn)
>>>
7.6CursorObjects
Onceyouhaveaconnectiontothedatabase,youcanuseittoretrieveacursor.
>>>cursor=conn.cursor()
A cursor makes us work with the IBM DB2 database. For example, ithasmethods whichwilltake in our
SQLSTATEMENTS(SELECT,INSERT,UPDATE, DELETE,CREATE,DROP,ALTER)asaparameterand
sendthemtothedatabase.Wewilldiscusstheseinmoredetailinthenextsection.
7.7PerformingSQLqueries
Beforewestart,letusfirstaddthismethoddefinitiontothenamespace.
>>>defprintrows(rows):
forrowinrows:
out=""
fordatainrow:
out+=str(data)+''
printout
7.7.1SELECT
The first thing that comes to mind regarding SQL is the SELECT statement. Let us get startedwithit in
Python! Use the same session thatweusedinthesetuppart.Ifyouhavealreadyclosedthatsession, open
anewoneandthenmakeanewconnection.
>>>cursor.execute("select*fromstudent)
>>>rows=cursor.fetchall()
>>>printrows(rows)
1AsuncionJosejasuncion219880408Manila
2DelgadoDandcdelgado419880420Manila
3LacanilaoArturoaclacanilao419890815Bulacan
4WatsonEmilieeawatson519870315Singapore
>>>
Youcanusethe
fetchone()
methodtogettherowsonebyone:
>>>whileTrue:
... row=curs.fetchone()
... ifrowisNone:
... break
... printrow
If you want, a parameter can specify the number of rows you want to retrieve by adding a numerical
parametertothe fetchone() method.
>>>rows=cursor.fetchmany(3)
>>>printrows(rows)
1AsuncionJosejasuncion219880408Manila
2DelgadoDandcdelgado419880420Manila
3LacanilaoArturoaduff419890815Bulacan
Maybeyouwouldliketoaddafiltertothequery.Justconstructanewqueryasastring.
>>>query2="select*fromartistswherelast_name='Asuncion'
>>>cursor.execute(query2)
>>>rows=cursor.fetchall()
>>>print(rows)
1AsuncionJosejasuncion219880408Manila
>>>
7.7.2INSERT
TheINSERTstatementisusedtoaddmorerowsintoatable.
Naively,thefollowingmethodworks:
>>>cursor.execute("INSERTINTOstudentVALUES
(1,'Webb','Ryan','rgwebb',5,'1071984','London')")
Let ustake that a stepfurther and save ourselves some typingspace so wedonthavetokeyinthewhole
cursor.execute(... line of code whenever we want to do an insert. By using dictionaries we can pass a
wholerowasaparametertoourPythoninsertstatement:
>>>new_entry=(6,"Man","Spider","scparker",5,"199011","NewYork")
>>>cursor.execute("insertintostudentvalues(?,?,?,?,?,?,?)",new_entry)
Wemakeupalistofsampledatatoinsert.
>>>list=[(i,Lastname,Firstname,lgname,i,112010,Hometown)
foriinrange(10,15)]
Weformthequeryandthefeeditaswellasthelisttothecursorsexecutemany()method:
>>>insert_sql=INSERTINTOstudentVALUES(?,?,?,?,?,?,?)
>>>cursor.executemany(insert_sql,list)
Checktoseeifallthevalueswereinsertedbyrunninga
SELECT*
queryfromthedatabase.
7.8Exercises
1.Createaprogramthatallowsauserto
CreateSection
Addalistofstudentsandsavetothedatabase
ViewSections
Viewalistofstudentsinasection
Addastudent/stoasection
Removeastudentfromasectionandupdatethedatabase
AppendixASolutionstothereviewquestions
A
Chapter2
1. a.
y=2*3
b.if4==2/2:#Checkif4isequalto2/2
print"4=2/2!"
c.forxin1,2,3:#printthefirstthreepositiveintegers
printx
d.x=4ifbelsex#assign4toxifbisTrue
or
ifb:x=4
e.whileTrue:
x=1
ifx:continue#indentationmustbethesame
2.n=5
a,b=0,1
foriinrange(n):
a,b=b,a+b
printa
3.
xx**3/(3*2*1)+x**5/(5*4*3*2*1)x**7/(7*6*5*4*3*2*1)+
x**9/(9*8*7*6*5*4*3*2*1)x**11/(11*10*9*8*7*6*5*4*3*2*1)
4.
m=6
months=(
('January','Garnet')
,('February','Amethyst')
,('March' ,'Aquamarine')
,('April' ,'Diamond')
,('May' ,'Emerald')
,('June' ,'Alexandrite')
,('July' ,'Ruby')
,('August','Peridot')
,('September','Sapphire')
,('October','Tourmaline')
,('November','Topaz')
,('December','Zircon')
)
print'Month{0}is{1}andit''sbirthstoneis{2}'\
.format(m,months[m1][0],months[m1][1])
Chapter3
1.
deffib_binet(n):
ifn==0:return0
phi=(1+math.sqrt(5))/2
F=int(math.floor(phi**n/math.sqrt(5)+.5))
returnF
2.
defcoroutine(func):
defstart(*args,**kwargs):
cr=func(*args,**kwargs)
cr.next()
returncr
returnstart
3.
defpywalk(dir):
"""
os.Walk(top)Foreachdirectoryinthetreerootedatdirectory
topityieldsa3tuple
(dirpath,dirnames,filenames).
"""
for(_,_,filenames)inos.walk(dir):
forfilenameinfilenames:
iffilename.endswith('.py'):
yieldfilename
#Exampleusage
forfilenameinpywalk(sys.path[7]):printfilename
4.(a)
frombisectimportbisect_left
deflistops(l,item,operation):
ifnotisinstance(l,list):
raiseTypeError('Firstargumentisnotalist')
ifoperation==0:
l.sort()
elifoperation==1:
i=bisect_left(l,item)
l.insert(i,item)
returni==len(l)orl[i+1]==item
elifoperation==2:
i=bisect_left(l,item)
ifi<len(l)andl[i]==item:
dell[i:i+1]
returnTrue
else:
returnFalse
elifoperation==4:
i=bisect_left(l,item)
ifi<len(l)andl[i]==item:
returnTrue
else:
returnFalse
4.(b)
defc0(l,item):returnlistops(l,item,0)
defc1(l,item):returnlistops(l,item,1)
defc2(l,item):returnlistops(l,item,2)
defc4(l,item):returnlistops(l,item,4)
4.(c)
fromfunctoolsimportpartial
mylistops=partial(listops,mylist)
Chapter4
1.
importsys
importos
fromcollectionsimportdefaultdict
mydict=defaultdict(list)
forpathinsys.path:
ifpath=='':continue #ignoreemptypaths
#handleWindowsdrives
ifpath[0].isalpha()andpath[1]==':':
drive,path=path.split(':')
drive+=':'
else:
drive=''
#assembleprefixfordirectorywalk
prefix=drive+os.sep.join(path.split(os.sep)[:3])
#Directorywalk
fordirpath,dirnames,_inos.walk(prefix):
#Processsubdirectoriesreturned
forsuffixindirnames:
#assemblefullpath
subdir=(os.sep.join([dirpath,suffix]))
#removeprefixandaddtodict
subdir=subdir[len(prefix)+1:]
mydict[prefix].append(subdir)
#printtheresults
forprefixinsorted(mydict):
printprefix
forsuffixinsorted(mydict[prefix]):
print''+suffix
2.(a)
defmovies(md):
#Getmovietitleanddirectorname
whileTrue:
movie_name=raw_input('Movienameandyear:')
ifmovie_name=='':break
director=raw_input('Directorname:')
ifdirector=='':break
#Getcastmembers
cast=[]
whileTrue:
cast_member=raw_input('Castmember:')
ifcast_member=='':break
cast.append(cast_member)
md[movie_name]=(director,tuple(cast))
2.(b)
defmoviestar(md,star):
#Buildlistofmoviesstarhasbeenin
movie_list=[]
formovie,(director,cast)inmd.iteritems():
ifany(star==cast_member.split('')[1]
forcast_memberincast):
movie_list.append(movie)
#Printthelistofmovies
formovieinmovie_list:
print'Title:'+movie
print'Director:'+md[movie][0]
print'Cast:'+md[movie][1][0]
forcast_memberinmd[movie][1][1:]:
print''+cast_member
print
3.(a)
fromrandomimportrandom
defbuildarray(rows,cols,min,max):
array=\
[
[min+random()*(maxmin)for_inrange(cols)]
for_inrange(rows)
]
returnarray
3.(b)
defmatrix_mult(A,B):
ifnotall(len(col)==len(A[0])forcolinA[1:]):
raiseValueError,'ArrayAisnotrectangular'
ifnotall(len(col)==len(B[0])forcolinB[1:]):
raiseValueError,'ArrayBisnotrectangular'
iflen(A)<>len(B[0]):
raiseValueError,'Arrayscannotbemultiplied'
AB=[[0for_inxrange(len(A))]for_inxrange(len(A))]
fori,jin((i,j)foriinxrange(len(AB))
forjinxrange(len(AB))):
AB[i][j]=sum(A[i][k]*B[k][i]
forkinxrange(len(B)))
returnAB
Chapter6
1.
classSection:
id=0
title=''
instructor=''
students=[]
def__init__(self,id,title,instructor,students):
self.id=id
self.title=title
self.instructor=instructor
self.students=students
2.
classInstructor:
name=''
subjects=[]
def__init__(self,name,subjects=[]):
self.name=name
self.subjects=subjects
3.Addclassmethod:
def__contains__(self,name):
returnnameinself.students
4.Addclassmethods:
defadd(self,name):
self.students.append(name)
defsize(self):
returnlen(self.students)
5.Addclassmethod:
def__iter__(self):
forstudentinself.students:
yieldstudent
Chapter7
1.
#importneededmodules
importibm_db
importibm_db_dbi
#connecttodatabaseandgetcursorobject
cibm=ibm_db.connect('sample','youruserid','yourpassword')
conn=ibm_db_dbi.Connection(cibm)
curs=conn.cursor()
#DefineCREATEcommandforSectiontable
create_section="""
CREATETABLESection(
IdINTEGERGENERATEDALWAYSASIDENTITY
,titlevarchar(50)
,instructorvarchar(50)
,studentvarchar(50))
"""
#CreateSectiontable
curs.execute(create_section)
#DefineINSERTINTOcommandforSectionTable
insert_section="""
INSERTINTOSection(title,instructor,student)VALUES
(?,?,?)
"""
#InsertstudentsintoSectiontable
title='GettingstartedwithPython'
instructor='GeraldandJose'
students=('Bob','Carol','Ted','Alice')
forstudentinstudents:
curs.execute(insert_section,(title,instructor,student))
#Viewsections
curs.execute('SELECT*FROMSection')
forrowincurs.fetchall():
printrow
#Viewstudentsinasection
curs.execute(
'SELECTstudentFROMSectionWHEREtitle=?',
[title])
forstudentincurs.fetchall():
printstudent
#Addstudentstoasection
new_students=('Frodo','Bilbo','Gandalf','Galadriel')
forstudentinnew_students:
curs.execute(insert_section,(title,instructor,student))
#Removestudentfromasection
curs.execute(
'DELETEFROMSectionWHEREtitle=?ANDStudent=?',
[title,'Bob'])
2.
#Formattedoutput
fromcollectionsimportnamedtuple
StudentRow=namedtuple('StudentRow','ID,LAST_NAME,
GIVEN_NAME,LOGIN_NAME,YEAR_LEVEL,BIRTHDAY,HOME_ADDRESS')
curs.execute('SELECT*FROMSTUDENT')
row_format='{0:>2}{1:<12}{2:<12}{3:<12}{4:>4}{5:>10}
{6:<12}'
printrow_format.format(
'ID','LAST_NAME','GIVEN_NAME','LOGIN_NAME','YEAR',
'BIRTHDAY','HOME_ADDRESS'
)
row_format='{0:>2}{1:<12}{2:<12}{3:<12}{4:>4}{5!s:>10}
{6:<12}'
forstuinmap(StudentRow._make,curs.fetchall()):
printrow_format.format(
stu.ID,stu.LAST_NAME,stu.GIVEN_NAME,
stu.LOGIN_NAME,stu.YEAR_LEVEL,stu.BIRTHDAY,
stu.HOME_ADDRESS
)
conn.close()
References
[1] ZIKOPOULOS, P. IBM DB2 Universal Database and the Microsoft Excel Application
Developer for Beginners, dbazine.com article, April 2005
http://www.dbazine.com/db2/db2disarticles/zikopoulos15
[2] ZIKOPOULOS, P. DB2 9 and Microsoft Access 2007 Part 1: Getting the Data...,
Database Journal
article,May2008
http://www.databasejournal.com/features/db2/article.php/3741221
Use Microsoft Access to interactwithyourDB2data
[3] BHOGAL, K. , developerWorks article,May2006.
http://www.ibm.com/developerworks/db2/library/techarticle/dm0605bhogal/
[4] CHUN, J., CIRONEP. DB2 packages:Concepts,examples,andcommonproblems , developerWorks
article,June2006http://www.ibm.com/developerworks/data/library/techarticle/dm0606chun/index.html
[5] CHEN WheiJen et all.
DB2 ExpressC: The Developer Handbookfor XML,PHP,C/C++,Java,and
.NET August2006SG24730100 http://www.redbooks.ibm.com/abstracts/sg247301.html?Open
Resources
Websites
1. DB2ExpressCwebsite:
www.ibm.com/db2/express
Use this web site to download the image for DB2 ExpressC servers, DB2 clients, DB2 drivers,
manuals,accesstotheteamblog,mailinglistsignup,etc.
2. DB2ExpressCforum: www.ibm.com/developerworks/forums/dw_forum.jsp?forum=805&cat=19
Usetheforumtoposttechnicalquestionswhenyoucannotfindtheanswersinthemanualsyourself.
3. DB2InformationCenter
http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp
The information center provides access to the online manuals. It is the mostup todate source of
information.
4. developerWorks
http://www128.ibm.com/developerworks/db2
This Web site isan excellentresource for developers andDBAsprovidingaccesstocurrentarticles,
tutorials,etc.forfree.
5. alphaWorks
http://www.alphaworks.ibm.com/
This Web site providesdirect accesstoIBM'semerging technology. Itis a place whereone can find
thelatesttechnologiesfromIBMResearch.
6. planetDB2
www.planetDB2.com
ThisisablogaggregatorfrommanycontributorswhoblogaboutDB2.
7. DB2TechnicalSupport
If you purchased the12 months subscription licenseofDB2 ExpressC, you can downloadfixpacks
fromthisWebsite.
http://www.ibm.com/software/data/db2/support/db2_9/
8. ChannelDB2
ChannelDB2 is a social network for the DB2 community. It features content such as DB2 related
videos, demos, podcasts, blogs, discussions, resources, etc. for Linux, UNIX, Windows, z/OS,and
i5/OS.
http://www.ChannelDB2.com/
Books
1. FreeRedbook:DB2ExpressC:TheDeveloperHandbookforXML,PHP,C/C++,Java,and.NET
WheiJenChen,JohnChun,NaomiNgan,RakeshRanjan,ManojK.Sardana,
August2006SG24730100
http://www.redbooks.ibm.com/abstracts/sg247301.html?Open
2. UnderstandingDB2LearningVisuallywithExamplesV9.5
RaulF.Chong,etall.January2008
ISBN10:0131580183
3. DB2 9: pureXMLoverview andfaststart byCynthiaM.Saracco,Don Chamberlin, RavAhujaJune
2006SG247298
http://www.redbooks.ibm.com/abstracts/sg247298.html?Open
4. DB2 SQL PL: Essential Guide for DB2 UDB on Linux, UNIX, Windows, i5/OS, and
z/OS,2ndEdition
ZamilJanmohamed, Clara Liu, Drew Bradstock,RaulChong, Michael Gao, Fraser McArthur, Paul
Yip
ISBN:0131007726
5. FreeRedbook:DB2pureXMLGuide
WheiJenChen, Art Sammartino,DobromirGoutev,FelicityHendricks,IppeiKomi,MingPangWei,
RavAhuja,MatthiasNicola.August2007
http://www.redbooks.ibm.com/abstracts/sg247315.html?Open
6. InformationonDemandIntroductiontoDB29NewFeatures
PaulZikopoulos,GeorgeBaklarz,ChrisEaton,LeonKatsnelson
ISBN10:0071487832
ISBN13:9780071487832
Contactemails
GeneralDB2ExpressCmailbox:
db2x@ca.ibm.com
GeneralDB2onCampusprogrammailbox:
db2univ@ca.ibm.com
Getting
started
with
DB2 application development
couldn't
be
easier.
DB2 Express-C from IBM is the no-charge edition of DB2 data server for managing
relational and XML data with ease. No-charge means DB2 Express-C is free to
download, free to develop your applications, free to deploy into production, and even
free to embed and distribute with your solution. And, DB2 does not place any
artificial limits on the size of databases, number of databases, or number of users.
DB2 Express-C runs on Windows , Linux , Solaris, and Mac OS X systems, and
provides application drivers for a variety of programming languages and frameworks
including C/C++, Java, .NET, Ruby on Rails, PHP, Perl, and Python. If you require
even greater scalability or more advanced functionality, you can seamlessly deploy
applications built using DB2 Express-C to other DB2 editions such as DB2 Workgroup
and DB2 Enterprise.
This free edition of DB2 is ideal for developers, consultants, ISVs, DBAs, students, or
anyone who intends to develop, test, deploy, or distribute database applications.
Join the growing DB2 Express-C user community today and take DB2 Express-C for
a test drive. Start discovering how you can create next generation applications and
deliver innovative solutions.
This book is part of the DB2 on Campus book series, free eBooks for the community.
Learn more at db2university.com