woneuy01 / python2

0 stars 0 forks source link

Class #10

Open woneuy01 opened 4 years ago

woneuy01 commented 4 years ago

Every class should have a method with the special name init. This initializer method, often referred to as the constructor, is automatically called whenever a new instance of Point is created. It gives the programmer the opportunity to set up the attributes required within the new instance by giving them their initial state values. The self parameter (you could choose any other name, but nobody ever does!) is automatically set to reference the newly created object that needs to be initialized.

class 빵가게의 빵을 만드는 틀과 같다. class 이름의 첫글자는 대문자

woneuy01 commented 4 years ago

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self):

    self.x = 0
    self.y = 0

p = Point() # Instantiate an object of type Point q = Point() # and make a second point

print("Nothing seems to have happened with the points")

woneuy01 commented 4 years ago

You can see that the output suggests that each one is a Point object. However, notice that the is operator returns False meaning that they are different objects (we will have more to say about this in a later section).

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self):

    self.x = 0
    self.y = 0

p = Point() # Instantiate an object of type Point q = Point() # and make a second point

print(p) print(q)

print(p is q)


<__main__.Point object> <__main__.Point object> False
woneuy01 commented 4 years ago

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

p = Point(7,6)


When the point is created, the values of initX and initY are assigned to the state of the object, in the instance variables x and y.

woneuy01 commented 4 years ago

Create a class called NumberSet that accepts 2 integers as input, and defines two instance variables: num1 and num2, which hold each of the input integers. Then, create an instance of NumberSet where its num1 is 6 and its num2 is 10. Save this instance to a variable t.

class NumberSet: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, x, y):

    self.num1 = x
    self.num2 = y

t = NumberSet(6,10)

woneuy01 commented 4 years ago

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def getX(self):   //adding other method to the class           def __ init__이외에는 불러야 나온다
    return self.x

def getY(self):   //adding other method to the class
    return self.y

p = Point(7,6) print(p.getX()) print(p.getY())


7 6

woneuy01 commented 4 years ago

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def getX(self):
    return self.x

def getY(self):
    return self.y

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

p = Point(7,6) print(p.distanceFromOrigin())


9.21954445729 Notice that the call of distanceFromOrigin does not explicitly supply an argument to match the self parameter. This is true of all method calls. The definition will always seem to have one additional parameter as compared to the invocation.

woneuy01 commented 4 years ago

Create a class called Animal that accepts two numbers as inputs and assigns them respectively to two instance variables: arms and legs. Create an instance method called limbs that, when called, returns the total number of limbs the animal has. To the variable name spider, assign an instance of Animal that has 4 arms and 4 legs. Call the limbs method on the spider instance and save the result to the variable name spidlimbs.

class Animal: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.arms = initX
    self.legs = initY

def limbs(self):
    return self.arms+self.legs

spider = Animal(4,4) spidlimbs=spider.limbs() print(spidlimbs)


8

woneuy01 commented 4 years ago

Here is a simple function called distance involving our new Point objects. The job of this function is to figure out the distance between two points.

import math

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def getX(self):
    return self.x

def getY(self):
    return self.y

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

def distance(point1, point2): xdiff = point2.getX()-point1.getX() ydiff = point2.getY()-point1.getY()

dist = math.sqrt(xdiff**2 + ydiff**2)
return dist

p = Point(4,3) q = Point(0,0) print(distance(p,q))


5.0

woneuy01 commented 4 years ago

We could have made distance be a method of the Point class. Then, we would have called the first parameter self, and would have invoked it using the dot notation, as in the following code

import math

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def getX(self):
    return self.x

def getY(self):
    return self.y

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

def distance(self, point2):
    xdiff = point2.getX()-self.getX()
    ydiff = point2.getY()-self.getY()

    dist = math.sqrt(xdiff**2 + ydiff**2)
    return dist

p = Point(4,3) q = Point(0,0) print(p.distance(q))


5.0

woneuy01 commented 4 years ago

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def getX(self):
    return self.x

def getY(self):
    return self.y

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

p = Point(7,6) print(p)


<__main__.Point object>
woneuy01 commented 4 years ago

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def getX(self):
    return self.x

def getY(self):
    return self.y

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

def __str__(self): //__str__ returning a string representation as defined by the class creator
    return "x = {}, y = {}".format(self.x, self.y)

p = Point(7,6) print(p)


x = 7, y = 6

woneuy01 commented 4 years ago

class Cereal: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, name, brand,fiber):

    self.name = name
    self.brand = brand
    self.fiber = fiber

def __str__(self):
    return "{} cereal is produced by {} and has {} grams of fiber in every serving!".format(self.name, self.brand, self.fiber)

