Example 8 — Make a Code Name (debugging) ตัวอย่างที่ 8 — สร้างชื่อรหัสจากชื่อกลับหลัง (debugging)

A debugging problem: the program below should turn a name into a code name written from the last letter to the first, but it hides one bug. โจทย์ debugging: โปรแกรมด้านล่างควรเปลี่ยนชื่อเป็นชื่อรหัสที่เขียนจากตัวสุดท้ายไปตัวแรก แต่มี bug ซ่อนอยู่ 1 จุด

How to work on this page: read the problem and the flowcharts, then check the code against the flowcharts box by box. Run the test list, find the wrong line, and fix the program in the code box yourself. Run the test list again until every test gives its expected output, and only then open the solution. To review the kinds of error, the kinds of test case and the bug-hunting tools, see 11 Testing and Debugging.

วิธีทำโจทย์หน้านี้: อ่านโจทย์และ flowchart แล้วตรวจโค้ดเทียบกับ flowchart ทีละกล่อง จากนั้นรันตามรายการทดสอบ หาบรรทัดที่ผิด และแก้โปรแกรมในกล่องโค้ดเอง รันรายการทดสอบซ้ำจนทุกข้อได้ผลตามที่ควรได้ แล้วจึงเปิดดูเฉลย ทบทวนชนิดของ error, ชนิดของ test case และเครื่องมือหา bug ได้ที่บท 11 การทดสอบและการแก้ไขโปรแกรม

1 The problem โจทย์

Read a name made of 1 to 10 English letters. If the name is empty, longer than 10 letters, or has anything else mixed in (spaces, digits, punctuation), warn the user and ask again. Once the name is valid, make a code name: write the name from its last letter to its first, with the first letter of the code name as a capital letter and every other letter small, then show Code name: <code name>.

รับชื่อที่เป็นตัวอักษรภาษาอังกฤษ 1 ถึง 10 ตัว ถ้าชื่อว่าง ยาวเกิน 10 ตัว หรือมีอย่างอื่นปน (ช่องว่าง ตัวเลข เครื่องหมาย) ให้แจ้งเตือนแล้วถามใหม่ เมื่อได้ชื่อที่ถูกต้องแล้ว ให้สร้างชื่อรหัส โดยเขียนชื่อจากตัวสุดท้ายไปตัวแรก ให้ตัวแรกของชื่อรหัสเป็นตัวพิมพ์ใหญ่และตัวที่เหลือเป็นตัวพิมพ์เล็กทั้งหมด แล้วแสดง Code name: <ชื่อรหัส>

  • Example: Robert → Code name: Trebor
  • is_name(text) — returns True only when text has 1 to 10 characters and every one of them is a letter
  • read_backward(text) — returns text written from the last letter to the first
  • name_case(text) — returns text with a capital first letter and small letters after it
  • ตัวอย่าง: Robert → Code name: Trebor
  • is_name(text) — คืนค่า True เฉพาะเมื่อ text มี 1 ถึง 10 ตัว และทุกตัวเป็นตัวอักษร
  • read_backward(text) — คืนค่า text ที่เขียนจากตัวสุดท้ายไปตัวแรก
  • name_case(text) — คืนค่า text ที่ตัวแรกเป็นตัวพิมพ์ใหญ่และตัวที่เหลือเป็นตัวพิมพ์เล็ก
New in this program:
  • isalpha() is True when the character is a letter.
  • len(text) == 0 or len(text) > 10 is True when at least one of the two checks is true: the text is empty or it is longer than 10.
  • text[i] is the character at position i counted from the left, starting at 0. A negative index counts from the end: text[-1] is the last letter and text[-2] the one before it.
  • upper() / lower() give the capital / small form of a letter.
  • while True repeats forever until break leaves the loop.
