Week 7 - Designing and Programming Classes/Objects
Design Activity
Last week we spent the week reading and watching videos trying to develop the concept of what goes in to a Class definition. Primarily, we talked about the fact that an Object has three things:
- StateĀ (data, "instance variables")
- Actions (methods, "instance methods")
- What instances look like when they are constructed (initialization)
To start this week I want you to think about the design of a couple of different classes.
With a partner if you want
When we worked with Scratch we were programming Sprites. It is very likely that each sprite you programmed was an instance of some form of "Sprite" class. Let's assume that they actually are and think about what the design for these would look like.
- What data does each individual sprite know about itself? Think about this carefully. I think you should be able to come up with no fewer than six pieces of data. When I thought about it for a while I came up with six obvious things, two mostly obvious things, and 6-12 more obscure things. Clearly your definition of "obvious", "mostly obvious" and "obscure" may differ from mine. But with a partner see how many things you can come up with.
- When you feel like you have really thought about/discussed it you can compare your answers with my answers.
- Now, we should think about the "default" values that these instance variables get when new sprites are created. For this part let's only worry about the six instance variables that I labeled as "obvious" in my solution posted in step #1.1. What are the default values given to these when a new sprite is created.
- When you feel like you have really thought about/discussed it you can compare your answers with my answers.
- Finally, what actions can each sprite perform. Again, this can get fairly large fairly quickly. So let's only focus on those actions in Scratch that manipulate the six values I labeled as "obvious".
- When you feel like you have really though about/discussed it you can compare your answers with my answers.
Code Activity
Last week I showed you working code for two classes:
- CreditCard.py (and it you like, here is the Wallet code to go with it.)
- Fraction.py
While we will not make a habit of having you write classes in this course - mostly just using them - I think it is worth TRYING to write a class from scratch. In fact, let's have you write a Python version of the Scratch Sprite that we designed together last week.
Using the CreditCard and Fraction examples from above, create a Python Class called Sprite which you save in a file named Sprite.py. This class should provide all of the data and functionality that was outlined in the class diagram shown below:
Most of these are fairly straight forward because they are simple operations. But a few of them have some error checking and one even has (heaven forbid) trigonometry. And non-standard trigonometry at that. Since my MAIN learning outcome with this is really just to get you to explore with the structure of Python class code, I will give you the option to create one of two versions.
A class called SimpleSprite in a file called SimpleSprite.py
- This version does not do any error checking about the validity of parameters.
- If the user says mySprite.setX(5000) then it is allowed.
- If the current direction is 90 and the user says mySprite.turnClockwise(100) then it goes to 190 rather than -170 (which is what Scratch would do).
- This version only allows move to happen if the current direction value is one of the four cardinal directions - 0, 90, 180, and -90 for the direction. In other words, a move() will change x or y but not both.
Once you write your Sprite you can download this tester program and run it to see if your outcomes agree with what I was expecting.
A class called Sprite in a file called Sprite.py
- This version does everything that the SimpleSprite did but adds some additional functionality that makes it a little closer to the true Scratch Sprite:
- If a user moves or sets an X/Y value that put it beyond the border of the stage (-240 to +240 for x and -180 to +180 for y). It just sets the appropriate value to that limit.
- mySprite.setX(5000) would end up with x=240
- If a change to the angle [either through pointInDirection(), turnClockwise() or turnCounterClockwise() ] were to cause an angle that is not between -180 to +180 inclusively than the value should "wrap" appropriately.
- mySprite.pointInDirection(200) should end up with direction=-160
- mySprite.pointInDirection(160) with mySprite.turnClockwise(400) should end up with direction=-160
- If a sprite is pointing in any valid direction (-180 to +180) and a move() is executed it should calculate the accurate trigonometry of the move.
- mysprite.pointInDirection(30) followed by mySprite.move(100) should create x=50 and y=86.6.
- Note, python has math.sin() and math.cos() in the math libarary. HOWEVER, they expect radians. Fortunately, there is a math.radians() which converts degrees to radians
- import math
- rad = math.radians(45)
- print(math.cos(rad))
- print(math.sin(rad))
- produces:
- 0.7071... as expected
- If a user moves or sets an X/Y value that put it beyond the border of the stage (-240 to +240 for x and -180 to +180 for y). It just sets the appropriate value to that limit.
Once you write your Sprite you can download this tester program and run it to see if your outcomes agree with what I was expecting.