โจทย์: โครงสร้างข้อมูลซ้อนใน#

เรื่องลิสต์ซ้อนลิสต์#

ข้อ 1 - คะแนนรวม#

สมมติว่าเรามีข้อมูลคะแนนสอบของนักเรียนตลอดหนึ่งเทอม เขียนฟังก์ชันที่คำนวณว่านักเรียนแต่ละคนสอบผ่านหรือไม่ โดยใช้เกณฑ์ดังนี้

คะแนน

เกรด

>=60

ผ่าน

<60

ไม่ผ่าน

อินพุตที่ได้มาเป็นลิสต์ของลิสต์ของคะแนนของนักเรียนแต่ละคน เพราะฉะนั้นอินพุตเป็นโครงสร้างข้อมูลประเภทลิสต์ของลิสต์ของเลขจำนวนเต็ม

ให้ฟังก์ชันคืนค่าลิสต์ของบูลีนที่ระบุว่านักเรียนแต่ละคนผ่านวิชานี้หรือไม่

def sum_scores(score_lists):
    """
    
    >>> sum_scores([[10, 15, 30, 15], [2, 12, 25, 18]])
    [True, False]
    """
    return []

ข้อ 2 - ประมวลผลประโยค 1#

เขียนฟังก์ชันที่เปลี่ยนลิสต์ของประโยคที่ยังไม่ได้มีการตัดคำ ให้เป็นลิสต์ของลิสต์ของคำ (สตริง) โดยใช้คำสั่ง .split(' ')

def process_paragraph(sentence_list):
    """
    
    >>> process_paragraph(['This is a sentence.', 'This is another sentence.'])
    [['This', 'is', 'a', 'sentence.'], ['This', 'is', 'another', 'sentence.']]
    """
    return []

ข้อ 3 - ประมวลผลประโยค 2#

เขียนฟังก์ชันที่เปลี่ยนลิสต์ของประโยคที่ยังไม่ได้มีการตัดคำ ให้เป็นลิสต์ของจำนวนคำ จากนั้นให้คืนค่าทูเปิลที่มีค่าต่ำสุดและค่าสูงสุด

กระบวนการนี้เป็นกระบวนการที่เราทำบ่อยๆ เวลาประมวลผลประโยคเพื่อตรวจสอบว่ามีประโยคที่สั้นเกินไปหรือไม่ซึ่งอาจจะเกิดจากตอนดึงข้อมูลแล้วเกิดการผิดพลาด

def get_min_max_sentence_length(sentence_list):
    """
    
    >>> get_min_max_sentence_length(['short sentence.', 'This is a very long long long sentence.', 'a normal sentence here', 'another normal sentence'])
    (2, 8)
    """
    return (0, 0)

ข้อ 4 - ประมวลผลประโยค 3#

เวลาเราประมวลผลข้อมูลที่เป็นประโยคเราจะตัดประโยคที่สั้นเกินไปออก เพราะว่าอาจจะเกิดจากความผิดพลาด และอาจจะเป็นประโยคที่ไม่ได้สื่อความหมายมาก นอกจากนั้นแล้วเรามักจะจำกัดความยาวของประโยคที่เราต้องการจะวิเคราะห์อีกด้วยไม่ให้มีความยาวเกินไป

จงเขียนฟังก์ชันที่รับอาร์กิวเมนต์ 3 ตัว

  1. ลิสต์ของประโยคที่ยังไม่ได้มีการตัดคำ

  2. จำนวนคำขั้นต่ำที่ของประโยคที่ต้องการ

  3. จำนวนคำสูงสุด

คืนค่าลิสต์ของประโยคที่มีความยาวมากกว่าจำนวนคำที่กำหนด และถ้าหากประโยคมีความยาวเกิดจำนวนคำสูงสุดให้เก็บไว้เฉพาะคำแรก ๆ ตัดเอาคำที่เกินทิ้งไป

def limit_sentence_lengths(sentence_list, min_words, max_words):
    """
    รับลิสต์ของประโยค และกรองประโยคตามจำนวนคำขั้นต่ำและสูงสุดที่กำหนด

    >>> limit_sentence_lengths(['short sentence', 'This is a very long long long sentence', 'a normal sentence here', 'another normal sentence'], 2, 4)
    ['This is a very', 'a normal sentence here', 'another normal sentence']
    """
    return []

ข้อ 5 - ประมวลผลประโยค 4#

