แบบฝึกหัด: สตริง#

ข้อ 1 - อุปสรรค ปัจจัย#

จงเขียนโปรแกรมที่ทำหน้าที่ตรวจสอบว่าคำมี “อุปสรรค” (prefix) หรือ “ปัจจัย” (suffix) ที่ระบุหรือไม่ และหากมี ให้แสดงหน่วยคำที่อุปสรรคหรือปัจจัยนั้นเกาะอยู่

เช่น คำว่า ‘ใจแตก’ มี ‘ใจ’ เป็นอุปสรรคที่เชื่อมต่อกับหน่วยคำ ‘-แตก’

detect_prefix_suffix('ใจแตก', 'ใจ') --> '-แตก'

คำว่า ‘เข็ญใจ’ มี ‘ใจ’ เป็นปัจจัยที่เชื่อมต่อกับหน่วยคำ ‘เข็ญ-’

detect_prefix_suffix('เข็ญใจ', 'ใจ') --> 'เข็ญ-'

หากคำที่ให้ไม่เป็นอุปสรรคหรือปัจจัย ให้คืนค่าเป็นช่องว่าง (‘’)

หมายเหตุ: อย่าลืมเติมเครื่องหมายขีด (-) ให้ถูกต้อง โดยขีดหน้าคืออุปสรรค และขีดหลังคือปัจจัย

คำใบ้: แนะนำให้แก้โจทย์เล็กๆ ก่อนสามโจทย์ได้แก่

  1. กรณีที่ไม่เป็น prefix และไม่เป็น suffix

  2. กรณีที่เป็น prefix

  3. กรณีที่เป็น suffix

def detect_prefix_suffix(word, affix):
    """
    ตัวอย่าง

    >>> detect_prefix_suffix('หน้าเนื้อ', 'หน้า')
    '-เนื้อ'
    >>> detect_prefix_suffix('การเดินทาง', 'การ')
    '-เดินทาง'
    >>> detect_prefix_suffix('เหลือใจ', 'ใจ')
    'เหลือ-'
    >>> detect_prefix_suffix('ใจ', 'ใจ')
    ''
    >>> detect_prefix_suffix('หน้าเนื้อใจเสือ', 'ใจ')
    ''
    """
    return ''

ข้อ 2 - คำประสม#

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

  • คำว่า ‘headband’ สามารถแบ่งออกเป็น ‘head’ และ ‘band’

  • คำว่า ‘warhead’ สามารถแบ่งออกเป็น ‘war’ และ ‘head’

  • คำว่า ‘headset’ สามารถแบ่งออกเป็น ‘head’ และ ‘set’

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

is_word('head') --> True 
is_word('set') --> True 
is_word('filt') --> False
def is_word(word):
	"""is word a valid word?
	
	Assume four words in the vocabulary
	"""
	return word in ['head', 'band', 'set', 'war']

	
def splittable(word):
	"""
	ตัวอย่าง
	>>> splittable('headband') 
	True
	>>> splittable('warhead')
	True
	>>> splittable('bandid')
	False
	"""
	return False

ข้อ 3 - กลับด้านสตริง#

จงเขียนฟังก์ชันชื่อ reverse_string ซึ่งรับพารามิเตอร์ 1 ตัวเป็นสตริง (สมมติว่าชื่อ original_string) แล้วคืนค่าเป็นข้อความที่มีลำดับตัวอักษรกลับด้านจากข้อความต้นฉบับ original_string

ตัวอย่าง

reverse_string รับข้อมูลเป็นคำว่า ‘Hello’ จะต้องคืนค่าเป็น ‘olleH’

def reverse_string(text):
    return ''

ข้อ 4 - พาลินโดรม#

เขียนฟังก์ชันชื่อ is_palindrome ซึ่งรับพารามิเตอร์เป็นข้อความ 1 ชุด แล้วตรวจสอบว่าข้อความนั้นเป็นพาลินโดรมหรือไม่ โดยจะต้องถือว่าตัวอักษรพิมพ์เล็กและตัวอักษรพิมพ์ใหญ่เป็นคนละตัวอักษร (case-sensitive)

พาลินโดรม หมายถึง ข้อความที่เมื่ออ่านจากซ้ายไปขวา จะเหมือนกับการอ่านจากขวาไปซ้ายทุกประการ ตัวอย่าง:

  • คำว่า ‘TENET’ และ ‘civic’ เป็นพาลินโดรม

  • คำว่า ‘hello’ และ ‘aloha’ ไม่เป็นพาลินโดรม

  • คำว่า ‘radar’ เป็นพาลินโดรม แต่ ‘RaDar’ ไม่ใช่พาลินโดรม เพราะตัวอักษร “R” และ “r” ถือว่าเป็นคนละตัวอักษร

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

def is_palindrome(word):
    pass

ข้อ 5 - เกมส์พิกลาติน#

ภาษาพิกลาติน (Pig Latin) เป็นภาษาที่มีรูปแบบใกล้เคียงกับภาษาอังกฤษ โดยมีกฎในการแปลงคำดังนี้:

  1. ย้ายตัวอักษรตัวแรกของคำไปไว้ด้านท้ายสุด

  2. เติมตัวอักษร ‘a’ ที่ท้ายคำหลังจากการย้ายตัวอักษร