คำสั่งใหม่ในโปรแกรมนี้:
  • isalpha() ให้ค่า True เมื่อตัวนั้นเป็นตัวอักษร
  • len(text) == 0 or len(text) > 10 เป็น True เมื่อเงื่อนไขข้อใดข้อหนึ่งเป็นจริง คือข้อความว่างหรือยาวเกิน 10 ตัว
  • text[i] คือตัวอักษรตำแหน่งที่ i นับจากซ้าย เริ่มที่ 0 ส่วนดัชนีติดลบนับจากท้าย text[-1] คือตัวสุดท้าย และ text[-2] คือตัวรองสุดท้าย
  • upper() / lower() แปลงตัวอักษรเป็นตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็ก
  • while True วนซ้ำไปเรื่อยๆ จนกว่าจะเจอ break ซึ่งสั่งให้ออกจาก loop
2 Main program — flowchart and full code (contains a bug) โปรแกรมหลัก — flowchart และโค้ดทั้งหมด (มี bug)

The program starts a while True loop and reads a name into name. It checks whether the name is valid with the sub-function is_name: if it is, break leaves the loop; if not, it shows a warning with print and goes back to ask again. After leaving the loop it calls read_backward(name), passes the result to name_case, shows the code name with print, and the program ends.

โปรแกรมนี้เริ่มต้นด้วยวน loop while True แล้วรับชื่อเก็บใน name ตรวจสอบเงื่อนไขว่าชื่อถูกต้องหรือไม่ด้วย function ย่อย is_name ถ้าใช่ให้ break ออกจาก loop ถ้าไม่ใช่ให้แสดงข้อความเตือนด้วย print แล้วกลับไปรับค่าใหม่ หลังออกจาก loop จึงเรียก read_backward(name) แล้วส่งผลที่ได้ต่อให้ name_case แสดงชื่อรหัสด้วย print และจบการทำงานของโปรแกรม

Start ask until the name is valid Keep asking while True Yes Ask for a name name = input(...) Valid name? is_name(name)? No Warn the user print('Use 1 to 10 ...') Yes Leave the loop break Show the code name print('Code name:', name_case(read_backward(name))) End
The code below follows the flowcharts of this card and cards 3–4 box by box, including the bug. Change the names in the [input] box or use the form under the output, then press Run. โค้ดด้านล่างเขียนตาม flowchart ของการ์ดนี้และการ์ดที่ 3–4 ทุกกล่อง รวมทั้ง bug ด้วย แก้ชื่อในกล่อง [input] หรือใช้ช่องใต้ผลลัพธ์ แล้วกด Run
[main]
[input]
[output]
Your name: Mary Ann
Use 1 to 10 letters (A-Z, a-z), please try again
Your name: Robert
Code name: Rtrebo

Try it yourself — the first value you submit clears the example and starts a new run. Submit one value at a time: a name that is not valid shows the warning and waits for the next value; a valid name finishes the run. Submitting after that starts a new run. Press Submit with an empty box to test an empty name.

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

3 is_name(text)

is_name starts by checking whether len(text) == 0 or len(text) > 10; if it is, it sends back False with return straight away. If not, it sets i = 0 as the character position and checks whether i < len(text); if it is, it checks whether text[i].isalpha(). If that character is not a letter, it sends back False with return straight away. If it is a letter, it increases i by 1 and checks again. This repeats until i < len(text) is false, so every character was a letter and it sends back True with return.

is_name เริ่มต้นด้วยตรวจสอบเงื่อนไขว่า len(text) == 0 or len(text) > 10 หรือไม่ ถ้าใช่ให้ส่งค่า False กลับด้วย return ทันที ถ้าไม่ใช่ให้กำหนดค่า i = 0 เป็นตัวชี้ตำแหน่งตัวอักษร แล้วตรวจสอบเงื่อนไขว่า i < len(text) หรือไม่ ถ้าใช่ให้ตรวจสอบว่า text[i].isalpha() หรือไม่ ถ้าตัวนั้นไม่ใช่ตัวอักษรให้ส่งค่า False กลับด้วย return ทันที ถ้าเป็นตัวอักษรให้เพิ่ม i ขึ้น 1 แล้วกลับไปตรวจสอบอีกครั้ง ทำแบบนี้จน i < len(text) เป็นเท็จ แสดงว่าทุกตัวเป็นตัวอักษร จึงส่งค่า True กลับด้วย return

