Presentation is loading. Please wait.

Presentation is loading. Please wait.

INTRO2CS Tirgul 9 1. What We’ll Be Seeing Today  Introduction to Object-Oriented Programming (OOP).  OOP and python.  Thinking in objects.  Ex 8.

Similar presentations


Presentation on theme: "INTRO2CS Tirgul 9 1. What We’ll Be Seeing Today  Introduction to Object-Oriented Programming (OOP).  OOP and python.  Thinking in objects.  Ex 8."— Presentation transcript:

1 INTRO2CS Tirgul 9 1

2 What We’ll Be Seeing Today  Introduction to Object-Oriented Programming (OOP).  OOP and python.  Thinking in objects.  Ex 8. 2

3 Programming Paradigms Procedural Modules and data structures with procedures/methods that operate on them. Object Oriented Encapsulate our data/state/behavior inside objects, these objects communicate among themselves. Functional Functions, closures, recursions etc. Treats everything as mathematical formulas 3

4 Too Many Options?  Python allows us to utilize every one of the programming paradigms mentioned! This allows the programmer to:  Choose the paradigm that best suits his program.  Mix paradigms together.  Switch between paradigms if needed. 4

5 Remember, Remember  Until now we have mostly seen algorithms and basic python syntax.  OOP on the other hand is a concept!  Meaning it is a way for us to create programs.  We can compare OOP to the architect designing a building: OOP will provide the plan, it’s building blocks will be Python and the algorithms we’ve seen. 5

6 Procedural vs. OOP  Procedural:  Program is a set of data structures, variables and subroutines/procedures.  Procedures operate on these data-structures.  OOP:  Objects hold the data structures.  We can expose their behavior using methods/API.  Objects operate on themselves. 6

7 OOP In Python  In python every thing we’ve seen is actually an object!  A list is an object.  A string is an object.  …  For example calling list() will create an empty list. 7

8 Modeling A Cake  Let’s say you wanted to make a cake - for that you need a recipe!  The recipe will tell you how many eggs, sugar, flour, milk etc. you will need to use.  It will also tell you on how long and on which temperature you need to bake it.  The recipe itself is not the cake! It is just the instructions on how to make one. 8

9 Classes  As in baking a cake, for us to create an object we need some sort of recipe – that is the class.  It tells us what ingredients (variables) we need to create it and what operations (methods) we have that makes it work.  So an object is just a manifestation (instance) of the class! 9

10 Some Syntax  Defining classes is very similar to defining methods with inner methods inside them:  The first parameter should be “self”.  Private variables and methods should start with double underscore (__). class MyClass: def my_method_1(self, …): … def my_method_2(self, …): … 10

11 The “self” Parameter - 1  In python when we call a method of an object, the object itself is passed to the function automatically.  This means that the variable self contains the actual object we are working on.  The only exception is the __init__ method – the constructor, where self is the object being created. 11

12 The “self” Parameter – 2  So why do we need to declare the variable “self” in every function?  Well because explicit is better than implicit (the python Zen).  It has other reasons, you can see some of them here.here  Also, the use of the word “self” is only common practice – you can use anything you’d like. 12

13 The Cake Class class Cake: def __init__(self, sugar = 2, milk = 1, butter = 0.5, flour = 2, eggs = 2): self.__sugar = sugar self.__milk = milk self.__butter = butter self.__flour = flour self.__eggs = eggs  To create a cake we need to specify the ingredients, we do that in our constructor!: Every cake could have different parameters! 13

14 The Cake Class  Now we need to bake the cake, so lets specify how to do that: class Cake: … def degrees_to_time(self, degrees): return degrees * \ (self.__sugar + self.__eggs * self.__milk) / self.__flour def bake(self, degrees): time2bake = self.degrees_to_time(degrees) print(“Baking this cake will take %d minutes” % time2bake) return time2bake 14

15 Application Programming Interface  An “Application Programming Interface” (API) is a way for us to expose the behavior of our objects without the actual way it was implemented.  Consider the list construct: The list object exposes a method called “sort” – does it matter which sort algorithm is used?  Most of the time what interest us is the final result. 15

16 Using The API  What can we do once we have prepared the ingredients for a cake? We need to bake it in the oven!  But is this the only thing we can bake?  We can also bake pies, bread and other sort of pastries.  So the ONLY thing an oven “cares” about is that it can bake what’s inside of it! 16

17 A Simple Oven class Oven: def __init__(self): self.__baked_items = 0 self.__total_time = 0 def start_baking(self, object, degrees): self.__total_time += object.bake(degrees) self.__baked_items += 1 def items_baked(self): return self.__baked_items def total_running_time(self): return self.__total_time 17