c1 = Cereal("Corn Flakes","Kellogg's",2) c2 = Cereal("Honey Nut Cheerios","General Mills",3)

print(c1) print(c2)


Corn Flakes cereal is produced by Kellogg's and has 2 grams of fiber in every serving! Honey Nut Cheerios cereal is produced by General Mills and has 3 grams of fiber in every serving!

woneuy01 commented 4 years ago

class Point:

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def getX(self):
    return self.x

def getY(self):
    return self.y

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

def __str__(self):
    return "x = {}, y = {}".format(self.x, self.y)

def halfway(self, target):
    mx = (self.x + target.x)/2
    my = (self.y + target.y)/2
    return Point(mx, my)

p = Point(3,4) q = Point(5,12) mid = p.halfway(q)

note that you would have exactly the same result if you instead wrote

mid = q.halfway(p)

because they are both Point objects, and the middle is the same no matter what

print(mid) print(mid.getX()) print(mid.getY())


x = 4.0, y = 8.0 4.0 8.0

woneuy01 commented 4 years ago

L = ["Cherry", "Apple", "Blueberry"]

print(sorted(L, key=len))

alternative form using lambda, if you find that easier to understand

print(sorted(L, key= lambda x: len(x)))


['Apple', 'Cherry', 'Blueberry'] ['Apple', 'Cherry', 'Blueberry']

woneuy01 commented 4 years ago

class Fruit(): def init(self, name, price): self.name = name self.price = price

L = [Fruit("Cherry", 10), Fruit("Apple", 5), Fruit("Blueberry", 20)] for f in sorted(L, key=lambda x: x.price): print(f.name, f.price)


Apple 5 Cherry 10 Blueberry 20

woneuy01 commented 4 years ago

class Fruit(): def init(self, name, price): self.name = name self.price = price

def sort_priority(self):
    return self.price

L = [Fruit("Cherry", 10), Fruit("Apple", 5), Fruit("Blueberry", 20)] print("-----sorted by price, referencing a class method-----") for f in sorted(L, key=Fruit.sort_priority): print(f.name)

print("---- one more way to do the same thing-----") for f in sorted(L, key=lambda x: x.sort_priority()): print(f.name)


-----sorted by price, referencing a class method----- Apple Cherry Blueberry ---- one more way to do the same thing----- Apple Cherry Blueberry

woneuy01 commented 4 years ago

class Point: """ Point class for representing and manipulating x,y coordinates. """

printed_rep = "*"

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def graph(self):
    rows = []
    size = max(int(self.x), int(self.y)) + 2
    for j in range(size-1) :
        if (j+1) == int(self.y):
            special_row = str((j+1) % 10) + (" "*(int(self.x) -1)) + self.printed_rep
            rows.append(special_row)
        else:
            rows.append(str((j+1) % 10))
    rows.reverse()  # put higher values of y first
    x_axis = ""
    for i in range(size):
        x_axis += str(i % 10)
    rows.append(x_axis)

    return "\n".join(rows)

p1 = Point(2, 3) p2 = Point(3, 12) print(p1.graph()) //p1에 graph가 없으면 object 로 가서 찾는다. //If it doesn’t find an instance variable, it checks whether the class has a class variable. If so it uses that value. print() print(p2.graph())


4 3 * 2 1 01234

3 2 * 1 0 9 8 7 6 5 4 3 2 1 01234567890123

woneuy01 commented 4 years ago

from random import randrange

Here's the original Pet class

class Pet(): boredom_decrement = 4 hunger_decrement = 6 boredom_threshold = 5 hunger_threshold = 10 sounds = ['Mrrp'] def init(self, name = "Kitty"): self.name = name self.hunger = randrange(self.hunger_threshold) self.boredom = randrange(self.boredom_threshold) self.sounds = self.sounds[:] # copy the class attribute, so that when we make changes to it, we won't affect the other Pets in the class

def clock_tick(self):
    self.boredom += 1
    self.hunger += 1

def mood(self):
    if self.hunger <= self.hunger_threshold and self.boredom <= self.boredom_threshold:
        return "happy"
    elif self.hunger > self.hunger_threshold:
        return "hungry"
    else:
        return "bored"

def __str__(self):
    state = "     I'm " + self.name + ". "
    state += " I feel " + self.mood() + ". "
    # state += "Hunger %d Boredom %d Words %s" % (self.hunger, self.boredom, self.sounds)
    return state

def hi(self):
    print(self.sounds[randrange(len(self.sounds))])
    self.reduce_boredom()

def teach(self, word):
    self.sounds.append(word)
    self.reduce_boredom()

def feed(self):
    self.reduce_hunger()

