Example 4 — Find the Biggest Sensor Jump (debugging) ตัวอย่างที่ 4 — หาจุดที่ค่าเซนเซอร์เปลี่ยนมากที่สุด (debugging)

A debugging problem: the program below should tell which sensor reading changed the most from the one before, 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 โจทย์

A sensor is read once every minute. The user types the readings as non-negative whole numbers separated by commas (at least 2 readings). The program must tell which reading changed the most from the reading just before it. The first reading is reading 1. A change counts in both directions, up or down (use the size of the difference and ignore its sign). If several readings share the biggest change, answer the first of them.

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

  • Example: 12,15,9,10 → 3 (reading 3 drops from 15 to 9, a change of 6)
  • to_numbers(line) — turns the typed text into a list of whole numbers
  • biggest_jump_at(readings) — returns the number of the reading with the biggest change
  • ตัวอย่าง: 12,15,9,10 → 3 (ครั้งที่ 3 ลดจาก 15 เป็น 9 เปลี่ยนไป 6)
  • to_numbers(line) — แปลงข้อความที่ป้อนเป็นลิสต์ของจำนวนเต็ม
  • biggest_jump_at(readings) — คืนค่าครั้งที่ของค่าที่อ่านได้ซึ่งเปลี่ยนมากที่สุด

New in this program: split(",") cuts text at every comma and gives a list of the pieces; int() turns text such as "15" into the whole number 15; range(1, len(readings)) starts counting at 1, so every reading it visits has a reading before it at i - 1.

คำสั่งใหม่ในโปรแกรมนี้: split(",") ตัดข้อความตรงทุกจุลภาค แล้วได้ลิสต์ของข้อความแต่ละช่วง int() แปลงข้อความ เช่น "15" เป็นจำนวนเต็ม 15 และ range(1, len(readings)) เริ่มนับที่ 1 ค่าที่อ่านได้ทุกครั้งที่ loop ผ่านจึงมีครั้งก่อนหน้าอยู่ที่ i - 1 เสมอ

2 Main program — flowchart and full code (contains a bug) โปรแกรมหลัก — flowchart และโค้ดทั้งหมด (มี bug)

The program starts by reading the typed readings into line. Next it turns the text into a list of numbers with the sub-function to_numbers and stores it in readings. Then it finds the reading with the biggest change with the sub-function biggest_jump_at, shows the result with print, and the program ends.

โปรแกรมนี้เริ่มต้นด้วยรับค่าที่อ่านได้ที่ผู้ใช้ป้อนเก็บใน line ถัดไปแปลงข้อความเป็นลิสต์ของตัวเลขด้วย function ย่อยชื่อ to_numbers แล้วเก็บใน readings หลังจากนั้นหาครั้งที่เปลี่ยนมากที่สุดด้วย function ย่อยชื่อ biggest_jump_at แล้วแสดงผลด้วย print และจบการทำงานของโปรแกรม

Start Read the readings line = input(...) Turn the text into numbers readings = to_numbers(line) Show the reading number print(biggest_jump_at(readings)) End
[main]
[input]
[output]
Readings: 12,15,9,10
2

Try it yourself — type readings separated by commas and press Submit. They replace the [input] box and run the code that is in the box right now (including your fix).

ลองป้อนค่าเอง — พิมพ์ค่าที่อ่านได้คั่นด้วยจุลภาคแล้วกดส่ง ค่าจะแทนที่กล่อง [input] แล้วรันโค้ดที่อยู่ในกล่องตอนนี้ (รวมถึงส่วนที่คุณแก้แล้ว)

3 to_numbers(line)

to_numbers starts by cutting line at every comma with split and storing the pieces in parts. It creates an empty list numbers and sets i = 0 as the position of the piece. It checks whether i < len(parts); if it is, it converts the piece with int, adds it to numbers with append, increases i by 1 and checks again. This repeats until the condition is false, so it sends numbers back with return.

