In earlier Years, we discussed how we should think of the problem from the point of view of the "objects" that make sense to a human describing the problem
In our example so far, we have:
• Wizard
• House
• Wand
An object that belongs to these classes has _attributes_
/2
You've already come across the two types of attributes an object can have
• Data attributes are variables that are connected to the instance of the class. They are also called instance variables
• Methods are functions connected to the instance of the class
/3
Let's add more classes to describe our situation better
One of the last additions in Year 3 was the `Wand` class. It has a method called `cast_spell()`
Perhaps, we could also create a `Spell` class
/4
We'll keep this class simple and give it three data attributes and one method
The method `is_successful()` returns a Boolean to indicate whether the spell worked!
/5
Now, we can finish writing the `cast_spell()` method in the `Wand` class
Since we have a `Spell` class, we can pass an object of type `Spell` to this method
/6
However, the `Wizard` class can also have a `cast_spell()` method. It's the wizard with the wand that cast spells, right?
Since `Wand` and `Wizard` are different classes, they could have methods with the same names—these don't conflict with each other
/7
Whether you want to have two classes with methods with the same name depends on what you're trying to achieve
As this is a demonstration example, I'll use the same name to highlight how `.cast_spell()` in `Wand` and `.cast_spell()` in `Wizard` are different methods
/8
Let's make sure these changes work
Note how Hermione has no wand, so can't cast spells
And each time the same spell is cast, the likelihood of success is random and depends on the spell's difficulty
/9
But wait a second! The wizard's skill surely must be a factor on how likely he or she is to cast the spell successfully.
Dumbledore is going to have a higher success rate than Crabbe!
Let's make some changes. First, let's add a new data attribute and method to `Wizard`
/10
Next we need to pass this information to the `Wand` class when the wizard casts a spell
You pass `self` to `self.wand.cast_spell(spell, self)`
This means `.cast_spell()` in the `Wand` class knows who the wizard casting the spell is (`self` in `Wizard` refers to the wizard)
/11
This means that we need to update `.cast_spell()` in `Wand`, too
And while we're in the `Wand` class, let's account for wands having different powers
We've added another parameter to `Wand.cast_spell()`
/12
Note that `spell.is_successful()` now needs information about the wand and the wizard
As you're in the `Wand` class, `self` refers to the wand
And yes, we need to update the `Spell` class, too
/13
You'll need to find the right values for the spell difficulties, wand powers, and wizard skills that make sense!
But I'll leave that as an exercise for you to do!
/14
And here are a few more additions you can make:
• Create a `.spells_known` attribute in `Wizard`. This should be a list. Then you can add a `.learn_spell()` method which adds spells to this list
• When a wizard casts a spell, he or she needs to know that spell first!
/15
I'll let your imagination (plus: see homework below) suggest more additions to these classes and how we can link them together
Here's the classes we have so far, before you make your modifications
/16
An important note: this example is a demonstration example. I wanted to show an example that goes beyond a couple of attributes, but without going through hundreds of lines of code in a Twitter thread
There, I've said it!
/17
The key point to take from Year 4 is that when using classes and OOP, we want to "encapsulate" the data and functionality for an object into one unit—the class
/18
Once the class and its data attributes and methods are written, a user of the class can deal with these objects at a "higher level"
`harry.cast_spell()` means you want Harry to cast a spell. You're not concerned too much about what's happening "behind the scenes"
/19
Your homework over the holidays: Expand the classes above further
Optional homework: If you have access to GPT-4, paste the code we've written so far and ask it to suggest other methods you could write and new classes that would fit in this project
---
Year 5: Inheritance
/20
• • •
Missing some Tweet in this thread? You can try to
force a refresh
Slightly off-topic from my usual on this account—but a lot of my work is also linked to children's education (coding primarily, but let's think beyond subjects)
I've taken a stab at what "homework" in the near-future could look like, using a GPT-first, cheat-proof approach…
/1
It solves reasonably well the problem of "cheating" by incorporating GPT into the process and requiring the whole conversation to be submitted, including first drafts, suggestions by GPT, second drafts, and so on
Teachers can craft the right prompts that all students use
/2
But main point is not that it's cheat-proof but that it leverages the opportunities LLMs provide to improve learning
I collated some ideas & examples of how learning (children, but also adult-learning) could change soon
What Python data type would [a multi-storey car park] be?
–––
You drive into a multi-storey car park, find a spot to park, and then you ask yourself: "what data structure would best represent this car park", of course
Let's explore
1/
Let's name the object `car_park` and it contains several levels. I'll also look at `level` which represents one the levels. This will be a different data type
The car park has a fixed number of levels which don't change. Therefore, `car_park` is immutable
2/
You can count the levels – `len(car_park)` exists
You can determine whether `level` is in `car_park`, so `car_park` is a container
You can go through the levels one after the other, so `car_park` is iterable
These three properties make `car_park` a collection, too
3/
It depends whether we want to prioritise the use case when the tables are being used during normal service, with diners sitting on them and waiters taking their orders and bringing them food [dictionary is a good choice]…
/2
…or if you want to prioritise the setting up process before the restaurant opens its doors when staff go from one table to the next to clean it and set it up. For this, you could be tempted to use a sequence instead, such as a tuple or list
/3
• Balls appear in random positions every few seconds and are tossed upwards with random velocities
• Click close to the ball to "bat it up"
• How long until you lose 10 balls?
/1
You'll work in 2 scripts–the 1st is `juggling_balls.py` where you'll define the class `Ball` which inherits from `turtle.Turtle`
The bounds of where the ball is created are passed as arguments to the function's `__init__()` method
Ball's colour, shape, and position are set
/2
In the second script named `juggling_balls_game.py` you can create the screen, set its size, and create two instances of `Ball` to test the class's `__init__()` method so far