ตัวอย่าง

  • คำว่า hello เมื่อแปลงเป็นภาษาพิกลาตินจะกลายเป็น elloha

  • คำว่า sleep เมื่อแปลงเป็นภาษาพิกลาตินจะกลายเป็น leepsa

เขียนฟังก์ชัน eng_to_pig_latin ซึ่งรับคำศัพท์ภาษาอังกฤษ 1 คำเป็นพารามิเตอร์ แล้วคืนค่าคำภาษาพิกลาตินของคำ ๆ นั้น

def eng_to_pig_latin(english_word):
    return ''

ข้อ 6 - ภาษาลับ#

คุณกับเพื่อนได้คิดค้นโค้ดลับของคำศัพท์ภาษาอังกฤษ โดยการแปลงคำศัพท์ภาษาอังกฤษดังนี้

  1. ถ้าคำศัพท์มีความยาวเป็นเลขคู่ ให้นำครึ่งหลังของคำมาไว้ข้างหน้า แล้วนำครึ่งหน้าของคำไปไว้ข้างหลัง

  2. ถ้าคำศัพท์มีความยาวเป็นเลขคี่ ให้ตัดตัวอักษรตัวแรกออก แล้วนำคำที่เหลือสลับเหมือนคำศัพท์ที่มีความยาวเป็นเลขคู่ แล้วนำตัวอักษรตัวแรกที่ตัดออกไว้ด้านหน้าคำตามเดิม

เขียนฟังก์ชัน flip_string ซึ่งรับคำศัพท์ภาษาอังกฤษ 1 คำเป็น พารามิเตอร์ แล้วคืนค่าโค้ดลับของคำ ๆ นั้น

ตัวอย่าง

‘bear’ แปลงเป็น ‘arbe’
‘hello’ แปลงเป็น ‘hloel’
‘language’ แปลงเป็น ‘uagelang’
‘natural’ แปลงเป็น ‘nralatu’

def flip_string(text_to_flip):
    pass

ข้อ 7 - ไม่ 1 ไม่ 5#

จงหาผลรวมของจำนวนเต็มที่น้อยกว่า 100 และไม่มีเลข 1 กับ 5

\(2 + 3 + 4 + 6 + 7 + 8 + 9 + 20 + 22 + 23 + 24 + 26 \cdots + 99\)

คำตอบคือ 3432

คำใบ้: เปลี่ยนเป็นสตริงแล้วใช้คำสั่ง in

def sum_except15():
    pass

ข้อ 8 - ไปรษณีย์#

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

ตัวอย่าง

data = 'Wattana 10110 Yannawa 10120 Dusit 10300'

ผลลัพธ์ที่ต้องการจะเป็น

Wattana 10110
Yannawa 10120
Dusit   10300
def postal_table(raw_text):
    """
    1. add each character to new_string, if not space
    2. replace space before postal code with tab \t
    3. replace space after postal code with newline \n
    """

ข้อ 9 - ทศนิยม#

เรียกใช้ฟังก์ชัน input เพื่อรับค่าทางหน้าจอจากผู้ใช้ 1 ค่า แล้วแสดงผลทางหน้าจอว่าค่าที่ผู้ใช้ใส่มาเป็น float หรือไม่

คำใบ้: float จะมีจุดทศนิยม 1 จุด และทีเหลือเป็นตัวเลข แต่ว่าอาจจะเป็นค่าลบได้

ตัวอย่าง

input

output

3.1415

True

12

False

-35.439145

True

43BDgk

False

def is_float():
    pass

ข้อ 10 - สร้างรหัสผ่าน#

ในโมดูล string มีตัวแปรที่ชุดตัวอักษรดังนี้ (ไม่ใช่ฟังก์ชั่น จึงไม่ต้องใส่วงเล็บ)

import string

string.ascii_letters
>>>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

string.digits
>>>'0123456789'

จงสร้างฟังก์ชันสุ่มเลือกรหัสผ่านจากตัวอักษรภาษาอังกฤษและตัวเลข รหัสต้องมีลักษณะดังนี้

  • ต้องมีตัวอักษรภาษาอังกฤษอย่างน้อย 4 ตัว

  • รหัส 2 ตัวสุดท้ายต้องเป็นตัวเลข

  • รหัสต้องมีความยาวอย่างน้อย 6 ตัว ผู้ใช้ฟังก์ชันนี้สามารถระบุความยาวของรหัสที่ต้องการได้ แต่ถ้าระบุความยาวมาต่ำกว่า 6 ตัวอักษร ให้ถือว่ารหัสที่ต้องการมีความยาว 6 ตัวอักษร

โจทย์ข้อนี้จำเป็นต้องนำเข้าโมดูล random และใช้คำสั่ง random.choice(x) จะสุ่มเลือกตัวอักษรที่อยู่ในสตริง x

import string, random
def generate_password(n):
    pass

ข้อ 11 - รูปอดีต#