to_numbers เริ่มต้นด้วยตัด line ตรงทุกจุลภาคด้วย split แล้วเก็บแต่ละช่วงไว้ใน parts สร้างลิสต์ว่างชื่อ numbers และกำหนดค่า i = 0 เป็นตัวชี้ตำแหน่งของช่วง แล้วตรวจสอบเงื่อนไขว่า i < len(parts) หรือไม่ ถ้าใช่ให้แปลงช่วงนั้นด้วย int แล้วเพิ่มเข้า numbers ด้วย append เพิ่ม i ขึ้น 1 และกลับไปตรวจสอบอีกครั้ง ทำแบบนี้จนเงื่อนไขเป็นเท็จ จึงส่งค่า numbers กลับด้วย return

to_numbers(line) Cut the text at each comma parts = line.split(",") Start an empty list numbers = [] Start at the first piece i = 0 More pieces? i < len(parts)? Yes Convert one piece and keep it numbers.append(int(parts[i])) Next piece i += 1 No return numbers

Test the function on its own: it should give a list of whole numbers.

ทดสอบฟังก์ชันนี้แยกเดี่ยวๆ ควรได้ลิสต์ของจำนวนเต็ม

[test]
[output]
[12, 15, 9, 10]
[40, 25]
4 biggest_jump_at(readings)

biggest_jump_at starts by setting best_step = 0 to hold the answer and best_jump = -1 as the biggest change found so far (smaller than any real change, so even a change of 0 is recorded). It sets i = 1 as the position of the reading and checks whether i < len(readings). If it is, it finds the change from the previous reading with jump = readings[i] - readings[i - 1], then checks whether jump > best_jump. If it is, it stores best_jump = jump and best_step = i + 1 (the reading number, counted from 1). Either way it increases i by 1 and goes back to check i < len(readings) again. This repeats until the condition is false, so it sends best_step back with return.

biggest_jump_at เริ่มต้นด้วยกำหนดค่า best_step = 0 สำหรับเก็บคำตอบ และ best_jump = -1 เป็นค่าการเปลี่ยนที่มากที่สุดที่พบจนถึงตอนนี้ (น้อยกว่าการเปลี่ยนจริงทุกค่า การเปลี่ยนเป็น 0 จึงยังถูกบันทึก) กำหนดค่า i = 1 เป็นตัวชี้ตำแหน่งของค่าที่อ่านได้ แล้วตรวจสอบเงื่อนไขว่า i < len(readings) หรือไม่ ถ้าใช่ให้หาการเปลี่ยนจากครั้งก่อนหน้าด้วย jump = readings[i] - readings[i - 1] แล้วตรวจสอบว่า jump > best_jump หรือไม่ ถ้าใช่ให้เก็บ best_jump = jump และ best_step = i + 1 (ครั้งที่ของค่าที่อ่านได้ ซึ่งนับจาก 1) ไม่ว่าทางใดทางหนึ่ง หลังจากนั้นเพิ่ม i ขึ้น 1 แล้วกลับไปตรวจสอบ i < len(readings) อีกครั้ง ทำแบบนี้จนเงื่อนไขเป็นเท็จ จึงส่งค่า best_step กลับด้วย return

biggest_jump_at(readings) No best reading yet best_step = 0, best_jump = -1 Start at reading 2 i = 1 More readings? i < len(readings)? Yes Change from the previous reading jump = readings[i] - readings[i - 1] Bigger than the best? jump > best_jump? Yes Remember this reading best_jump = jump best_step = i + 1 No Next reading i += 1 No return best_step

Test the function on its own with lists of numbers (no typing needed).

ทดสอบฟังก์ชันนี้แยกเดี่ยวๆ ด้วยลิสต์ของตัวเลข (ไม่ต้องพิมพ์ค่า)

[test]
[output]
2
3
5 Test list รายการทดสอบ

Run each input yourself (type it into the form in card 2) and compare the result with the expected output column. The last column shows what the code with the bug gives.

