Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1.Checkingbooleanconditionswithif/else
Often,peoplehaveatendencytobeoververbose.Observethefollowingexample: i f m y _ f u n c t i o n ( ) = = T r u e : # m y _ f u n c t i o n r e t u r n s T r u e o r F a l s e r e t u r n T r u e e l s e : r e t u r n F a l s e WhenPythonevaluatesmy_function(),thisbecomesthefollowing(letspretenditreturned True): i f T r u e = = T r u e : # m y _ f u n c t i o n r e t u r n s T r u e o r F a l s e r e t u r n T r u e e l s e : r e t u r n F a l s e Thisseemsrepetitive,doesntit?WeknowthatT r u e isequalT r u e ,andF a l s e isnot.So, insteadofkeepingthat= = T r u e around,wecouldjusthavethefunctioncallinsidethei f statement: i f m y _ f u n c t i o n ( ) : # m y _ f u n c t i o n r e t u r n s T r u e o r F a l s e r e t u r n T r u e e l s e : r e t u r n F a l s e Thereisanimportantpointtonotehere.Sincem y _ f u n c t i o n ( ) isgoingtobeaboolean,and wereeffectivelyreturningthevalueofthatboolean,theresnoreasonnottojustreturnthe booleanitself.Hereshowthislooks: r e t u r n m y _ f u n c t i o n ( ) # m y _ f u n c t i o n r e t u r n s T r u e o r F a l s e Thisisniceandconcise,butwhatifwewanttoreturnT r u e ifm y _ f u n c t i o n returnsF a l s e , andF a l s e whenitreturnsT r u e ?ThereisaPythonkeywordforthat!So,imagineourcode
2.Changingcollectionswhileiteratingoverthem
Wevementionedthatitspoorpracticetomodifyacollectionwhileiteratingoverit.Thisis becausethebehaviorresultingfrommodificationduringiterationisambiguous.Thef o r statementmaintainsaninternalindex,whichisincrementedforeachloopiteration.Thismeans thatifyoumodifythelistyoureloopingover,theindexeswillgetoutofsync,andyoumayendup skippingoveritems,orprocessingthesameitemmultipletimes. Letslookatacoupleofexamples: e l e m s = [ ' a ' , ' b ' , ' c ' ] f o r e i n e l e m s : p r i n t e e l e m s . r e m o v e ( e ) Thisprints: a c Meanwhile,ifwelookatwhatelemsnowcontains,weseethefollowing: > > > e l e m s [ ' b ' ] Whydoesthishappen?Letslookatthiscoderewrittenusingawhileloop. e l e m s = [ ' a ' , ' b ' , ' c ' ] i = 0 w h i l e i < l e n ( e l e m s ) : e = e l e m s [ i ] p r i n t e e l e m s . r e m o v e ( e ) i + = 1 Thiscodehasthesameresult.Nowitsclearwhatshappening:whenyouremovethe'a'from e l e m s ,theremainingelementsslidedownthelist.Thelistisnow['b','c'].Now'b'isatindex0, and'c'isatindex1.Sincethenextiterationisgoingtolookatindex1(whichisthe'c'element),
the'b'getsskippedentirely!Thisisnotwhattheprogrammerintendedatall! Letstakealookatanotherexample.Insteadofremovingfromthelist,wearenowadding elementstoit.Whathappensinthefollowingpieceofcode? f o r e i n e l e m s : p r i n t e e l e m s . a p p e n d ( e ) Wemightexpecttheliste l e m s tobe[ ' a ' , ' b ' , ' c ' , ' a ' , ' b ' , ' c ' ] attheendof execution.However,instead,wegetaninfiniteloopaswekeepaddingnewitemstothee l e m s listwhileiterating.Oops!
3.WhichdatastructureshouldIuse?
Inproblemset6,weaskedyoutostorethestateofcleanlinessforw*htilesinarectangular room.Wesawdifferentsolutionstothis,andwewanttodiscusstheprosandconsofdifferent approaches. List Mostpeoplechosetostorealistoftuples(x,y)foreverycleantile.Whilethisworks,therearea fewthingsthatmakethisimplementationdifficulttoworkwith. Thefirstisthatwheneveratileiscleaned,wemustiteratethroughtheentirelist(an
O(len(cleanTileList)operation)toseeifthetileisnotyetconsideredcleanbeforeaddingthe tilescoordinatestothecleantilelist.Thenecessityofthischeckcanleadtobugsandreduces efficiency. Anotherissuewiththisrepresentationisthatbyincludingonlythosetilesthatarecleaninthelist, wearestoringabooleanvalueforeachtileimplicitly(i.e.,iftileispresent,itisclean).Here,since whatwearedoingisstoringboththetilescoordinatesandsomethingaboutthetile,expressing itexplicitlywouldbeclearer(seedictionarybasedsolution).Forinstance,whatifwechanged thepossiblestatesoftheroomtobeoneofclean,dirty,andjustalittlemessy?This representationwouldnotbeflexibleenoughtoaccommodatethat. Set Anothersolutioninvolvedstoringcoordinatesasasetoftuplesinthesetifthetilewasclean, e.g., set((x,y),...) Thissolutionissuperiortothesolutionusinglists,sinceaddingatupletothesetthatalready existswillnoteveryieldaduplicate,sothisislesslikelytorunintobugs.Additionally,set operationslikelookupandremovalareO(1),soitisveryefficient.However,ithasthesame problemasthelistrepresentationinthatweareimplicitlystoringaboolean,andweshouldtryto makethatmoreexplicit. Listoflists Somepeopleusedalistofliststoimplementasortofmatrix,withabooleanrepresenting whetherornottheroomwasclean.Thelistoflistswouldbeindexedtwice,correspondingtothe xandycoordinatesofthetile,toseeifthattileisclean. e.g., [[True,True,True,True,True,True,True,True], [True,True,True,True,True,True,True,True], ... [True,True,True,True,True,True,True,True]] Thissolutionavoidstheproblemofimplicitbooleanstorage,butitislessefficientinthatupdating anentryrequiresindexingtwolists.Itcanalsobeconfusingknowingwhichdimensiontoindex firstcanbetricky. Dictionary Amorenaturalwaytorepresentthisproblemisusingadictionary,wherethekeyisatuple(x,y) ofthetilesposition,andthevalueisabooleanthatisTrueifthetileisclean. Thisismoreflexibleinthatifwewereaskedtoaccommodatethestatesclean,dirty,and justalittlemessy,wecouldswitchthevaluestoredinthedictionarytobe,say,anintegerinthe set{0,1,2}.
4.Docstrings
Whenwritingnewclassesandfunctions,itisimportanttodocumentyourintentbyusing docstrings.Forinstance,inpset5,sincetherewerealotofnewclassestoimplement,addinga docstringexplainingthepurposeofeachclassisagoodidea. Evensomethingassimpleas: c l a s s T i t l e T r i g g e r ( W o r d T r i g g e r ) : " " " S u b c l a s s o f W o r d T r i g g e r t h a t r e p r e s e n t s a T r i g g e r w h i c h c h e c k s i f t h e s t o r y ' s t i t l e m a t c h e s a g i v e n w o r d . " " " etc. Includingadocstringmeansthespecificationyouvewrittencanbeaccessedbythosewhotry tocreateaninstanceofyourclass.Forexample,ifyouchangeyourTitleTriggerclassdefinition totheabove,runthefile,thentypethefollowingattheinterpreter: > > > T i t l e T r i g g e r ( Youwillseeyourdocstringpopup.:)
5.DirectlyAccessingInstanceVariables
Thiscanbeaproblem,becauseitbreakstheinterfaceyourclassprovidestotheAbstractData Type.Hereisanexampleofthis,asalineofcodeyoumightwriteforsomethinglike T i t l e T r i g g e r . e v a l u a t e inpset5: t i t l e = s t o r y . t i t l e # e v i l Thisisbad,becauseitmeansthattheinstancevariableforthetitleinN e w s S t o r y hadtobe storedass e l f . t i t l e forthistowork.However,theprogrammerwritingN e w s S t o r y (yes, thatsyou,too)mightnothavestoreditass e l f . t i t l e ,becausemaybehe/she/youpreferred
6.Pitfallsofstoringcustomobjectsindatastructures
SomepeopletriedtostorePositionobjectsintheirdatastructureofcleantiles,writingcode suchasthefollowing: d e f i s T i l e C l e a n e d ( s e l f , m , n ) : n e w P o s i t i o n = P o s i t i o n ( m , n ) r e t u r n n e w P o s i t i o n i n s e l f . c l e a n T i l e L i s t ThiscodewillalwaysreturnFalse,evenifthetileat(m,n)isclean.Thereasonwhythisis problematicgetsintotheinternalsofhowobjectsarecomparedforequalityinPython. HowdoesPythoncompareobjectsforequality?Well,forprimitiveslikeintegers,it'spretty simplejustseeifthetwonumbershavethesamevalue.Similarly,forstrings,checkifthe charactersateachpositioninthestringarethesame. WheneverwecreateanewclassfromscratchinPython,whatisthedefaultwaytocheckfor equality? Theansweristhatforobjects,thedefaultwayPythonchecksiftheyareequalistocheckthe locationwherethatobjectisstoredinmemory.BecausethiscodecreatesanewPosition object,n e w P o s i t i o n ,itmakessensethatthisparticularinstancebeingcreatedisnotstoredin thesamelocationasanyotherPositionobjectinthelistofcleantiles!Therefore,ofcourseit won'tbefoundwhenPythoncheckstoseeifit'sinthelist. Thereareacoupleofwaystoavoidthisissue.Ourrecommendedwayforthepurposesofthis courseinvolveschangingwhatisbeingstoredinthedatastructure.Representingasetofx,y coordinatesasatuplewouldmaketestingforequalitymuchsimpler. Thereareother,betterwaystosolvethisproblemthataremorecomplicated.Ifyoudliketoget moreinformation,pleasecometoofficehoursandaskaTAorLA.:)
7.Callingasuperclassconstructorfromasubclass
Forasubclassthatextendsthefunctionalityofasuperclass(e.g.ResistantVirusand SimpleVirusinpset7),alwaysreusethefunctionalityofthesuperclassinsteadofrewritingit. Thisgoesbacktotheconceptthatweshouldavoidrepeatedcode. SaywehavethefollowingconstructorfortheSimpleVirusclass: c l a s s S i m p l e V i r u s ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , m a x B i r t h P r o b , c l e a r P r o b ) : s e l f . m a x B i r t h P r o b = m a x B i r t h P r o b s e l f . c l e a r P r o b = c l e a r P r o b WhenwedefinetheResistantVirusclass,wecouldjustrepeatthetwolinesofcodecontainedin theconstructorasinthebelowcodesnippet: # M e t h o d 1 c l a s s R e s i s t a n t V i r u s ( S i m p l e V i r u s ) : d e f _ _ i n i t _ _ ( s e l f , m a x B i r t h P r o b , c l e a r P r o b , r e s i s t a n c e s , m u t P r o b ) : s e l f . m a x B i r t h P r o b = m a x B i r t h P r o b s e l f . c l e a r P r o b = c l e a r P r o b s e l f . r e s i s t a n c e s = r e s i s t a n c e s s e l f . m u t P r o b = m u t P r o b Alternatively,wecouldmakeuseofinheritanceandcallthesuperclassconstructoronthefirst twoparameterssincethiswouldhavethesameeffect. # M e t h o d 2 c l a s s R e s i s t a n t V i r u s ( S i m p l e V i r u s ) : d e f _ _ i n i t _ _ ( s e l f , m a x B i r t h P r o b , c l e a r P r o b , r e s i s t a n c e s , m u t P r o b ) : # A l w a y s c a l l t h e s u p e r c l a s s c o n s t r u c t o r a s t h e f i r s t l i n e o f # t h e s u b c l a s s c o n s t r u c t o r . S i m p l e V i r u s . _ _ i n i t _ _ ( s e l f , m a x B i r t h P r o b , c l e a r P r o b ) s e l f . r e s i s t a n c e s = r e s i s t a n c e s s e l f . m u t P r o b = m u t P r o b Method2issuperiortoMethod1inthatwepreventourselvesfromrepeatingthecodethat initializesthevariabless e l f . m a x B i r t h P r o b ands e l f . c l e a r P r o b .Whyisthisso important?