8: Basic Dict

8-4: Checking Key Existence

** ถ้าใช้งานบนมือถือหรือ tablet แนะนำให้ใช้ Chrome หรือ Safari เท่านั้น **

แบบฝึกหัด 8-4 ข้อที่ 1

p1 และ p2 เป็นดิกเก็บคะแนนของนักเรียนที่เรียนวิชา 1 และ 2 ตามลำดับในรูปแบบ {เลขประจำตัว: คะแนน} จงเขียนฟังก์ชัน take_both(st_id, p1, p2) เพื่อหาว่านักเรียนที่มีเลขประจำตัว st_id เรียนทั้งสองวิชาหรือไม่

def take_both(st_id, p1, p2): def take_both(st_id, p1, p2): return st_id in p1 and st_id in p2 q = "`" fname = "take_both" func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์สามตัว') p1 = {33:3, 22:2, 44:4, 55:5} p2 = {30:3, 20:2, 44:4, 50:5} func.check_call(fname + "(44, " + str(p1) + "," + str(p2) + ")").\ has_equal_value(incorrect_msg="มี แต่คืนว่าไม่มี") func.check_call(fname + "(22, " + str(p1) + "," + str(p2) + ")").\ has_equal_value(incorrect_msg="ไม่มี แต่คืนว่ามี") func.check_call(fname + "(50, " + str(p1) + "," + str(p2) + ")").\ has_equal_value(incorrect_msg="ไม่มี แต่คืนว่ามี")
ใช้ key in dict ในการค้น
แบบฝึกหัด 8-4 ข้อที่ 2

p1 และ p2 เป็นดิกเก็บคะแนนของนักเรียนที่เรียนวิชา 1 และ 2 ตามลำดับในรูปแบบ {เลขประจำตัว: คะแนน} จงเขียนฟังก์ชัน both(p1, p2) เพื่อคืนลิสต์ที่เก็บเลขประจำตัวนักเรียนเรียนทั้งสองวิชา โดยเรียงลำดับเลขประจำตัวนักเรียนในลิสต์จากน้อยไปมากด้วย

def both(p1, p2): def both(p1, p2): result = [] for sid in p1: if sid in p2: result.append(sid) result.sort() return result q = "`" fname = "both" func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์สองตัว') p1 = {33:3, 22:2, 44:4, 55:5} p2 = {30:33, 22:12, 44:40, 50:53} p3 = {444:2, 555:23} func.check_call(fname + "(" + str(p1) + "," + str(p2) + ")").\ has_equal_value(incorrect_msg="ได้ผลผิด") func.check_call(fname + "(" + str(p1) + "," + str(p3) + ")").\ has_equal_value(incorrect_msg="กรณีที่ควรได้ลิสต์ว่าง แต่ไม่ได้")
ใช้ for k in dict หนึ่ง ถ้า k มีในอีก dict ก็เก็บใส่ผลลัพธ์
แบบฝึกหัด 8-4 ข้อที่ 3

สตริง DNA เป็นสตริงที่มีตัวอักษรแค่ A, T, G และ C เท่านั้น จงเขียนฟังก์ชัน count_bases(dna) คืนดิกในรูปแบบ {เบส: จำนวน} เช่น count_bases("AAAATTTGG") ได้ {"A":4, "T":3, "G":2, "C":0}

def count_bases(dna): def count_bases(dna): count = {"A":0, "T":0, "G":0, "C":0} for b in dna: count[b] += 1 return count def count_bases(dna): count = {"A":0, "T":0, "G":0, "C":0} for b in dna: count[b] += 1 return count import random q = "`" fname = "count_bases" func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์sหนึ่งตัว') dna1 = "'" + "A"*random.randint(0,4) + "T"*random.randint(0,4) + \ "G"*random.randint(0,4) + "C"*random.randint(0,4) + "'" for p in ["'AAAATTTT'", dna1, "''"]: fcall = fname + "(" + p + ")" func.check_call(fcall).has_equal_value(incorrect_msg = (q+fcall+q) + " ต้องได้ " + str(eval(fcall)))
สร้างดิกเริ่มต้น {"A":0, "T":0, "G":0, "C":0} ก่อน จะทำให้นับง่ายขึ้น
แบบฝึกหัด 8-4 ข้อที่ 4