is_name(text) Empty or longer than 10? len(text) == 0 or len(text) > 10? Yes return False No Start at the first character i = 0 More characters? i < len(text)? Yes Is it a letter? text[i].isalpha()? No return False Yes Next character i += 1 No return True

Test the function on its own before using it in the main program. Decide which kind of test case each value is.

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

[test]
[output]
True
False
False
True
False
False
Show the kinds of test case ดูชนิดของ test case
  • 'Robert' — Normal
  • 'Maximilian' (10 letters, the longest name allowed) — Boundary
  • 'Christopher' (11 letters, one past the edge), '' (empty text) — Boundary
  • 'Mary Ann' (has a space), 'R2D2' (has digits) — Error
  • 'Robert' — Normal
  • 'Maximilian' (10 ตัว ยาวที่สุดที่รับได้) — Boundary
  • 'Christopher' (11 ตัว เลยขอบไปหนึ่งค่า), '' (ข้อความว่าง) — Boundary
  • 'Mary Ann' (มีช่องว่าง), 'R2D2' (มีตัวเลข) — Error
4 read_backward(text) & name_case(text)

read_backward starts by setting backward = '' to hold the result and i = 0 as the letter position. It checks whether i < len(text); if it is, it adds the letter text[-i] to the end of backward, increases i by 1 and checks again. This repeats until the condition is false, so it sends backward back with return.

read_backward เริ่มต้นด้วยกำหนดค่า backward = '' สำหรับเก็บผลลัพธ์ และ i = 0 เป็นตัวชี้ตำแหน่งตัวอักษร แล้วตรวจสอบเงื่อนไขว่า i < len(text) หรือไม่ ถ้าใช่ให้ต่อตัวอักษร text[-i] เข้าท้าย backward เพิ่ม i ขึ้น 1 แล้วกลับไปตรวจสอบอีกครั้ง ทำแบบนี้จนเงื่อนไขเป็นเท็จ จึงส่งค่า backward กลับด้วย return

read_backward(text) Start an empty result backward = '' Start at the first letter i = 0 More letters? i < len(text)? Yes Add one letter from the end backward += text[-i] Next letter i += 1 No return backward

name_case starts by setting result = '' to hold the result and i = 0 as the letter position. It checks whether i < len(text); if it is, it checks whether i == 0. If it is the first letter, it adds text[i].upper() to the end of result; if not, it adds text[i].lower(). Either way it increases i by 1 and checks i < len(text) again. This repeats until the condition is false, so it sends result back with return.

name_case เริ่มต้นด้วยกำหนดค่า result = '' สำหรับเก็บผลลัพธ์ และ i = 0 เป็นตัวชี้ตำแหน่งตัวอักษร แล้วตรวจสอบเงื่อนไขว่า i < len(text) หรือไม่ ถ้าใช่ให้ตรวจสอบว่า i == 0 หรือไม่ ถ้าเป็นตัวแรกให้ต่อ text[i].upper() เข้าท้าย result ถ้าไม่ใช่ให้ต่อ text[i].lower() ไม่ว่าทางใดทางหนึ่ง หลังจากนั้นเพิ่ม i ขึ้น 1 แล้วกลับไปตรวจสอบ i < len(text) อีกครั้ง ทำแบบนี้จนเงื่อนไขเป็นเท็จ จึงส่งค่า result กลับด้วย return

name_case(text) Start an empty result result = '' Start at the first letter i = 0 More letters? i < len(text)? Yes First letter? i == 0? Yes Add it as a capital letter result += text[i].upper() No Add it as a small letter result += text[i].lower() Next letter i += 1 No return result
5 Test list รายการทดสอบ

Submit the values in order with the form in card 2, or put them one per line in the [input] box, then compare with the expected output column. Every run ends with a line Code name: …; the table shows only the part after it. The last column shows what the code with the bug gives.

ส่งค่าตามลำดับด้วยช่องในการ์ดที่ 2 หรือใส่ไว้บรรทัดละค่าในกล่อง [input] แล้วเทียบกับคอลัมน์ผลที่ควรได้ ทุกครั้งที่รันจบจะได้บรรทัด Code name: … ตารางแสดงเฉพาะส่วนหลัง Code name: ส่วนคอลัมน์สุดท้ายคือผลจากโค้ดที่ยังมี bug