เขียนฟังก์ชันเพื่อแปลงข้อมูลให้อยู่ในรูปของลิสต์ของลิสต์ของคำ โดยที่อินพุตที่ได้รับมาเป็นลิสต์ของประโยค ซึ่งแต่ละประโยคเป็นสตริงที่ถูกแบ่งคำไว้แล้ว แต่ละคำคั่นด้วย | โดยที่ให้กรองคำที่อยู่ในเซ็ตของคำที่ต้องการกรองออก และกรองคำที่ไม่ใช่ตัวอักษรภาษาไทยออกไปโดยใช้เรกเอกซ์ [ก-์]

import re

def tokenize_clean(sentences, stopset):
    """
    >>> tokenize_clean(['ฉัน|รัก|การ|เขียน|โปรแกรม|Python', 'ใน|ที่|สุด|ก็|สำเร็จ'],  {'ฉัน', 'การ', 'ใน', 'ที่', 'ก็'}) 
    [['รัก', 'เขียน', 'โปรแกรม'],  ['สำเร็จ']]
    """ 
    return []

ข้อ 6 - ประมวลผลประโยค 5#

จงเขียนฟังก์ชันเพื่อวิเคราะห์ลิสต์ของประโยค ซึ่งแต่ละประโยคเป็นลิสต์ของสตริงคำ ฟังก์ชันจะต้องคำนวณว่าแต่ละประโยคมีคำที่สั้นกว่าสามตัวอักษรคิดเป็นร้อยละเท่าไร (จำนวนคำที่สั้นกว่าสามตัวอักษร หารด้วยจำนวนคำทั้งหมด) และคืนค่าที่คำนวณออกมาได้

def calculate_ratio_3_chars(sentences):
    """
    >>> calculate_ratio_3_chars([['Stay', 'in', 'the', 'middle'],['Like','you', 'a', 'little'], ["Don't", 'want','no','riddle']])
    0.25
    """
    return 0

ข้อ 7 - หาชื่อเล่นผู้ชาย#

สมมติว่าเรามีข้อมูลชื่อของนิสิตปัจจุบันซึ่งเก็บไว้ในลิสต์ของทูเปิล (ชื่อจริง, ชื่อเล่น, เพศ) จงเขียนฟังก์ชันที่คืนค่าลิสต์ที่มีชื่อเล่นของผู้ชายเรียงลำดับตามพจนานุกรม และไม่ซ้ำกัน

def get_male_nicknames(students):
    """
    >>> get_male_nicknames([('Maysa', 'May', 'Female'),('Waruntorn', 'Ing', 'Female'),('Maysaya', 'May', 'Female'), ('Watsakorn', 'May', 'Female'),('Chonkan', 'Atom', 'Male'),('Saran', 'Ton', 'Male'), ('Tonkid', 'Ton', 'Male')])
    ['Atom', 'Ton']  
    """
    return []

เรื่องลิสต์ของดิกชันนารีคู่ฟิลด์แวลู#

ข้อ 1 - ความนิยม#

เขียนฟังก์ชันหาจำนวนคอมเมนต์ของไอดีแอ็กเคานต์ที่กำหนดให้ โดยที่ทวีตถูกเก็บอยู่ในรูปดิกชันนารีคู่ฟิลด์แวลู

data = [ {'id': 'BarackObama', 'date': 'October 17, 2019', 'num comments': 243000,
  'num retweets': 37000, 'num fav': 250300, 'text': 'I was proud to work with Justin Trudeau as President'},
 {'id': 'SpeakerPelosi', 'date': 'October 17, 2019', 'num comments': 22700,
  'num retweets': 10000, 'num fav': 45600, 'text': 'What courage does it take to pass legislation that will save lives?'},
 {'id': 'BarackObama', 'date': 'October 15, 2019', 'num comments': 2000,
  'num retweets': 5000, 'num fav': 52800, 'text': 'In December, Michelle and I will head to Malaysia for the first @ObamaFoundation Leaders: Asia-Pacific gathering'}
]
def sum_comments_for_id(tweet_id, tweet_list):
    """
    
    >>> sum_comments_for_id('BarackObama', data)
    42000
    """
    return 0

ข้อ 2 - การปิดกั้นสื่อ#

สมมติว่าเราได้รับข้อมูลเกี่ยวกับเว็บไซต์ที่ถูกปิดกั้นมาจากองค์กรหนึ่งในรูปแบบของลิสต์ของดิกชันนารีคู่ฟิลด์แวลู แต่ว่าข้อมูลชุดนี้ต้องได้รับการอัพเดท จงเขียนฟังก์ชันที่คืนค่าลิสต์ของดิกชันนารีคู่ฟิลด์แวลูที่มีการอัพเดทดังนี้

  1. เว็บไซต์ที่ฟิลด์ ‘title’ มีคำว่า ‘men’ หรือคำว่า ‘women’ จะต้องถูกเอาออกจากลิสต์

  2. เว็บไซต์ที่ฟิลด์ ‘url’ มี ‘.co.th’ และจำนวนผู้เข้าชมรวมทุกประเทศมากกว่า 30000 ให้เพิ่มฟิลด์ ‘big Thai site’ และตั้งค่าเป็น True ถ้าหากไม่ตรงเงื่อนไขให้ตั้งค่าเป็น False

  3. ลบฟิลด์ ‘viewer’ ออก (ใช้ dict.pop)

