Example 12 — Rotate a Text Picture 90° ตัวอย่างที่ 12 — หมุนภาพตัวอักษร 90°

Last updated แก้ไขล่าสุด

Use nested loops to read the characters in a new order and turn the picture 90° clockwise. ใช้ loop ซ้อนกันอ่านตัวอักษรใหม่ตามลำดับ เพื่อหมุนภาพตามเข็มนาฬิกา 90°

Read the problem, see how the positions change in the 3×3 picture, then press Run. You can change picture to a picture of your own, as long as it is a square.

อ่านโจทย์ ดูว่าตำแหน่งเปลี่ยนไปอย่างไรจากภาพ 3×3 แล้วกด Run โดยแก้ picture เป็นภาพของตัวเองได้ ภาพต้องเป็นสี่เหลี่ยมจัตุรัส

1 The problem โจทย์

picture holds a text picture of N×N characters as a list of strings, one string per row. Show the picture rotated 90° clockwise.

picture เก็บภาพตัวอักษรขนาด N×N เป็น list ของ string แถวละ 1 string จงแสดงภาพที่หมุนตามเข็มนาฬิกา 90°

Before — picture ก่อนหมุน — picture
c = 0 c = 1 c = 2
r = 0 1 2 3
r = 1 4 5 6
r = 2 7 8 9
After — turned 90° clockwise หลังหมุน — ตามเข็มนาฬิกา 90°
c′ = 0 c′ = 1 c′ = 2
r′ = 0 7 4 1
r′ = 1 8 5 2
r′ = 2 9 6 3

With picture as the rows "123", "456", "789", the result is 741, 852, 963.

เมื่อ picture มีแถวเป็น "123", "456", "789" ภาพผลคือ 741, 852, 963

The first row of the result is the first column of the picture read from bottom to top: 7, 4, 1. Write r′ and c′ for the row and the column of the result, and r and c for the row and the column of the picture the character comes from. Going down a column of the picture moves to the right along a row of the result, so c = r′, and the column of the result counts the rows of the picture from the bottom, so r = size - 1 - c′. The table works this out for every character of the result.

แถวแรกของภาพผลคือคอลัมน์แรกของภาพเดิมอ่านจากล่างขึ้นบน คือ 7, 4, 1 ให้ r′ และ c′ เป็นแถวและคอลัมน์ของภาพผล ส่วน r และ c เป็นแถวและคอลัมน์ของภาพเดิมที่ตัวอักษรนั้นมาจาก การไล่ลงตามคอลัมน์ของภาพเดิมคือการไล่ไปทางขวาตามแถวของภาพผล จึงได้ c = r′ และคอลัมน์ของภาพผลนับแถวของภาพเดิมจากล่างขึ้นบน จึงได้ r = size - 1 - c′ ตารางนี้แสดงการคิดครบทุกตัวอักษรของภาพผล

Every character of the result (size = 3) ตัวอักษรทุกตัวของภาพผล (size = 3)
New data — the resultข้อมูลใหม่ — ภาพผล Old data — the pictureข้อมูลเดิม — ภาพเดิม Equationสมการ
Valueค่า Row r′แถว r′ Column c′คอลัมน์ c′ Row rแถว r Column cคอลัมน์ c r c
7 00 20 r = size - 1 - c′ c = r′
4 01 10
1 02 00
8 10 21
5 11 11
2 12 01
9 20 22
6 21 12
3 22 02

In the code the loop counters r and c run over the result, so they are r′ and c′ of this table, and the character to take is picture[size - c - 1][r].

ในโค้ด ตัวนับของ loop คือ r และ c ซึ่งไล่ไปตามภาพผล จึงเป็น r′ และ c′ ของตารางนี้ ตัวอักษรที่ต้องหยิบจึงอยู่ที่ picture[size - c - 1][r]

