KT 的 Python 進階程式設計

W07|把資料再拿出來用:一維串列的多輪走訪

今天完成後,我可以

  1. 先保存整批資料,算出需要的資訊後,再由左到右走訪同一個串列。
  2. 分清楚索引i與串列內容L[i],依保存方式判斷題目編號。
  3. 分清原始數值與調整後的數值,用正確的資料完成統計。

本週沿用W06的固定長度串列與索引寫法,重點是再次使用已保存的資料。

課中配分:b033、b034各50分。課後配分:a379、a387各30分,a388 40分。

一、課中練習

1-1|b033 在平均之上(教師示範,50分)

題目先輸入全班成績,最後要回答有多少人成績大於等於全班平均。教師示範時,請一邊在自己的電腦操作,一邊觀察:

  1. 輸入第一筆成績時,能知道全班平均嗎?
  2. 如果沿用W04邊輸入邊計算、不把成績存進L,等全班平均算出後會遇到什麼問題?
  3. 平均算出後,為什麼要再走訪一次L?
  4. 迴圈中的i與L[i],哪一個是成績?

這題延續W06的b023串列版:先保存成績並算平均,再增加一輪統計。成績可以自行決定放在L的第0~n - 1格,或第1~n格;選定後,每一輪的範圍都要一致。

需要時展開:再次走訪的骨架
Python 3圖片
完成後整理:不知道錯在哪裡時分段檢查

可以暫時在三個位置加入輸出:

Python 3圖片

確認後要刪除多餘輸出再提交。

1-2|b034 平均之上的平均(獨立練習,50分)

這題沿用b033保存的成績與算出的全班平均,改求「平均以上同學」的平均成績。先用少量資料手算,再寫出你的處理方式。

開始前先回答:

  1. 若成績是50、70、90,全班平均是70,新平均應根據哪幾筆成績?
  2. 手算新平均時,分子和分母各代表什麼?
需要時展開:手算與程式選到相同資料嗎?

用上面的三筆成績,先在紙上圈出應納入新平均的資料,再對照程式實際納入哪幾筆。若選到的資料相同而結果不同,檢查你用什麼數字當分子和分母。

二、解題後整理:Top Down 思考,Bottom Up 實作

回看b033與b034:兩題有哪些資訊可以共用?最後要的結果不同,程式的哪一部分因此改變?

三、課後挑戰

先到JMJ依題號閱讀完整題目與範例。第一題延伸課中的多輪走訪;第二題要依條件分階段輸出,第三題要對照同一人的兩種資料。

表格可左右滑動
題目 本週目標
a379 加分後的飲料 找出最低分,統計調分後超過100分的人數
a387 出遊分帳 先輸出所有補款動作,再輸出所有領款動作
a388 敗部復活賽 對照評審分數與人氣票數,選出復活者

3-1|a379 加分後的飲料

沿用W06的方式,逐筆讀入原始成績並存進L。如果邊輸入邊判斷誰有飲料,當下還缺少哪個資訊?

你可以自行決定是否更新L中的分數;題目要求的是需要準備的飲料杯數。

開始寫程式前,先用自己選的兩三筆成績手算共同加分、調整後的分數與飲料杯數,再用這組資料檢查程式。

需要時展開:最低分為什麼變成 0?

用原始成績50、80檢查:最低分應是50。如果程式得到0,檢查「目前最低分」是不是一開始就設成0,而沒有取自真正輸入的一筆成績。若你保留L[0]不放成績,也確認沒有把那格算進去。

3-2|a387 出遊分帳

先看JMJ題目與範例。每人應分攤多少錢,要等哪個數值算出後才能確定?為了稍後依編號處理每個人的動作,輸入時哪些資料需要留下?

需要時展開:整數分攤額與輸出順序

先用範例逐人算出已代墊金額與應分攤金額的差,分清楚誰要補款、誰要領款。

Python 用 // 做除法並向下取整,例如 7 // 2 得到 3;用 / 則得到 3.5。本題保證總費用能被人數整除,算每人分攤額時可以用 //。

題目要求所有補款動作先出現,所有領款動作後出現。可以用第一個for迴圈只輸出補款動作,再用第二個for迴圈只輸出領款動作;兩輪都依編號由小到大走訪。

需要時展開:一行輸出文字、編號與金額
Python 3圖片

number和money是示意名稱,寫程式時要換成題目編號與這次動作的金額。print()會在逗號分隔的項目之間自動印出空白,並在這行結束後換行;領款時把"PAY"改成"GET"。題目編號是1到n,請留意它與自己使用的串列索引是否相同。

3-3|a388 敗部復活賽

先看JMJ題目與範例。第一位參賽者的分數輸入時,直接晉級的門檻已經知道了嗎?如果還不知道,之後要怎麼找回這位參賽者的資料?

需要時展開:一行讀入兩個數字
Python 3圖片

split()切開後的兩份資料仍是文字,存進去前記得用int()轉成整數。

需要時展開:兩種資料怎麼保存?

讀完所有人之後,你還找得到第2位的人氣票數嗎?串列的每一格只能放一個數字。兩種資料要怎麼保存,才能用同一個i找回同一個人的評審分數和人氣票數?

需要時展開:整數平均與復活資格

評審平均要無條件捨去至整數時,可以用 //:7 // 2 得到 3,而 7 / 2 得到 3.5。本題分數都是非負整數,// 符合這裡的取整數規則。

先用範例圈出直接晉級者,再看看程式考慮復活者時,是否只比較未直接晉級者的人氣票數。若票數相同,請核對選出的編號。

完成後挑戰:把讀入縮成一行

這是完成題目後的選學延伸,看懂、會用即可,不要求改寫已完成的程式。

  1. W06 a066的提示看過month, day = map(int, input().split())。它和先split()、再分別用int()轉型的寫法差在哪裡?改用它,讀入時可以少掉哪幾行?
  2. W06學過L[i] = 值會直接把值寫進串列的某一格。等號左邊的兩個變數,能不能直接換成你要寫入的那兩格?
  3. 改完後,在輸入迴圈結束時暫時印出你的兩個串列,確認每格都是整數。如果少了map(int, …),存進去的會是什麼?比較人氣票數時會出什麼問題?試比較"90"和"100"。

四、完成後自我檢查