18 Using Our Oven my_oven = Oven() # create an oven object cake1 = Cake() # default arguments cake2 = Cake(eggs=4) # only change #eggs my_oven.start_baking(cake1,100) my_oven.start_baking(cake2,200) print(my_oven.items_baked ) print(my_oven.items_baked() ) What’s the difference between these 2? 18

19 Using Our Oven my_oven.start_baking(cake1,100) Baking this cake will take 200 minutes my_oven.start_baking(cake2,200) Baking this cake will take 600 minutes print(my_oven.items_baked ) > print(my_oven.items_baked() ) 2 19

20  What could go wrong with this example:  As a car (most probably) does not have a “bake” method, the 3 rd command will fail! Using Our Oven my_oven = Oven() # create an oven object car = Car() # assuming we have a car object my_oven. start_baking(car, 300) # will this work? 20

21 Sanity Checks  As always, and especially with objects, we want to trust our users as little as possible!  In our Oven case – don’t trust that there is a bake method for the supplied object.  We will show the one classic approach to deal with these situations. 21

22 Sanity Check  We can simply test if the method “bake” exists inside the given object: def start_baking(self, object, degrees): if hasattr(object, ‘bake’): self.__total_time += object.bake(degrees) self.__baked_items += 1 else: print( “cannot bake objects of type %s” % type(object) ) What other assumption is taken here? 22

23 Dynamic Programming Languages  A dynamic programming language is a language in which new code could be generated during runtime.  We can add new methods, variables and we can change the type system.  Javascript, Ruby, Lisp (and more) are such.  Although a very neat concept, you should be VERY careful not to allow malicious code to be inserted into your program during runtime. 23

24  You saw in class the following code:  But what will this line print? Power To The People? class Car: pass my_car = Car() your_car = Car() my_car.fuel = 5 print(my_car.fuel) # 5 print(your_car.fuel) AttributeError: Car instance has no attribute ’fuel' 24

25 Power To The People?  A more severe example would be:  What would happen here? class Car: pass def add_gas(self, fuel): self.fuel += fuel my_car.add_gas = add_gas my_car.add_gas(5) TypeError: add_gas() takes exactly 2 arguments (1 given) 25

26 Power To The People!  To keep our program consistent throughout we need to dynamically add our new properties into the objects class!  This will ensure us that every instance of the class now contains this additional information! Car.fuel = 0 Car.add_gas = add_gas 26

27 Movie Player  We will now consider the parts needed to build a movie player application such as PopcornTime.  It is an application that allows you to stream media from torrents to your computer.  We will try to analyze the parts needed for this system to work, and we will implement some of them – the rest you could implement by the end of the course! 27

28 Why A Movie Player?  Although building a movie player in procedural programming is possible – it would be too hard and not generic enough.  Each part of the player is independent of the other parts – what we care about is only the API they supply us! 28

29 PopcornTime Analysis 29

30 PopcornTime Analysis  What do we need to represent for us to implement this (no user-interface for now)? Movie Title Length Language(s?) Thumbnail Subtitles Qualities Was seen? Rating (from where?) Actors Categories … User Preferences Usage history Favorites Saved for later Login? Communication type … Search Engine By actors By category By year By director … Player Play a movie Continue a paused movie Display subtitles Change subtitles Change audio language Cast to Chromecast? … 30

31 Cakes And Movies  Like our cake example this program will be no different – only more complex.  We will need to create classes to represent a movie (and its properties), movie player, settings class and so on.  This is the idea of OOP, divide our program structure into objects with some sort of relationship between them. 31

32 Building From The Ground Up  There are several ways to write complex software, but they could usually be divided into two categories:  From the ground up – We start with the most basic component (movie) until we reach the upper most level (the display)  From the top down – The reverse order.  There is no “right” way, it is mostly application dependent. 32

33 Our Movie Class  First let’s think about what we are going to do with our movie:  Watch it  Display it’s info  Search for it  … Do we need to keep all of the data? Or just it’s location? Should we ask for this data each time? Or should we cache it? Which pieces of information are we going to search on? 33

34 Designing An API  One of the most common operations we will need from our movie is to query about it’s data – it does not change (for now).  So we will need to have access to:  Actors, year, description etc…  This should be done using “getters” – they get information from the object.  There are also “setters” which set/update new information. 34

35 Our Movie Class class Movie: def __init__(self, ???): ??? def get_actors(self): pass def get_description(self): pass def get_year(self): pass def get_length(self): pass def get_rating(self): pass def get_title(self): pass def get_torrent_link(self): pass def get_available_qualities(self): pass def get_available_subtitles(self): pass 35

