Skip to content

🏋️ 7.4 Bài tập luyện tập

📖 Giới thiệu

Đây là bài tổng hợp tất cả kiến thức về vòng lặp while, kết hợp với break, continue và các kỹ thuật đã học. Chúng ta sẽ làm các bài tập từ cơ bản đến nâng cao để thành thạo vòng lặp while.

Mục tiêu bài học:

  • Tổng hợp kiến thức về while, break, continue
  • Giải quyết bài toán thực tế với while
  • Xây dựng ứng dụng hoàn chỉnh
  • Luyện tập debug và tối ưu code

🔢 Bài tập số học

Bài 1: Máy tính số học liên tục

python
# may_tinh_lien_tuc.py
print("🧮 MÁY TÍNH SỐ HỌC LIÊN TỤC")
print("=" * 35)

ket_qua = 0
phep_toan_dau = True

print("💡 Nhập 'q' để thoát, 'r' để reset")

while True:
    if phep_toan_dau:
        print(f"\n🎯 Bắt đầu tính toán")
        try:
            ket_qua = float(input("Số đầu tiên: "))
            phep_toan_dau = False
        except ValueError:
            print("❌ Vui lòng nhập số!")
            continue
    
    print(f"\nKết quả hiện tại: {ket_qua}")
    
    # Nhập phép toán
    phep_toan = input("Phép toán (+, -, *, /, r-reset, q-quit): ").strip()
    
    if phep_toan.lower() == 'q':
        print(f"👋 Kết quả cuối: {ket_qua}")
        break
    
    if phep_toan.lower() == 'r':
        ket_qua = 0
        phep_toan_dau = True
        print("🔄 Đã reset!")
        continue
    
    if phep_toan not in ['+', '-', '*', '/']:
        print("❌ Phép toán không hợp lệ!")
        continue
    
    # Nhập số thứ hai
    try:
        so_thu_hai = float(input(f"Số để {phep_toan}: "))
    except ValueError:
        print("❌ Vui lòng nhập số!")
        continue
    
    # Thực hiện phép tính
    ket_qua_cu = ket_qua
    
    if phep_toan == '+':
        ket_qua += so_thu_hai
    elif phep_toan == '-':
        ket_qua -= so_thu_hai
    elif phep_toan == '*':
        ket_qua *= so_thu_hai
    elif phep_toan == '/':
        if so_thu_hai == 0:
            print("❌ Không thể chia cho 0!")
            continue
        ket_qua /= so_thu_hai
    
    print(f"📊 {ket_qua_cu} {phep_toan} {so_thu_hai} = {ket_qua}")

Bài 2: Tìm ước chung lớn nhất (GCD)

python
# tim_gcd.py
print("🔍 TÌM ƯỚC CHUNG LỚN NHẤT")
print("=" * 35)

while True:
    try:
        a = int(input("\nNhập số thứ nhất (0 để thoát): "))
        if a == 0:
            break
            
        b = int(input("Nhập số thứ hai: "))
        if b == 0:
            print("❌ Số thứ hai không được là 0!")
            continue
            
    except ValueError:
        print("❌ Vui lòng nhập số nguyên!")
        continue
    
    # Lưu giá trị gốc để hiển thị
    a_goc, b_goc = a, b
    
    # Thuật toán Euclid
    print(f"\n🔍 Tìm GCD({a_goc}, {b_goc}):")
    buoc = 1
    
    while b != 0:
        print(f"Bước {buoc}: {a} = {b} × {a // b} + {a % b}")
        a, b = b, a % b
        buoc += 1
    
    print(f"\n✅ GCD({a_goc}, {b_goc}) = {a}")
    
    # Tìm bội chung nhỏ nhất
    lcm = (a_goc * b_goc) // a
    print(f"💡 LCM({a_goc}, {b_goc}) = {lcm}")

Bài 3: Dãy Fibonacci với điều kiện dừng

python
# day_fibonacci.py
print("📈 DÃY FIBONACCI VỚI ĐIỀU KIỆN DỪNG")
print("=" * 40)

while True:
    try:
        gioi_han = int(input("\nGiới hạn số Fibonacci (0 để thoát): "))
        if gioi_han == 0:
            break
        if gioi_han < 0:
            print("❌ Vui lòng nhập số dương!")
            continue
    except ValueError:
        print("❌ Vui lòng nhập số nguyên!")
        continue
    
    print(f"\n📈 Dãy Fibonacci ≤ {gioi_han}:")
    
    # Khởi tạo
    a, b = 0, 1
    day_fib = []
    
    # Tạo dãy Fibonacci
    while a <= gioi_han:
        day_fib.append(a)
        print(f"F({len(day_fib) - 1}) = {a}")
        a, b = b, a + b
    
    print(f"\n📊 THỐNG KÊ:")
    print(f"Có {len(day_fib)} số Fibonacci ≤ {gioi_han}")
    print(f"Tổng: {sum(day_fib)}")
    print(f"Dãy: {day_fib}")
    
    # Tìm số Fibonacci gần nhất
    if day_fib:
        gan_nhat = day_fib[-1]
        print(f"Số Fibonacci lớn nhất ≤ {gioi_han}: {gan_nhat}")

