Está en la página 1de 8

TableofContents:

1.Checkingbooleanconditionswithif/else 2.Changingcollectionswhileiteratingoverthem 3.WhichdatastructureshouldIuse? 4.Docstrings 5.DirectlyAccessingInstanceVariables 6.Pitfallsofstoringcustomobjectsindatastructures 7.Callingasuperclassconstructorfromasubclass

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

startsas: 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 F a l s e e l s e : r e t u r n T r u e Wecanusen o t towritethisas: r e t u r n n o t 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

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!

Toworkaroundthiskindofissue,youcanloopoveracopyofthelist.Forinstance,inthe followingcodesnippets,wewishtoretainalltheelementsofthelistthemeetsomecondition. e l e m s _ c o p y = e l e m s [ : ] f o r i t e m i n e l e m s _ c o p y : i f n o t c o n d i t i o n : e l e m s . r e m o v e ( i t e m ) e l e m s willcontainthedesireditems. Alternatively,youcancreateanewlist,andappendtoit: e l e m s _ c o p y = [ ] f o r i t e m i n e l e m s : i f c o n d i t i o n : e l e m s _ c o p y . a p p e n d ( o b j e c t ) e l e m s _ c o p y willnowcontainthedesireditems. Notethatthesameruleappliestothesetanddicttypeshowever,mutatingasetordictionary whileiteratingoveritwillactuallyraiseaRuntimeErrorinthisway,Pythonexplicitlyprevents this.

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}.

Updatingthecleanlinessstatusofatilewouldbeaconstanttimeoperation(O(1)),andforevery tile,wearestoringitscoordinatesandcleanlinessstatusinthesamedictionaryentry,whichis clearerthantheotherrepresentations. Takeaway Inthiscourse,wearetryingtoteachyoutousethedatastructuremostappropriateforthe problemathand.Forfutureproblems,thinkabouthowbesttostoreyourdatabeforejustpicking thedatastructurethatyouhappentobemostfamiliarwith.:)

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

s e l f . t ,ors e l f . m y _ s t o r y _ t i t l e ,ormaybethe1stelementofthelist s e l f . s t o r y _ a t t r i b u t e s ,oranythingelse.Infact,theonlypromisemadeabout N e w s S t o r y isthatthereisaconstructorthattakesinsomeelementsofastory(guid,title,etc.), andthereisagettermethodforeachoftheseproperties. So,thesaferwaytodothis?Usegettermethods! t i t l e = s t o r y . g e t _ t i t l e ( ) # m u c h b e t t e r !

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?

Sayforsomereason,whileimplementingMethod1,wedecidedtocallthemaximumbirth probabilityintheResistantVirusclasss e l f . m a x i m u m B i r t h P r o b insteadof s e l f . m a x B i r t h P r o b .InPython,thesuperclassconstructorisnotautomaticallycalledwhen constructingasubclassinstance.Now,inallofthesuperclassmethodsthatreference s e l f . m a x B i r t h P r o b ,wewillgetanerrorbecauseitonlyexistsas s e l f . m a x i m u m B i r t h P r o b . AnotherreasontouseMethod2isthatthesuperclassconstructormaydosomeother,more complicatedinitializationandwewanttoensurethatitisexecuted.

También podría gustarte