ตัวอย่าง input:

data = [
{'title': 'Hottest men for you on this site', 'url': 'www.hotthing.com', 
 'viewer': {'thai': 1000, 'malaysia': 100, 'singapore': 600} },
{'title': 'Welcome to Zentrale', 'url': 'www.zen-zen.co.th', 
 'viewer': {'thai': 40000, 'malaysia': 10000, 'singapore': 600} },
{'title': 'Apply now for better life', 'url': 'www.betterlife.co.th', 
 'viewer': {'thai': 100, 'malaysia': 700, 'singapore': 200} },
{'title': 'We have everything you want.', 'url': 'www.everything.com', 
 'viewer': {'thai': 10000, 'malaysia': 20000, 'china': 60000} }
]
def tag_thai_sites(site_dict_list):
    """

    >>> tag_thai_sites(data)
    [
    {'title': 'Welcome to Zentrale', 'url': 'www.zen-zen.co.th','big Thai site': True},
    {'title': 'Apply now for better life', 'url': 'www.betterlife.co.th', 'big Thai site': False },
    {'title': 'We have everything you want.', 'url': 'www.everything.com', 'big Thai site': False}
    ]
    """
    return []

เรื่องดิกชันนารีซ้อนใน#

ข้อ 1 - รายชื่อ#

จงเขียนโปรแกรมที่สร้างลิสต์ของทูเปิล (name, line id) จากดิกชันนารีซ้อนใน โดยเรียงลำดับตามอักษรของชื่อ

def list_contact(contacts):
    """
    
    >>> list_contact({
    'Alex' : {'phone': '123-456-789', 'line': 'alexcool'},
    'Bo': {'home phone': '111-222-3333', 'line': 'bobo'},
    'Chris': {'phone': '444-555-6666', 'line': 'chrissie'},
    'Doug': {'mobile phone': '444-555-6666', 'line': 'dougd'}   
    })
    [('Alex', 'alexcool'), ('Bo', 'bobo'), ('Chris', 'chrissie'), ('Doug', 'dougd')]
    """
    return []

ข้อ 2 - ทูเปิลเป็นคีย์#

สมมติว่าเราได้ข้อมูลเบอร์โทรศัพท์ที่เก็บอยู่ในดิกชันนารีที่มีคีย์เป็นทูเปิลของชื่อและนามสกุล และแวลูเป็นสตริงที่เก็บเบอร์โทรศัพท์

จงเขียนฟังก์ชัน lookup_by_lastname ที่รับนามสกุลที่เป็นสตริง และดิกชันนารีข้อมูลเบอร์โทรศัพท์ และคืนค่าเบอร์โทรศัพท์ของคนที่มีนามสกุลที่กำหนดให้ ถ้าเกิดว่านามสกุลนั้นไม่มีอยู่ในดิกชันนารีให้คืนค่า None

def lookup_by_lastname(last_name, data):
    """
    
    >>> name_to_phone =  { ('Mark', 'Wahlberg') : '111-222-3333',
        ('Jane', 'Doe'): '222-333-4444',
        ('Jane', 'Eyre'): '333-444-5555'
        }
    >>> lookup_by_lastname('Doe', name_to_phone_numbers)
    '222-333-4444'
    """
    return None

ข้อ 3 - Name to age - Age to name#

เปลี่ยนจาก

name_to_age = {'ชญา': 33, 
         'อรรถพล': 34,
         'โนโซมิ': 34}

ให้เป็น