🎮 Bài tập game và tương tác

Bài 4: Game 21 (Blackjack đơn giản)

python
# game_21.py
import random

print("🃏 GAME 21 (BLACKJACK ĐƠN GIẢN)")
print("=" * 35)

while True:
    print(f"\n🎮 GAME MỚI!")
    print("🎯 Mục tiêu: Đạt 21 điểm mà không vượt quá")
    
    # Khởi tạo game
    diem_nguoi = 0
    diem_may = 0
    
    # Chia bài đầu (mỗi người 2 lá)
    for i in range(2):
        la_bai_nguoi = random.randint(1, 11)
        la_bai_may = random.randint(1, 11)
        diem_nguoi += la_bai_nguoi
        diem_may += la_bai_may
        
        if i == 0:
            print(f"🃏 Lá đầu của bạn: {la_bai_nguoi}")
            print(f"🃏 Lá đầu của máy: {la_bai_may}")
        else:
            print(f"🃏 Lá thứ 2 của bạn: {la_bai_nguoi}")
            print(f"🃏 Lá thứ 2 của máy: ??? (úp)")
    
    print(f"\n📊 Điểm của bạn: {diem_nguoi}")
    
    # Lượt người chơi
    while diem_nguoi < 21:
        lua_chon = input("\n🤔 Rút thêm bài? (y/n): ").lower()
        
        if lua_chon not in ['y', 'yes', 'n', 'no']:
            print("❌ Vui lòng nhập 'y' hoặc 'n'")
            continue
        
        if lua_chon in ['n', 'no']:
            break
        
        # Rút bài mới
        la_bai_moi = random.randint(1, 11)
        diem_nguoi += la_bai_moi
        print(f"🃏 Bạn rút được: {la_bai_moi}")
        print(f"📊 Tổng điểm: {diem_nguoi}")
        
        if diem_nguoi > 21:
            print("💥 QUẮC! Bạn vượt quá 21 điểm!")
            break
    
    # Lượt máy (nếu người chơi chưa quắc)
    if diem_nguoi <= 21:
        print(f"\n🤖 Lượt máy (điểm hiện tại: {diem_may}):")
        
        while diem_may < 17:  # Máy rút bài đến khi >= 17
            la_bai_may = random.randint(1, 11)
            diem_may += la_bai_may
            print(f"🃏 Máy rút: {la_bai_may} (tổng: {diem_may})")
            
            if diem_may > 21:
                print("💥 Máy bị QUẮC!")
                break
    
    # Xác định kết quả
    print(f"\n🏁 KẾT QUẢ:")
    print(f"👤 Bạn: {diem_nguoi} điểm")
    print(f"🤖 Máy: {diem_may} điểm")
    
    if diem_nguoi > 21:
        print("❌ Bạn thua (quắc)!")
    elif diem_may > 21:
        print("✅ Bạn thắng (máy quắc)!")
    elif diem_nguoi > diem_may:
        print("✅ Bạn thắng!")
    elif diem_nguoi < diem_may:
        print("❌ Bạn thua!")
    else:
        print("🤝 Hòa!")
    
    # Hỏi chơi lại
    while True:
        choi_lai = input("\n🔄 Chơi lại? (y/n): ").lower()
        if choi_lai in ['y', 'yes']:
            break
        elif choi_lai in ['n', 'no']:
            print("👋 Cảm ơn bạn đã chơi!")
            exit()
        else:
            print("❌ Vui lòng nhập 'y' hoặc 'n'")

Bài 5: Quiz kiến thức với điểm số

python
# quiz_kien_thuc.py
import random

print("🧠 QUIZ KIẾN THỨC")
print("=" * 20)

# Ngân hàng câu hỏi
cau_hoi = [
    {"hoi": "Thủ đô của Việt Nam?", "dap_an": "hà nội", "goi_y": "Bắt đầu bằng chữ H"},
    {"hoi": "2 + 2 = ?", "dap_an": "4", "goi_y": "Phép cộng đơn giản"},
    {"hoi": "Ngôn ngữ lập trình chúng ta học?", "dap_an": "python", "goi_y": "Con rắn bằng tiếng Anh"},
    {"hoi": "Hành tinh thứ 3 từ Mặt Trời?", "dap_an": "trái đất", "goi_y": "Nhà của chúng ta"},
    {"hoi": "1000 gram = ? kg", "dap_an": "1", "goi_y": "Đơn vị khối lượng"},
]

