10: Tuple, Set, Dict

10-4: More on Dict

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

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

มีดิกตัวหนึ่งอยู่แล้วชื่อ tel_no เก็บข้อมูลในรูปแบบ {สตริงชื่อเพื่อน: สตริงหมายเลขโทรศัพท์} จงเขียนคำสั่งเพิ่มเบอร์ 091-011-1929 ของเพื่อนใหม่ชื่อ Amy ใน tel_no

tel_no = {'Kid': '089-129-2929', 'P': '089-291-2145'} # เพิ่มเบอร์ 091-011-1929 ของ Amy # tel_no['Amy'] = '091-011-1929' var = 'tel_no' obj = Ex().check_object(var, missing_msg = "ไม่มีตัวแปร " + var) obj.has_equal_value(incorrect_msg = 'ยังเพิ่มข้อมูลใน ' + var + " ไม่ถูกต้อง")
แบบฝึกหัด 10-4 ข้อที่ 2

ข้อที่แล้วเพื่อนหนึ่งคนมีแค่หมายเลขโทรศัพท์แค่หมายเลขเดียว จึงขอเปลี่ยนให้ดิก tel_no เก็บข้อมูลในรูปแบบ {สตริงชื่อเพื่อน: ลิสต์ของสตริงหมายเลขโทรศัพท์} จงเขียนคำสั่งเพิ่มเบอร์ 091-011-1929 ของเพื่อนใหม่ชื่อ Amy ใน tel_no

tel_no = {'Kid': ['089-129-2929'], 'P': ['089-291-2145', '061-232-5555']} # Amy เป็นเพื่อนใหม่แน่ ๆ # เพิ่มเบอร์ 091-011-1929 ของ Amy # tel_no['Amy'] = ['091-011-1929'] var = 'tel_no' obj = Ex().check_object(var, missing_msg = "ไม่มีตัวแปร " + var) obj.has_equal_value(incorrect_msg = 'ยังเพิ่มข้อมูลใน ' + var + " ไม่ถูกต้อง") obj.has_equal_value(expr_code = "type(tel_no['Amy'])", incorrect_msg = "value ของดิกต้องเป็นลิสต์")
แบบฝึกหัด 10-4 ข้อที่ 3

จากข้อที่แล้ว ดิก tel_no เก็บข้อมูลในรูปแบบ {สตริงชื่อเพื่อน: ลิสต์ของสตริงหมายเลขโทรศัพท์} จงเขียนคำสั่งเพิ่มเบอร์ 091-011-1929 ซึ่งเป็นเบอร์ใหม่ของเพื่อนเดิมชื่อ Amy ที่มีในดิกแล้ว (ให้เพิ่มเบอร์ใหม่โดยการต่อท้ายลิสต์)

tel_no = {'Kid': ['089-129-2929'], 'Amy': ['089-291-2145', '061-232-5555']} # Amy เป็นเพื่อนที่เราเคยเก็บหมายเลขไว้แล้ว # เพิ่มเบอร์ใหม่ 091-011-1929 ของ Amy tel_no['Amy'].append('091-011-1929') var = 'tel_no' obj = Ex().check_object(var, missing_msg = "ไม่มีตัวแปร " + var) obj.has_equal_value(incorrect_msg = 'ยังเพิ่มข้อมูลใน ' + var + " ไม่ถูกต้อง อย่าลืมเพิ่มโดยการต่อท้ายลิสต์")
แบบฝึกหัด 10-4 ข้อที่ 4

จากข้อที่แล้ว ดิก tel_no เก็บข้อมูลในรูปแบบ {สตริงชื่อเพื่อน: ลิสต์ของสตริงหมายเลขโทรศัพท์} จงเขียนคำสั่งเพิ่มเบอร์ 091-011-1929 ซึ่งเป็นเบอร์ของเพื่อน Amy ที่ไม่แน่ใจเหมือนกันว่า มีในดิกแล้วหรือยัง

tel_no = {'Amy': ['111']} new_tel_no = '091-011-1929' if 'Amy' not in tel_no: tel_no['Amy'] = [new_tel_no] else: tel_no['Amy'].append(new_tel_no) var = 'tel_no' obj = Ex().check_object(var, missing_msg = "ไม่มีตัวแปร " + var) Ex().multi( set_env(tel_no = {}).has_equal_value(name="tel_no", incorrect_msg = "ยังเพิ่มผิด กรณีไม่มี Amy ในดิก"), set_env(tel_no = {'Amy':['089-101-0000']}).has_equal_value(name="tel_no", incorrect_msg = "ยังเพิ่มผิด กรณีมี Amy ในดิกอยู่แล้ว") )
แบบฝึกหัด 10-4 ข้อที่ 5

