1 / 35

Python Classes

Python Classes. Python Classes Require Politeness:. Python does not have the privacy mechanisms of C++ and Java and relies upon the user to not take advantage of this. The class hierarchy allows multiple inheritance derived class methods can override base class methods

Download Presentation

Python Classes

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programming Robot Python Classes

  2. Programming Robot Python Classes Require Politeness: • Python does not have the privacy mechanisms of C++ and Java and relies upon the user to not take advantage of this. • The class hierarchy allows multiple inheritance • derived class methods can override base class methods • derived class methods can invoke methods of the same name in the base class • In C++ jargon, all methods are public and virtual (overridable). • operation overloading is possible

  3. Programming Robot Objects: • Objects have individuality: • Objects can have multiple references and a mutable object, passed as an argument to a method, can be modified inside the method • We only need a single syntax for parameters (unlike Pascal, C, C++). x = 3 y = 3 # both reference the same place in memory

  4. Programming Robot Scopes and Namespaces • A namespace is a mapping of names to objects. • Namespaces are implemented with a Python dictionary but this is not noticeable except for its effect on performance. • Namespace examples: • reserved words and built-in names (like abs()). • global names in a module • local names within a method invocation • Different namespaces can reuse the same name. • If a namespace is associated with a module then import myModule print myModule.myName

  5. Programming Robot Scopes and Namespaces • An attribute is anything that follows a “.”. • Attributes are read-only or writable. • Module attributes are writeable • You can delete a writable attribute • Namespace survival: • the built-in namespace is created as the interpreter loads • a module namespace is created when the module loads • method namespaces survive only while the method executes an attribute just like a data field or method in a class print myModule.myName del myModule.myName

  6. Programming Robot Well-known Namespaces: • __main__: the top-level namespace • __builtin__: - the namespace for built-in names.

  7. Programming Robot Scope: • A scope is a text region where unqualified names can be used from some namespace. • There are three or more namespaces active at any moment: • the inner-most namespace • the calling environment namespaces (at least 1)‏ • the built-in namespace • Names from an outer namespace are read-only unless labeled global. • If you attempt to write to an outer namespace name you will just create a new local name # prints 4 3 a = 3 def foo(): a = 4; print a foo()‏ print a

  8. Programming Robot Local and Global Scopes • Local Scope inside a method references the local names of the method • Outside a function or method, local scope is the module scope. • Class definitions introduce a new scope • The global scope of a function is scope of the module it is defined in; not where it is used. We describe this by saying that scope is defined “textually”. • By default, global scope is not in effect. You must specify it explicitly # prints 4 4 a = 3 def foo(): global a a = 4; print a foo()‏ print a

  9. Programming Robot Classes • Class definitions must be executed before the classes are used. • Entering a class definition creates a new namespace which becomes the local scope and new names are part of this scope. • Exiting a class definition creates a class object (not an instance) which wraps the class namespace and the original scope is reinstated. • Inside the new scope the new class object is bound to the name, MyClass. class MyClass: <statement-1> ... <statement-N> most statements are method definitions

  10. Programming Robot Class Objects: • Support two kinds of operations: • attribute references: Standard notation (MyClass.a). • instantiation: Doesn't use new. class MyClass: """ A simple class example""" a = 4 def f(self): return "Hello, world!" print MyClass.a MyClass.b = 5 myClass = MyClass()‏ print myClass.b print myClass.__doc__ print MyClass.__doc__ a docstring creates a new MyClass attribute; future instantiations will include this attribute __doc__ is a valid attribute of all classes that prints out docstrings. # output 4 5 A simple class example A simple class example

  11. Programming Robot ClassAttributes: • Classes are usually defined with no data attributes but rather just a list of method definitions. • Data attributes are added to the instantiated class objects during instantiation by invoking the method __init__(). class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart x = Complex(3.0, -4.5)‏ print x.r, x.i (3.0, -4.5)‏ define an __init__() method to add data attributes to a class self is the local scope name of the instantiate object.

  12. Programming Robot Data Attributes: • The same as “data members” in C++. • Don't need to be pre-declared before use. • They can spring into existence and disappear just as easily x = AnotherClass()‏ . . . x.counter = 1 while x.counter < 10: x.counter = x.counter * 2 print x.counter del x.counter

  13. Programming Robot Method Attributes: • Just notation but function attributes in a class are called method attributes in an instantiation of the class. • Methods are objects just like other things and so you can create new references to them as you wish x = MyClass()‏ xf = x.f while True: print xf()‏ xf is just another reference to the method f() in the MyClass object called x.

  14. Programming Robot What happens when a method is called? • In the MyClass definition we defined f() with parameter self. • When we call x.f() we don't pass f an argument. • What is happening? • Referencing a method, x.f(), causes a new method object to be created consisting of (pointers to) the function object in the class definition packed together with the instance object. • Calling a method, x.f(), the method object is unpacked and the necessary arguments are passed to it. x.f() is really MyClass.f(x)‏

  15. Programming Robot Random Observations: • There is no shorthand for referencing an instance data attribute inside a method; you must use self.x. • The name, self, is just a convention. • Class methods can actually be defined outside the class: # Function defined outside the class def f1(self, x, y): return min(x, x+y)‏ class C: f = f1 def g(self): return 'hello world' h = g f, g and h are all function objects in the class, C. This example shows what is “possible” but its use would only confuse people.

  16. Programming Robot Inheritence: • What would a class be without inheritance? • Resolving attribute or variable references proceeds from the derived class scope to the base class scope to the module scope. • Method overriding is ok. • All Python methods are virtual in C++ terms. • Calling a base class method of the same name is ok: class DerivedClassName(BaseClassName): <statement-1> . . . <statement-N> BaseClassName(self,arguments)‏

  17. Programming Robot Creating an empty class: Class Employee: pass

  18. Programming Robot Robot class: • Myro allows you to create objects from the robot class: • In your robot object I want you to save two lists: • List of all methods you have written or inherited • List of all methods you will use in a particular program • The first list gives me a way to access all MyScribbler methods by their string name. • The second list tells me the methods used in the current program in the order in which they will appear in the behaviours list. from myro import * class MyScribbler(Scribbler):

  19. Programming Robot MyScribbler.__init__(): def __init__(self,port): Scribbler.__init__(self,port,t=0,r=0)‏ # a dictionary of <str(methodname),methodName> pairs self.masterMethodsList = {'move':Scribbler.move, 'beep':Scribbler.beep, 'motors':Scribbler.motors, 'avoidLight':self.avoidLight, 'nudgeTowardsLight':self.nudgeTowardsLight, 'nudgeAwayFromLight':self.nudgeAwayFromLight, 'obstacleHit':self.obstacleHit, 'obstacleSensed':self.obstacleSensed, 'dflt':self.dflt } # remember, no comma after the # last method name self.programMethodslist = [ ] # a list of method names in use self.T = t self.R = r self.setAmbientLight()‏ self.brightestLight = 50.0 self.debug = False

  20. Programming Robot Printing out Info about Scribbler: • The Scribbler class has a method called __str__() that needs to be overridden. • This method prints out info about the base class and we can extend it to print our info about our class. def __str__(self): retVal = '' retVal += '\nCurrent Program Methods:' for meth in self.programMethodsList: for (methodName,method) in self.masterMethodsList.items(): if method == meth: retVal += '\n %s ' % methodName retVal += '\nTranslate: %f' % self.T retVal += '\nRotate: %f' % self.R retVal += '\nAmbient: %f' % self.ambient retVal += '\nDebug: %r'% self.debug return retVal ‏

  21. Programming Robot Additional Useful Methods (more to come): def getMasterList(self): return self.masterMethodsList def getProgramList(self): return self.programMethodsList def addToProgramList(self,methodName): if methodName in self.masterMethodsList.keys(): self.programMethodslist.append(self.masterMethodsList[methodName])‏ def setAmbientLight(self): self.ambient = sum(getLight('all'))/3.0

  22. Programming Robot Main Methods: def arbitrate(self): for behaviour in self.programMethodsList: if self.debug: print behaviour option,T,R,action = behaviour() if option: return T,R,action def main(self,tr): while(timeRemaining(tr)): T,R,action = self.arbitrate()‏ if self.debug: print T, R, action action(T,R)‏ stop()‏

  23. Programming Robot MyScribbler Behavioural Methods (behaviours): # turns Left if dir == 1; Right if dir == -1 # speed = speed of turn def reactToLight(self,dir,speed): if dir != 1: dir = -1 return True, self.T, (dir*speed),self.move def nudgeTowardsLight(self): (L,C,R) = self.getLight('all')‏ print L,C,R if (L < R - 300): return self.reactToLight(1,0.2)‏ elif (R < L - 300): return self.reactToLight(-1,0.2)‏ else: return False,self.T,self.R,self.move

  24. Programming Robot MyScribbler Behavioural Methods (behaviours): # obstacleHit() really only useful if speed above 0.75 def obstacleHit(self): # obstacle if getStall() returns 1; ob = self.getStall() if ob: return True, 0,-1,self.move else: return False,self.T,self.R,self.move def obstacleSensed(self): L,R = getIR()‏ L = 1 - L R = 1 - R if (L == 1 and R == 1): return True,0, 0.5,self.move elif (L == 1): return True,self.T,-0.5,self.move elif (R == 1): return True,self.T,0.5,self.move else: return False,self.T,self.R,self.move

  25. Programming Robot MyScribbler Behavioural Methods (behaviours): def dflt(self): if self.debug: print 'dflt' return True,self.T,self.R,self.move

  26. Programming Robot How to Use MyScribbler: from myro import * from myRobot import * class Template (MyScribbler): def __init__(self,port,t=0,r=0): MyScribbler.__init__(self,port,t,r)‏ # add additional behaviours here for this program only self.masterMethodsList['myBehaviour'] = self.myBehaviour self.masterMethodsList['dflt'] = self.dflt self.debug = True # turn on debug if wanted def __str__(self): retVal = MyScribbler.__str__(self)‏ return retVal # determines if it is time to charge the cape def myBehaviour(self): # this test behaviour alwasy fails so only dflt is used if self.debug: print 'myBehaviour' return [False,self.T,self.R,self.move] change the name

  27. Programming Robot How to Use MyScribbler: # a normal function def main(): temp = Template('/dev/rfcomm0',0.5,0)‏ temp.addToProgramList('myBehaviour')‏ temp.addToProgramList('dflt')‏ print temp.__str__()‏ MyScribbler.main(temp,2)‏ main()‏

  28. Programming Robot Dictionary: • A dictionary is a set of <key,value> pairs. • You can initialize a dictionary by putting elements in the dictionary as a key:value pair. self.masterMethodsList = {'move':Scribbler.move, 'beep':Scribbler.beep, 'moveForward5':self.moveForward5 }

  29. Programming Robot How To Write Programs: • You first need to think about the behaviours you want to capture. For example, in simulating the bull in a bull ring you need to think about • bull-behaviour (find and charge the red cape) • incidental behaviour (avoiding other obstacles). • Next you have to think about the behaviours in the order in which you should determine their appropriateness. chargeCape(), followLight()‏ obstacleHit(), obstacleSensed(), dflt()‏

  30. Programming Robot How To Write Programs: • Next you have to think about the behaviours in the order in which you should determine their appropriateness. • For example, the bull begins to detect a cape by sensing a light source. As it gets closer to the light source it detects an obstacle. • The program mechanism asks for the first desirable behaviour. • Since the cape is an obstacle together with a light, if we use the behaviours1 list we will never find the cape since we will always see the light first and only perform light-seeking behaviour. behaviours1 = [..., 'followLight', 'chargeCape', ... ] vs behaviours2 = [..., 'chargeCape', 'followLight', ... ]

  31. Programming Robot bull_class.py from myro import * from myRobot import * class Bull (MyScribbler): def __init__(self,port,t=0,r=0): MyScribbler.__init__(self,port,t,r)‏ self.foundObstacle = False self.masterMethodsList['chargeCape'] = self.chargeCape self.masterMethodsList['obstacleHit'] = self.obstacleHit self.masterMethodsList['obstacleSensed'] = self.obstacleSensed self.masterMethodsList['followLight'] = self.followLight self.masterMethodsList['dflt'] = self.dflt self.lightThreshhold = 0.4*self.ambient self.debug = True

  32. Programming Robot bull_class.py def __str__(self): retVal = MyScribbler.__str__(self)‏ retVal += '\nThreshhold: %f' % self.lightThreshhold retVal += '\nDebug: %r' % self.debug return retVal # determines if it is time to charge the cape def chargeCape(self): C = getLight('center')‏ lightAhead = (C < self.lightThreshhold)‏ if self.debug: print 'chargeCape: ', 'center < thresh: %r'% lightAhead if lightAhead: [Option,T,R,action] = MyScribbler.obstacleSensed(self)‏ if Option and T == 0: return [Option,1,0,self.doCharge] return [False,self.T,self.R,self.move]

  33. Programming Robot bull_class.py # no cape, but perhaps an obstacle def obstacleSensed(self): [Option,T,R,action] = MyScribbler.obstacleSensed(self)‏ return [Option,T,R,action] # keep going towards the light def followLight(self): L, C, R = getLight()‏ if L < R-200: # straight but adjust slightly left if self.debug: print 'followLight: left' return [True, self.T,0.2,self.move] elif R < L-200: # straight but adjust slightly right if self.debug: print 'followLight: right' return [True, self.T,-0.2,self.move] else: if self.debug: print 'followLight: no' return [False, self.T, self.R, self.move]

  34. Programming Robot bull_class.py def doCharge(self,t,r): if self.debug: print 'doCharge: ' self.backward(0.5,0.3)‏ self.beep(0.5,800)‏ self.move(t,r) wait(1.5) self.move(0,-0.3)‏ wait(2) def flourish(self): self.motors(1,0.8)‏ wait(1.8)‏ #stop()‏ self.rotate(1)‏ wait(1)‏ #stop()‏ self.rotate(-1)‏ wait(1)‏ self.stop()‏ self.rotate(0.4)‏

  35. Programming Robot bull_class.py def main(): bull = Bull('/dev/rfcomm0',0.6,0)‏ # bull.addToProgramList('chargeCape')‏ # bull.addToProgramList('obstacleHit')‏ # bull.addToProgramList('obstacleSensed')‏ # bull.addToProgramList('followLight')‏ bull.addToProgramList('dflt')‏ print bull.__str__()‏ wait(4)‏ bull.flourish()‏ MyScribbler.main(bull,60)‏ main()‏

More Related