Input (in order)ข้อมูลที่ป้อน (ตามลำดับ) Kindชนิด Expected outputผลที่ควรได้ Output of the buggy codeผลจากโค้ดที่มี bug
Robert Normal Trebor Rtrebo ✗
sIMON Normal (mixed case)Normal (ตัวพิมพ์ปนกัน) Nomis Snomi ✗
j Boundary (one letter)Boundary (ตัวอักษรเดียว) J J ✓
Maximilian Boundary (exactly 10 letters)Boundary (10 ตัวพอดี) Nailimixam Mnailimixa ✗
Christopher, Leo Boundary (11 letters)Boundary (11 ตัว) 1 warning, thenเตือน 1 ครั้ง แล้ว Oel 1 warning, thenเตือน 1 ครั้ง แล้ว Loe ✗
(empty), then(ว่าง) แล้ว Tom Boundary (empty text)Boundary (ข้อความว่าง) 1 warning, thenเตือน 1 ครั้ง แล้ว Mot 1 warning, thenเตือน 1 ครั้ง แล้ว Tmo ✗
Mary Ann, R2D2, Kim Error 2 warnings, thenเตือน 2 ครั้ง แล้ว Mik 2 warnings, thenเตือน 2 ครั้ง แล้ว Kmi ✗
6 Your tasks ภารกิจ
  1. Check the code of all three functions and the main program against their flowcharts, and note anything that looks suspicious.
  2. Run every input in the test list and note whether the actual output matches the expected output.
  3. The name check (warn, then ask again) works, but the code name is wrong. Compare Rtrebo with Trebor: which letter is in the wrong place? And why does j give the right answer even though the program has a bug?
  4. Which kind of error is this bug, and why?
  5. Find the wrong line:
    • change the last line to print(read_backward(name)) for a moment, to see whether the letters are already in the wrong order before name_case runs, or
    • add print(i, -i, text[-i], backward) inside the loop of read_backward,
    then fill in the trace table below for text = 'Leo'.
  6. Fix the code in the box and run the test list again. Every input must give its expected output.
  7. Think further: why is testing with j alone not enough?
  1. ตรวจโค้ดทั้ง 3 ฟังก์ชันและส่วนหลักเทียบกับ flowchart แล้วจดจุดที่สงสัย
  2. รันทุกข้อในรายการทดสอบ แล้วจดผลที่ได้จริงว่าตรงกับผลที่ควรได้หรือไม่
  3. ส่วนตรวจชื่อ (เตือนแล้วถามใหม่) ทำงานถูก แต่ชื่อรหัสผิด ลองเทียบ Rtrebo กับ Trebor ตัวอักษรตัวไหนอยู่ผิดที่ และทำไม j ได้ผลถูกทั้งที่โปรแกรมมี bug
  4. bug นี้เป็น error ชนิดไหน เพราะอะไร
  5. หาบรรทัดที่ผิด
    • เปลี่ยนบรรทัดสุดท้ายเป็น print(read_backward(name)) ชั่วคราว เพื่อดูว่าตัวอักษรเรียงผิดตั้งแต่ก่อนเข้า name_case หรือไม่ หรือ
    • ใส่ print(i, -i, text[-i], backward) ใน loop ของ read_backward
    แล้วกรอก trace table ด้านล่าง เมื่อ text = 'Leo'
  6. แก้โค้ดในกล่อง แล้วรันรายการทดสอบซ้ำ ทุกข้อต้องได้ผลตามที่ควรได้
  7. ชวนคิดต่อ: ทำไมทดสอบด้วย j อย่างเดียวจึงไม่พอ
Trace table of read_backward: text = 'Leo' trace table ของ read_backward: text = 'Leo'
i-itext[-i]backward
0   
1   
2   
7 Solution เฉลย
Show the fixed code ดูโค้ดที่แก้แล้ว

The bug is on the line backward += text[-i] in read_backward. Because i starts at 0, -i is -0, which is the same as 0, so the first round takes the first letter instead of the last one. After that, -1, -2, … read from the end, so the result is the first letter followed by the other letters backward: R + trebo. Change the line to backward += text[-(i + 1)]. It is a logic error: the program runs to the end with no error message.

