10. คำสั่งทำซ้ำ while

https://drive.google.com/file/d/1ONujygp4YA3-h3oHSYDiCBAdbJImlTPi/view?usp=sharing

10.1. จุดประสงค์รายสัปดาห์

  1. ระบุข้อแตกต่างระหว่างการทำซ้ำแบบ for และ while ได้

  2. ใช้คำสั่ง while เพื่อรับข้อมูลตามเงื่อนไขที่กำหนดให้ได้

  3. ใช้คำสั่ง for และ while เพื่อแก้ปัญหาแบบ indefinite และ definite ได้

10.2. ที่มาและความสำคัญ

ในการเขียนโปรแกรมโดยส่วนใหญ่จำเป็นต้องเขียนคำสั่งเพื่อทำงานเดิมซ้ำกันหลายๆครั้ง การใช้คำสั่งทำซ้ำวนไปหลายๆรอบนั้นเรียกว่า Loop

การใช้คำสั่ง Loop มีสองแบบได้แก่

  1. แบบที่รู้จำนวนครั้งในการทำซ้ำแน่นอน เรียกว่า definite loop

  2. แบบที่ไม่รู้จำนวนครั้งในการทำซ้ำ เรียกว่า indefinite loop จำเป็นต้องตั้งเงื่อนไขในการทำงาน ถ้าเงื่อนไขในการทำงานเป็นเท็จก็จะหยุดทำงาน

โดยปกติแล้วถ้าเป็นรู้จำนวนครั้งที่ต้องทำงานซ้ำแน่นอนจะใช้คำสั่ง for แต่ถ้าไม่รู้จำนวนครั้งที่แน่นอนต้องใช้เงื่อนไขตรวจสอบการทำงานจะใช้คำสั่ง while

10.3. คำสั่ง For

คำสั่งรับคะแนน ``n`` ค่า โดยให้ผู้ใช้กำหนดค่า ``n``

# sample1201.py
n = int( input() )
scores = [ ]
for i in range(n):
    x = float( input() )
    scores.append( x )

10.4. โจทย์ทบทวน for

  1. จงเขียนคำสั่งเพื่อรับลำดับ (list) ของข้อมูลที่เป็นชื่อของนักศึกษา 10 ชื่อ

  2. จงเขียนคำสั่งเพื่อรับลำดับ (list) ของข้อมูลอาจารย์ 7 ข้อมูล โดยข้อมูลแต่ละชุดประกอบด้วย ชื่อ อายุการทำงาน email และ ห้องพัก

  3. นับเกรด 1 วิชา จงเขียนคำสั่งเพื่อรับเกรด A B C D หรือ F จากผู้ใช้ โดยให้ผู้ใช้ระบุจำนวนเกรดที่ต้องการกรอกก่อน เมื่อรับเกรดครบแล้วจะต้องแสดงเกรดพร้อมจำนวนเรียงจากเกรดที่นับได้มากที่สุดจนถึงเกรดที่นับได้น้อยที่สุด

  4. จงเขียนโปรแกรม นับเกรด สำหรับ 10 หลักสูตร หลักสูตรละ 40 วิชา แต่ละวิชามีจำนวนเกรด(นักศึกษา) ไม่เท่ากัน?

10.5. คำสั่ง while

while-flowchart

while-flowchart

while เงื่อนไข:
    คำสั่งใน while

ตัวอย่างคำสั่ง

# sample1202.py
คำตอบ = 'ต่อ'
while คำตอบ == 'ต่อ':
    คำตอบ = input('ต่อ หรือ หยุด? ')

10.6. คำสั่งใน while

while-body

คำสั่งประเภทต่างๆ ที่เรียนมาทั้งหมดสามารถใส่ไว้ใน คำสั่งใน while ได้

  1. คำสั่งประกาศตัวแปร

  2. คำสั่งกำหนดค่า

  3. คำสั่งเรียกใช้ฟังก์ชัน

  4. คำสั่งประมวลผล

  5. คำสั่งกำหนดเงื่อนไขการทำงาน

  6. คำสั่งทำซ้ำ

10.7. การรับตัวเลขจนกว่าผู้ใช้กรอก -1

# sample1203.py
a = [ ]
x = int( input() )
while x != -1:
    a.append( x )
    x = int( input() )
flowchart2

flowchart2

10.8. การเขียนคำสั่งทำซ้ำแบบมีตัวเลือก