รันทีละข้อด้วยตัวเอง (พิมพ์ลงในช่องของการ์ดที่ 2) แล้วเทียบผลกับคอลัมน์ผลที่ควรได้ คอลัมน์สุดท้ายคือผลจากโค้ดที่ยังมี bug

Inputข้อมูลที่ป้อน Kindชนิด Expected outputผลที่ควรได้ Output of the buggy codeผลจากโค้ดที่มี bug
12,15,9,10 Normal 3 2 ✗
5,7,12,13 Normal (rising only)Normal (ขึ้นอย่างเดียว) 3 3 ✓
30,5,6,8 Boundary (biggest change at reading 2)Boundary (เปลี่ยนมากสุดที่ครั้งที่ 2) 2 4 ✗
3,4,5,20 Boundary (biggest change at the last reading)Boundary (เปลี่ยนมากสุดที่ครั้งสุดท้าย) 4 4 ✓
40,40 Boundary (2 readings, no change)Boundary (2 ค่า ไม่เปลี่ยน) 2 2 ✓
40,25 Boundary (2 readings, a drop)Boundary (2 ค่า ลดลง) 2 0 ✗
10,14,10 Boundary (equal changes → the first one)Boundary (เปลี่ยนเท่ากัน → ตอบครั้งแรก) 2 2 ✓
12,abc,15 Error (not a number)Error (ไม่ใช่ตัวเลข) should be rejected, but this program does not check its input ควรถูกปฏิเสธ แต่โปรแกรมนี้ไม่ได้ตรวจข้อมูลที่รับเข้ามา ValueError: invalid literal for int() with base 10: 'abc'
6 Your tasks ภารกิจ
  1. Check the code of both functions and the main program against their flowcharts, box by box.
  2. Run every input in the test list and note whether the actual output matches the expected output.
  3. Why does 5,7,12,13 pass while 12,15,9,10 fails? What do all the failing inputs have in common?
  4. Which kind of error is this bug, and why?
  5. Add print(i, jump, best_jump) inside the loop of biggest_jump_at and fill in the trace table below for 12,15,9,10.
  6. Fix the code in the box and run the test list again. Every Normal and Boundary input must give its expected output.
  7. Think further: why does the buggy code answer 0 for 40,25, when there is no reading 0? And how should the program deal with 12,abc,15?
  1. ตรวจโค้ดของทั้ง 2 ฟังก์ชันและโปรแกรมหลักเทียบกับ flowchart ทีละกล่อง
  2. รันทุกข้อในรายการทดสอบ แล้วจดผลที่ได้จริงว่าตรงกับผลที่ควรได้หรือไม่
  3. ทำไม 5,7,12,13 ผ่าน แต่ 12,15,9,10 ไม่ผ่าน ข้อที่ไม่ผ่านทุกข้อมีอะไรเหมือนกัน
  4. bug นี้เป็น error ชนิดไหน เพราะอะไร
  5. ใส่ print(i, jump, best_jump) ใน loop ของ biggest_jump_at แล้วกรอก trace table ด้านล่างของ 12,15,9,10
  6. แก้โค้ดในกล่อง แล้วรันรายการทดสอบซ้ำ ข้อที่เป็น Normal และ Boundary ต้องได้ผลตามตารางทุกข้อ
  7. ชวนคิดต่อ: ทำไมโค้ดที่มี bug ตอบ 0 กับ 40,25 ทั้งที่ไม่มีค่าที่อ่านได้ครั้งที่ 0 และโปรแกรมควรจัดการกับ 12,abc,15 อย่างไร
Trace table: readings = [12, 15, 9, 10] trace table: readings = [12, 15, 9, 10]
ijumpjump > best_jump?best_jumpbest_step
1    
2    
3    
7 Solution เฉลย
Show the fixed code ดูโค้ดที่แก้แล้ว