bug อยู่ที่บรรทัด backward += text[-i] ใน read_backward เพราะ i เริ่มที่ 0 ทำให้ -i คือ -0 ซึ่งเท่ากับ 0 รอบแรกจึงหยิบตัวแรกแทนตัวสุดท้าย หลังจากนั้น -1, -2, … อ่านจากท้ายตามปกติ ผลที่ได้จึงเป็นตัวแรกตามด้วยตัวที่เหลือแบบกลับหลัง คือ R + trebo แก้เป็น backward += text[-(i + 1)] เป็น logic error เพราะโปรแกรมรันจบโดยไม่มีข้อความ error

is_name and name_case are already correct. The symptom shows in the final code name, but the letters are already in the wrong order when read_backward returns; name_case only changes their case. A one-letter name such as j hides the bug, because its first letter is also its last one.

is_name และ name_case ถูกต้องอยู่แล้ว อาการแสดงที่ชื่อรหัสตอนท้าย แต่ตัวอักษรเรียงผิดตั้งแต่ read_backward ส่งค่ากลับมา ส่วน name_case แค่เปลี่ยนตัวพิมพ์ ชื่อที่มีตัวอักษรตัวเดียวอย่าง j ซ่อน bug ไว้ เพราะตัวแรกกับตัวสุดท้ายเป็นตัวเดียวกัน

Trace table of the buggy line: text = 'Leo' trace table ของบรรทัดที่มี bug: text = 'Leo'
i-itext[-i]backward
00'L''L'
1-1'o''Lo'
2-2'e''Loe'

After the fix, -(i + 1) runs through -1, -2, -3, so backward grows as 'o', 'oe', 'oeL', and name_case turns it into Oel.

หลังแก้แล้ว -(i + 1) มีค่า -1, -2, -3 ตามลำดับ backward จึงเพิ่มทีละตัวเป็น 'o', 'oe', 'oeL' แล้ว name_case เปลี่ยนเป็น Oel

[fixed]
[input]
[output]
Your name: Mary Ann
Use 1 to 10 letters (A-Z, a-z), please try again
Your name: Robert
Code name: Trebor

This program needs two loops after the name check: one in read_backward and one in name_case. Example 9 does the same job with one loop.

โปรแกรมนี้ใช้ 2 loop หลังตรวจชื่อ คือใน read_backward และใน name_case ตัวอย่างที่ 9 ทำงานเดียวกันได้ด้วย loop เดียว

The Run buttons on this page simulate Python with JavaScript, the same as the other lessons. To run the real Python, paste the code into Google Colab.

ปุ่ม Run ในหน้านี้จำลองโค้ด Python ด้วย JavaScript เหมือนบทเรียนอื่นๆ หากต้องการรัน Python จริง ให้คัดลอกโค้ดไปวางที่ Google Colab

References References / แหล่งอ้างอิง

  1. Python docs — String Methods (isalpha, upper, lower) (isalpha, upper, lower)
  2. Python docs — Common Sequence Operations (indexing a string, including negative indexes counted from the end) (การใช้ดัชนีกับสตริง รวมถึงดัชนีติดลบที่นับจากท้าย)
  3. Python docs — The while statement (while True and break) (while True และ break)
  4. Kinds of error, kinds of test case and bug-hunting tools: 11 Testing and Debugging; flowchart symbols: 01 Basic → Flowchart Basic. ชนิดของ error, ชนิดของ test case และเครื่องมือหา bug: 11 การทดสอบและการแก้ไขโปรแกรม ; สัญลักษณ์ของ flowchart: 01 Basic → Flowchart Basic

End-of-lesson quizแบบฝึกหัดท้ายบท

ตอบแล้ว 0 / 10

ข้อ 1

1 / 10