# sample1204.py
def display_options():
    print('ตัวเลือก')
    print('1. ผลรวม')
    print('2. ผลคูณ')
    print('3. เรียงลำดับ')
    print('4. ปิดโปรแกรม')
    return int(input('เลือก: '))

x = display_options()
while x != 4:
    x = display_options()

10.9. EX1201

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

solution 1

def display_options():
    print('ตัวเลือก')
    print('1. ผลรวม')
    print('2. ผลคูณ')
    print('3. เรียงลำดับ')
    print('4. ปิดโปรแกรม')
    return int(input('เลือก: '))

def รวม(a):
    return sum(a)

def คูณ(a):
    total = 1
    for i in a:
        total = total * i
    return total

def เรียง(a):
    return sorted(a)

x = display_options()
while x != 4:
    a = map(int, input().split(','))
    if x == 1:
        print( f'ผลรวมคือ {รวม(a)}' )
    elif x == 2:
        print( f'ผลคูณคือ {คูณ(a)}' )
    elif x == 3:
        print( f'ผลการเรียงคือ {เรียง(a)}' )
    x = display_options()

solution 2 อนุญาตให้ผู้ใช้กรอกตัวเลขใหม่เมื่อต้องการ

from functools import reduce
import sys

ข้อมูล = []

def display_options():
    print('ตัวเลือก')
    print('1. กรอกลำดับของตัวเลข')
    print('2. ผลรวม')
    print('3. ผลคูณ')
    print('4. เรียงลำดับ')
    print('5. ปิดโปรแกรม')
    return input('เลือก: ').split('.')[0]

def คูณ(a, b):
    return a*b

def รับข้อมูลใหม่():
    global ข้อมูล
    ข้อมูล = list( map(int, input().split(',')) )

def หาผลรวม():
    print( f'ผลรวมคือ {sum(ข้อมูล)}' )

def หาผลคูณ():
    print( f'ผลคูณคือ {reduce(คูณ, ข้อมูล)}' )

def เรียงลำดับ():
    print( f'ผลการเรียงคือ {sorted(ข้อมูล)}' )

def ปิด():
    sys.exit()

# dict - key=str, value=function
actions = {
    '1': รับข้อมูลใหม่,
    '2': หาผลรวม,
    '3': หาผลคูณ,
    '4': เรียงลำดับ,
    '5': ปิด
}

while True:
    x = display_options()
    actions[x]()

10.10. ทำซ้ำ n ครั้ง

10.10.1. รับจำนวนเต็ม n ครั้ง

# sample1205.py
a = [ ]
count = 0
while count < n:
    a.append( int(input()) )
    count = count + 1

10.10.2. แสดงข้อมูลในชุดลำดับ

# sample1206.py
a = [5,7,6,3,2]
i = 0
while i < len(a):
    print( a[i] )
    i = i + 1

10.11. กำหนดการทำงานใน loop

คำสั่งกำหนดการทำงานในคำสั่งทำซ้ำไม่ว่าจะเป็น for หรือ while นั้นสามารถใช้คำสั่งกำหนดการทำงานต่อไปนี้ได้

  1. break คำสั่ง หยุด การวนซ้ำ

  2. continue คำสั่ง ข้ามต่อ การวนซ้ำไปรอบถัดไป

  3. pass คำสั่งที่ใช้เมื่อไม่มีคำสั่งภายใน for หรือ while

10.11.1. break

ใช้เมื่อต้องการหยุดการทำซ้ำ

# sample1207.py
for i in range(1,10):
    if i == 5:
        break
    print(i)

a = [ ]
while True:
    x = int(input())
    if x == -1:
        break
    a.append(x)
print(a)

10.11.2. continue

ใช้เมื่อต้องการข้ามต่อไปรอบถัดไป

# sample1208.py
name = 'Paul Phoenix'
i = -1
while i < len(name):
    i = i + 1
    if i%2 == 0:
        continue
    print(name[i], end='')
print()

for i in range(1,10):
    if i%2 == 0:
        continue
    print(i)

10.11.3. pass

ใช้เมื่อไม่มีคำสั่งใดๆ ภายใน for หรือ while

# sample1209.py
for i in range(10):
    pass

while 4 < 3:
    pass

10.12. การสร้างเงื่อนไขจากชุดข้อมูล

10.12.1. ชุดข้อมูลที่มีสมาชิก True

10.12.2. ชุดข้อมูลที่ไม่มีสมาชิก False

  • ''

  • {}

  • []

  • None