The bug is on the line jump = readings[i] - readings[i - 1]. A drop gives a negative jump, so it is never bigger than best_jump and drops are ignored. The problem asks for the size of the change, so use the absolute value: abs() gives a number without its sign, e.g. abs(-6) is 6. Change the line to jump = abs(readings[i] - readings[i - 1]). It is a logic error: the program runs to the end with no error message. Inputs that only rise hide the bug, because every change is already positive. With 40,25 the only change is negative, so best_step keeps its starting value 0.

bug อยู่ที่บรรทัด jump = readings[i] - readings[i - 1] เมื่อค่าลดลง jump จะติดลบ จึงไม่มีทางมากกว่า best_jump การเปลี่ยนขาลงจึงถูกมองข้ามทั้งหมด โจทย์ต้องการขนาดของการเปลี่ยน จึงต้องใช้ค่าสัมบูรณ์ abs() ให้ค่าตัวเลขโดยไม่คิดเครื่องหมาย เช่น abs(-6) ได้ 6 แก้บรรทัดเป็น jump = abs(readings[i] - readings[i - 1]) เป็น logic error เพราะโปรแกรมรันจบโดยไม่มีข้อความ error ส่วนข้อมูลที่มีแต่ขาขึ้นซ่อน bug ไว้ เพราะการเปลี่ยนทุกครั้งเป็นบวกอยู่แล้ว และ 40,25 มีการเปลี่ยนครั้งเดียวซึ่งติดลบ best_step จึงยังเป็นค่าเริ่มต้น 0

Trace table of the buggy code: readings = [12, 15, 9, 10] trace table ของโค้ดที่มี bug: readings = [12, 15, 9, 10]
ijumpjump > best_jump?best_jumpbest_step
13✓32
2-6✗32
31✗32
[fixed]
[input]
[output]
Readings: 12,15,9,10
3

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 — str.split (cutting the typed text at each comma) (ตัดข้อความที่ป้อนตรงทุกจุลภาค)
  2. Python docs — Built-in Functions: abs andและ int (absolute value in the fix; text to whole number) (ค่าสัมบูรณ์ในเฉลย และการแปลงข้อความเป็นจำนวนเต็ม)
  3. 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

In the buggy code, what is jump when the reading goes from 15 to 9?ในโค้ดที่มี bug เมื่อค่าที่อ่านได้เปลี่ยนจาก 15 เป็น 9 ตัวแปร jump มีค่าเท่าไร?

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

เฉลย / Answer: (C) -6-6

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

  • (A) 66
    Wrong: 6 is the size of the change, but the buggy code does not use abs().ผิด: 6 คือขนาดของการเปลี่ยน แต่โค้ดที่มี bug ไม่ได้ใช้ abs()
  • (B) 2424
    Wrong: the code subtracts, it does not add.ผิด: โค้ดหาผลต่าง ไม่ใช่ผลบวก
  • (C) -6-6
    Correct! 9 - 15 is -6, because the reading dropped.ถูกต้อง! 9 - 15 ได้ -6 เพราะค่าลดลง
  • (D) 00
    Wrong: the reading really changed, so the difference is not 0.ผิด: ค่าเปลี่ยนจริง ผลต่างจึงไม่ใช่ 0

ข้อ 2

2 / 10

What is abs(-6)?abs(-6) ได้ค่าใด?

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

เฉลย / Answer: (A) 66

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

  • (A) 66
    Correct! abs() gives the absolute value: the number without its sign.ถูกต้อง! abs() ให้ค่าสัมบูรณ์ คือตัวเลขโดยไม่คิดเครื่องหมาย
  • (B) -6-6
    Wrong: abs() removes the minus sign.ผิด: abs() ตัดเครื่องหมายลบออก
  • (C) 00
    Wrong: the absolute value of -6 is not 0.ผิด: ค่าสัมบูรณ์ของ -6 ไม่ใช่ 0
  • (D) ValueErrorValueError
    Wrong: abs() accepts negative numbers without any problem.ผิด: abs() รับตัวเลขติดลบได้ปกติ