11.1 ตรวจรูปอดีต#

จงเขียนฟังก์ชันในการตรวจสอบว่าคำภาษาอังกฤษที่ได้รับมาเป็นกริยาที่เป็นรูปอดีต (past form) หรือไม่ โดยให้ใช้กฎง่าย ๆ ดังนี้

  • ห้ามขึ้นต้นด้วยตัวใหญ่

  • ห้ามมีตัวเลขเลย และ

  • ต้องลงท้ายด้วย ed

def is_past_form(word):
    """
    ตัวอย่าง
    >>> is_past_form('pasted')
    True
    >>> is_past_form('brushed')
    True
    >>> is_past_form('SpotTed')
    False
    >>> is_past_form('ate')
    False
    >>> is_past_form('M34ed')
    False
    """
    return False

11.2 ออกเสียง ed#

คำกริยาภาษาอังกฤษที่เป็นรูปอดีตมักจะลงท้ายด้วย -ed แต่ว่า -ed จะออกเสียงออกมาเป็นอย่างไรนั้นขึ้นอยู่กับพยัญชนะที่อยู่ข้างหลังสุดของหน่วยคำกริยา โดยมีกฎดังนี้

  1. กริยาที่ลงท้ายด้วย s sh ถ้าเปลี่ยนเป็นรูปอดีตโดยการเติม -ed จะออกเสียงเป็น /t/

  2. กริยาที่ลงท้ายด้วย t d ถ้าเปลี่ยนเป็นรูปอดีตโดยการเติม -ed จะออกเสียงเป็น /id/

  3. กริยาอื่น ๆ ที่เหลือ ถ้าเปลี่ยนเป็นรูปอดีตโดยการเติม -ed จะออกเสียงเป็น /d/

ตัวอย่าง

  • crashed → /t/

  • missed → /t/

  • wanted → /id/

  • reminded → /id/

  • scrubbed → /d/

  • tuned → /d/

จงเขียนฟังก์ชันที่รับคำภาษาอังกฤษเป็นพารามิเตอร์ และคืนค่าสตริงที่บอกว่า -ed ออกเสียงเป็นอะไร (สำหรับกฎข้อแรก ไม่ต้องคำนึงถึงคำที่ลงท้ายด้วย k p ch x gh z) ถ้าคำที่รับมาไม่ใช่รูปอดีต (ตามที่กำหนดไว้ในฟังก์ชันจาก 11.1) ให้คืนค่าเป็นสตริงเปล่า

def pronounce_ed(word):
    """
    ตัวอย่าง
    >>> pronounce_ed('SpotTed')
    ''
    >>> pronounce_ed('spotted')
    '/id/'
    >>> pronounce_ed('1254ed')
    ''
    >>> pronounce_ed('refreshed')
    '/t/'
    """
    return ''

ข้อ 12 - ชื่อย่อ#

จงเขียนฟังก์ชัน convert_to_initials เปลี่ยนชื่อภาษาอังกฤษเป็นชื่อย่อสองตัวอักษรโดยนำตัวอักษรพิมพ์ใหญ่ 2 ตัวในชื่อแปลงมาเป็นชื่อย่อ ทั้งนี้ถ้าชื่อนั้นมีตัวอักษรพิมพ์ใหญ่น้อยกว่า 2 ตัว หรือมากกว่า 2 ตัวจะไม่สามารถแปลงได้และคืนค่า ‘’ และ print ข้อความว่า ‘Please enter valid name.’

def initial_name(name):
    """
    >>> initial_name('Mary Beth')
    MB
    >>> initial_name('Lara Jean')
    LJ
    >>> initial_name('Alexander')
    Please enter valid name.
    >>> initial_name('Mary McLeod')
    Please enter valid name.
    """
    return ''

ข้อ 13 - นับตัวสะกดแปลก#

ตัวอักษรภาษาอังกฤษนั้นมีทั้ง “ตัวพิมพ์ใหญ่” (uppercase) และ “ตัวพิมพ์เล็ก” (lowercase) โดยในสภาวะปกติ ตัวพิมพ์ใหญ่จะสามารถปรากฏได้เพียงตำแหน่งแรกของคำเท่านั้น จงเขียนฟังก์ชันชื่อ count_anomalies ที่รับพารามิเตอร์เป็นสตริง 1 ตัว แล้วคืนค่าจำนวนตัวอักษรพิมพ์ใหญ่ที่ปรากฏในตำแหน่งอื่น ๆ นอกเหนือจากตำแหน่งเริ่มต้น โดยสตริงที่เป็นอินพุตประกอบไปด้วยตัวอักษรอังกฤษเท่านั้นและจะไม่มีช่องว่างอยู่ภายใน

def count_anomalies(word):
    """
    ตัวอย่าง input และ output ที่ถูกต้อง:
    >>> num_anomalies("Hello")
    0
    >>> num_anomalies("hello")
    0
    >>> num_anomalies("hEllo")
    1
    >>> num_anomalies("HeLLo")
    2
    >>> num_anomalies("hELLo")
    3
    >>> num_anomalies("HELLO")
    4
    """
    return 0