% class-8 talking points (including notes from cancelled class-7) (go over first two paras quickly or skip - we missed a week) Review quiz_6 Code similar to word histogram 13.3, 149-150, most got it, but some details: 1.for word in histo:... just prints the keys, not the key/value pairs or values 2. histo.keys(), histo.values() both return lists [,,] not tuples (,,) or ,, 3. histo['violet'] raises KeyError, does not return None. Review points from the book: warning ch 15 is *not* typical Python style, ch 17 is typical style you typically *don't* create empty instances, then assign attribs from outside nested objects 15.3, p. 175 sharing and copy, 15.6, 177 "modifiers" (mutators): function can update object passed as arg. 16.3 invariants and assert: 16.5 (lecture really starts here) Classes, objects, object-oriented programming (continue in week 9) Even without these, Python is powerful - often you don't need them. Much more important in Java, C#, ... because they are missing many Python features. In Python there are alternatives so we have to confront a question that Java (etc.) programmers never face: should we use classes/objects here -- or not? Modularity: in Python provided by modules put related variables and functions together, separate namespaces Review import foo, import foo as f, from foo import * Compound data: In Python provided by tuples, lists, dictionaries dictionaries provide named components, show example So what do Python classes/objects add? Classes *define new types* they *extend the language* (do you want/need this?) type: set of values, with operations python provides lots of types already: numbers, lists, dictionaries... Note foo.bar syntax is same for modules, classes, instances all define namespaces Where new data types really help: extend the language: like numpy seamlessly adds array and matrix ... for science! vector.py example - next week 9 Features that really make classes helpful: *inheritance* and *polymorphism* inheritance: define new types from old, only describe the differences eliminates duplicated code polymorphism: same operations (names) do the right thing with different types eliminates if..elif..else branching on data type arise when building many similar components that are not quite the same only gain advantages if you define several/many related classes: design problem examples: GUIs, other system software (collections with for x in s, file-like with open/read/write/close), simulations, GNU Radio, FLiP, ... Another possible advantage: style, psychology: active agents, not passive data Also helps to understand Python *itself*, which is built with classes and objects (more on this in week 9) Classes and objects have lots of complications I'll discuss only typical, recommended practices and style case study: traffic simulation + animation (in 1-d ascii graphics) contrast to traffic.py queue simulation in week 5 vehicle.py: class vehicle only for now class vehicle, derives from/is a subclass of object - no inheritance, really census class variable is shared among all objects methods - self must be first arg of every one to create an instance, call class with function syntax, __init__ is called. __init__ uses special method syntax - means something special to python interpreter: if someone calls the class, create an empty object, then execute this method recall we create attributes by assignment (not declaration as in Java, C#, ...) __init__ puts all those assignments in one place __init__ defines/assigns attributes - typical style. __init__ does not return the new object - in fact it must return None. note use of optional args with defaults using keywords - typical style __str___ defines print representation move - note use of attributes self.x, self.v move - signals arg for passing in environment - what driver might see our windshield move - one time step, we're integrating a de here, simulation integrates system of de's - how about that! Like the guy told he was speaking in prose ... draw - takes the view (into which we draw this object) as a parameter if __name__ == '__main__': ... test code simulator.py: (initally comment out safe_vehicle, pedestrian lines) this pattern is ubiquitious everywhere from scientific simulations to computer games creates, coordinates objects defined in vehicle.py we need all the objects in some collection - so create them with a list comprehension also create stoplight and view simulation outer loop: time steps, inner loop: objects each outer loop clears, populates, draws view inner loop moves, then draws every object demo, notice print statements from if __name__ ... do not appear when we import here explain graphic output, x across page, time down page, high velocity/more slant stoplight at right edge - we're not using it yet but we will we could have programmed the same thing in slightly less space with no class, just fcns Break - quiz, presentations quiz_8.py - class, _init_, and object creation, object nesting, aliasing can add attributes to individual object by assignment outside class defn vehicle.py: class safe_vehicle inherits from vehicle redefines move method to observe/obey signal, everyting else is the same method signature (name and params) is the same but method body is different uncomment line that creates/adds safe_vehicle no changes to main loop, no if ... else ... branch on vehicle type, Python finds method polymorphism - same operation 'move' behaves differently, depending on type demo, show S behavior differs, responds to stoplight this is a real win, couldn't do this as easily without classes/inheritance pedestrian.py: class pedestrian does NOT inherit from vehicle does not have any of the same attributes BUT has same interface (method signatures) so it also can be invoked from simulator in simulator, uncomment pedestrian line, demo this is called "duck typing" - if it quacks like a duck etc, ... typical python style, not even allowed in some languages enables more flexibilty - can add classes ad lib, needn't anticipate in design