diem = 0
so_cau_da_hoi = 0
cau_sai = []

print("🎯 Trả lời câu hỏi để ghi điểm!")
print("💡 Gõ 'goi_y' để xem gợi ý (-1 điểm)")
print("💡 Gõ 'bo_qua' để bỏ qua câu hỏi")
print("💡 Gõ 'quit' để kết thúc")

while True:
    if so_cau_da_hoi >= len(cau_hoi):
        print("\n🎉 Bạn đã trả lời hết câu hỏi!")
        break
    
    # Chọn câu hỏi ngẫu nhiên
    cau = random.choice([c for c in cau_hoi if c not in cau_sai])
    if not cau:
        break
    
    so_cau_da_hoi += 1
    da_xem_goi_y = False
    
    print(f"\n❓ Câu {so_cau_da_hoi}: {cau['hoi']}")
    
    while True:
        tra_loi = input("Đáp án: ").strip().lower()
        
        if tra_loi == "quit":
            print("👋 Kết thúc quiz!")
            break
        
        if tra_loi == "goi_y":
            if not da_xem_goi_y:
                print(f"💡 Gợi ý: {cau['goi_y']}")
                da_xem_goi_y = True
                diem = max(0, diem - 1)  # Trừ 1 điểm, không âm
                print(f"📉 -1 điểm gợi ý. Điểm hiện tại: {diem}")
            else:
                print("💡 Bạn đã xem gợi ý rồi!")
            continue
        
        if tra_loi == "bo_qua":
            print(f"⏭️ Bỏ qua. Đáp án đúng: {cau['dap_an']}")
            cau_sai.append(cau)
            break
        
        # Kiểm tra đáp án
        if tra_loi == cau["dap_an"]:
            diem_cong = 3 if not da_xem_goi_y else 2
            diem += diem_cong
            print(f"✅ Đúng! +{diem_cong} điểm")
            print(f"📈 Điểm hiện tại: {diem}")
            break
        else:
            print("❌ Sai rồi! Thử lại.")
            print("💡 Gõ 'goi_y' để xem gợi ý hoặc 'bo_qua' để bỏ qua")
    
    if tra_loi == "quit":
        break
    
    # Hiển thị tiến độ
    con_lai = len(cau_hoi) - so_cau_da_hoi
    if con_lai > 0:
        print(f"📊 Còn {con_lai} câu")

# Kết quả cuối
print(f"\n🏁 KẾT QUẢ CUỐI CÙNG:")
print(f"🎯 Điểm số: {diem}")
print(f"📊 Đã trả lời: {so_cau_da_hoi}/{len(cau_hoi)} câu")

if diem >= 10:
    print("🏆 Xuất sắc!")
elif diem >= 7:
    print("🥈 Khá tốt!")
elif diem >= 5:
    print("🥉 Tạm được!")
else:
    print("📚 Cần học thêm!")

📊 Bài tập xử lý dữ liệu

Bài 6: Quản lý danh bạ điện thoại

python
# quan_ly_danh_ba.py
print("📞 QUẢN LÝ DANH BẠ ĐIỆN THOẠI")
print("=" * 35)

danh_ba = {}  # Dictionary lưu {tên: số_điện_thoại}

