INTRO2CS Tirgul 8 1. What We’ll Be Seeing Today  Introduction to Object-Oriented Programming (OOP).  Using Objects  Special methods 2.

Slides:



Advertisements
Similar presentations
Python Mini-Course University of Oklahoma Department of Psychology Lesson 28 Classes and Methods 6/17/09 Python Mini-Course: Lesson 28 1.
Advertisements

Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
OBJECT ORIENTED PROGRAMMING (OOP) IN PYTHON David Moodie.
CS 106 Introduction to Computer Science I 04 / 11 / 2008 Instructor: Michael Eckmann.
Types in Scripting Languages CS 351 – Programming Paradigms.
1 Programming for Engineers in Python Autumn Lecture 5: Object Oriented Programming.
CS 106 Introduction to Computer Science I 04 / 16 / 2010 Instructor: Michael Eckmann.
Binary Search Trees Section Trees Trees are efficient Many algorithms can be performed on trees in O(log n) time. Searching for elements.
Class 24: Programming with Objects University of Virginia cs1120 David Evans.
Inheritance #1 First questions Similar to Python? What about visibility and encapsulation? – can an object of the child class access private members.
Guide to Programming with Python
REFERENCES: CHAPTER 8 Object-Oriented Programming (OOP) in Python.
Guide to Programming with Python Chapter Eight (Part II) Object encapsulation, privacy, properties; Critter Caretaker game.
1 Python Control of Flow and Defining Classes LING 5200 Computational Corpus Linguistics Martha Palmer.
Centre for Computer Technology ICT115 Object Oriented Design and Programming Week 2 Intro to Classes Richard Salomon and Umesh Patel Centre for Information.
Inheritance. Inhertance Inheritance is used to indicate that one class will get most or all of its features from a parent class. class Dog(Pet): Make.
Chapter 10 Classes. Review of basic OOP concepts  Objects: comprised of associated DATA and ACTIONS (methods) which manipulate that data.  Instance:
CIT 590 Intro to Programming Style Classes. Remember to finish up findAllCISCourses.py.
Inheritance. Recall the plant that we defined earlier… class Plant { public: Plant( double theHeight ) : hasLeaves( true ), height (theHeight) { } Plant(
Chapter 11 Introduction to Classes Intro to Computer Science CS1510, Section 2 Dr. Sarah Diesburg.
CSC1018F: Object Orientation, Exceptions and File Handling Diving into Python Ch. 5&6 Think Like a Comp. Scientist Ch
Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.
1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.
Spring 2008 Mark Fontenot CSE 1341 Principles of Computer Science I Note Set 2.
CSCI-383 Object-Oriented Programming & Design Lecture 13.
Georgia Institute of Technology Creating Classes part 1 Barb Ericson Georgia Institute of Technology Oct 2005.
Best Practices. Contents Bad Practices Good Practices.
Chapter 12 Object Oriented Design.  Complements top-down design  Data-centered view of design  Reliable  Cost-effective.
Guide to Programming with Python Week 11 Chapter Nine Inheritance Working with multiple objects.
Objects & Dynamic Dispatch CSE 413 Autumn Plan We’ve learned a great deal about functional and object-oriented programming Now,  Look at semantics.
Python uses boolean variables to evaluate conditions. The boolean values True and False are returned when an expression is compared or evaluated.
CLASSES Python Workshop. Introduction  Compared with other programming languages, Python’s class mechanism adds classes with a minimum of new syntax.
C++ Classes and Data Structures Jeffrey S. Childs
Overview The Basics – Python classes and objects Procedural vs OO Programming Entity modelling Operations / methods Program flow OOP Concepts and user-defined.
1 Programming for Engineers in Python Autumn Lecture 6: More Object Oriented Programming.
CS0007: Introduction to Computer Programming Classes: Documentation, Method Overloading, Scope, Packages, and “Finding the Classes”
Programming with Java © 2002 The McGraw-Hill Companies, Inc. All rights reserved. 1 McGraw-Hill/Irwin Chapter 5 Creating Classes.
CSC 205 Java Programming II Defining & Implementing Classes.
Object-Oriented Programming Chapter Chapter
Object Oriented Programing (OOP)
Comp1004: Inheritance I Super and Sub-classes. Coming up Inheritance and Code Duplication – Super and sub-classes – Inheritance hierarchies Inheritance.
Guide to Programming with Python Chapter Eight (Part I) Object Oriented Programming; Classes, constructors, attributes, and methods.
INTRO2CS Tirgul 9 1. What We’ll Be Seeing Today  Short recap  Student enrollment system  Popcorn Time  Ex 9 2.
Python – May 19 Review –What is the difference between: list, tuple, set, dictionary? –When is it appropriate to use each? Creating our own data types:
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
Topics Instance variables, set and get methods Encapsulation
Introduction to Classes Intro to Computer Science CS1510, Section 2 Dr. Sarah Diesburg.
OOP Basics Classes & Methods (c) IDMS/SQL News
Today… Modularity, or Writing Functions. Winter 2016CISC101 - Prof. McLeod1.
INTRO2CS Tirgul 9 1. What We’ll Be Seeing Today  Introduction to Object-Oriented Programming (OOP).  OOP and python.  Thinking in objects.  Ex 8.
CONDITIONALS CITS1001. Scope of this lecture if statements switch statements Source ppts: Objects First with Java - A Practical Introduction using BlueJ,
CPS120: Introduction to Computer Science Lecture 16A Object-Oriented Concepts.
CSCI/CMPE 4341 Topic: Programming in Python Chapter 7: Introduction to Object- Oriented Programming in Python – Exercises Xiang Lian The University of.
Object-Oriented Programming (OOP) in Python References: Chapter 8.
ENCAPSULATION. WHY ENCAPSULATE? So far, the objects we have designed have all of their methods and variables visible to any part of the program that has.
EECS 110: Lec 15: Classes and Objects (2)
Object Oriented Programming
Object-Oriented Programming (OOP) in Python
Lecture VI Objects The OOP Concept Defining Classes Methods
To Get Started Paper sheet
Guide to Programming with Python
Introduction to Object-Oriented Programming (OOP) II
Object Oriented Programming in Python
An Introduction to Object Orientated Programming
Comp1202: Inheritance I Super and Sub-classes.
EECS 110: Lec 15: Classes and Objects (2)
Programming For Big Data
Object-Oriented Design AND CLASS PROPERTIES
Introduction to Object-Oriented Programming (OOP) II
CSG2H3 Object Oriented Programming
Presentation transcript:

INTRO2CS Tirgul 8 1

What We’ll Be Seeing Today  Introduction to Object-Oriented Programming (OOP).  Using Objects  Special methods 2

What is OOP?  So far our programs were made of different variables and functions operating on them.  This programming paradigm is called Procedural Programming  Object Oriented Programming is a different programming paradigm!  In OOP, we encapsulate our data inside objects.  Objects operate on/between themselves.  Don’t worry – it will become clearer.. 3

Let’s play an RPG! 4

name = ‘Mark‘ health = 50 magic_points = 80 inventory = {'gold': 40, 'healing potion': 2, ‘sword’: 1} weapon = ‘sword’ location = [4, 6] inspired by: We have a hero!

We add a goblin.. 6

7 We’ll have to change the variables accordingly: hero_name = ‘Mark‘ hero_health = 50 hero_magic_points = 80 hero_inventory = {'gold': 40, 'healing potion': 2, ‘sword’: 1} hero_weapon = ‘sword’ hero_location = [4, 6] monster_name = ‘Goblin‘ monster_health = 20 monster_magic_points = 0 monster_inventory = {'gold': 12, ‘dagger’: 1} moster_weapon = ‘dagger’ monster_location = [2, 3]

We want more monsters! 8

What now? 9  monster1_name, monster2_name… - Bad coding!  Instead, Maybe: monster_names = ['Goblin', 'Dragon', 'Goblin'] monster_healths = [20, 300, 18] monster_magic_points = [0, 200, 0] monster_inventories = [{'gold': 12, 'dagger': 1}, {'gold': 890, 'magic amulet': 1}, {'gold': 15, 'dagger': 1}] moster_weapons= [‘dagger’, ‘fire’, ‘dagger’] monster_locations = [[2, 3], [1, 5], [4, 2]]  Gets confusing..  A single creature is “spread” over many lists

What now? 10  How about: monsters = [{'name': 'Goblin', 'health': 20, 'magic points': 0, 'inventory': {'gold': 12, 'dagger': 1}, ‘weapon’: ‘dagger’, ‘location’: [2, 3]}, {'name': ‘Dragon', 'health': 300, 'magic points': 200, 'inventory': {'gold': 890, ‘magic_amulet': 1}, ‘weapon’: ‘fire’, ‘location’: [1, 5]}, {'name': 'Goblin', 'health': 18, 'magic points': 0, 'inventory': {'gold': 15, 'dagger': 1}, ‘weapon’: ‘dagger’, ‘location’: [4, 2]}]  But the inventory of a monster is a dictionary-in-a- dictionary-in-a-list!!  Using OOP this is becomes simple!

The OOP Way - Classes 11  Define a Class for similar objects  The hero and monsters are all living things: class LivingThing(): pass hero = LivingThing() Creates an object of the class hero.name = ‘Mark‘Set Member Variables for the object hero.health = 50Access Members by ‘.’ hero.magic_points = 80 hero.inventory = {'gold': 40, 'healing potion': 2, ‘sword’: 1} hero.weapon = ‘sword’ hero.location = [4, 6] …

Classes (cont.) 12 … monsters = [] temp_monster = LivingThing() Creates a new object of the class temp_monster.name = ‘Goblin‘ temp_monster.health = 20 temp_monster.magic_points = 0 temp_monster.inventory = {'gold': 12, ‘dagger': 1} temp_monster.weapon = ‘dagger’ temp_monster.location = [2, 3] monsters.append(temp_monster) temp_monster = LivingThing() Creates a new object of the class temp_monster.name = ‘Dragon‘ temp_monster.health = 300 temp_monster.magic_points = 200 temp_monster.inventory = {'gold': 890, ‘magic amulet': 1} temp_monster.weapon = ‘fire’ temp_monster.location = [1, 5] monsters.append(temp_monster) …

Classes (cont.) 13  Seems a bit inefficient - All LivingThing are similar!  We can define functions for all objects of the same class: class LivingThing(): def set_attributes(self, name, health, magic_points, inventory, weapon, location): self.name = name self.health = health self.magic_points = magic_points self.inventory = inventory self.weapon = weapon self.location = location hero = LivingThing() hero.set_attributes(‘Mark‘, 50, 80, {'gold': 40, 'healing potion': 2, ‘sword’: 1}, ‘sword’, [4, 6]) monsters = [] temp_monster = LivingThing() temp_monster.set_attributes(‘Goblin‘, 20, 0, {'gold': 12, ‘dagger’: 1}, ‘dagger’, [2, 3]) monster.append(temp_monster) temp_monster = LivingThing() temp_monster.set_attributes(‘Dragon‘, 300, 200, {'gold': 890, ‘magic amulet’: 1}, ‘fire’, [1, 5]) …

The special word ‘self’ 14  A Class is not an Object!  Objects are instances of a class  A class “function” is called a method  Methods are called by specific Objects  The first parameter all Methods get is ‘self’  ‘self’ is the specific object that called the method!

The special method __init__(): 15  A special method that is called after we create a new object: class LivingThing(): def __init__ (self, name, health, magic_points, inventory, weapon, location, armor=None): self.name = name self.health = health self.magic_points = magic_points self.inventory = inventory self.weapon = weapon self.location = location self.armor = armor hero = LivingThing(Mark‘, 50, 80, {'gold': 40, 'healing potion': 2, ‘sword’: 1}, ‘sword’, [4, 6]) monsters = [] temp_monster = LivingThing(‘Goblin‘, 20, 0, {'gold': 12, ‘dagger’: 1}, ‘dagger’, [2, 3]) monster.append(temp_monster) temp_monster = LivingThing(‘Dragon‘, 300, 200, {'gold': 890, ‘magic amulet’: 1}, ‘fire’, [1, 5])

The special method __init__(): 16  Called a “constructor”  If no explicit constructor is defined - default empty constructor  All instances will have the members defined in the constructor  The constructor is always called __init__ !

What else can we do? 17  Assume our hero takes damage: hero.health -= 10 if hero.health < 0: print(hero.name + ' has died!')  Can lead to code duplication..  The non-OOP solution – use a function: def take_damage(living_object, damage): living_object.health -= damage if living_object.health < 0: print(living_object.name + ' has died!')  Much better!  Still, difficult to maintain. Can have thousands of functions!

Using methods: 18  The OOP way: use a Method! class LivingThing(): #…other code in the class… def take_damage(self, damage): self.health -= damage if self.health <= 0: print(self.name + ‘ is dead!’) #...other code in the class… hero = LivingThing(Mark‘, 50, 80, {'gold': 40, 'healing potion': 2, ‘sword’: 1}, ‘sword’, [4, 6]) hero.take_damage(10)

Let’s try moving.. 19 class LivingThing(): #…other code in the class… def move(self, direction): if direction == UP: self.location[0] -= 1 elif direction == DOWN: self.location[0] += 1 elif direction == LEFT: self.location[1] -= 1 elif direction == RIGHT: self.location[1] += 1 #...other code in the class…

Let’s try moving.. (cont.) 20  But what about avoiding collisions? class LivingThing(): UP, DOWN, LEFT, RIGHT = range(4) #…other code in the class… def move(self, direction, monsters): new_location = self.location[:] if direction == self.UP: new_location[0] -= 1 elif direction == self.DOWN: new_location [0] += 1 elif direction == self.LEFT: new_location [1] -= 1 elif direction == self.RIGHT: new_location [1] += 1 for monster in monsters: if monster.location == new_location: return self.location = new_location #...other code in the class…

Let’s try moving.. (cont.) 21  Do we only care about collisions?  Let’s define another class: class GameBoard(): def __init__(self, height, width): self.height = height self.width = width self.monsters = [] self.hero = None self.trees = [] self.game_over = False …

Let’s try moving.. (cont.) 22 … def is_free(self, location): if not 0 <= location[0] < self.height or not 0 <= location[1] < self.width: return False for monster in self.monsters: if location == monster.location: return False for tree in self.trees: if location == tree: return False if location == self.hero.location: return False return True …

Let’s try moving.. (cont.) 23 … def put_tree(self, location): if self.is_free(location): self.trees.append(location) return True return False def put_monster(self, monster): if self.is_free(monster.location): self.monsters.append(monster) return True return False def put_hero(self, hero): if self.is_free(hero.location): self.hero = hero return True return False

Let’s try moving.. (cont.) 24 class LivingThing(): #…other code in the class… def move(self, direction, board): new_location = self.location[:] if direction == UP: new_location[0] -= 1 elif direction == DOWN: new_location [0] += 1 elif direction == LEFT: new_location [1] -= 1 elif direction == RIGHT: new_location [1] += 1 if board.is_free(new_location): self.location = new_location return True else: return False #…other code in the class…

Let’s try moving.. (cont.) 25  Do we have to pass ‘board’ each time?  Instead, save as a member! class LivingThing(): def __init__ (self, name, health, magic_points, inventory, weapon, location, board): self.name = name self.health = health self.magic_points = magic_points self.inventory = inventory self.weapon = weapon self.location = location self.board = board …

Let’s try moving.. (cont.) 26 … def move(self, direction): new_location = self.location[:] if direction == UP: new_location[0] -= 1 elif direction == DOWN: new_location [0] += 1 elif direction == LEFT: new_location [1] -= 1 elif direction == RIGHT: new_location [1] += 1 if self.board.is_free(new_location): self.location = new_location return True else: return False #…other code in the class…

Are we safe? 27  What if we change location directly?  In Python, every method and member can be accessed directly!  We use a naming convention to declare “private” members/methods: self._location def _get_item(): self._monsters self._width  Private members/methods should only be used by their parent object!  Part of a bigger concept - Encapsulation

Encapsulation 28  A driver doesn’t need to know what’s inside his car!  Easier to code  Specific implementation doesn’t matter  Prevents bugs (like changing “location”)  If direct access is need:  Getters – return an inner value def get_location(): return self.location  Setters – set an inner value def set_location(location): self.location = location  Still implementation invariant!

Application Programming Interface 29  The API defines the functionality an object allows  Explains how to interact with an instance  “Design by Contract”  Not committed to internal implementation!

Everything in Python is an Object! 30 a = [] a.append(4) ‘ ‘.join(a) b = 5 dir(b)

__str__(self) 31  returns a String to be printed  print(obj)  print(obj.__str__())  print(str(obj)) class LivingThing(): PRINTABLE = {‘goblin’: ‘G’, ‘dragon’: ‘D’} #Better ways to do this – in the future! #…other code in the class… def __str__(self): if self.name in self.PRINTABLE: return self.PRINTABLE[self.name] else: return ‘H’ #…other code in the class…

__str__(self) (cont.) 32 class GameBoard(): #…other code in the class… def __str__(self): board_lists = [[' '] * self.width for rows in range(self.height)] for tree_row, tree_column in self.trees: board_lists[tree_row][tree_column] = ‘*’ for monster in self.monsters: monster_row, monster_column = monster.get_location() board_lists[monster_row][monster_column] = str(monster) hero_row, hero_column = self.hero.get_location() board_lists[hero_row][hero_column] = str(self.hero) board_strings = [‘#’ * (self.width + 1)] for row in board_lists: board_strings.append(‘’.join(row)) board_strings.append(‘#’ * (self.width + 1)) return ‘#\n#’.join(board_strings) #…other code in the class…

__repr__(self) 33  returns a String to represent the object  calling the obj in interpreter  print(obj.__repr__()) class LivingThing(): #…other code in the class… def __repr__(self): return ‘A LivingThing in Location: ’ + str(self.location) + ‘ By the name: ‘ + self.name #…other code in the class…

__contains__(self, element) 34  Checks if an element is in our object.  element in obj  obj.__contains__(element) class GameBoard(): #…other code in the class… def __contains__(self, living_thing): return living_thing in self.heroes or living_thing in self.monsters #…other code in the class…

Other special operators 35 +object.__add__(self, other) -object.__sub__(self, other) *object.__mul__(self, other) //object.__floordiv__(self, other) /object.__div__(self, other) %object.__mod__(self, other) **object.__pow__(self, other[, modulo]) <<object.__lshift__(self, other) >>object.__rshift__(self, other) &object.__and__(self, other) ^object.__xor__(self, other) |object.__or__(self, other) <object.__lt__(self, other) <=object.__le__(self, other) ==object.__eq__(self, other) !=object.__ne__(self, other) >=object.__ge__(self, other) >object.__gt__(self, other)

What else can we do? 36 class Weapon(): def __init__(self, name, damage): self.name = name self.damage = damage def get_damage(self): return self.damage def __str__(self): return self.name

What else can we do? 37 class Armor(): def __init__(self, name, protection): self.name = name self.protection = protection def get_protection(self): return self.protection def __str__(self): return self.name

What else can we do? 38 class GameBoard(): #…other code in the class… def reset(self): self.__init__(self.height, self.width) self.put_tree((1,1)) self.put_tree((1,2)) self.put_tree((1,3)) self.put_tree((2,3)) weapon = Weapon(‘sword’, 6) armor = Armor(‘wooden shield’, 1) hero = LivingThing(’Mark‘, 50, 80, {'gold': 40, ‘potion': 2, ‘sword’:1}, weapon, [4, 6], armor) self.put_hero(hero) weapon = Weapon(‘dagger’, 2) monster = LivingThing(‘Goblin‘, 20, 0, {'gold': 12, ‘dagger’: 1}, weapon, [3, 3]) self.put_monster(monster)...

What else can we do? 39 … weapon = Weapon(‘fire’, 30) monster = LivingThing(‘Dragon‘, 300, 200, {'gold': 890, ‘amulet’: 1}, weapon, [1, 5]) self.put_monster(monster) weapon = Weapon(‘dagger’, 2) monster = LivingThing(‘Goblin‘, 18, 0, {'gold': 15, ‘dagger’: 1}, weapon, [4, 2]) self.put_monster(monster) #…other code in the class…

What else can we do? 40 class LivingThing(): #…other code in the class… def attack(self, enemy): if not enemy.take_damage(self.weapon.get_damage()): self.inventory[gold] += enemy.get_inventory[gold] return false return true def take_damage(self, damage): damage_adjustment = 0 if self.armor: damage_adgustment += self.armor.get_protection() self.health -= max((damage – damage_adjustment), 0) if self.healf > 0: return true return false …

What else can we do? 41 … def random_move(self): choice = randint(0,10) if choice in range(4): self.move(choice) else: #attack everybody around us self.board.attack_neighbors(self) #we leave implementing this #to GameBoard! #…other code in the class…

What else can we do? 42 class GameBoard(): def play_turn(self, action): if action in self.hero.UP, self.hero.DOWN, self.hero.LEFT, self.hero.RIGHT: self.hero.move(action) elif action == self.hero.ATTACK: self.attack_neighbors(self.hero) for monster in self.monsters: monster.random_move() return not self.game_over def attack_neighbors(self, attcker): for neighbor in attacker.get_neighbors(): #left to be implemented in #LivingThing! killed = attacker.attack(neighbor) if killed: self._kill(neighbor) #no problem calling private …#method by self!

What else can we do? 43 … def _kill(self, living_thing): if living_thing is self.hero: self.game_over = True return True if living_thing in self.monsters: self.monsters.remove(living_thing) return True return False #...other code in class

What else do we need? 44 class LivingThis(): #...other code in class def get_neighbors(self): neightbors = [] if self is not self.board.get_hero() and self.near(self.board.get_hero()): neighbors.append(self.board.get_hero()) for monster in self.board.get_monsters(): if self is not monster and self.near(monster): neighbors.append(monster) return neighbors def near(self, living_thing): self_row, self_column = self.location other_row, other_column = living_thing.get_location return abs(self_row-other_row) < 2 and abs(self_column-other_column) < 2 #...other code in class

What else do we need? 45 from os import system class GameRunner(): def __init__(self): self.board = GameBoard() self.board.reset() …

What else do we need? 46 … def run(self): while True: system(‘cls’) print(self.board) action = self.get_action_from_usr() if action == ABORT_GAME: break alive = self.board.play_turn(action) if not alive: play_again = input(GAME_OVER_MSG) if play_again == PLAY_AGAIN: self.board.reset() else: break