อินพุตมีหลายบรรทัด บรรทัดแรกเป็นจำนวนเต็ม n ตามมาอีก n บรรทัด แต่ละบรรทัดมีรหัสผู้ซื้อและรหัสสินค้าที่ผู้ซื้อสนใจ (คั่นด้วยช่องว่าง) จงเขียนโปรแกรมเพื่ออ่านอินพุตเข้ามาเก็บในดิกชื่อ wishlist ในรูปแบบ {รหัสสินค้า: เซตของรหัสผู้ซื้อที่สนใจสินค้านี้} จากตัวอย่างอินพุต เมื่อโปรแกรมทำงานแล้วจะได้ wishlist = {'P01': {'U01', 'U02'}, 'P02': {'U01'}, 'P03': {'U02', 'U03'}, 'P04': {'U02'}}

___inp___ = [ "6", "U01 P01", "U01 P02", "U03 P03", "U02 P01", "U02 P03", "U02 P04" ] def input(): t = ___inp___.pop(0) ___inp___.append(t) return t wishlist = {} wishlist = {} n = int(input()) for k in range(n): user, product = input().split() if product not in wishlist: wishlist[product] = {user} else: wishlist[product].add(user) var = 'wishlist' obj = Ex().check_object(var, missing_msg = "ไม่มีตัวแปร " + var) inputs = [['3', 'u1 p1', 'u2 p1', 'u3 p1'], ['3', 'u1 p1', 'u1 p2', 'u1 p3'], ['7', 'u1 p1', 'u2 p1', 'u3 p1', 'u1 p2', 'u3 p1', 'u3 p2', 'u4 p4']] for inp in inputs: obj.has_equal_value(pre_code = "___inp___[:] = " + str(inp), incorrect_msg = var + " มีค่าไม่ตรงตามโจทย์")
แบบฝึกหัด 10-4 ข้อที่ 6

จงเขียนฟังก์ชัน top3_most_wished(wishlist) ที่รับ wishlist ในรูปแบบ {รหัสสินค้า: เซตของรหัสผู้ซื้อที่สนใจสินค้านี้} (ซึ่งก็คือดิก wishlist ในข้อก่อนนี้) ฟังก์ชันนี้คืนลิสต์ของรหัสสินค้าที่มีผู้ซื้อสนใจมากสุด 3 อันดับแรก [สนใจมากสุด, สนใจมากสุดเป็นอันดับสอง, สนใจมากสุดเป็นอันดับสาม] ถ้ามีจำนวนที่สนใจเป็นจำนวนเท่ากัน ก็ให้เรียงตามรหัสสินค้าจากน้อยไปมาก จากตัวอย่างอินพุตในข้อที่แล้ว จะได้ผลคือ ['P01', 'P03', 'P02']

def top3_most_wished(wishlist): def top3_most_wished(wishlist): x = [(-len(wishlist[p]), p) for p in wishlist] x.sort() top3 = [p for _, p in x[:3]] return top3 q = "`" fname = "top3_most_wished" func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์ตัวเดียว') for a in [{'P1':{'A','B','C'}, 'P2':{'A','B','D','Z'}, 'P3':{'B','D','Z'}, 'P4':{'Z'}}, {'P8':{'A'}, 'P7':{'B','C'}, 'P9':{'A','Z','C'}}]: fcall = fname + "(" + str(a) + ")" func.check_call(fcall).has_equal_value(incorrect_msg=(q+fcall+q) + " ให้ผลผิด")
แบบฝึกหัด 10-4 ข้อที่ 7

อินพุตมีหลายบรรทัด บรรทัดแรกเป็นจำนวนเต็ม n ตามมาอีก n บรรทัด แต่ละบรรทัดมีเลขประจำตัวนิสิตและคะแนน คั่นด้วยช่องว่าง (คะแนนเป็นจำนวนเต็ม) จงเขียนโปรแกรมเพื่ออ่านอินพุตเข้ามาเก็บในดิกชื่อ point ในรูปแบบ {สตริงรหัสคณะ: [คะแนนรวมของนิสิตในคณะนี้, จำนวนนิสิตในคณะนี้]} จากตัวอย่างอินพุต เมื่อโปรแกรมทำงานแล้วจะได้ point = {'26': [50, 2], '21': [75, 3], '30': [25, 1]}