ข้อ 3

3 / 10

Why does 5,7,12,13 give the right answer even though the program still has the bug?ทำไม 5,7,12,13 ได้ผลถูกทั้งที่โปรแกรมยังมี bug?

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

เฉลย / Answer: (D) Because every change goes up, so every difference is already positiveเพราะทุกครั้งเป็นการเปลี่ยนขาขึ้น ผลต่างจึงเป็นบวกอยู่แล้ว

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

  • (A) Because it has 4 readingsเพราะมีค่าที่อ่านได้ 4 ค่า
    Wrong: 12,15,9,10 also has 4 readings but gives the wrong answer.ผิด: 12,15,9,10 ก็มี 4 ค่าแต่ได้ผลผิด
  • (B) Because the last reading is the largestเพราะค่าสุดท้ายมากที่สุด
    Wrong: what matters is the direction of each change, not which reading is largest.ผิด: สิ่งที่สำคัญคือทิศของการเปลี่ยน ไม่ใช่ค่าที่มากที่สุด
  • (C) Because int() converts every valueเพราะ int() แปลงค่าได้ครบ
    Wrong: int() converts every value in all the numeric tests, including the failing ones.ผิด: int() แปลงค่าได้ครบในทุกข้อที่เป็นตัวเลข รวมถึงข้อที่ผิดด้วย
  • (D) Because every change goes up, so every difference is already positiveเพราะทุกครั้งเป็นการเปลี่ยนขาขึ้น ผลต่างจึงเป็นบวกอยู่แล้ว
    Correct! With no drops, leaving out abs() changes nothing.ถูกต้อง! เมื่อไม่มีขาลง การไม่ใช้ abs() จึงไม่ทำให้คำตอบผิด

ข้อ 4

4 / 10

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

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

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

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

  • (A) Syntax errorSyntax error
    Wrong: the program runs, so its grammar is fine.ผิด: โปรแกรมรันได้ จึงไม่ผิดไวยากรณ์
  • (B) Logic errorLogic error
    Correct! The program runs to the end with no error message, but gives wrong answers for some data.ถูกต้อง! โปรแกรมรันจบโดยไม่มีข้อความ error แต่ให้คำตอบผิดในบางข้อมูล
  • (C) Run-time errorRun-time error
    Wrong: numeric data never makes the program stop halfway.ผิด: ข้อมูลที่เป็นตัวเลขไม่ทำให้โปรแกรมหยุดกลางทาง
  • (D) There is no errorไม่มี error
    Wrong: 12,15,9,10 gives 2 but should give 3.ผิด: 12,15,9,10 ได้ 2 แต่ควรได้ 3

ข้อ 5

5 / 10

Why does the buggy code answer 0 for 40,25?ทำไมโค้ดที่มี bug ตอบ 0 เมื่อป้อน 40,25?

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

เฉลย / Answer: (C) Because jump is -15, which is not bigger than -1, so best_step stays 0เพราะ jump เป็น -15 ซึ่งไม่มากกว่า -1 best_step จึงยังเป็น 0

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

  • (A) Because int() cannot convert 25เพราะ int() แปลง 25 ไม่ได้
    Wrong: 25 converts normally.ผิด: 25 แปลงได้ปกติ
  • (B) Because the loop never runsเพราะ loop ไม่ทำงานเลย
    Wrong: the loop runs once, with i = 1.ผิด: loop ทำงาน 1 รอบ ที่ i = 1
  • (C) Because jump is -15, which is not bigger than -1, so best_step stays 0เพราะ jump เป็น -15 ซึ่งไม่มากกว่า -1 best_step จึงยังเป็น 0
    Correct! The only change is negative, so the answer is never stored.ถูกต้อง! การเปลี่ยนครั้งเดียวติดลบ จึงไม่เคยเข้าไปเก็บคำตอบ
  • (D) Because the first reading is counted as reading 0เพราะค่าที่อ่านได้ครั้งแรกนับเป็นครั้งที่ 0
    Wrong: the problem counts the first reading as 1, and the code writes i + 1.ผิด: โจทย์นับครั้งแรกเป็นครั้งที่ 1 และโค้ดก็เขียน i + 1