while True:
    print(f"\n📱 DANH BẠ ({len(danh_ba)} liên hệ)")
    print("1. Thêm liên hệ")
    print("2. Tìm kiếm")
    print("3. Hiển thị tất cả")
    print("4. Sửa số điện thoại")
    print("5. Xóa liên hệ")
    print("0. Thoát")
    
    lua_chon = input("Chọn (0-5): ").strip()
    
    if lua_chon == "0":
        print("👋 Tạm biệt!")
        break
    
    elif lua_chon == "1":
        # Thêm liên hệ
        ten = input("Tên liên hệ: ").strip().title()
        if not ten:
            print("❌ Tên không được để trống!")
            continue
        
        if ten in danh_ba:
            print(f"⚠️ {ten} đã có trong danh bạ: {danh_ba[ten]}")
            ghi_de = input("Ghi đè? (y/n): ").lower()
            if ghi_de not in ['y', 'yes']:
                continue
        
        while True:
            sdt = input("Số điện thoại: ").strip()
            if sdt.isdigit() and len(sdt) >= 10:
                danh_ba[ten] = sdt
                print(f"✅ Đã thêm {ten}: {sdt}")
                break
            else:
                print("❌ SĐT phải là số và ít nhất 10 chữ số!")
    
    elif lua_chon == "2":
        # Tìm kiếm
        tim_kiem = input("Tìm kiếm (tên hoặc số): ").strip().lower()
        if not tim_kiem:
            continue
        
        ket_qua = []
        for ten, sdt in danh_ba.items():
            if tim_kiem in ten.lower() or tim_kiem in sdt:
                ket_qua.append((ten, sdt))
        
        if ket_qua:
            print(f"\n🔍 Tìm thấy {len(ket_qua)} kết quả:")
            for ten, sdt in ket_qua:
                print(f"📞 {ten}: {sdt}")
        else:
            print("❌ Không tìm thấy!")
    
    elif lua_chon == "3":
        # Hiển thị tất cả
        if danh_ba:
            print(f"\n📋 DANH BẠ ({len(danh_ba)} liên hệ):")
            print("-" * 30)
            for ten in sorted(danh_ba.keys()):
                print(f"📞 {ten}: {danh_ba[ten]}")
        else:
            print("📭 Danh bạ trống!")
    
    elif lua_chon == "4":
        # Sửa số điện thoại
        if not danh_ba:
            print("📭 Danh bạ trống!")
            continue
        
        ten = input("Tên cần sửa: ").strip().title()
        if ten in danh_ba:
            print(f"📞 SĐT hiện tại: {danh_ba[ten]}")
            sdt_moi = input("SĐT mới: ").strip()
            if sdt_moi.isdigit() and len(sdt_moi) >= 10:
                danh_ba[ten] = sdt_moi
                print(f"✅ Đã cập nhật {ten}: {sdt_moi}")
            else:
                print("❌ SĐT không hợp lệ!")
        else:
            print(f"❌ Không tìm thấy {ten}")
    
    elif lua_chon == "5":
        # Xóa liên hệ
        if not danh_ba:
            print("📭 Danh bạ trống!")
            continue
        
        ten = input("Tên cần xóa: ").strip().title()
        if ten in danh_ba:
            print(f"📞 Sẽ xóa: {ten} - {danh_ba[ten]}")
            xac_nhan = input("Xác nhận xóa? (y/n): ").lower()
            if xac_nhan in ['y', 'yes']:
                del danh_ba[ten]
                print(f"🗑️ Đã xóa {ten}")
        else:
            print(f"❌ Không tìm thấy {ten}")
    
    else:
        print("❌ Lựa chọn không hợp lệ!")

🎯 Bài tập tổng hợp

Bài 7: Hệ thống quản lý sinh viên mini

python
# quan_ly_sinh_vien.py
print("🎓 HỆ THỐNG QUẢN LÝ SINH VIÊN")
print("=" * 35)

sinh_vien = []  # List chứa dict thông tin sinh viên

def them_sinh_vien():
    print("\n➕ THÊM SINH VIÊN MỚI")
    
    # Nhập MSSV
    while True:
        mssv = input("MSSV: ").strip()
        if not mssv:
            print("❌ MSSV không được để trống!")
            continue
        
        # Kiểm tra trùng MSSV
        trung = False
        for sv in sinh_vien:
            if sv["mssv"] == mssv:
                print(f"❌ MSSV {mssv} đã tồn tại!")
                trung = True
                break
        
        if not trung:
            break
    
    # Nhập tên
    while True:
        ten = input("Họ tên: ").strip().title()
        if ten:
            break
        print("❌ Tên không được để trống!")
    
    # Nhập điểm
    while True:
        try:
            diem = float(input("Điểm TB (0-10): "))
            if 0 <= diem <= 10:
                break
            print("❌ Điểm phải từ 0-10!")
        except ValueError:
            print("❌ Vui lòng nhập số!")
    
    # Thêm vào danh sách
    sv_moi = {"mssv": mssv, "ten": ten, "diem": diem}
    sinh_vien.append(sv_moi)
    print(f"✅ Đã thêm sinh viên: {ten} ({mssv})")

def hien_thi_danh_sach():
    if not sinh_vien:
        print("📭 Danh sách trống!")
        return
    
    print(f"\n📋 DANH SÁCH SINH VIÊN ({len(sinh_vien)} sinh viên):")
    print("-" * 50)
    print(f"{'STT':3} {'MSSV':10} {'Họ tên':20} {'Điểm':6} {'Xếp loại':10}")
    print("-" * 50)
    
    for i, sv in enumerate(sinh_vien, 1):
        # Xếp loại
        if sv["diem"] >= 8.5:
            xep_loai = "Giỏi"
        elif sv["diem"] >= 7.0:
            xep_loai = "Khá"
        elif sv["diem"] >= 5.5:
            xep_loai = "TB"
        else:
            xep_loai = "Yếu"
        
        print(f"{i:3} {sv['mssv']:10} {sv['ten']:20} {sv['diem']:6.1f} {xep_loai:10}")

