Basic Object Orientated Methods#
Follow these simple OOP exercises to practice and gain confidence in coding classes.
Exercise 1#
Task:
Create a class called
Patient
.The class should contain a constructor that accepts the following parameters. The parameters should be stored in appropriately named attributes.
patient_id: int
age: int
Hints
Don’t forget to include the
self
parameter!Make sure you use correct case for the class name.
Patient
follows PEP8 guidelines whilepatient
does not!
# your code here ...
# example solution
class Patient:
def __init__(self, patient_id, age):
self.id = patient_id
self.age = age
Exercise 2:#
Task:
Create a class called
Ward
Code a constructor method.
It should accept
ward_id
(int) as parameter and assign it to an attributeIt should create a new empty list attribute that will hold patients staying on the ward.
Create a method called
add_patient
. It should accept a parameter calledpatient
(that is a patient class).Create a method or property called
n_patients
. It should return the number of patients on the ward.
Hints:
Don’t forget the
self
parameter in the method!
class Ward:
def __init__(self, ward_id):
self.ward_id = ward_id
self.patients = []
def add_patient(self, patient):
self.patients.append(patient)
@property
def n_patients(self):
'''
Number of the patients...
'''
return len(self.patients)
Exercise 3:#
You will now test the Ward
class by generating a number of patients and adding them to a ward object.
Task:
Code a function that first creates a
Ward
object and then adds a user specified number ofPatient
instances via theadd_patient
function.The function must return the ward object.
Test your function with 5 patients.
Hints:
You will need to design the function so that it allocates a patient an age. One option is to randomly generate an age in a given range. You could achieve this using the
random.randint()
function. E.g.
from random import randint
lower, upper = 60, 95
age = randint(lower, upper)
# your code here ...
# example solution
from random import randint
def new_ward(ward_id, n_patients, age_range=(60,95)):
'''
Create a new ward with an id.
The ward will contain n_patients with random
age
Params:
------
ward_id: int
Unique id of ward
n_patients: int
Number of patients on ward
age_range: (int, int), optional (default=(60,95))
Age range for random allocation to patients.
Returns:
-------
Ward
'''
ward = Ward(ward_id)
for i in range(n_patients):
to_add = Patient(i, randint(age_range[0], age_range[1]))
ward.add_patient(to_add)
return ward
WARD_ID = 1
N_PATIENTS = 5
ward = new_ward(WARD_ID, N_PATIENTS)
# test
print(len(ward.patients))
print(ward.patients[4].id)
print(ward.patients[4].age)
5
4
72
Exercise 4:#
Task:
Now create a
Hospital
classThe class should allow the creation of new wards as well as adding a patient to a user specified ward.
The class must provide a
n_patients
method or property that returns the uptodate total of patients in the hospital.Create some test data and create a
Hospital
object. Return the total number of patients in the hospital.
# your code here ...
class Hospital:
'''
Encapsulates a hosptial made up of wards...
'''
def __init__(self, n_patients, age_ranges):
self.wards = [new_ward(i, n_patients[i], age_ranges[i])
for i in range(len(n_patients))]
def add_patient(self, ward_id, patient):
self.wards[ward_id].add_patient(patient)
def add_ward(self, n_patients=0, age_range=(60, 95)):
to_add = new_ward(len(self.wards), n_patients, age_range)
self.wards.append(to_add)
@property
def n_patients(self):
return sum([ward.n_patients for ward in self.wards])
@property
def n_wards(self):
return len(self.wards)
# age ranges
DEFAULT_RANGE = (60, 95)
YOUNG_ADULTS = (18,25)
DAY_CASES = (18, 88)
# parameters
n_patients= [5, 10, 8, 6, 15]
age_ranges = [DEFAULT_RANGE, DEFAULT_RANGE, DEFAULT_RANGE, YOUNG_ADULTS,
DAY_CASES]
# init hospital
hosp = Hospital(n_patients, age_ranges)
# test
hosp.n_patients
44
Exercise 5#
Task:
Let’s create a new type of patient specific to those with respiratory conditions.
The new class will also accept patient_id
and age
. You will need to create two new parameters as well: pack_yrs
and fev1
. Fyi:
A pack year is defined as twenty cigarettes smoked everyday for one year
FEV1 stands for Forced Expiratory Volumne and is a percentage measured out of 100%. Lower values are worse.
Call the class RespiratoryPatient
# example solution via inheritance
class RespiratoryPatient(Patient):
def __init__(self, patient_id, age, pack_yrs, fev1):
super().__init__(patient_id, age)
self.pack_yrs = pack_yrs
self.fev1 = fev1
# test
resp_patient = RespiratoryPatient(1, 25, 10, 80.0)
print(resp_patient.id)
print(resp_patient.age)
print(resp_patient.fev1)
1
25
80.0
# example solution via object composition
class RespiratoryPatient:
def __init__(self, patient, pack_yrs, fev1):
self.patient = patient
self.pack_yrs = pack_yrs
self.fev1 = fev1
@property
def id(self):
return self.patient.id
@property
def age(self):
return self.patient.age
# test composition...
patient = Patient(1, 25)
resp_patient = RespiratoryPatient(patient, 10, 80.0)
print(resp_patient.id)
print(resp_patient.age)
print(resp_patient.fev1)
1
25
80.0