Transcript Lecture9
CIT 590 Intro to Programming Style Classes Remember to finish up findAllCISCourses.py Elements of style • Do not make an extremely long function. Break it up in some manner • Generally in this course the long function will be your main method • Remember coke-machine.py • Is there repeated code – just make a function out of it • Do not write an incredibly long single line of code • In Python you can break a line up by using parantheses for instance • docStrings! – write a docString for every function. Triply quoted string telling the user what the function does Elements of style • Break the program into small portions and write the smallest portion first • Your functions need to be reusable • Take pride in your functions. • Make your worst enemy want to use them • General purpose • Try and make them robust to bad inputs • Write the smallest function first = write unit tests for the smallest function first • The main function should be the last thing you complete Elements of testing • Write more than 1 test case for each function • Check the test files that we used for your homeworks • Your tests and meant to find bugs so you do not want to be gentle! • Adding tests is easy. Do not be hesitant about adding more. • See movieTests.py in the repo • All unit tests being used for evaluation can be found in the files section of canvas (we will organize it better) Design Buzzwords • Don’t Repeat Yourself • As a software developer your goal always always is to • • • • avoid copy pasting code. The opposite of DRY is …. WET – Write Everything Twice Keep It Simple Stupid (KISS) You Ain’t Gonna Need It (YAGNI) • Reduce the number of components if you feel you are implementing functionality that you were not asked for • 80-20 rule gets applied a lot in the industry Classes • Encapsulate functions that can be used for a common purpose • bankAccount.py • Classes implicitly apply the principles of abstraction and information hiding • The user of the bank account class does not need to know how balance is being maintained • Just get a handle to the class and use the deposit and withdrawal functions Class definition class BankAccount(object): Parent class def __init__ (self, initBalance): self.balance = initBalance def deposit(self, amount): self.balance += amount methods Creating an instance of the class • The class definition by itself does not create an instance of the class • myFirstAccount = BankAccount() • For those of you with some java background, there is no ‘new’ • An instance of a class is called an object Methods • A class method looks very very much like a regular function • The first argument HAS to be ‘self’ • Calling methods within other methods • We have to always refer to which object we are calling the method on def transfer (self, amount, toAccount): self.withdraw(amount) toAccount.deposit(amount) Constructors • The __init__ is implicitly called when you say B = BankAccount() • First time we are seeing the __<function name>__ convention • Python uses this when we have functions that are used behind the scenes Objects are references => be careful • Very similar to the situation of two lists • The copy module is your best friend • import copy • bankAccount2 = copy.copy(bankAccount1) • Passing an object as a function parameter • Again similar to lists, the object will be modified • Sometimes you want the modification • Sometimes you want to copy How to print out an object • __str__ When you call print <objectname> this internal function will be called. Python will always provide some kind of default However the default is ‘lame’ Try commenting out the __str__ in the bankAccount object Accessing the data fields • Python classes expose their data fields. • For the bankaccount example you could always manipulate the balance data field directly BUT this is considered bad programming practice • It is considered much better form to provide what is called a getter and a setter • In this bank account example, a getter for balance is fully justified since that is a service you would want • However a direct setting of bank balance = xyz seems inappropriate. • We have deposit and withdraw • More on this when we get to Java Inheritance • You’ve already seen it without it being explicitly called as such • Idea = Using methods defined on the parent class • Software reuse • By inheriting from a class you only need to define the specialized methods • Often you might be inheriting from a different developer’s class • Checking account example class CheckingAccount(bankAccount.BankAccount) • Checking account inherits from bankaccount • Checking account is a special type of bankaccount • When should I use inheritance • Apply the ‘is-a’ method • A real number is a complex number • A checking account is a bank account Question on classes Using one class inside another class A bank contains a lot of bankAccounts. bank = Bank() What do we get when we do print Bank() a) The account is owned by CEO balance is 100 b) The account is owned by CEO balance is 0 c) The account is owned by Arvind balance is 100 d) The account is owned by Arvind balance is 0 e) I am confused Inbuilt functions to help explore inheritance • Use isinstance • Issubclass • Using the types module (import types) • You can check for an int by doing • Isinstance(3, types.IntType) The is-a versus has-a concept • A common method used to identify inheritance is to ask the question ‘Is class B a special case of class A?’ If the answer is yes, B extends A. • If the answer is no, then you might want one class contained inside the other – composition • A Bank contains BankAccounts - composition • A CheckingAccount is a BankAccount - inheritance