Commands used in this program:
  • picture[2][3] is the fourth character of the third row, because picture[2] is a string that can be indexed too.
  • len(picture) is the number of rows, which equals the number of columns in a square picture.
คำสั่งที่ใช้ในโปรแกรมนี้:
  • picture[2][3] คือตัวอักษรที่ 4 ของแถวที่ 3 เพราะ picture[2] เป็น string ที่ใช้ index ต่อได้
  • len(picture) คือจำนวนแถว ซึ่งเท่ากับจำนวนคอลัมน์ของภาพจัตุรัส
2 Main program — flowchart and full code โปรแกรมหลัก — flowchart และโค้ดทั้งหมด

The code keeps two pictures to test with and picks one with case: case = 1 is the 3×3 picture of numbers and case = 2 is the 9×9 smiley face. Change this one value and press Run to see the other picture.

โค้ดเก็บภาพสำหรับทดสอบไว้ 2 ภาพ แล้วเลือกด้วยตัวแปร case โดย case = 1 คือภาพตัวเลขขนาด 3×3 และ case = 2 คือภาพหน้ายิ้มขนาด 9×9 แก้ค่านี้ค่าเดียวแล้วกด Run เพื่อดูอีกภาพหนึ่ง

After the picture is chosen, the program starts by setting the picture in picture and finding its size with len, which it keeps in size. Next it sets r = 0 as the row counter of the result and checks whether r < size. If so, it makes text, an empty string that collects this row, and sets c = 0 as the column counter. It then takes the character at picture[size - c - 1][r], adds it to the end of text and adds 1 to c, repeating until c < size is false, when it leaves the inner loop. It shows the row with print, adds 1 to r and goes back to check r < size again. It repeats this until every row is done, and the program ends.

เมื่อเลือกภาพแล้ว โปรแกรมเริ่มต้นด้วยกำหนดภาพไว้ใน picture แล้วหาขนาดภาพด้วย len เก็บใน size ถัดไปกำหนด r = 0 เป็นตัวนับแถวของภาพผล แล้วตรวจสอบเงื่อนไขว่า r < size หรือไม่ ถ้าใช่ให้สร้าง text เป็น string ว่างสำหรับเก็บแถวนี้ กำหนด c = 0 เป็นตัวนับคอลัมน์ แล้วหยิบตัวอักษรจาก picture[size - c - 1][r] ต่อท้าย text และเพิ่ม c ทีละ 1 ทำแบบนี้จน c < size เป็นเท็จจึงออกจาก loop ด้านใน แล้วแสดงแถวด้วย print และเพิ่ม r ทีละ 1 กลับไปตรวจ r < size อีกครั้ง ทำแบบนี้จนครบทุกแถวแล้วจบการทำงานของโปรแกรม

one round = one row one round = one character Start Set the picture picture = [...] Find the size size = len(picture) Start at the first row r = 0 Row left? r < size? Yes Start an empty row text = "" Start at the first column c = 0 Column left? c < size? Yes Add the character to the row text += picture[size - c - 1][r] Go to the next column c += 1 No Show this row print(text) Go to the next row r += 1 No End
[main]
[output]
741
852
963
3 Results of the program ผลของโปรแกรม

Change case or picture in card 2 and press Run to check each row of this table.

แก้ case หรือ picture ในการ์ดที่ 2 แล้วกด Run เพื่อตรวจแต่ละแถวของตารางนี้

picture Outputผลลัพธ์
"123", "456", "789" (case = 1) 741, 852, 963
"X" (1×1) X
"ab", "cd" (2×2) ca, db
Smiley face 9×9 (case = 2)หน้ายิ้ม 9×9 (case = 2) the eyes @ move to the right, the mouth + moves to the leftตา @ ย้ายมาอยู่ด้านขวา ปาก + ย้ายมาอยู่ด้านซ้าย
4 Think further ชวนคิดต่อ

Suppose the picture should turn 90° counterclockwise instead. What should the index be?

