こんにちは。
今回は今まで学習した、Pythonのオブジェクト指向の知識を総動員して、練習問題に取り組んでみましょう。
Pythonのオブジェクト指向については、以下の記事で学習する事が出来ます。
Pythonにおけるオブジェクト指向について解説【入門編その①】
続きを見る
Pythonにおけるオブジェクト指向について解説【入門編その②】
続きを見る
では早速、練習問題に取り組んでみましょう。
【Python】オブジェクト指向の練習問題【病院の予約システムのアプリを開発してみよう】
病院の予約アプリケーション想定した課題です。
患者のオブジェクトをHuman Classとして親クラス、Patient Classを子クラスにして作成してください。
病院をClinic Classとして、患者オブジェクトのリストを取り扱って、予約、診察のメソッドを作成しましょう。
また患者の待ち人数の増減を管理し、その待ち人数を表示する機能を実装してください。
課題では次の仕様を満たすように実装してください。
仕様
まず、以下の3つのクラスを作ってください。
- Human (親クラス)
- Patient(Humanの子クラス)
- Clinic
次に、以下の順番でコードを作成してください。
step
1Human class(親クラス)を作る
【Human Class】
変数名 | 備考 | |
属性 | name | 人の名前 |
step
2Patientクラス(Humanの子クラス)を作る
【Patient Class】
変数名 | 備考 | |
属性 | symptom | 症状 |
patient_id | 患者のID |
step
3Clinicのクラスを作る
【Clinic Class】
変数名/メソッド名 | 備考 | |
属性 | patient_list | list型のPatient Classを格納する変数 |
振る舞い | show_waiting_count() | 診察待ち人数を表示 引数:なし 返り値:なし |
reserve() | 患者の予約処理をする。 すでに予約済みの患者を _check_reserved で確認して、予約済みですと表示する。引数:予約する患者の Patient Class 返り値:なし | |
diagnosis() | 患者の診察処理をする。 引数で患者が指定されたときは、その患者を優先して診察。 指定がない時は、予約の早い患者を順に診察。 引数:診察する患者の Patient Class 。初期値は None 返り値:なし | |
_check_reserved() | 患者の診察予約がすでにされているか確認 引数:予約する Patient Classs 返り値:True(予約されている) / False(予約されていない) |
step
4Clinicを変数名 myclinic
でインスタンスする
step
5以下の患者リストを Cinic Class
の reserveメソッド
で予約(患者リストの追加)する
名前 | ID | 症状 |
佐藤 | 111 | 咳 |
田中 | 222 | 腹痛 |
鈴木 | 333 | 鼻水 |
山田 | 444 | 倦怠感 |
ご自身の名前 | 555 | 何か症状 |
step
6 Clinic Classの show_waiting_count()
メソッドで、現在の待ち人数を表示する
step
7 先ほどの患者リストと重複する一人を再度予約して、予約済みですのメッセージを確認する
step
8 Clinicの diagnosis
(診察)メソッドを実行し、待ち人数が減ったことを待ち人数を表示して確認する
step
9 Clinicの diagnosis
に患者のIDを引数に与えて実行し、待ち人数が減ったことを待ち人数を表示して確認する
補足
Clinicの患者リストである patient_list
のlist型がわからない方は以下を参照ください。
In[]
1 2 3 4 5 6 7 8 9 | # 初期化 sample_list = [] # データ追加 p = Patient('中田', '555', 'インフル') sample_list.append(p) # 配列の長さ = データの格納数 print(len(sample_list)) |
練習問題【演習方法その①】
課題と仕様を見て、自身でコーディングしてみてください。
コーディングに不安な方は、演習方法2のコードの穴埋めにて演習を実施してください。
練習問題【演習方法その①】
— コード追加 —
に1行ずつコードを埋めていって、プログラムを完成させてください。
演習のJupyter notebookをご利用される方は演習(google driveリンク)を参照いただければと思います。
step
1Human class(親クラス)を作る
1 2 3 4 | class Human(): def __init__(self, name): # 名前 --- コード追加 --- |
step
2Patientクラス(Humanの子クラス)を作る
1 2 3 4 5 6 7 8 | class Patient(Human): def __init__(self, name, patient_id, symptom): super().__init__(name) # 症状 --- コード追加 --- # 診察番号 --- コード追加 --- |
step
3Clinicのクラスを作る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | class Clinic(): def __init__(self): # 患者リスト --- コード追加 --- # 待ち人数表示 def show_waiting_count(self): --- コード追加 --- # 予約 def reserve(self, patient): if self._check_reserved(patient): print(f'{patient.name}さんはすでに予約済みです。') else: print(f'{patient.name}さん予約完了') # 患者リストpatients_listにpatientを追加 --- コード追加 --- # 診察 def diagnosis(self, patient_id=None): # 患者指定なしの場合順番に patient = None if patient_id == None: if len(self.patients_list)>0: patient = self.patients_list[0] else: for p in self.patients_list: if p.patient_id == patient_id: patient = p # 診察患者がいない場合 if patient == None: print('診察する患者がいません。') else: print(f'{patient.name}さん、{patient.symptom}ですね。') print(f'診察終わりました。お大事に。') # 患者リストpatients_listから除外 --- コード追加 --- # 予約済み確認 def _check_reserved(self, patient): for p in self.patients_list: # 引数のpatientとpatients_listの中のpatient_idの比較 if --- コード追加 ---: return True return False |
step
4Clinicを変数名 myclinic
でインスタンス化する
1 2 | # Clinic Classのインスタンス --- コード追加 --- |
step
5患者の数名の予約・待ち人数の表示を行う
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 患者予約対象データ # name、age、symptomの順 patients = [['佐藤', '111', '咳'], ['田中', '222', '腹痛'], ['鈴木', '333', '鼻水'], ['山田', '444', '倦怠感'], ['中田', '555', 'インフル'],] # 患者予約 for p in patients: name, age, symptom = p # loopで取得する name, age, symptomでPatientをインスタンス --- コード追加 --- # myclinicに予約 *reserveメソッド使用 --- コード追加 --- # 現在の待ち人数を表示 --- コード追加 --- |
step
6 重複した患者を予約する
1 2 3 4 5 6 | # 自分の名前でインスタンス me = Patient('中田', '555', 'インフル') # 予約する --- コード追加 --- # 現在の待ち人数表示 --- コード追加 --- |
step
7 患者リスト順に表示して、待ち人数を表示する
1 2 3 4 | # 診察 --- コード追加 --- # 現在の待ち人数表示 --- コード追加 --- |
step
8 患者ID "555" を指定して、急患の診察を行う。待ち人数を表示する。
1 2 3 4 | # 診察 patient_id 555指定 --- コード追加 --- # 現在の待ち人数表示 --- コード追加 --- |
実行結果
実行結果の例になります。コード部分は隠してあります。
解答例
解答例(google driveリンク)を参照いただければと思います。
step
1Human class(親クラス)を作る
1 2 3 4 | class Human(): def __init__(self, name): # 名前 self.name = name |
step
2Patientクラス(Humanの子クラス)を作る
1 2 3 4 5 6 7 8 | class Patient(Human): def __init__(self, name, patient_id, symptom): super().__init__(name) # 症状 self.symptom = symptom # 診察番号 self.patient_id = patient_id |
step
3Clinicのクラスを作る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | class Clinic(): def __init__(self): # 患者リスト self.patients_list = [] # 待ち人数表示 def show_waiting_count(self): print(f'ただいまの待ち人数は{len(self.patients_list)}人です。') # 予約 def reserve(self, patient): if self._check_reserved(patient): print(f'{patient.name}さんはすでに予約済みです。') else: print(f'{patient.name}さん予約完了') self.patients_list.append(patient) # 診察 def diagnosis(self, patient_id=None): # 患者指定なしの場合順番に patient = None if patient_id == None: if len(self.patients_list)>0: patient = self.patients_list[0] else: for p in self.patients_list: if p.patient_id == patient_id: patient = p # 診察患者がいない場合 if patient == None: print('診察する患者がいません。') else: print(f'{patient.name}さん、{patient.symptom}ですね。') print(f'診察終わりました。お大事に。') # 診察リストから除外 self.patients_list.remove(patient) # 予約済み確認 def _check_reserved(self, patient): for p in self.patients_list: if p.patient_id == patient.patient_id: return True return False |
step
4Clinicを変数名 myclinic
でインスタンス化する
1 2 | # Clinic Classのインスタンス myclinic = Clinic() |
step
5患者の数名の予約・待ち人数の表示を行う
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 患者予約対象データ # name、age、symptomの順 patients = [['佐藤', '111', '咳'], ['田中', '222', '腹痛'], ['鈴木', '333', '鼻水'], ['山田', '444', '倦怠感'], ['中田', '555', 'インフル'],] # 患者予約 for p in patients: name, age, symptom = p # loopで取得する name, age, symptomでPatientをインスタンス化 patient = Patient(name, age, symptom) # myclinicに予約 *reserveメソッド使用 myclinic.reserve(patient) # 現在の待ち人数を表示 myclinic.show_waiting_count() |
step
6 重複した患者を予約する
1 2 3 4 5 6 | # 自分の名前でインスタンス生成 me = Patient('中田', '555', 'インフル') # 予約する myclinic.reserve(me) # 現在の待ち人数表示 myclinic.show_waiting_count() |
step
7 患者リスト順に表示して、待ち人数を表示する
1 2 3 4 | # 診察 myclinic.diagnosis() # 現在の待ち人数表示 myclinic.show_waiting_count() |
step
8 患者ID "555" を指定して、急患の診察を行う。待ち人数を表示する。
1 2 3 4 | # 診察 myclinic.diagnosis(patient_id='555') # 現在の待ち人数表示 myclinic.show_waiting_count() |
演習は以上です。お疲れ様でした。
どうでしょうか?クラスの作り方、使い方に慣れたでしょうか?
最初は人の作った、クラスを眺めつつ、自分で作ってどんどん慣れていきましょう。
今回の課題は以上となります。お疲れ様でした。