全球公衛教授和公共教育家漢斯.羅斯林(Hans Rosling)在其著名的暢銷書「
真確」中,提出了13個關於全球貧富、人口、出生/死亡率、教育、公衛等的「留意認知落差測驗」,回答的人不乏受過良好教育的專業人士,結果顯示,受測者在前12題平均只答對2題,遠不如隨機亂選的黑猩猩(如果黑猩猩會答題的話)。作者指出,這樣的結果來自於人類的誇大直覺與偏誤認知,並舉出十個扭曲認知的直覺是如何造成我們誤解身處的世界。
這篇文章並沒有要繼續深入本書的精華,但這本書絕對是連微軟共同創辦人比爾.蓋茲(Bill Gates)都掛保證的好書。這篇的靈感來自於這13道題,事實上,作者所創立的Gapminder基金會就把這一系列的問題放在
網路上,提供一般的民眾接受測試,而本篇的目的在於使用到目前為止所學習的概念,實作一個Python版本的測驗程式。
程式架構
資料整理
我們取「真確」書中13道題的其中12道(排除一個圖表題),使用字典建成12個問題與答案形成的鍵值對。
fact_data = [
{"question": "現今全世界的低所得國家裡,多少女孩會讀完小學?"
"(A)20%(B)40%(C)60%", "answer": "C"},
{"question": "世界上的多數人是生活在哪裡?"
"(A)低所得國家(B)中所得國家(C)高所得國家", "answer": "B"},
{"question": "在過去20年,全球赤貧人口占總人口的比例是⋯⋯"
"(A)幾乎翻倍(B)大致不變(C)幾乎減半", "answer": "C"},
{"question": "現今全球的平均壽命是多少?"
"(A)50歲(B)60歲(C)70歲", "answer": "C"},
{"question": "現今全球有20億個兒童,年齡介於0到15歲之間。根據聯合國的估算,到了2100年全球會有多少個兒童?"
"(A)40億(B)30億(C)20億", "answer": "C"},
{"question": "根據聯合國的估算,到了2100年全球會再增加40億人,而主要原因是什麼?"
"(A)兒童人口增加(不到15歲)(B)成年人口增加(15歲到74歲)(C)老年人口增加(75歲以上)", "answer": "B"},
{"question": "過去100年間,全球死於天災的人數是如何變化?"
"(A)幾乎翻倍(B)大致不變(C)幾乎減半", "answer": "C"},
{"question": "現今全球多少2歲兒童有接種疫苗?"
"(A)20%(B)50%(C)80%", "answer": "C"},
{"question": "全球30歲的男性平均接受過10年的學校教育,而同齡的女性平均接受過幾年的學校教育?"
"(A)9年(B)6年(C)3年", "answer": "A"},
{"question": "1996年,老虎、熊貓和黑犀牛都列為瀕危動物。現在這3種動物裡,哪幾種面臨更迫切的危機?"
"(A)2種(B)1種(C)0種", "answer": "C"},
{"question": "全球多少人口享有電力?"
"(A)20%(B)50%(C)80%", "answer": "C"},
{"question": "全球氣象專家認為接下來一百年裡平均氣溫會⋯⋯"
"(A)更暖(B)一樣(C)更冷", "answer": "A"}
]
建立測驗庫類別
建立一個測驗庫類別CreateTestPool,使每一個問題與答案的配對都能生成一個獨立的物件,這個物件包含兩個屬性,即為問題(self.question)與答案(self.answer)。接著,我們把這些獨立的物件放入一個串列(test_pool)中,以方便取用。
class CreateTestPool:
def __init__(self, question, answer):
self.question = question
self.answer = answer
test_pool = []
for fact in fact_data:
fact_obj = CreateTestPool(fact["question"], fact["answer"])
test_pool.append(fact_obj)
建立測驗產生器類別
測驗產生器類別(TestGenerator)的目的在於接受測驗庫類別所生成的物件串列,並與使用者互動完成測驗與計分。因此,這個類別包含了以下屬性:
- 題庫的物件串列(self.question_list)
- 使用者得分(self.score)
- 使用者當下測驗的題號(self.question_number)
為了完成這個測驗,我們需要有以下的操作(方法):
- 查詢是否後面還有題目(is_last_questions(self))
- 產生下一道題目(generate_next_question(self))
- 檢查答案(check_answer(self, user_answer, correct_answer))
- 查詢分數(get_score(self))
class TestGenerator:
def __init__(self, question_list):
self.score = 0
self.question_number = 0
self.question_list = question_list
def is_last_questions(self):
return self.question_number < len(self.question_list)
def generate_next_question(self):
current_question = self.question_list[self.question_number]
self.question_number += 1
user_answer = input(f"Q{self.question_number}: {current_question.question} (A/B/C)?: ")
self.check_answer(user_answer, current_question.answer)
def check_answer(self, user_answer, correct_answer):
if user_answer.lower() == correct_answer.lower():
self.score += 1
print("\t 答案正確!")
else:
print("\t 答案錯誤!")
print(f"\t 正確答案是 {correct_answer}.")
print(f"\t 你的分數: {self.score}/{self.question_number}.")
def get_score(self):
return self.score
測驗主程式
建立一個測驗產生器類別的物件,並在while迴圈內查詢是否已完成測驗,以決定是否繼續呈現下一個題目或是計算總分。
fact_test = TestGenerator(test_pool)
while fact_test.is_last_questions():
fact_test.generate_next_question()
# comments
print(f"你的總分: {fact_test.score}/{fact_test.question_number}.")
if fact_test.get_score() > 4:
print("恭喜你答得比黑猩猩好!")
elif fact_test.get_score() == 4:
print("黑猩猩4ni?")
else:
print("趕快買本書來看吧!")
在此專題中,我們把測驗產生器包裝成一個類別,它不需要知道測驗的內容,只需要提供正確的測驗庫,它便可呈現整個測驗的過程給使用者;此外,我們也把建立測驗庫的功能包裝成一個類別,只需要專注於測驗資料的內容與格式,便可以輕鬆更新題庫。
測驗畫面
以下是程式執行與答題的畫面:
Q1: 現今全世界的低所得國家裡,多少女孩會讀完小學?(A)20%(B)40%(C)60% (A/B/C)?: C
答案正確!
正確答案是 C.
你的分數: 1/1.
Q2: 世界上的多數人是生活在哪裡?(A)低所得國家(B)中所得國家(C)高所得國家 (A/B/C)?: B
答案正確!
正確答案是 B.
你的分數: 2/2.
Q3: 在過去20年,全球赤貧人口占總人口的比例是⋯⋯(A)幾乎翻倍(B)大致不變(C)幾乎減半 (A/B/C)?: B
答案錯誤!
正確答案是 C.
你的分數: 2/3.
Q4: 現今全球的平均壽命是多少?(A)50歲(B)60歲(C)70歲 (A/B/C)?: C
答案正確!
正確答案是 C.
你的分數: 3/4.
Q5: 現今全球有20億個兒童,年齡介於0到15歲之間。根據聯合國的估算,到了2100年全球會有多少個兒童?(A)40億(B)30億(C)20億 (A/B/C)?: C
答案正確!
正確答案是 C.
你的分數: 4/5.
Q6: 根據聯合國的估算,到了2100年全球會再增加40億人,而主要原因是什麼?(A)兒童人口增加(不到15歲)(B)成年人口增加(15歲到74歲)(C)老年人口增加(75歲以上) (A/B/C)?: B
答案正確!
正確答案是 B.
你的分數: 5/6.
Q7: 過去100年間,全球死於天災的人數是如何變化?(A)幾乎翻倍(B)大致不變(C)幾乎減半 (A/B/C)?: C
答案正確!
正確答案是 C.
你的分數: 6/7.
Q8: 現今全球多少2歲兒童有接種疫苗?(A)20%(B)50%(C)80% (A/B/C)?: C
答案正確!
正確答案是 C.
你的分數: 7/8.
Q9: 全球30歲的男性平均接受過10年的學校教育,而同齡的女性平均接受過幾年的學校教育?(A)9年(B)6年(C)3年 (A/B/C)?: B
答案錯誤!
正確答案是 A.
你的分數: 7/9.
Q10: 1996年,老虎、熊貓和黑犀牛都列為瀕危動物。現在這3種動物裡,哪幾種面臨更迫切的危機?(A)2種(B)1種(C)0種 (A/B/C)?: B
答案錯誤!
正確答案是 C.
你的分數: 7/10.
Q11: 全球多少人口享有電力?(A)20%(B)50%(C)80% (A/B/C)?: C
答案正確!
正確答案是 C.
你的分數: 8/11.
Q12: 全球氣象專家認為接下來一百年裡平均氣溫會⋯⋯(A)更暖(B)一樣(C)更冷 (A/B/C)?: A
答案正確!
正確答案是 A.
你的分數: 9/12.
你的總分: 9/12.
恭喜你答得比黑猩猩好!
程式範例