age_to_name = {33: ['ชญา'], 
         34: ['อรรถพล', 'โนโซมิ']
name_to_age = {'ชญา': 33, 
         'อรรถพล': 34,
         'โนโซมิ': 34}

ข้อ 4 - เปลี่ยนคีย์#

เปลี่ยนโครงสร้างของดิกชันนารีจากที่เคยมีคีย์เป็นทูเปิล (first name, last name) เป็นแค่ last name อย่างเดียว

name_to_phone = { ('Mark', 'Wahlberg') : '111-222-3333',
  ('Jane', 'Doe'): '222-333-4444',
  ('Jane', 'Eyre'): '333-444-5555'
}

ข้อ 5 - นับจำนวนนักเรียน#

สมมติว่าเรามีข้อมูลการลงทะเบียนเรียนในดิกชันนารีที่มีคีย์เป็นสตริงที่เก็บชื่อวิชา และแวลูเป็นลิสต์ของสตริงที่เก็บชื่อนักเรียนที่ลงเรียนวิชานั้นอยู่

จงเขียนฟังก์ชันที่คืนค่าลิสต์ของชื่อนักเรียนทั้งหมดที่ไม่ซ้ำกัน

def list_all_students(registration):
    """
    >>> registration = {'CompLing': ['Andy', 'Brittney', 'Catherine'],
        'SoundSys': ['Andy', 'Brittney', 'Donald', 'Elaine', 'Fodor'],
        'GramSys': ['Brittney', 'Girth', 'Harry'],
        'ManGeog': ['Andy', 'Donald', 'Girth']
    }
    >>> list_all_students(registration)
    ['Andy', 'Brittney', 'Catherine', 'Donald', 'Elaine', 'Fodor', 'Girth', 'Harry']
    """
    return []

ข้อ 6 - ใครชอบเรียนเยอะ#

สมมติว่าเรามีข้อมูลการลงทะเบียนเรียนในดิกชันนารีที่มีคีย์เป็นสตริงที่เก็บชื่อวิชา และแวลูเป็นลิสต์ของสตริงที่เก็บชื่อนักเรียนที่ลงเรียนวิชานั้นอยู่

จงเขียนฟังก์ชันที่คืนค่าดิกชันนารีที่คีย์คือจำนวนคลาสที่เรียนต่อคน และแวลูคือคนที่ลงเรียนจำนวนคลาสเท่ากับคีย์

def get_num_classes_to_students(registration):
    """
    
    Example:
    >>> registration = {'CompLing': ['Andy', 'Brittney', 'Catherine'],
        'SoundSys': ['Andy', 'Brittney', 'Donald', 'Elaine', 'Fodor'],
        'GramSys': ['Brittney', 'Girth', 'Harry'],
        'ManGeog': ['Andy', 'Donald', 'Girth']
    }
    >>> get_num_classes_to_students(registration)
    {3: ['Andy', 'Brittney'],
    2: ['Donald', 'Girth'],
    1: ['Catherine', 'Elaine', 'Fodor', 'Harry']}
    """
    return {}

ข้อ 7 - รวมดิกชันนารี#

จงเขียนฟังก์ชัน combine_dicts ที่รวมดิกชันนารีสองอันเข้าไว้ด้วยกัน โดยที่ดิกชันนารีมีคีย์และแวลูเป็นสตริง ฟังก์ชันต้องคืนค่าดิกชันนารีที่มีคีย์เป็นสตริงและแวลูเป็นลิสต์ของสตริง เช่น

dict1 = {'a': 'ant', 'b': 'bird', 'c':'caterpillar'}
dict2 = {'a': 'ant', 'c': 'cat', 'd': 'dog'}
combine_dicts(dict1 , dict2)
>>> {'a': ['ant', 'ant'], 
     'b': ['bird'], 
     'c': ['caterpillar','cat'], 
     'd':['dog']}

แวลูที่คู่กับ 'c' เป็นลิสต์ที่มี 'catepillar' ซึ่งมาจาก dict1 และ 'cat' ซึ่งมาจาก dict2

แวลูที่คู่กับ 'd' เป็นลิสต์ที่มี 'dog' ซึ่งมาจาก dict2 เพราะว่า dict1 ไม่มีคีย์ 'c' อยู่

def combine_dicts(d1, d2):
    return {}

ข้อ 8 - ใครไม่ส่งการบ้าน#

สมมติว่าเรามีข้อมูลการส่งงานของนิสิต เก็บอยู่ในดิกชันนารีที่มีคีย์เป็นสตริงที่เก็บชื่อการบ้านทั้งหมด และแวลูเป็นลิสต์ของสตริงที่เก็บชื่อนิสิตที่ส่งการบ้านชิ้นนั้นแล้ว จงเขียนฟังก์ชันที่คืนค่าลิสต์ของชื่อนิสิตที่ส่งการบ้านไม่ครบ

def find_missing_work(data):
    """
    >>> find_missing_work( {'PA1': ['Bew', 'Mild', 'Nipun'],
        'PA2': ['Mild', 'Bew', 'PP'],
        'PA3': ['Bew', 'Nipun', 'Mild'] } )
    ['Nipun', 'PP']
    """
    return []