Difference between revisions of "CSC111 Lab 10 2010"
(→Fish) |
m (Thiebaut moved page CSC111 Lab 10 to CSC111 Lab 10 2010) |
||
(18 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | {| | ||
+ | | width="40%" | | ||
+ | __TOC__ | ||
+ | | | ||
<bluebox> | <bluebox> | ||
− | |||
This lab deals with classes, objects, and graphics. It builds on the examples we saw in class on Monday and Wednesday. | This lab deals with classes, objects, and graphics. It builds on the examples we saw in class on Monday and Wednesday. | ||
<br> | <br> | ||
</bluebox> | </bluebox> | ||
− | + | |} | |
<br /> | <br /> | ||
Line 12: | Line 15: | ||
</tanbox> | </tanbox> | ||
<br /> | <br /> | ||
− | == | + | ==Classes for a wheel and a Car== |
Below is the code we wrote in class yesterday: | Below is the code we wrote in class yesterday: | ||
<source lang="python"> | <source lang="python"> | ||
− | + | # carNew.py | |
− | + | # D. Thiebaut | |
− | + | # first program using a class to define | |
+ | # a new graphic object: a wheel, which | ||
+ | # is made of 2 concentric circles. The class | ||
+ | # Wheel supports methods to initialize the | ||
+ | # graphics object, draw it on the window, | ||
+ | # and move it. | ||
+ | |||
+ | from graphics import * | ||
+ | W = 400 | ||
+ | H = 400 | ||
− | + | #---------------------------------------------------------------- | |
− | + | class Wheel: | |
− | + | """A class with two concentric circles""" | |
+ | def __init__( self, center, r1, r2 ): | ||
+ | """constructor""" | ||
+ | self.radius1 = min( r1, r2 ) | ||
+ | self.radius2 = max( r1, r2 ) | ||
+ | self.circ1 = Circle( center, self.radius1 ) | ||
+ | self.circ2 = Circle( center, self.radius2 ) | ||
+ | |||
+ | def draw( self, win ): | ||
+ | """draws the wheel on the graphics window win""" | ||
+ | self.circ2.draw( win ) | ||
+ | self.circ1.draw( win ) | ||
− | + | def move( self, dx, dy ): | |
− | + | self.circ1.move( dx, dy ) | |
− | + | self.circ2.move( dx, dy ) | |
− | |||
− | |||
− | + | def setFill( self, color1, color2 ): | |
− | + | self.circ1.setFill( color1 ) | |
− | + | self.circ2.setFill( color2 ) | |
− | |||
− | + | def getRadius1( self ): | |
− | + | """returns the smallest radius""" | |
− | + | return self.radius1 | |
− | |||
− | + | def getRadius2( self ): | |
− | + | """returns the largest radius""" | |
− | + | return self.radius2 | |
− | |||
− | + | class Car: | |
− | + | def __init__( self, P1, P2 ): | |
− | + | self.body = Rectangle( P1, P2 ) | |
− | + | w =abs( P2.getX()-P1.getX() ) | |
− | + | h =abs( P2.getY()-P1.getY() ) | |
− | + | center1 = Point( w/4+P1.getX(), P2.getY() ) | |
− | + | center2 = Point( P2.getX()-w/4, P2.getY() ) | |
− | + | r2 = w/8 | |
− | + | r1 = r2/2 | |
+ | self.w1 = Wheel( center1, r1, r2 ) | ||
+ | self.w2 = Wheel( center2, r1, r2 ) | ||
+ | def setFill( self, bodyc, tirec, insidec ): | ||
+ | self.body.setFill( bodyc ) | ||
+ | self.w1.setFill( tirec, insidec ) | ||
+ | self.w2.setFill( tirec, insidec ) | ||
− | + | def draw( self, win ): | |
− | + | self.body.draw( win ) | |
− | + | self.w1.draw( win ) | |
− | + | self.w2.draw( win ) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | def move( self, dx, dy): | |
− | + | self.body.move( dx, dy ) | |
+ | self.w1.move( dx, dy ) | ||
+ | self.w2.move( dx, dy ) | ||
+ | #---------------------------------------------------------------- | ||
+ | def waitForClick( win, message ): | ||
+ | """ waitForClick: stops the GUI and displays a message. | ||
+ | Returns when the user clicks the window. The message is erased.""" | ||
− | + | # wait for user to click mouse to start | |
+ | startMsg = Text( Point( win.getWidth()/2, win.getHeight()/2 ), message ) | ||
+ | startMsg.draw( win ) # display message | ||
+ | win.getMouse() # wait | ||
+ | startMsg.undraw() # erase | ||
− | |||
− | + | def main(): | |
+ | """demo program for wheel: draws wheel on screen""" | ||
+ | global W, H | ||
+ | win = GraphWin( "wheel demo", W, H ) | ||
+ | waitForClick( win, "click to start" ) | ||
− | + | #--- create new wheel object --- | |
+ | #w = Wheel( Point( W/2, H/2 ), 20, 40 ) | ||
+ | #w.setFill( "black", "yellow" ) | ||
+ | #w.draw( win ) | ||
− | + | car = Car( Point( 20, 20 ), Point( 120, 60 ) ) | |
+ | car.setFill( "red", "yellow", "black" ) | ||
+ | car.draw( win ) | ||
+ | waitForClick( win, "click to move" ) | ||
− | |||
− | : | + | #--- move the wheel --- |
+ | for i in range( 100 ): | ||
+ | car.move( 3, 0 ) | ||
− | + | waitForClick( win, "click to end" ) | |
− | + | main() | |
− | |||
− | |||
− | |||
− | + | </source> | |
− | |||
− | |||
− | + | * Run the program a few times to make sure you understand how it works. | |
− | * | ||
− | + | * Assume that the programmer writing the main program (we always assume that the programmer writing the main program is different from the programmer writing the classes, as is most often the case in real life) forgot the rule that when building a car, the first point passed to the constructor is the top left point of the rectangle defining the body, and that the second point is the bottom right point of the body. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | :Instead the programmer creates the object '''car''' as follows: | |
− | + | car = Car( Point( 120, 60 ), Point( 20, 20 ) ) | |
− | |||
− | + | :Make this modification and run your program. What happens? | |
− | + | * Fix the '''class''' ''Car'' so that the user can specify any point in any order (top-left, bottom-right), or (top-right, bottom-left), or (bottom-left, top-right), and constructor will correctly define the body and the wheels to fit the shape defined by the two points. | |
− | |||
− | |||
− | |||
− | |||
− | + | * Oh, by the way, the car is a two-door convertible. Add a door to the car. The door should be a simple rectangle in the middle of the body of the car, between the two wheels. (You may want to sketch the shape of the car on paper and figure out what proportions to use to position the door.) | |
− | |||
− | + | * Add a windshield to the car as well. You are free to define its shape, and the '''Polygon''' class will provide a nice solution for you. '''Polygons''' are defined in Section 3.6 of [http://cs.smith.edu/dftwiki/images/1/17/ZelleGraphicsDescription.pdf Zelle's 4-page document on his graphics library]. | |
− | |||
− | |||
− | |||
− | |||
==Random cars going in random directions== | ==Random cars going in random directions== | ||
Line 148: | Line 154: | ||
* Make your program create a list of 5 cars. | * Make your program create a list of 5 cars. | ||
− | * Each car has a random horizontal velocity, making it go left, or right. | + | * Each car has a random horizontal velocity (dy=0), making it go left, or right. Make dx and dy part of the class, i.e. make these variables '''member variables''' of the class '''Car'''. |
− | * Make your program move all 5 cars at the same time, until all the cars have exited the window. As soon as the cars all disappear your program will stop. | + | * Make your program move all 5 cars at the same time, until all the cars have exited the window. As soon as the cars all disappear your program will stop. Think of an efficient way to do this... This is a bit tricky... (But we are at a time in the semester where you can deal with tricky questions... :-) |
==Fish== | ==Fish== | ||
− | * get a copy of | + | This section is reported to [[CSC111 Lab 11| Lab 11]]... |
+ | |||
+ | * Point your browser to http://maven.smith.edu/~111c/index.html | ||
+ | |||
+ | * See all the fish? Make a note of one of the fish, and get a copy of its file as follows | ||
+ | |||
+ | getcopy fishxx.gif ''(replace xx by the actual number of the fish you want)'' | ||
+ | |||
+ | * Write a new graphics program and copy/paste the following code in it: | ||
+ | <br /> | ||
− | + | <source lang="python"> | |
+ | . | ||
− | * | + | from graphics import * |
+ | H = 400 | ||
+ | W = 400 | ||
− | + | def waitForClick( win, message ): | |
+ | """ waitForClick: stops the GUI and displays a message. | ||
+ | Returns when the user clicks the window. The message is erased.""" | ||
− | + | # wait for user to click mouse to start | |
+ | startMsg = Text( Point( win.getWidth()/2, win.getHeight()/2 ), message ) | ||
+ | startMsg.draw( win ) # display message | ||
+ | win.getMouse() # wait | ||
+ | startMsg.undraw() # erase | ||
− | |||
− | : | + | def main(): |
+ | global H, W | ||
+ | win = GraphWin( "Fish Tank", W, H ) | ||
+ | waitForClick( win, "click to start" ) | ||
− | + | fish = Image( Point( W/2, H/2 ), "fish15.gif" ) # replace 15 by the number of your fish | |
+ | fish.draw( win ) | ||
− | + | waitForClick( win, "click to end" ) | |
+ | win.close() | ||
− | + | main() | |
− | + | ||
+ | . | ||
+ | </source> | ||
− | + | * Add a for loop and make the object ''fish'' move by dx, dy some fixed number of steps... | |
− | * | + | * Create a an new class which is a fish, with its own file name, and its own dx and dy. |
− | + | * Create an object issued from the class. Verify that you can make the object move on the screen. | |
− | * | + | * Create a school of several fish that move around the screen. The fish may move in opposite directions, but we'll assume that all fish move in the direction of where their head points to!!! |
− | + | * Make the fish go up or down, slightly, randomly, as it moves forward... | |
− | + | <br /> | |
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | [[Category:CSC111]][[Category:Labs]][[Category:Python]] |
Latest revision as of 06:53, 29 March 2015
This lab deals with classes, objects, and graphics. It builds on the examples we saw in class on Monday and Wednesday.
|
You may find the following document describing the different graphic objects introduce in the Zelle's textbook useful.
Classes for a wheel and a Car
Below is the code we wrote in class yesterday:
# carNew.py
# D. Thiebaut
# first program using a class to define
# a new graphic object: a wheel, which
# is made of 2 concentric circles. The class
# Wheel supports methods to initialize the
# graphics object, draw it on the window,
# and move it.
from graphics import *
W = 400
H = 400
#----------------------------------------------------------------
class Wheel:
"""A class with two concentric circles"""
def __init__( self, center, r1, r2 ):
"""constructor"""
self.radius1 = min( r1, r2 )
self.radius2 = max( r1, r2 )
self.circ1 = Circle( center, self.radius1 )
self.circ2 = Circle( center, self.radius2 )
def draw( self, win ):
"""draws the wheel on the graphics window win"""
self.circ2.draw( win )
self.circ1.draw( win )
def move( self, dx, dy ):
self.circ1.move( dx, dy )
self.circ2.move( dx, dy )
def setFill( self, color1, color2 ):
self.circ1.setFill( color1 )
self.circ2.setFill( color2 )
def getRadius1( self ):
"""returns the smallest radius"""
return self.radius1
def getRadius2( self ):
"""returns the largest radius"""
return self.radius2
class Car:
def __init__( self, P1, P2 ):
self.body = Rectangle( P1, P2 )
w =abs( P2.getX()-P1.getX() )
h =abs( P2.getY()-P1.getY() )
center1 = Point( w/4+P1.getX(), P2.getY() )
center2 = Point( P2.getX()-w/4, P2.getY() )
r2 = w/8
r1 = r2/2
self.w1 = Wheel( center1, r1, r2 )
self.w2 = Wheel( center2, r1, r2 )
def setFill( self, bodyc, tirec, insidec ):
self.body.setFill( bodyc )
self.w1.setFill( tirec, insidec )
self.w2.setFill( tirec, insidec )
def draw( self, win ):
self.body.draw( win )
self.w1.draw( win )
self.w2.draw( win )
def move( self, dx, dy):
self.body.move( dx, dy )
self.w1.move( dx, dy )
self.w2.move( dx, dy )
#----------------------------------------------------------------
def waitForClick( win, message ):
""" waitForClick: stops the GUI and displays a message.
Returns when the user clicks the window. The message is erased."""
# wait for user to click mouse to start
startMsg = Text( Point( win.getWidth()/2, win.getHeight()/2 ), message )
startMsg.draw( win ) # display message
win.getMouse() # wait
startMsg.undraw() # erase
def main():
"""demo program for wheel: draws wheel on screen"""
global W, H
win = GraphWin( "wheel demo", W, H )
waitForClick( win, "click to start" )
#--- create new wheel object ---
#w = Wheel( Point( W/2, H/2 ), 20, 40 )
#w.setFill( "black", "yellow" )
#w.draw( win )
car = Car( Point( 20, 20 ), Point( 120, 60 ) )
car.setFill( "red", "yellow", "black" )
car.draw( win )
waitForClick( win, "click to move" )
#--- move the wheel ---
for i in range( 100 ):
car.move( 3, 0 )
waitForClick( win, "click to end" )
main()
- Run the program a few times to make sure you understand how it works.
- Assume that the programmer writing the main program (we always assume that the programmer writing the main program is different from the programmer writing the classes, as is most often the case in real life) forgot the rule that when building a car, the first point passed to the constructor is the top left point of the rectangle defining the body, and that the second point is the bottom right point of the body.
- Instead the programmer creates the object car as follows:
car = Car( Point( 120, 60 ), Point( 20, 20 ) )
- Make this modification and run your program. What happens?
- Fix the class Car so that the user can specify any point in any order (top-left, bottom-right), or (top-right, bottom-left), or (bottom-left, top-right), and constructor will correctly define the body and the wheels to fit the shape defined by the two points.
- Oh, by the way, the car is a two-door convertible. Add a door to the car. The door should be a simple rectangle in the middle of the body of the car, between the two wheels. (You may want to sketch the shape of the car on paper and figure out what proportions to use to position the door.)
- Add a windshield to the car as well. You are free to define its shape, and the Polygon class will provide a nice solution for you. Polygons are defined in Section 3.6 of Zelle's 4-page document on his graphics library.
Random cars going in random directions
- Make your program create a list of 5 cars.
- Each car has a random horizontal velocity (dy=0), making it go left, or right. Make dx and dy part of the class, i.e. make these variables member variables of the class Car.
- Make your program move all 5 cars at the same time, until all the cars have exited the window. As soon as the cars all disappear your program will stop. Think of an efficient way to do this... This is a bit tricky... (But we are at a time in the semester where you can deal with tricky questions... :-)
Fish
This section is reported to Lab 11...
- Point your browser to http://maven.smith.edu/~111c/index.html
- See all the fish? Make a note of one of the fish, and get a copy of its file as follows
getcopy fishxx.gif (replace xx by the actual number of the fish you want)
- Write a new graphics program and copy/paste the following code in it:
.
from graphics import *
H = 400
W = 400
def waitForClick( win, message ):
""" waitForClick: stops the GUI and displays a message.
Returns when the user clicks the window. The message is erased."""
# wait for user to click mouse to start
startMsg = Text( Point( win.getWidth()/2, win.getHeight()/2 ), message )
startMsg.draw( win ) # display message
win.getMouse() # wait
startMsg.undraw() # erase
def main():
global H, W
win = GraphWin( "Fish Tank", W, H )
waitForClick( win, "click to start" )
fish = Image( Point( W/2, H/2 ), "fish15.gif" ) # replace 15 by the number of your fish
fish.draw( win )
waitForClick( win, "click to end" )
win.close()
main()
.
- Add a for loop and make the object fish move by dx, dy some fixed number of steps...
- Create a an new class which is a fish, with its own file name, and its own dx and dy.
- Create an object issued from the class. Verify that you can make the object move on the screen.
- Create a school of several fish that move around the screen. The fish may move in opposite directions, but we'll assume that all fish move in the direction of where their head points to!!!
- Make the fish go up or down, slightly, randomly, as it moves forward...