def tim_sinh_vien():
    if not sinh_vien:
        print("📭 Danh sách trống!")
        return
    
    tim_kiem = input("Nhập MSSV hoặc tên cần tìm: ").strip().lower()
    ket_qua = []
    
    for sv in sinh_vien:
        if tim_kiem in sv["mssv"].lower() or tim_kiem in sv["ten"].lower():
            ket_qua.append(sv)
    
    if ket_qua:
        print(f"\n🔍 Tìm thấy {len(ket_qua)} sinh viên:")
        for sv in ket_qua:
            print(f"📝 {sv['ten']} ({sv['mssv']}) - Điểm: {sv['diem']}")
    else:
        print("❌ Không tìm thấy!")

def thong_ke():
    if not sinh_vien:
        print("📭 Danh sách trống!")
        return
    
    # Tính toán thống kê
    tong_diem = sum(sv["diem"] for sv in sinh_vien)
    diem_tb = tong_diem / len(sinh_vien)
    
    # Phân loại
    gioi = len([sv for sv in sinh_vien if sv["diem"] >= 8.5])
    kha = len([sv for sv in sinh_vien if 7.0 <= sv["diem"] < 8.5])
    tb = len([sv for sv in sinh_vien if 5.5 <= sv["diem"] < 7.0])
    yeu = len([sv for sv in sinh_vien if sv["diem"] < 5.5])
    
    print(f"\n📊 THỐNG KÊ:")
    print(f"Tổng sinh viên: {len(sinh_vien)}")
    print(f"Điểm TB lớp: {diem_tb:.2f}")
    print(f"Giỏi: {gioi}, Khá: {kha}, TB: {tb}, Yếu: {yeu}")

# Menu chính
while True:
    print(f"\n🎓 MENU QUẢN LÝ")
    print("1. Thêm sinh viên")
    print("2. Hiển thị danh sách")
    print("3. Tìm kiếm") 
    print("4. Thống kê")
    print("0. Thoát")
    
    lua_chon = input("Chọn (0-4): ").strip()
    
    if lua_chon == "0":
        print("👋 Tạm biệt!")
        break
    elif lua_chon == "1":
        them_sinh_vien()
    elif lua_chon == "2":
        hien_thi_danh_sach()
    elif lua_chon == "3":
        tim_sinh_vien()
    elif lua_chon == "4":
        thong_ke()
    else:
        print("❌ Lựa chọn không hợp lệ!")

📋 Tóm tắt

Kỹ năng đã luyện tập:

Kỹ năngBài tậpỨng dụng
while + validationQuiz, MenuKiểm tra đầu vào
while + break/continueGame, Tìm kiếmĐiều khiển luồng
while + data processingDanh bạ, Quản lýXử lý dữ liệu
while + algorithmsGCD, FibonacciThuật toán

Patterns quan trọng:

python
# Pattern 1: Menu với validation
while True:
    choice = input("Menu: ")
    if choice == "exit":
        break
    if choice not in valid_choices:
        continue
    process(choice)

# Pattern 2: Input validation
while True:
    try:
        value = int(input("Nhập số: "))
        if value > 0:
            break
        print("Phải > 0!")
    except ValueError:
        print("Phải là số!")

# Pattern 3: Game loop
while True:
    play_game()
    if not play_again():
        break

# Pattern 4: Data processing
while data_available():
    item = get_next_item()
    if not valid(item):
        continue
    process(item)

Lưu ý khi code:

  1. 🔄 Luôn có cách thoát: Đảm bảo while có thể kết thúc
  2. ✅ Validate input: Kiểm tra dữ liệu đầu vào
  3. 📝 Clear feedback: Thông báo rõ ràng cho người dùng
  4. 🚫 Handle errors: Xử lý lỗi gracefully

Chuẩn bị cho chương tiếp theo:

Chương tiếp theo sẽ học về 📚 Cấu trúc dữ liệu list - cách lưu trữ và xử lý nhiều dữ liệu!


💡 Mẹo: Bắt đầu với logic đơn giản, sau đó thêm validation và error handling!

🏋️ Thực hành: Thử tạo biến thể của các bài tập để củng cố kiến thức!

🐍 Khóa học Python căn bản bằng tiếng Việt