# sample1210.py
if 1:
    print("1 is True.")
else:
    print("1 is False.")

print("1 is True.")    if 1    else print("1 is False.")
print("0 is True.")    if 0    else print("0 is False.")
print("-1 is True.")   if -1   else print("-1 is False.")
print("'' is True.")   if ''   else print("'' is False.")
print("{} is True.")   if {}   else print("{} is False.")
print("[] is True.")   if []   else print("[] is False.")
print("None is True.") if None else print("None is False.")

10.13. สรุป

10.13.1. Definite Loop

รู้จำนวนครั้งในการทำซ้ำแน่นอน เช่น ทำซ้ำ n ครั้ง

for i in range(n):
    work()

ไล่ทำงานตามสมาชิกของชุดข้อมูล เช่น ``students``
for สมาชิก in range(ชุดข้อมูล):
    work(สมาชิก)

10.13.2. Indefinite Loop

ทำงานไปเรื่อยๆ จนกว่าเงื่อนไขจะเป็นเท็จ

while เงื่อนไข == True:
    work()
    ปรับ(เงื่อนไข)

10.14. ตัวอย่างโจทย์

10.14.1. EX1202

โจทย์

จงเขียนโปรแกรมเพื่ออ่านชุดคำสั่ง ภาษางานทะเบียน ซึ่งคำสั่งแต่ละบรรทัดจะเริ่มด้วยคำสั่งดำเนินการ A โดย

  • A เป็นคำสั่งดำเนินการ ได้แก่

  • เพิ่ม,B,C - หมายถึง เพิ่มนักศึกษา B เข้าหลักสูตร C

    • ถ้ารหัสนักศึกษา B อยู่ในหลักสูตรอื่น ให้ย้ายออกจากหลักสูตรนั้น แล้วเพิ่มไปในหลักสูตร C

    • ถ้ารหัสนักศึกษา B ไม่อยู่ในหลักสูตรใดเลย ให้เพิ่มเข้าหลักสูตร C ได้ตามปกติ

    • ถ้ารหัสนักศึกษา B อยู่ในหลักสูตร C อยู่แล้ว ไม่ต้องทำอะไร

  • ถอน,B - หมายถึง ถอนรหัสนักศึกษา B ออกจากระบบ

    • ไม่ต้องทำอะไร ถ้าไม่มีรหัสนักศึกษา B อยู่ในหลักสูตรใดเลย

    • ในกรณีที่รหัสนักศึกษา B อยู่ในหลักสูตรใดหลักสูตรหนึ่งให้ถอนออก

  • ย้าย,B,C - หมายถึง ย้ายรหัสนักศึกษา B ออกจากหลักสูตรเดิม เข้าหลักสูตร C

    • ถ้ารหัสนักศึกษา B เป็นนักศึกษาใหม่ ให้เพิ่มเข้าไปในหลักสูตร C

    • ถ้ารหัสนักศึกษา B อยู่ในหลักสูตรอื่น ให้ย้ายออกจากหลักสูตรนั้น แล้วเพิ่มไปในหลักสูตร C

    • ถ้ารหัสนักศึกษา B อยู่ในหลักสูตร C อยู่แล้ว ไม่ต้องทำอะไร

  • หมด - หมายถึง สิ้นสุดข้อมูล

เมื่อสิ้นสุดแล้วโปรแกรมจะต้องแสดงรายการรหัสหลักสูตรพร้อมรหัสนักศึกษาในหลักสูตร

ตัวอย่างชุดข้อมูลนำเข้า

เพิ่ม,611111,1144
เพิ่ม,611121,1141
เพิ่ม,611113,1142
ย้าย,611142,1144
เพิ่ม,613242,1144
ถอน,612131
หมด

ตัวอย่างชุดข้อมูลส่งออก

> 1144
    611111
    611142
    613242
> 1141
    611121
> 1142
    611113

Solution

programs = {}

def remove(b):
    for k in programs.keys():
        if b in programs[k]:
            programs[k].remove(b)

def add(b, c):
    remove(b)
    if c not in programs.keys():
        programs[c] = [ b ]
    else:
        programs[c].append(b)

actions = {
    'เพิ่ม': add,
    'ย้าย': add,
    'ถอน': remove
}

line = input().split(',')
while line[0] != 'หมด':
    actions[line[0]](*line[1:])
    line = input().split(',')

for k,v in programs.items():
    print(f'> {k}\n\t' + '\n\t'.join(v))