def reduce_hunger(self):
    self.hunger = max(0, self.hunger - self.hunger_decrement)

def reduce_boredom(self):
    self.boredom = max(0, self.boredom - self.boredom_decrement)

Here's the new definition of class Cat, a subclass of Pet.

class Cat(Pet): # the class name that the new class inherits from goes in the parentheses, like so. sounds = ['Meow']

def chasing_rats(self):
    return "What are you doing, Pinky? Taking over the world?!"

p1 = Pet("Fido") print(p1) # we've seen this stuff before!

p1.feed() p1.hi() print(p1)

cat1 = Cat("Fluffy") print(cat1) # this uses the same str method as the Pets do

cat1.feed() # Totally fine, because the cat class inherits from the Pet class! cat1.hi() print(cat1)

print(cat1.chasing_rats())

print(p1.chasing_rats()) # This line will give us an error. The Pet class doesn't have this method!


 I'm Fido.  I feel happy. 

Mrrp I'm Fido. I feel happy. I'm Fluffy. I feel happy. Meow I'm Fluffy. I feel happy. What are you doing, Pinky? Taking over the world?!

woneuy01 commented 4 years ago

class inheritance

class Cheshire(Cat): # this inherits from Cat, which inherits from Pet

def smile(self): # this method is specific to instances of Cheshire
    print(":D :D :D")

Let's try it with instances.

cat1 = Cat("Fluffy") cat1.feed() # Totally fine, because the cat class inherits from the Pet class! cat1.hi() # Uses the special Cat hello. print(cat1)

print(cat1.chasing_rats())

new_cat = Cheshire("Pumpkin") # create a Cheshire cat instance with name "Pumpkin" new_cat.hi() # same as Cat! new_cat.chasing_rats() # OK, because Cheshire inherits from Cat new_cat.smile() # Only for Cheshire instances (and any classes that you make inherit from Cheshire)

cat1.smile() # This line would give you an error, because the Cat class does not have this method!

None of the subclass methods can be used on the parent class, though.

p1 = Pet("Teddy") p1.hi() # just the regular Pet hello

p1.chasing_rats() # This will give you an error -- this method doesn't exist on instances of the Pet class.
p1.smile() # This will give you an error, too. This method does not exist on instances of the Pet class.

Meow I'm Fluffy. I feel happy. What are you doing, Pinky? Taking over the world?! Meow :D :D :D Mrrp

woneuy01 commented 4 years ago

This is how the interpreter looks up attributes: First, it checks for an instance variable or an instance method by the name it’s looking for. If an instance variable or method by that name is not found, it checks for a class variable. (See the previous chapter for an explanation of the difference between instance variables and class variables.) If no class variable is found, it looks for a class variable in the parent class. If no class variable is found, the interpreter looks for a class variable in THAT class’s parent (the “grandparent” class). This process goes on until the last ancestor is reached, at which point Python will signal an error.

woneuy01 commented 4 years ago

Overriding Methods

from random import randrange

Here's the original Pet class

class Pet(): boredom_decrement = 4 hunger_decrement = 6 boredom_threshold = 5 hunger_threshold = 10 sounds = ['Mrrp'] def init(self, name = "Kitty"): self.name = name self.hunger = randrange(self.hunger_threshold) self.boredom = randrange(self.boredom_threshold) self.sounds = self.sounds[:] # copy the class attribute, so that when we make changes to it, we won't affect the other Pets in the class

def clock_tick(self):
    self.boredom += 1
    self.hunger += 1

def mood(self):
    if self.hunger <= self.hunger_threshold and self.boredom <= self.boredom_threshold:
        return "happy"
    elif self.hunger > self.hunger_threshold:
        return "hungry"
    else:
        return "bored"

def __str__(self):
    state = "     I'm " + self.name + ". "
    state += " I feel " + self.mood() + ". "
    # state += "Hunger %d Boredom %d Words %s" % (self.hunger, self.boredom, self.sounds)
    return state

def hi(self):
    print(self.sounds[randrange(len(self.sounds))])
    self.reduce_boredom()

def teach(self, word):
    self.sounds.append(word)
    self.reduce_boredom()

def feed(self):
    self.reduce_hunger()

def reduce_hunger(self):
    self.hunger = max(0, self.hunger - self.hunger_decrement)

def reduce_boredom(self):
    self.boredom = max(0, self.boredom - self.boredom_decrement)

class Cat(Pet): sounds = ['Meow']

def mood(self):
    if self.hunger > self.hunger_threshold:
        return "hungry"
    if self.boredom <2:
        return "grumpy; leave me alone"
    elif self.boredom > self.boredom_threshold:
        return "bored"
    elif randrange(2) == 0:
        return "randomly annoyed"
    else:
        return "happy"