If text = 'Leo', what is text[-0]?ถ้า text = 'Leo' แล้ว text[-0] คืออะไร?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (A) 'L', the same as text[0]'L' เหมือน text[0]

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) 'L', the same as text[0]'L' เหมือน text[0]
    Correct! -0 equals 0, so it gives the first letter, not the last one.ถูกต้อง! -0 เท่ากับ 0 จึงได้ตัวแรก ไม่ใช่ตัวสุดท้าย
  • (B) 'o', the last letter'o' ตัวสุดท้าย
    Wrong: the last letter is given by text[-1]; -0 equals 0.ผิด: ตัวสุดท้ายได้จาก text[-1] ส่วน -0 เท่ากับ 0
  • (C) An empty text ''ข้อความว่าง ''
    Wrong: a single index inside the range always gives one letter.ผิด: การใช้ดัชนี 1 ตัวที่อยู่ในช่วงจะได้ตัวอักษร 1 ตัวเสมอ
  • (D) It raises IndexErrorเกิด IndexError
    Wrong: -0 is 0, which is inside the range, so there is no error.ผิด: -0 คือ 0 ซึ่งอยู่ในช่วง จึงไม่เกิด error

ข้อ 2

2 / 10

With the buggy code, what does read_backward('Leo') return?ด้วยโค้ดที่มี bug read_backward('Leo') คืนค่าอะไร?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (B) 'Loe''Loe'

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) 'oeL''oeL'
    Wrong: 'oeL' is the result after the bug is fixed.ผิด: 'oeL' คือผลหลังแก้ bug แล้ว
  • (B) 'Loe''Loe'
    Correct! The first round, text[-0], gives 'L'; the next rounds give 'o' and 'e' from the end.ถูกต้อง! รอบแรก text[-0] ได้ 'L' แล้วรอบต่อมาได้ 'o' และ 'e' จากท้าย
  • (C) 'eoL''eoL'
    Wrong: no round takes 'e' first; the first round gives text[0].ผิด: ไม่มีรอบไหนที่หยิบ 'e' เป็นตัวแรก รอบแรกได้ text[0]
  • (D) 'Leo''Leo'
    Wrong: round 2 uses text[-1], which is 'o', not 'e'.ผิด: รอบที่ 2 ใช้ text[-1] ซึ่งคือ 'o' ไม่ใช่ 'e'

ข้อ 3

3 / 10

Why does the name j give the right answer (J) even though the program has a bug?ทำไมชื่อ j จึงได้ผลถูก (J) ทั้งที่โปรแกรมมี bug?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (C) Because it has one letter, so its first letter is also its last oneเพราะมีตัวอักษรตัวเดียว ตัวแรกจึงเป็นตัวสุดท้ายด้วย

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) Because name_case fixes the order of the lettersเพราะ name_case แก้ลำดับตัวอักษรให้
    Wrong: name_case only changes the case, not the order.ผิด: name_case เปลี่ยนแค่ตัวพิมพ์ ไม่เปลี่ยนลำดับ
  • (B) Because is_name rejects this nameเพราะ is_name ปฏิเสธชื่อนี้
    Wrong: j is 1 letter, so is_name accepts it.ผิด: j เป็นตัวอักษร 1 ตัว is_name จึงรับชื่อนี้
  • (C) Because it has one letter, so its first letter is also its last oneเพราะมีตัวอักษรตัวเดียว ตัวแรกจึงเป็นตัวสุดท้ายด้วย
    Correct! Taking the first letter instead of the last one gives the same letter, so the bug does not show.ถูกต้อง! หยิบตัวแรกแทนตัวสุดท้ายก็ได้ตัวเดียวกัน bug จึงไม่แสดงอาการ
  • (D) Because -0 raises an error that is skippedเพราะ -0 ทำให้เกิด error ที่ถูกข้ามไป
    Wrong: -0 raises no error at all; it equals 0.ผิด: -0 ไม่ทำให้เกิด error เลย มันเท่ากับ 0

ข้อ 4

4 / 10