ข้อ 6

6 / 10

Testing with 40,40 (2 readings, no change) is which kind of test case?การทดสอบด้วย 40,40 (2 ค่า ไม่เปลี่ยน) เป็น test case ชนิดใด?

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

เฉลย / Answer: (A) Boundary test caseBoundary test case

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

  • (A) Boundary test caseBoundary test case
    Correct! 2 readings is the smallest input the problem accepts, and a change of 0 is also an edge case.ถูกต้อง! 2 ค่าคือจำนวนน้อยที่สุดที่โจทย์ยอมรับ และการเปลี่ยนเป็น 0 ก็เป็นกรณีที่ขอบ
  • (B) Normal test caseNormal test case
    Wrong: this data sits at the edge, it is not ordinary data.ผิด: ข้อมูลนี้อยู่ที่ขอบ ไม่ใช่ข้อมูลทั่วไป
  • (C) Error test caseError test case
    Wrong: 40,40 is valid data for this problem.ผิด: 40,40 เป็นข้อมูลที่ถูกต้องตามโจทย์
  • (D) Logic test caseLogic test case
    Wrong: there is no such kind of test case; logic is a kind of error.ผิด: ไม่มี test case ชนิดนี้ logic เป็นชื่อชนิดของ error

ข้อ 7

7 / 10

What happens when 12,abc,15 is entered into this program?ป้อน 12,abc,15 ให้โปรแกรมนี้ จะเกิดอะไรขึ้น?

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

เฉลย / Answer: (D) A run-time error: ValueError from int('abc')Run-time error: ValueError จาก int('abc')

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

  • (A) It prints 0พิมพ์ 0
    Wrong: the program stops before it looks for an answer.ผิด: โปรแกรมหยุดก่อนถึงการหาคำตอบ
  • (B) A syntax errorSyntax error
    Wrong: the code is grammatically correct; the problem comes from the data during the run.ผิด: โค้ดถูกไวยากรณ์ ปัญหาเกิดจากข้อมูลระหว่างรัน
  • (C) It skips abc and answers from 12 and 15ข้าม abc แล้วตอบจาก 12 และ 15
    Wrong: the program does not check or skip data that is not a number.ผิด: โปรแกรมไม่ได้ตรวจหรือข้ามข้อมูลที่ไม่ใช่ตัวเลข
  • (D) A run-time error: ValueError from int('abc')Run-time error: ValueError จาก int('abc')
    Correct! int() cannot turn 'abc' into a whole number, so the run stops.ถูกต้อง! int() แปลง 'abc' เป็นจำนวนเต็มไม่ได้ โปรแกรมจึงหยุดระหว่างรัน

ข้อ 8

8 / 10

Why does the code write best_step = i + 1 instead of best_step = i?ทำไมโค้ดเขียน best_step = i + 1 ไม่ใช่ best_step = i?

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