class Dog(Pet): sounds = ['Woof', 'Ruff']

def mood(self):
    if (self.hunger > self.hunger_threshold) and (self.boredom > self.boredom_threshold):
        return "bored and hungry"
    else:
        return "happy"

c1 = Cat("Fluffy") d1 = Dog("Astro")

c1.boredom = 1 print(c1.mood()) c1.boredom = 3 for i in range(10): print(c1.mood()) print(d1.mood())


grumpy; leave me alone happy happy happy randomly annoyed happy randomly annoyed randomly annoyed happy randomly annoyed randomly annoyed happy

woneuy01 commented 4 years ago

class Book(): def init(self, title, author): self.title=title self.author=author def str(self): return '"{}" by {}'.format(self.title, self.author)

class PaperBook(Book): #inhereted from class Book def init(self, title, author, numPages): Book. init(self, title, author) # inhereted title and author from class Book self.numPages=numPages

class EBook(Book): def init(self, title, author, size): Book.init(self, title, author) self.size=size

class Library: def init(self): self.books=[] def addBook(self, book): self.books.append(book) def getNumBooks(self): return len(self.books)

myBook = EBook('The Odyssey', 'Homer', 2) myPaperBook=PaperBook('The Odyssey', 'Homer', 500)

print(myBook.size)

print(myPaperBook.numPages)

aadl=Library() aadl.addBook(myBook) aadl.addBook(myPaperBook)

print(aadl.getNumBooks())


2

woneuy01 commented 4 years ago

Invoking the Parent Class’s Method from random import randrange

Here's the original Pet class

class Pet(): boredom_decrement = 4 hunger_decrement = 6 boredom_threshold = 5 hunger_threshold = 10 sounds = ['Mrrp'] def init(self, name = "Kitty"): self.name = name self.hunger = randrange(self.hunger_threshold) self.boredom = randrange(self.boredom_threshold) self.sounds = self.sounds[:] # copy the class attribute, so that when we make changes to it, we won't affect the other Pets in the class

def clock_tick(self):
    self.boredom += 1
    self.hunger += 1

def mood(self):
    if self.hunger <= self.hunger_threshold and self.boredom <= self.boredom_threshold:
        return "happy"
    elif self.hunger > self.hunger_threshold:
        return "hungry"
    else:
        return "bored"

def __ str__(self):
    state = "     I'm " + self.name + ". "
    state += " I feel " + self.mood() + ". "
    # state += "Hunger %d Boredom %d Words %s" % (self.hunger, self.boredom, self.sounds)
    return state

def hi(self):
    print(self.sounds[randrange(len(self.sounds))])
    self.reduce_boredom()

def teach(self, word):
    self.sounds.append(word)
    self.reduce_boredom()

def feed(self):
    self.reduce_hunger()

def reduce_hunger(self):
    self.hunger = max(0, self.hunger - self.hunger_decrement)

def reduce_boredom(self):
    self.boredom = max(0, self.boredom - self.boredom_decrement)

from random import randrange

class Dog(Pet): sounds = ['Woof', 'Ruff']

def feed(self):
    Pet.feed(self)
    print("Arf! Thanks!")

d1 = Dog("Astro")

d1.feed()

Arf! Thanks!


class Bird(Pet): sounds = ["chirp"] def vinit(self, name="Kitty", chirp_number=2): Pet. vinit(self, name) # call the parent class's constructor

basically, call the SUPER -- the parent version -- of the constructor, with all the parameters that it needs.

    self.chirp_number = chirp_number # now, also assign the new instance variable

def hi(self):
    for i in range(self.chirp_number):
        print(self.sounds[randrange(len(self.sounds))])
    self.reduce_boredom()

b1 = Bird('tweety', 5) b1.teach("Polly wanna cracker") b1.hi()


Polly wanna cracker chirp Polly wanna cracker chirp Polly wanna cracker

woneuy01 commented 4 years ago

testing classes

class Point: """ Point class for representing and manipulating x,y coordinates. """

def __init__(self, initX, initY):

    self.x = initX
    self.y = initY

def distanceFromOrigin(self):
    return ((self.x ** 2) + (self.y ** 2)) ** 0.5

def move(self, dx, dy):
    self.x = self.x + dx
    self.y = self.y + dy

testing class constructor (init method)

p = Point(3, 4) assert p.y == 4 //오류이면 에러난다. assert p.x == 3

testing the distance method

p = Point(3, 4) assert p.distanceFromOrigin() == 5.0

testing the move method

p = Point(3, 4) p.move(-2, 3) assert p.x == 1 assert p.y == 7