จงเขียนฟังก์ชัน count_chars(text) ที่นับว่าใน text มีอักขระอะไรเท่าไรบ้าง (โดยให้ตัวอักษรเล็กเหมือนใหญ่ เช่น count_chars("ABCabcZ") ได้ดิก {'A': 2, 'B': 2, 'C': 2, 'Z': 1} เป็นผลลัพธ์

def count_chars(text): count = {} for c in text: c = c.upper() if c in count: count[c] += 1 else: count[c] = 1 return count def count_chars(text): c = {} for e in text.upper(): if e not in c : c[e] = 0 c[e] += 1 return c q = "`" fname = "count_chars" func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์ตัวเดียว') import random text = "'" for i in range(5): c = chr(random.randint(65,65+25)) text += c*random.randint(0,3) + c.lower()*random.randint(0,3) text += "'" for p in ["''", text, "'AaBbKkZzz'"]: fcall = fname + "(" + p + ")" func.check_call(fcall).has_equal_value(incorrect_msg = (q+fcall+q) + " ต้องได้ " + str(eval(fcall)))
แบบฝึกหัด 8-4 ข้อที่ 5

income1 และ income2 เป็นดิกในรูปแบบ {รหัสสาขาร้าน: รายได้} ซึ่งเก็บรายรับของร้านอาหารสาขาต่าง ๆ จงเขียนฟังก์ชัน merge(income1, income2) ที่คืนดิกใหม่ในรูปแบบเดียวกัน แต่เก็บข้อมูลรวมจากทั้งสองดิกที่รับมา เช่น income1 = {"P100":100, "P200":200} และ income2 = {"P200":300, "P300":90} merge กันแล้วจะได้ดิกใหม่ {"P100":100, "P200":500, "P300":90}

def merge(income1, income2): def merge(income1, income2): result = {} for k in income1: result[k] = income1[k] for k in income2: if k in result: result[k] += income2[k] else: result[k] = income2[k] return result q = "`" fname = "merge" func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์สองตัว') ic1 = {"A":10, "B":20, "C":30, "D":40} ic2 = {"A":20, "X":20, "Y":30, "D":90} func.check_call(fname + "(" + str(ic1) + "," + str(ic2) + ")").\ has_equal_value(incorrect_msg="ได้ผลผิด")
copy income1 มาไว้ดิกผลลัพธ์ก่อน แล้วค่อยอ่านจาก income2 ว่าจะเพิ่มในสาขาที่มีอยู่ หรือใส่ใหม่เลย
แบบฝึกหัด 8-4 ข้อที่ 6

จงเขียนโปรแกรมอ่านบรรทัดแรกของอินพุตเป็นรายการของรหัสสินค้า บรรทัดที่สองเป็นรายการของราคา (มีจำนวนข้อมูลเท่ากับของบรรทัดแรก โดยสินค้าชิ้นที่ตำแหน่ง i ก็มีราคาที่ตำแหน่ง i) และอ่านบรรทัดถัด ๆ มา (จบด้วย end) ที่เป็นรหัสสินค้าที่ต้องการให้แสดงราคา ถ้าหาไม่พบให้แสดง Not found จากตัวอย่างจะแสดง 35.0, Not found และ 50.0 บรรทัดละราคา (หรือข้อความ)

___inp___ = ["A100 A200 A300 A400", "20.5 50.0 35.0 65.0", "A300", "A999", "A200", "end"] def input(): t = ___inp___.pop(0) ___inp___.append(t) return t pids = input().split() p = input().split() prices = {} for i in range(len(pids)): prices[pids[i]] = p[i] #------------------------- pid = input() while pid != "end": if pid in prices: print(prices[pid]) else: print("Not found") pid = input() v = ["A B C D E F", "1.5 2.5 3.0 4.0 5.0 6.0", "A", "B", "X", "E", "end"] Ex().has_equal_output(pre_code = "___inp___[:] = " + str(v), incorrect_msg = "แสดงผลไม่ถูกต้อง")
สร้างดิก {รหัสสินค้า: ราคา} จะทำให้หาราคาจากรหัสสินค้าได้ง่ายมาก ๆ
แบบฝึกหัด 8-4 ข้อที่ 7

ข้อมูลที่อ่านจากอินพุตเป็นบรรทัด ๆ ไปจนถึง end คือรายการการประมูลสินค้า แต่ละบรรทัดประกอบด้วย รหัสผู้ประมูล รหัสสินค้า ราคาประมูล เราต้องการสร้างดิกชื่อ bid = {รหัสสินค้า: [รหัสผู้ประมูลสูงสุด, ราคาประมูลสูงสุด]} คือ มีรหัสสินค้าเป็นคีย์ ส่วนค่าเป็นลิสต์สองช่องเก็บรหัสผู้ประมูลกับราคาประมูลสูงสุด จากตัวอย่างอินพุต จะได้ bid = {'P001': ['U102', 120], 'P002': ['U101', 150]}

จงเขียนคำสั่งอ่านข้อมูลการประมูลเพื่อสร้าง bid ให้ได้ตามที่ต้องการ

___inp___ = [ "U101 P101 100", "U101 P102 100", "U102 P101 100", "U102 P102 200", "U102 P101 110", "U101 P101 120", "end"] def input(): t = ___inp___.pop(0) ___inp___.append(t) return t bid = {} x = input().split() while x[0] != "end": x = input().split() bid = {} x = input().split() while x[0] != "end": user = x[0] prod = x[1] price = int(x[2]) if prod not in bid or price > bid[prod][1]: bid[prod] = [user, price] x = input().split() var = "bid" obj = Ex().check_object(var, missing_msg = "ไม่พบตัวแปร " + var) obj.has_equal_value(expr_code="type("+var+")", incorrect_msg=var + " ต้องเป็น dict") obj.has_equal_value(incorrect_msg = "ยังตั้งค่าในดิกไม่ถูกต้อง")
ถ้าไม่มีรหัสสินค้าใน bid หรือ ราคาประมูลใหม่มีราคาสูงกว่าที่เก็บไว้ ก็เปลี่ยนค่า value