Which kind of error is the bug in this program?bug ในโปรแกรมนี้เป็น error ชนิดไหน?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (D) Logic errorLogic error

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) Syntax errorSyntax error
    Wrong: the code follows the grammar of Python, so the program starts to run.ผิด: โค้ดเขียนถูกไวยากรณ์ โปรแกรมจึงเริ่มรันได้
  • (B) Run-time errorRun-time error
    Wrong: the program does not stop halfway and shows no error message.ผิด: โปรแกรมไม่หยุดกลางทางและไม่มีข้อความ error
  • (C) Not an error, because the program runs to the endไม่ใช่ error เพราะโปรแกรมรันจบ
    Wrong: it runs to the end but the result is wrong, so it is still an error.ผิด: รันจบได้แต่ผลผิด จึงยังเป็น error
  • (D) Logic errorLogic error
    Correct! The program runs to the end with no error message, but the code name is wrong.ถูกต้อง! โปรแกรมรันจบโดยไม่มีข้อความ error แต่ชื่อรหัสที่ได้ผิด

ข้อ 5

5 / 10

What should the line backward += text[-i] become?ควรแก้บรรทัด backward += text[-i] เป็นอะไร?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (B) backward += text[-(i + 1)]backward += text[-(i + 1)]

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) backward += text[i]backward += text[i]
    Wrong: text[i] reads from left to right, giving the same name, not the name backward.ผิด: text[i] อ่านจากซ้ายไปขวา ได้ชื่อเดิมไม่ใช่ชื่อกลับหลัง
  • (B) backward += text[-(i + 1)]backward += text[-(i + 1)]
    Correct! -(i + 1) starts at -1, the last letter, then -2, -3, ...ถูกต้อง! -(i + 1) เริ่มที่ -1 คือตัวสุดท้าย แล้วเป็น -2, -3, ...
  • (C) backward = text[-i]backward = text[-i]
    Wrong: = overwrites the old value in every round, and -i still starts at 0.ผิด: = เขียนทับค่าเดิมทุกรอบ และ -i ยังเริ่มที่ 0 อยู่
  • (D) backward += text[-i - 0]backward += text[-i - 0]
    Wrong: -i - 0 equals -i, so the bug is still there.ผิด: -i - 0 มีค่าเท่ากับ -i bug จึงยังอยู่

ข้อ 6

6 / 10

What does is_name('') return?is_name('') คืนค่าอะไร?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (C) False, because len(text) == 0 is trueFalse เพราะ len(text) == 0 เป็นจริง

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) True, because no character is a non-letterTrue เพราะไม่มีตัวไหนที่ไม่ใช่ตัวอักษร
    Wrong: this function checks the length first, so empty text never reaches the loop.ผิด: ฟังก์ชันนี้ตรวจความยาวก่อน ข้อความว่างจึงไม่ถึง loop
  • (B) It raises IndexErrorเกิด IndexError
    Wrong: no index is used on the empty text, so there is no error.ผิด: ไม่มีการใช้ดัชนีกับข้อความว่าง จึงไม่เกิด error
  • (C) False, because len(text) == 0 is trueFalse เพราะ len(text) == 0 เป็นจริง
    Correct! The first check is true, so it does return False straight away.ถูกต้อง! เงื่อนไขแรกเป็นจริง จึง return False ทันที
  • (D) NoneNone
    Wrong: every path of the function ends with return True or return False.ผิด: ทุกทางของฟังก์ชันจบด้วย return True หรือ return False

ข้อ 7

7 / 10

Which kind of test case is the name Maximilian (10 letters)?ชื่อ Maximilian (10 ตัว) เป็น test case ชนิดไหน?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (A) BoundaryBoundary

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) BoundaryBoundary
    Correct! 10 letters is the longest length the problem accepts, so it sits right on the edge.ถูกต้อง! 10 ตัวคือความยาวมากที่สุดที่โจทย์รับได้ จึงอยู่ที่ขอบพอดี
  • (B) NormalNormal
    Wrong: Normal data is well inside the range, but 10 letters is on its edge.ผิด: Normal คือข้อมูลกลางช่วง ส่วน 10 ตัวอยู่ที่ขอบของช่วง
  • (C) ErrorError
    Wrong: this name meets the rule of the problem and the program accepts it.ผิด: ชื่อนี้ถูกเงื่อนไขของโจทย์และโปรแกรมรับได้
  • (D) It is not a test caseไม่ใช่ test case
    Wrong: it is test data with an expected output (Nailimixam), so it is a test case.ผิด: เป็นข้อมูลทดสอบพร้อมผลที่ควรได้ (Nailimixam) จึงเป็น test case