ถ้าต้องการหมุนทวนเข็มนาฬิกา 90° ต้องแก้ index เป็นอะไร

Show the answer ดูคำตอบ

Use picture[c][size - r - 1]. The first row of the result is now the last column of the picture, read from top to bottom. 123, 456, 789 gives 369, 258, 147.

ใช้ picture[c][size - r - 1] เพราะแถวแรกของภาพผลกลายเป็นคอลัมน์สุดท้ายของภาพเดิม อ่านจากบนลงล่าง 123, 456, 789 จึงได้ 369, 258, 147

[ccw]
[output]
369
258
147

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 — Common Sequence Operations (indexing a list and a string) (การใช้ index กับ list และ string)
  2. Python docs — The for statement (nested loops with range) (loop ซ้อนกันด้วย range)

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

ตอบแล้ว 0 / 10

ข้อ 1

1 / 10

If picture = ["123", "456"], what is picture[1][2]?picture = ["123", "456"] แล้ว picture[1][2] คืออะไร?

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

เฉลย / Answer: (C) 66

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

  • (A) 33
    Wrong: 3 is in the row at index 0.ผิด: 3 อยู่ในแถว index 0
  • (B) 55
    Wrong: 5 is index 1 of that row.ผิด: 5 คือ index 1 ของแถวนั้น
  • (C) 66
    Correct! The row at index 1 is 456, and index 2 of that row is 6.ถูกต้อง! แถว index 1 คือ 456 และ index 2 ของแถวนั้นคือ 6
  • (D) 44
    Wrong: 4 is index 0 of that row.ผิด: 4 คือ index 0 ของแถวนั้น

ข้อ 2

2 / 10

picture is a list of strings. If the picture has 9 rows, what is size?
size = len(picture)
picture เป็น list ของ string ถ้าภาพมี 9 แถว size เท่ากับเท่าไร?
size = len(picture)

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

เฉลย / Answer: (A) 99

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

  • (A) 99
    Correct! len(picture) counts the strings in the list.ถูกต้อง! len(picture) นับจำนวน string ใน list
  • (B) 88
    Wrong: 8 is the last index, not the number of rows.ผิด: 8 คือ index สุดท้าย ไม่ใช่จำนวนแถว
  • (C) 8181
    Wrong: 81 is the number of characters in the whole picture.ผิด: 81 คือจำนวนตัวอักษรทั้งภาพ
  • (D) 1010
    Wrong: len simply counts the items.ผิด: len นับจำนวนสมาชิกตรงๆ

ข้อ 3

3 / 10

After a 90° clockwise turn, where does the first row of the result come from?หลังหมุน 90° ตามเข็มนาฬิกา แถวแรกของภาพผลมาจากไหน?

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

เฉลย / Answer: (D) The first column, read from bottom to topคอลัมน์แรก อ่านล่างขึ้นบน

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

  • (A) The first row, read from left to rightแถวแรก อ่านซ้ายไปขวา
    Wrong: that is the picture with no turn at all.ผิด: แบบนี้คือภาพเดิมที่ไม่ได้หมุน
  • (B) The last row, read from right to leftแถวสุดท้าย อ่านขวาไปซ้าย
    Wrong: that is a 180° turn.ผิด: แบบนี้คือการหมุน 180°
  • (C) The last column, read from top to bottomคอลัมน์สุดท้าย อ่านบนลงล่าง
    Wrong: that is a counterclockwise turn.ผิด: แบบนี้คือการหมุนทวนเข็มนาฬิกา
  • (D) The first column, read from bottom to topคอลัมน์แรก อ่านล่างขึ้นบน
    Correct! So 123, 456, 789 gives 741 as the first row.ถูกต้อง! 123, 456, 789 จึงได้แถวแรกเป็น 741

ข้อ 4

4 / 10