36 Our Movie Class  So each of the get_ methods body will probably just be: return self.__  This leaves us with the task of just deigning the __init__ method  We will assume some magic API is given for us to use – by whom was it given? Later on in the course… 36

37 Magic API class MagicAPI: # Returns a list of strings, each string represents a movie in the # following format: # _ _ _ _ def get_all_movies(): … # Returns the rating (float between 0-5) of a given movie def get_rating(movieName): … # Returns a list of strings, each string represents an actor: # _ def get_actors(movieName): … We will assume more magical possible operations as we go 37

38 Our Movie Class  To finish our movie class we will implement the __init__ method and some other methods using our MagicAPI: class Movie: def __init__(self, movieStr): strAsList = movieStr.split(‘_’) self.__title = strAsList[0] self.__year = strAsList[1] self.__description = strAsList[2] self.__thumbnailLnk = strAsList[3] self.__torrentLnk = strAsList[4] def get_actors(self): return MagicAPI.get_actors(self.__title) def get_rating(self): return MagicAPI.get_rating(self.__title) 38

39 Rethinking Our Design  So we can now get a list of actors of a specific movie, but is that enough?  What if we want to search movies by actors?  Right now it would require us to query for the actors of every movie and only return those with specific actors.  What if we want to find movies with several actors? 39

40 An Actor Class class Actor: def __init__(self, name, movies = []): self.__first,self.__last = name.split(‘_’) self.__movies = MySet() # From class for movieName in movies: # List of movie names self.__movies.add_item( movie ) def get_movies(self): return self.__movies def get_name(self): return self.__first+“ ”+self.__last 40

41 An Actor Class class Actor: … def appeared_in(self, movie): return movie in self.__movies def add_movie(self, movie): self.__movies.add_item(movie) 41

42 Our Situation So Far  So we have an Actor and a Movie classes, but what can we do with them?  We need some entity to manage everything for us!  This entity should allow us to search over our movies and actors. Also, it should support adding new movies/actors to it’s existing knowledge base. 42

43 Movie Manager Class class MovieManager: def __init__(self): self.__movies = Map() # A class that maps a key to a value self.__actors = Map() for movieStr in MagicAPI. get_all_movies(): movie = Movie(movieStr) for actorName in movie.get_actors(): if actorName not in self.__actors.keys(): self.__actors.add(actorName, Actor(actorName)) self.__actors.get(actorName).add_movie( movie ) 43

44 Movie Manager Class  Now we can think of many operations we could do with this data, we could:  Query for movies starting with some string. Query for movies by actors.  Find movies where one (or more) actors appear. 44

45 Movie Manager Class class MovieManager: … def find_movies_start_with(self, query): result = [] for movieName in self.__movies.keys(): if movieName.startswith(query): #endswith result.append( self.__movies.get(movieName) ) return result def find_movies_with_actor(self, actor): return self.__actors(actor).get_movies() 45

46 Movie Manager Class class MovieManager: … def find_movies_with_actors(self, actor1, actor2): result = [] for movie in self.__actors.get(actor1).get_movies(): if movie in self.__actors.get(actor2).get_movies(): result.append( movie ) return result def find_movies_with_rating(self, rating): return [movie for movie in self.__movies.values() if movie.get_rating() == rating ] 46

47 Is It Over?  Well no, we are still missing much of the required functionality – but is it that difficult to achieve?  If we continue to assume things about our MagicAPI class (ability to download a torrent) we could build our infrastructure.  And then we are left with the task of implementing our MagicAPI 47

48 Ex8 48

49 Ex8 – Playing With Objects  In this exercise you will need to implement the game of Asteroids using our beloved Turtle module.  Most of the objects are given to you, you are then left with the task of implementing the game loop.  Some bonuses for those who implement new behavior. 49

50 Ex8 – Game Loop  Most of the time games (and programs) are event driven:  Move right/left if a key pressed.  Fire when requested to.  Reduce HP if got shot.  Etc…  We will take a more sequential approach. 50

51 Ex8 – Game Loop  We can think that everything happens in the same time!  All objects (ship, asteroids, torpedoes) move one after the other.  Only then we fire/accelerate (if requested)  More in the exercise.  Note: Try to implement it step by step (as described in the exercise description). 51


Download ppt "INTRO2CS Tirgul 9 1. What We’ll Be Seeing Today  Introduction to Object-Oriented Programming (OOP).  OOP and python.  Thinking in objects.  Ex 8."

Similar presentations


Ads by Google