WEEK12: defining our own classes/object-oriented programming
---------------------------------------------------------------
 W: more classes...


PLANET CLASS:

 - look at worksheet.planetclass and answer the questions
   at the bottom:

import math

earthmass = 5.97e24 # kg
au = 1.50e11        # meters

class Planet(object):

  def __init__(self,n,r,m,x,y,vx,vy):
    self.name = n
    self.radius = r
    self.mass = m
    self.x = x
    self.y = y
    self.vx = vx
    self.vy = vy

  def __str__(self):
    str = ""
    str = str + "    Name: %s\n" % (self.name)
    str = str + "  Radius: %0.1f (km)\n" % (self.radius)
    str = str + "    Mass: %0.1f (EM) = %0.2e (kg) \n" % (self.mass, self.massKG())
    str = str + " Density: %0.2e (kg/m^3) \n" % (self.density())
    str = str + "Distance: %0.1f (AU) = %0.2e (m) \n" % (self.distance(),\
        self.distanceM())
    return str

  def getX(self):
    return self.x

  def getY(self):
    return self.y

  def getVx(self):
    return self.vx

  def getVy(self):
    return self.vy

  def getName(self):
    return self.name

  def getRadius(self):
    return self.radius

  def getMass(self):
    return self.mass

  def massKG(self):
    return self.mass*earthmass

  def distance(self):
    r = math.sqrt(self.x**2 + self.y**2)
    return r

  def distanceM(self):
    return self.distance()*au

  def volume(self):
    v = (4.0/3.0)*math.pi*(self.radius**3)
    return v

  def surfaceArea(self):
    sa = 4.0 * math.pi * (self.radius**2)
    return sa

  def density(self):
    rho = self.massKG()/self.volume()
    return rho

  def setVx(self, vx):
    self.vx = vx

  def setVy(self, vy):
    self.vy = vy

  def moveTo(self, newx, newy):
    self.x = newx
    self.y = newy

if __name__ == '__main__':
  # ............name, radius, mass, x, y, vx, vy
  p = Planet("Tatooine", 5685, 0.78, 2.7, 0.0, 0.0, 2.0)
  print p
  earth = Planet("Earth", 6378, 1.0, 1.0, 0.0, 1.0, 4.0)
  print earth
  naboo = Planet("Naboo", 3397, 0.61, 1.57, 0.0, 0.0, 5.0)
  print naboo

###############################################################

* which method is the constructor? and how many arguments do you 
  need to specify?

* how many mutators are there? what are they called?

* what data is stored inside each planet object?

* how many accessor methods are there?

* what function is executed when I type "print earth"?

* what is the first parameter of the moveTo method?

* what is self in the moveTo method for earth.moveTo(0,0)?

* what does self.massKG() do in the density method??


REVIEW and USE of RAINDROP class:

 - open raindrop.py in one window and a new file (game.py) in
   a second window

 - let's make it rain in game.py:

from raindrop import *
from graphics import *
from time import *
from random import *

gw = GraphWin("rain game", 400, 700)
gw.setBackground("grey20")

#################################################
# main code goes here

drops = []

while True:
  # make new drop every now and then
  if random() > 0.96:
    d = Raindrop(gw, 2)
    drops.append(d)
  # move all drops their appropriate amounts
  for d in drops:
    d.move()
  sleep(0.01)

#################################################

gw.getMouse()
gw.close()

 - now stop any drops that hit the ground (hint: use onGround() method)

  for d in drops:
    if d.onGround(gw):
      drops.remove(d)

 - now stop the game if 10 drops hit the ground

num_on_ground = 0
while True:
  ...
  ...
  for d in drops:
    if d.onGround(gw):
      num_on_ground += 1
      drops.remove(d)
  if num_on_ground >= 10:
    break

 - now check for mouse clicks...vanish drop if clicked

  clickpoint = gw.checkMouse()
  if clickpoint != None:
    for d in drops:
      if d.clicked(clickpoint):
        d.vanish()
        drops.remove(d)



CLASS WRITER vs CLASS USER:

 - notice how we are now the class USER
 - the only way to access or change raindrops is through the
   methods provided by the class WRITER