When size = 3, r = 0 and c = 0, which position does this line take?
text += picture[size - c - 1][r]
เมื่อ size = 3, r = 0, c = 0 บรรทัดนี้จะหยิบจากตำแหน่งใด?
text += picture[size - c - 1][r]

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

เฉลย / Answer: (B) picture[2][0]picture[2][0]

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

  • (A) picture[0][0]picture[0][0]
    Wrong: that position is used when c = 2.ผิด: ตำแหน่งนี้ใช้ตอน c = 2
  • (B) picture[2][0]picture[2][0]
    Correct! 3 - 0 - 1 = 2 and r = 0.ถูกต้อง! 3 - 0 - 1 = 2 และ r = 0
  • (C) picture[0][2]picture[0][2]
    Wrong: size - c - 1 is the row index, not the column.ผิด: size - c - 1 เป็น index ของแถว ไม่ใช่คอลัมน์
  • (D) picture[2][2]picture[2][2]
    Wrong: the second index is r, which is 0.ผิด: index ตัวที่สองคือ r ซึ่งเป็น 0

ข้อ 5

5 / 10

Why is text = "" set inside the outer loop?
for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)
ทำไมต้องกำหนด text = "" ใน loop ด้านนอก?
for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)

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

เฉลย / Answer: (C) To start collecting a new row in every roundเพื่อเริ่มเก็บแถวใหม่ทุกรอบ

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

  • (A) To stop the loopเพื่อหยุด loop
    Wrong: the loop ends when the range runs out.ผิด: loop จบเมื่อ range หมด
  • (B) To clear pictureเพื่อล้าง picture
    Wrong: picture does not change.ผิด: picture ไม่ถูกเปลี่ยน
  • (C) To start collecting a new row in every roundเพื่อเริ่มเก็บแถวใหม่ทุกรอบ
    Correct! Without it, a new row would be added to the end of the old one.ถูกต้อง! ถ้าไม่ล้าง แถวใหม่จะต่อท้ายแถวเดิม
  • (D) Because print needs itเพราะ print ต้องการ
    Wrong: the reason is to keep the rows separate.ผิด: เหตุผลคือการแยกแถว

ข้อ 6

6 / 10

This code turns the picture 90° clockwise. What is the last row it shows?
picture = ["123", "456", "789"]
size = len(picture)

for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)
โค้ดนี้หมุนภาพ 90° ตามเข็มนาฬิกา แถวสุดท้ายที่แสดงคืออะไร?
picture = ["123", "456", "789"]
size = len(picture)

for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)

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

เฉลย / Answer: (A) 963963

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

  • (A) 963963
    Correct! The last row is the last column of the picture, read from bottom to top.ถูกต้อง! แถวสุดท้ายคือคอลัมน์สุดท้ายของภาพเดิม อ่านล่างขึ้นบน
  • (B) 321321
    Wrong: this is the first row read backward.ผิด: นี่คือแถวแรกอ่านกลับหลัง
  • (C) 741741
    Wrong: this is the first row of the result.ผิด: นี่คือแถวแรกของภาพผล
  • (D) 789789
    Wrong: this is the last row of the original picture.ผิด: นี่คือแถวสุดท้ายของภาพเดิม

ข้อ 7

7 / 10

Why is it size - c - 1 and not size - c?
for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)
ทำไมต้องเขียน size - c - 1 ไม่ใช่ size - c?
for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)

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

เฉลย / Answer: (B) The last position is size - 1, so without the 1 the index runs past the listตำแหน่งสุดท้ายคือ size - 1 ถ้าไม่ลบ 1 จะเกิน list

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

  • (A) To run fasterให้รันเร็วขึ้น
    Wrong: the reason is the position of the index.ผิด: เหตุผลคือตำแหน่งของ index
  • (B) The last position is size - 1, so without the 1 the index runs past the listตำแหน่งสุดท้ายคือ size - 1 ถ้าไม่ลบ 1 จะเกิน list
    Correct! When c = 0, size is not a valid index.ถูกต้อง! เมื่อ c = 0 ค่า size ไม่ใช่ index ที่ใช้ได้
  • (C) Because c starts at 1เพราะ c เริ่มที่ 1
    Wrong: c starts at 0.ผิด: c เริ่มที่ 0
  • (D) To skip the first rowเพื่อข้ามแถวแรก
    Wrong: every row is used.ผิด: ทุกแถวถูกหยิบครบ