___inp___ = [ '6', '6240827226 30', '6230192830 25', '6231010221 25', '6230383821 20', '6231301221 30', '6240918226 20' ] def input(): t = ___inp___.pop(0) ___inp___.append(t) return t point = {} n = int(input()) point = {} for k in range(n): student_id, p = input().split() p = int(p) fcode = student_id[-2:] if fcode not in point: point[fcode] = [p, 1] else: point[fcode][0] += p point[fcode][1] += 1 var = 'point' obj = Ex().check_object(var, missing_msg = "ไม่มีตัวแปร " + var) inputs = [['4','6231010221 20','6230383822 20','6240827223 30','6231301224 30'], ['4','6231010221 20','6230383821 20','6240827226 30','6231301221 30']] for inp in inputs: obj.has_equal_value(pre_code = "___inp___[:] = " + str(inp), incorrect_msg = var + " มีค่าไม่ตรงตามโจทย์")
แบบฝึกหัด 10-4 ข้อที่ 8

จงเขียนฟังก์ชัน top_average_point(point): ที่รับ point ในรูปแบบ {สตริงรหัสคณะ: [คะแนนรวมของนิสิตในคณะนี้, จำนวนนิสิตในคณะนี้]} (ซึ่งก็คือดิก point ในข้อก่อนนี้) ฟังก์ชันนี้คืนลิสต์ของรหัสคณะที่มีคะแนนเฉลี่ยของนิสืตที่สังกัดมากสุด (ในกรณีที่มีหลายคณะได้คะแนนเฉลี่ยมากสุดเท่ากัน ให้เรียงตามรหัสคณะที่ได้คะแนนเฉลี่ยมากสุดจากน้อยไปมาก) จากตัวอย่างอินพุตในข้อที่แล้ว จะได้ผลคือ ['21', '26', '30']

def top_average_point(point): def top_average_point(point): x = [(point[fcode][0]/point[fcode][1], fcode) for fcode in point] max_avg_point = max(x)[0] top = [fcode for avg_point,fcode in x if avg_point == max_avg_point] return sorted(top) q = "`" fname = "top_average_point" func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์ตัวเดียว') for a in [{'21': [100,2], '30':[150,5], '23':[120,4]}, {'22': [100,2], '30':[150,5], '23':[200,4], '25':[50,1]}]: fcall = fname + "(" + str(a) + ")" func.check_call(fcall).has_equal_value(incorrect_msg=(q+fcall+q) + " ให้ผลผิด")
แบบฝึกหัด 10-4 ข้อที่ 9

โจทย์ข้อนี้ให้นำสองข้อที่แล้วมารวมกัน คืออ่านอินพุตมา เพื่อหาและแสดงรหัสคณะที่มีคะแนนเฉลี่ยสูงสุด จะต่างเล็กน้อยก็ตรงที่ ในกรณีที่มีหลายคณะได้คะแนนเฉลี่ยมากสุดเท่ากัน ให้แสดงรหัสคณะตามลำดับที่พบในอินพุต จากตัวอย่างอินพุต จะแสดง 26, 30 และ 21 บรรทัดละรหัส (เพราะการอ่านอินพุต ได้พบรหัสคณะตามลำดับก่อนหลัง คือ 26, 30, แล้วก็ 21)

___inp___ = [ '6', '6240827226 30', '6230192830 25', '6231010221 25', '6230383821 20', '6231301221 30', '6240918226 20' ] def input(): t = ___inp___.pop(0) ___inp___.append(t) return t n = int(input()) fcode_seq = [] point = {} for k in range(n): student_id, p = input().split() p = int(p) fcode = student_id[-2:] if fcode not in point: point[fcode] = [p, 1] fcode_seq.append(fcode) else: point[fcode][0] += p point[fcode][1] += 1 x = [point[fcode][0]/point[fcode][1] for fcode in point] max_avg_point = max(x) for fcode in fcode_seq: if point[fcode][0]/point[fcode][1] == max_avg_point: print(fcode) inputs = [['7','6231010226 20','6240383823 20','6230827230 20', '6230827230 20', '6231301222 20', '6240030329 5','6231397230 20', '6241002228 20']] for inp in inputs: Ex().has_equal_output(pre_code = "___inp___[:] = " + str(inp), incorrect_msg = "แสดงผลไม่ตรงตามโจทย์")
เพิ่มอีกลิสต์เพื่อเก็บลำดับของรหัสคณะที่อ่านเข้ามา (ไม่เก็บตัวซ้ำ) แล้วใช้ลิสต์นี้ช่วยตอนหาและแสดงคณะที่มีคะแนนมากสุด