เฉลย / Answer: (B) Because list indexes start at 0 but the problem counts the first reading as 1เพราะดัชนีของลิสต์เริ่มที่ 0 แต่โจทย์นับครั้งแรกเป็นครั้งที่ 1

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

  • (A) To skip the first readingเพื่อข้ามค่าที่อ่านได้ครั้งแรก
    Wrong: starting the loop at i = 1 is what skips the first reading.ผิด: การเริ่ม loop ที่ i = 1 คือส่วนที่ข้ามครั้งแรก
  • (B) Because list indexes start at 0 but the problem counts the first reading as 1เพราะดัชนีของลิสต์เริ่มที่ 0 แต่โจทย์นับครั้งแรกเป็นครั้งที่ 1
    Correct! The value at index i is reading number i + 1.ถูกต้อง! ค่าที่ดัชนี i คือค่าที่อ่านได้ครั้งที่ i + 1
  • (C) It is the bug in the programเป็น bug ของโปรแกรม
    Wrong: this line is correct; the bug is in how jump is found.ผิด: บรรทัดนี้ถูกต้องแล้ว bug อยู่ที่การหา jump
  • (D) To keep the index in rangeเพื่อกันไม่ให้ดัชนีเกินขอบเขต
    Wrong: best_step is never used as a list index.ผิด: best_step ไม่ได้ใช้เป็นดัชนีของลิสต์

ข้อ 9

9 / 10

Which change makes every Normal and Boundary test pass?แก้บรรทัดใดแล้วโปรแกรมให้ผลถูกทุกข้อที่เป็น Normal และ Boundary?

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

เฉลย / Answer: (A) jump = abs(readings[i] - readings[i - 1])jump = abs(readings[i] - readings[i - 1])

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

  • (A) jump = abs(readings[i] - readings[i - 1])jump = abs(readings[i] - readings[i - 1])
    Correct! It uses the size of the change, so drops are counted too.ถูกต้อง! ใช้ขนาดของการเปลี่ยน การเปลี่ยนขาลงจึงถูกนับด้วย
  • (B) best_jump = 0best_jump = 0
    Wrong: drops are still ignored, and 40,40 would give 0 instead of 2.ผิด: ขาลงยังไม่ถูกนับ และ 40,40 จะได้ 0 แทน 2
  • (C) for i in range(len(readings)):for i in range(len(readings)):
    Wrong: with i = 0 it compares with readings[-1], the last reading.ผิด: เมื่อ i = 0 จะเทียบกับ readings[-1] ซึ่งคือค่าสุดท้าย
  • (D) if jump >= best_jump:if jump >= best_jump:
    Wrong: drops are still ignored, and equal changes would give the later reading instead of the first.ผิด: ขาลงยังไม่ถูกนับ และเมื่อเปลี่ยนเท่ากันจะได้ครั้งหลังแทนครั้งแรก

ข้อ 10

10 / 10

Why does best_jump start at -1 instead of 0?ทำไมตั้งค่าเริ่มต้น best_jump = -1 ไม่ใช่ 0?

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

เฉลย / Answer: (C) So that a change of 0 (e.g. 40,40) is still stored as the answerเพื่อให้การเปลี่ยนเป็น 0 (เช่น 40,40) ยังถูกบันทึกเป็นคำตอบ

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

  • (A) So that drops are countedเพื่อให้นับขาลงได้
    Wrong: the starting value does not help count drops; that needs abs().ผิด: ค่าเริ่มต้นไม่ได้ช่วยนับขาลง ต้องใช้ abs()
  • (B) Because readings can be negativeเพราะค่าที่อ่านได้อาจติดลบ
    Wrong: the problem says readings are never negative.ผิด: โจทย์กำหนดว่าค่าที่อ่านได้ไม่ติดลบ
  • (C) So that a change of 0 (e.g. 40,40) is still stored as the answerเพื่อให้การเปลี่ยนเป็น 0 (เช่น 40,40) ยังถูกบันทึกเป็นคำตอบ
    Correct! 0 > -1 is true; starting at 0 would test 0 > 0, which is false, and answer 0.ถูกต้อง! 0 > -1 เป็นจริง ถ้าเริ่มที่ 0 จะได้ 0 > 0 ซึ่งเป็นเท็จ และตอบ 0
  • (D) No reason, any value worksไม่มีเหตุผล ใช้ค่าใดก็ได้
    Wrong: the starting value must be smaller than every possible change.ผิด: ค่าเริ่มต้นต้องน้อยกว่าการเปลี่ยนที่เป็นไปได้ทุกค่า