ข้อ 8

8 / 10

Which pictures does this program work with?
size = len(picture)

for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)
โปรแกรมนี้ใช้ได้กับภาพแบบใด?
size = len(picture)

for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)

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

เฉลย / Answer: (D) Square pictures of any sizeภาพจัตุรัสทุกขนาด

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

  • (A) Only pictures wider than they are tallภาพที่กว้างกว่าสูงเท่านั้น
    Wrong: the program uses one size for both rows and columns.ผิด: โปรแกรมใช้ size เดียวกับแถวและคอลัมน์
  • (B) Only 9×9 picturesภาพ 9×9 เท่านั้น
    Wrong: size comes from the picture, so it is not fixed.ผิด: size คำนวณจากภาพ จึงไม่ได้ตายตัว
  • (C) Only 3×3 picturesภาพ 3×3 เท่านั้น
    Wrong: it works with 1×1, 2×2 and 9×9 pictures too.ผิด: โปรแกรมใช้กับภาพ 1×1, 2×2 และ 9×9 ได้ด้วย
  • (D) Square pictures of any sizeภาพจัตุรัสทุกขนาด
    Correct! The rows and the columns must be equal in number.ถูกต้อง! จำนวนแถวต้องเท่ากับจำนวนคอลัมน์

ข้อ 9

9 / 10

How many characters are taken for a 9×9 picture?
for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)
ภาพ 9×9 มีการหยิบตัวอักษรกี่ครั้ง?
for r in range(size):
    text = ""
    for c in range(size):
        text += picture[size - c - 1][r]
    print(text)

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

เฉลย / Answer: (C) 8181

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

  • (A) 99
    Wrong: 9 is the number of rounds of the outer loop.ผิด: 9 คือจำนวนรอบของ loop ด้านนอก
  • (B) 1818
    Wrong: nested loops multiply, they do not add.ผิด: loop ซ้อนกันจึงเป็นการคูณ ไม่ใช่การบวก
  • (C) 8181
    Correct! 9 rows of 9 characters.ถูกต้อง! 9 แถว แถวละ 9 ตัว
  • (D) 7272
    Wrong: every cell is taken.ผิด: ทุกช่องถูกหยิบครบ

ข้อ 10

10 / 10

Which index in place of ??? gives a 90° counterclockwise turn?
for r in range(size):
    text = ""
    for c in range(size):
        text += ???
    print(text)
จะหมุนทวนเข็มนาฬิกา 90° ต้องใช้ index ใดแทน ????
for r in range(size):
    text = ""
    for c in range(size):
        text += ???
    print(text)

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

เฉลย / Answer: (A) picture[c][size - r - 1]picture[c][size - r - 1]

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

  • (A) picture[c][size - r - 1]picture[c][size - r - 1]
    Correct! The first row of the result is the last column, read from top to bottom.ถูกต้อง! แถวแรกของผลคือคอลัมน์สุดท้าย อ่านบนลงล่าง
  • (B) picture[r][c]picture[r][c]
    Wrong: this index gives the original picture.ผิด: index นี้ให้ภาพเดิม
  • (C) picture[size - c - 1][r]picture[size - c - 1][r]
    Wrong: this index turns the picture clockwise.ผิด: index นี้หมุนตามเข็มนาฬิกา
  • (D) picture[size - r - 1][c]picture[size - r - 1][c]
    Wrong: this index flips the rows upside down, which is not a turn.ผิด: index นี้กลับแถวจากล่างขึ้นบน ไม่ใช่การหมุน