Example 9 — Make a Code Name with One Loop ตัวอย่างที่ 9 — สร้างชื่อรหัสด้วย loop เดียว
The same problem as Example 8, solved with one loop that takes each letter from the end and sets its case in the same round. โจทย์เดียวกับตัวอย่างที่ 8 แต่เขียนด้วย loop เดียว ที่หยิบตัวอักษรจากท้ายและจัดตัวพิมพ์ในรอบเดียวกัน
This page solves the problem of Example 8 again, with a shorter program. Read the problem, follow the flowcharts and run the code, then see in card 4 why this program is better than the one in Example 8.
หน้านี้แก้โจทย์ของตัวอย่างที่ 8อีกครั้งด้วยโปรแกรมที่สั้นกว่า อ่านโจทย์ ไล่ตาม flowchart และรันโค้ด แล้วดูในการ์ดที่ 4 ว่าโปรแกรมนี้ดีกว่าโปรแกรมในตัวอย่างที่ 8 อย่างไร
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 (the same function as in Example 8)
- code_name(text) — returns the code name of text in one loop
- ตัวอย่าง: Robert → Code name: Trebor
- is_name(text) — คืนค่า True เฉพาะเมื่อ text มี 1 ถึง 10 ตัว และทุกตัวเป็นตัวอักษร (ฟังก์ชันเดียวกับตัวอย่างที่ 8)
- code_name(text) — คืนค่าชื่อรหัสของ text ด้วย loop เดียว
- 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.
- A negative index counts from the end: text[-1] is the last letter, so text[-(i + 1)] is the letter at position i counted from the end, starting at 0.
- 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 เมื่อเงื่อนไขข้อใดข้อหนึ่งเป็นจริง
- ดัชนีติดลบนับจากท้าย text[-1] คือตัวสุดท้าย ดังนั้น text[-(i + 1)] คือตัวอักษรตำแหน่งที่ i นับจากท้าย เริ่มที่ 0
- upper() / lower() แปลงตัวอักษรเป็นตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็ก
- while True วนซ้ำไปเรื่อยๆ จนกว่าจะเจอ break ซึ่งสั่งให้ออกจาก loop
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 code_name(name), shows the code name with print, and the program ends.
โปรแกรมนี้เริ่มต้นด้วยวน loop while True แล้วรับชื่อเก็บใน name ตรวจสอบเงื่อนไขว่าชื่อถูกต้องหรือไม่ด้วย function ย่อย is_name ถ้าใช่ให้ break ออกจาก loop ถ้าไม่ใช่ให้แสดงข้อความเตือนด้วย print แล้วกลับไปรับค่าใหม่ หลังออกจาก loop จึงเรียก code_name(name) แสดงชื่อรหัสด้วย print และจบการทำงานของโปรแกรม
Your name: Mary Ann Use 1 to 10 letters (A-Z, a-z), please try again Your name: Robert Code name: Trebor
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.
ลองป้อนค่าเอง — ค่าแรกที่กดส่งจะล้างตัวอย่างเดิมแล้วเริ่มรันใหม่ ส่งทีละค่า: ถ้าชื่อไม่ถูกต้องจะขึ้นข้อความเตือนแล้วรอค่าถัดไป ถ้าชื่อถูกต้องโปรแกรมจะจบ และการส่งครั้งถัดไปจะเริ่มรันใหม่ ถ้ากดส่งโดยไม่พิมพ์อะไรจะเป็นการทดสอบชื่อว่าง
| Input (in order)ข้อมูลที่ป้อน (ตามลำดับ) | Outputผลลัพธ์ |
|---|---|
| Robert | Trebor |
| sIMON | Nomis |
| j | J |
| Maximilian | Nailimixam |
| Ada | Ada |
| Christopher, Leo | 1 warning, thenเตือน 1 ครั้ง แล้ว Oel |
| (empty), then(ว่าง) แล้ว Tom | 1 warning, thenเตือน 1 ครั้ง แล้ว Mot |
| Mary Ann, R2D2, Kim | 2 warnings, thenเตือน 2 ครั้ง แล้ว Mik |
code_name 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 takes the letter text[-(i + 1)] from the end side and stores it in ch, then checks whether i == 0. If it is the first letter of the code name, it adds ch.upper() to the end of result; if not, it adds ch.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.
code_name เริ่มต้นด้วยกำหนดค่า result = '' สำหรับเก็บผลลัพธ์ และ i = 0 เป็นตัวชี้ตำแหน่งตัวอักษร แล้วตรวจสอบเงื่อนไขว่า i < len(text) หรือไม่ ถ้าใช่ให้หยิบตัวอักษร text[-(i + 1)] จากด้านท้ายเก็บใน ch แล้วตรวจสอบว่า i == 0 หรือไม่ ถ้าเป็นตัวแรกของชื่อรหัสให้ต่อ ch.upper() เข้าท้าย result ถ้าไม่ใช่ให้ต่อ ch.lower() ไม่ว่าทางใดทางหนึ่ง หลังจากนั้นเพิ่ม i ขึ้น 1 แล้วกลับไปตรวจสอบ i < len(text) อีกครั้ง ทำแบบนี้จนเงื่อนไขเป็นเท็จ จึงส่งค่า result กลับด้วย return
Example 8 (after its bug is fixed) makes the code name in two steps: read_backward loops over the name to build backward, then name_case loops over backward again to set the case of each letter. But the case of a letter depends only on its place in the code name, which is i, and that is already known at the moment the letter is taken. So this program sets the case of each letter in the same round as it takes the letter, and never needs to keep the whole name backward.
ตัวอย่างที่ 8 (หลังแก้ bug) สร้างชื่อรหัส 2 ขั้น read_backward วน loop ตามชื่อเพื่อสร้าง backward แล้ว name_case วน loop ตาม backward อีกรอบเพื่อจัดตัวพิมพ์ทีละตัว แต่ตัวพิมพ์ของแต่ละตัวขึ้นกับตำแหน่งในชื่อรหัสเท่านั้น ซึ่งก็คือ i และรู้อยู่แล้วตั้งแต่ตอนที่หยิบตัวอักษรตัวนั้น โปรแกรมนี้จึงจัดตัวพิมพ์ในรอบเดียวกับที่หยิบตัวอักษร และไม่ต้องเก็บชื่อกลับหลังทั้งชื่อไว้
| Example 8 (fixed)ตัวอย่างที่ 8 (หลังแก้ bug) | Example 9ตัวอย่างที่ 9 | |
|---|---|---|
| Functionsจำนวนฟังก์ชัน | 3 (is_name, read_backward, name_case) | 2 (is_name, code_name) |
| Loops that make the code nameจำนวน loop ที่ใช้สร้างชื่อรหัส | 2 (read backward, then set the case)2 (กลับหลัง แล้วจัดตัวพิมพ์) | 1 |
| What the extra variable holdsตัวแปรเพิ่มเก็บอะไร | backward holds the whole name backwardbackward เก็บชื่อกลับหลังทั้งชื่อ | ch holds one letterch เก็บตัวอักษรตัวเดียว |
| Rounds for a 6-letter name (Robert)จำนวนรอบเมื่อชื่อยาว 6 ตัว (Robert) | 12 (6 to read backward + 6 to set the case)12 (กลับหลัง 6 + จัดตัวพิมพ์ 6) | 6 |
The index -(i + 1) also avoids the trap of Example 8: it starts at -1, the last letter, so there is no -0. Run the code below to see each round. It is the loop of code_name with one print added. Try other names too.
ดัชนี -(i + 1) ยังเลี่ยงกับดักของตัวอย่างที่ 8 ด้วย เพราะเริ่มที่ -1 ซึ่งคือตัวสุดท้าย จึงไม่มี -0 รันโค้ดด้านล่างเพื่อดูแต่ละรอบ โค้ดนี้คือ loop ของ code_name ที่เพิ่ม print 1 บรรทัด ลองป้อนชื่ออื่นด้วย
Your name: Robert 0 -1 t T 1 -2 r Tr 2 -3 e Tre 3 -4 b Treb 4 -5 o Trebo 5 -6 R Trebor Code name: Trebor
Think further: suppose the code name should also end with a capital letter, so that Robert gives TreboR. Which line of code_name would you change, and how?
ชวนคิดต่อ: ถ้าต้องการให้ตัวสุดท้ายของชื่อรหัสเป็นตัวพิมพ์ใหญ่ด้วย เช่น Robert ได้ TreboR ต้องแก้บรรทัดไหนของ code_name และแก้อย่างไร
Show the answer ดูคำตอบ
Change the condition if i == 0: to if i == 0 or i == len(text) - 1:. In a name of N letters, i runs from 0 to N - 1, so i == len(text) - 1 is true only in the last round, which adds the last letter of the code name. Only one loop has to change, because taking the letter and setting its case happen in the same place.
แก้เงื่อนไข if i == 0: เป็น if i == 0 or i == len(text) - 1: สำหรับชื่อยาว N ตัว i มีค่าตั้งแต่ 0 ถึง N - 1 ดังนั้น i == len(text) - 1 เป็นจริงเฉพาะรอบสุดท้าย ซึ่งเป็นรอบที่ต่อตัวสุดท้ายของชื่อรหัส แก้แค่ loop เดียวก็พอ เพราะการหยิบตัวอักษรและการจัดตัวพิมพ์อยู่ในที่เดียวกัน
Your name: Robert Code name: TreboR
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 / แหล่งอ้างอิง
-
Python docs — String Methods
(
isalpha,upper,lower) (isalpha,upper,lower) - Python docs — Common Sequence Operations (indexing a string, including negative indexes counted from the end) (การใช้ดัชนีกับสตริง รวมถึงดัชนีติดลบที่นับจากท้าย)
-
Python docs — The while statement
(
while Trueandbreak) (while Trueและbreak) - The two-loop version of this program: Example 8 — Make a Code Name (debugging); flowchart symbols: 01 Basic → Flowchart Basic. โปรแกรมแบบ 2 loop ของโจทย์นี้: ตัวอย่างที่ 8 — สร้างชื่อรหัสจากชื่อกลับหลัง (debugging) ; สัญลักษณ์ของ flowchart: 01 Basic → Flowchart Basic