ข้อ 8

8 / 10

What does name_case('nOMIS') return?name_case('nOMIS') คืนค่าอะไร?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (D) 'Nomis''Nomis'

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) 'nomis''nomis'
    Wrong: the round where i == 0 uses upper(), so the first letter is a capital.ผิด: รอบที่ i == 0 ใช้ upper() ตัวแรกจึงเป็นตัวพิมพ์ใหญ่
  • (B) 'NOMIS''NOMIS'
    Wrong: the second letter onwards uses lower().ผิด: ตัวที่ 2 เป็นต้นไปใช้ lower()
  • (C) 'nOMIS''nOMIS'
    Wrong: every letter goes through upper() or lower().ผิด: ทุกตัวถูกเปลี่ยนตัวพิมพ์ด้วย upper() หรือ lower()
  • (D) 'Nomis''Nomis'
    Correct! The first letter becomes a capital and the rest become small letters.ถูกต้อง! ตัวแรกเป็นตัวพิมพ์ใหญ่ ตัวที่เหลือเป็นตัวพิมพ์เล็ก

ข้อ 9

9 / 10

What does the program do with R2D2, and which kind of test case is it?เมื่อป้อน R2D2 โปรแกรมทำอะไร และเป็น test case ชนิดไหน?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (C) Error: it shows the warning and asks againError: เตือนแล้วถามชื่อใหม่

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) Normal: it gives the code name 2d2rNormal: ได้ชื่อรหัส 2d2r
    Wrong: R2D2 has digits, so is_name returns False.ผิด: R2D2 มีตัวเลข is_name จึงคืนค่า False
  • (B) Boundary: accepted because it is 4 characters longBoundary: รับได้เพราะยาว 4 ตัว
    Wrong: the length is fine, but some characters are not letters, so it fails.ผิด: ความยาวผ่าน แต่มีตัวที่ไม่ใช่ตัวอักษร จึงไม่ผ่าน
  • (C) Error: it shows the warning and asks againError: เตือนแล้วถามชื่อใหม่
    Correct! It is data in the wrong form, so the program rejects it and asks again.ถูกต้อง! เป็นข้อมูลผิดรูปแบบ โปรแกรมจึงปฏิเสธแล้วถามใหม่
  • (D) Error: the program stops with ValueErrorError: โปรแกรมหยุดด้วย ValueError
    Wrong: this program converts nothing to a number, so there is no ValueError; it warns and asks again.ผิด: โปรแกรมนี้ไม่แปลงเป็นตัวเลข จึงไม่เกิด ValueError แต่เตือนแล้วถามใหม่

ข้อ 10

10 / 10

Where should you put print(i, -i, text[-i], backward) to find the bug?ควรใส่ print(i, -i, text[-i], backward) ไว้ตรงไหนเพื่อหา bug?

เฉลย / Answerซ่อนเฉลย / Hide

เฉลย / Answer: (B) Inside the loop of read_backwardใน loop ของ read_backward

คำอธิบายแต่ละตัวเลือก / Explanation for each choice

  • (A) After the while True loopหลัง loop while True
    Wrong: the variables i, text and backward of read_backward do not exist there.ผิด: ตรงนั้นไม่มีตัวแปร i, text และ backward ของ read_backward
  • (B) Inside the loop of read_backwardใน loop ของ read_backward
    Correct! You see -i and the letter taken in each round.ถูกต้อง! จะเห็นค่า -i และตัวอักษรที่หยิบได้ในแต่ละรอบ
  • (C) Inside the loop of is_nameใน loop ของ is_name
    Wrong: is_name has no backward, and the name check already works.ผิด: is_name ไม่มี backward และส่วนตรวจชื่อทำงานถูกอยู่แล้ว
  • (D) Before def name_caseก่อน def name_case
    Wrong: that line runs before any name is read, so there are no values to see yet.ผิด: บรรทัดนั้นทำงานก่อนรับชื่อ จึงยังไม่มีค่าให้ดู