THỰC HÀNH TỔNG HỢP 2 - CẤU TRÚC ĐIỀU KHIỂN¶
I. Mục tiêu buổi học¶
Mục tiêu chính¶
Buổi học này nhằm củng cố và thực hành kiến thức từ Buổi 6-10, tập trung vào:
- List và Tuple - Cấu trúc dữ liệu tập hợp
- Cấu trúc rẽ nhánh - if, elif, else
- Vòng lặp - for và while
- Kết hợp điều kiện và vòng lặp để giải bài toán phức tạp
Kỹ năng đạt được¶
Sau buổi học, học viên sẽ có khả năng:
- Thành thạo cấu trúc điều khiển trong Python
- Xử lý dữ liệu với List và Tuple hiệu quả
- Áp dụng thuật toán cơ bản vào bài toán thực tế
- Tư duy logic để giải quyết bài toán phức tạp
II. Cấu trúc buổi học (90 phút)¶
Hoạt động | Thời gian | Nội dung |
---|---|---|
Ôn tập nhanh | 15 phút | Review kiến thức cốt lõi |
Thực hành thuật toán cơ bản | 40 phút | 4 bài thuật toán quan trọng |
Thực hành dự án nhỏ | 25 phút | 1 dự án tích hợp kiến thức |
Thảo luận và tối ưu | 10 phút | Code review và best practices |
III. Ôn tập kiến thức (15 phút)¶
Checklist kiến thức cần nhớ¶
✅ List và Tuple:
# List - có thể thay đổi
numbers = [1, 2, 3, 4, 5]
numbers.append(6) # Thêm phần tử
numbers.remove(3) # Xóa phần tử
numbers[0] = 10 # Sửa phần tử
# Tuple - không thể thay đổi
point = (10, 20)
x, y = point # Unpacking
✅ Cấu trúc rẽ nhánh:
if condition1:
# Code block 1
elif condition2:
# Code block 2
else:
# Code block 3
✅ Vòng lặp:
# For loop với range
for i in range(1, 6): # 1, 2, 3, 4, 5
print(i)
# For loop với list
for item in my_list:
print(item)
# While loop
count = 0
while count < 5:
print(count)
count += 1
IV. Thực hành thuật toán cơ bản (40 phút)¶
Bài 1: Tìm số nguyên tố (10 phút)¶
Đề bài: Viết hàm kiểm tra số nguyên tố và tìm tất cả số nguyên tố từ 1 đến n.
Phân tích đề
Khái niệm số nguyên tố: - Số nguyên tố là số tự nhiên lớn hơn 1 chỉ chia hết cho 1 và chính nó - Ví dụ: 2, 3, 5, 7, 11, 13, 17, 19, 23...
Thuật toán kiểm tra: 1. Nếu số < 2 → không phải số nguyên tố 2. Kiểm tra chia hết từ 2 đến √n 3. Nếu không chia hết cho số nào → là số nguyên tố
Input/Output mẫu:
Input | Quá trình kiểm tra | Output |
---|---|---|
n = 10 | Kiểm tra 2,3,4,5,6,7,8,9,10 | [2, 3, 5, 7] |
n = 20 | Kiểm tra 2→20 | [2, 3, 5, 7, 11, 13, 17, 19] |
Gợi ý code
def is_prime(num):
"""Kiểm tra số nguyên tố"""
if num < 2:
return False
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
return False
return True
def find_primes(n):
"""Tìm tất cả số nguyên tố từ 1 đến n"""
primes = []
for num in range(2, n + 1):
if is_prime(num):
primes.append(num)
return primes
# Test
n = int(input("Nhập n: "))
prime_list = find_primes(n)
print(f"Các số nguyên tố từ 1 đến {n}: {prime_list}")
print(f"Tổng cộng có {len(prime_list)} số nguyên tố")
Bài 2: Sắp xếp danh sách (10 phút)¶
Đề bài: Implement thuật toán sắp xếp nổi bọt (Bubble Sort).
Phân tích đề
Thuật toán Bubble Sort: 1. So sánh 2 phần tử liền kề 2. Nếu phần tử trước > phần tử sau → hoán đổi 3. Lặp lại cho đến khi không còn hoán đổi nào
Ví dụ với [64, 34, 25]: - Lần 1: [34, 25, 64] (64 "nổi" lên cuối) - Lần 2: [25, 34, 64] (34 "nổi" lên vị trí 2) - Kết quả: [25, 34, 64]
Input/Output mẫu:
Input | Các bước sắp xếp | Output |
---|---|---|
[64, 34, 25, 12] | Bước 1: [34, 25, 12, 64] | [12, 25, 34, 64] |
Bước 2: [25, 12, 34, 64] | ||
Bước 3: [12, 25, 34, 64] |
Gợi ý code
def bubble_sort(arr):
"""Sắp xếp mảng bằng thuật toán nổi bọt"""
n = len(arr)
for i in range(n):
# Flag để tối ưu hóa
swapped = False
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
# Hoán đổi
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
# Nếu không có hoán đổi nào, mảng đã sắp xếp
if not swapped:
break
return arr
# Test
numbers = [64, 34, 25, 12, 22, 11, 90]
print("Mảng gốc:", numbers)
sorted_numbers = bubble_sort(numbers.copy())
print("Mảng đã sắp xếp:", sorted_numbers)
Bài 3: Tìm kiếm trong danh sách (10 phút)¶
Đề bài: Tìm kiếm tuyến tính và tìm kiếm nhị phân.
Phân tích đề
So sánh 2 thuật toán:
Thuật toán | Điều kiện | Độ phức tạp | Ưu điểm |
---|---|---|---|
Linear Search | Mảng bất kỳ | O(n) | Đơn giản, không cần sắp xếp |
Binary Search | Mảng đã sắp xếp | O(log n) | Nhanh với mảng lớn |
Binary Search hoạt động: 1. Tìm phần tử giữa mảng 2. So sánh với target 3. Loại bỏ một nửa mảng 4. Lặp lại cho đến khi tìm thấy
Ví dụ tìm 7 trong [1,3,5,7,9,11,13,15]: - Bước 1: mid=7 (index 3) → target=7 → tìm thấy!
Gợi ý code
def linear_search(arr, target):
"""Tìm kiếm tuyến tính"""
for i in range(len(arr)):
if arr[i] == target:
return i
return -1
def binary_search(arr, target):
"""Tìm kiếm nhị phân (mảng đã sắp xếp)"""
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# Test
numbers = [1, 3, 5, 7, 9, 11, 13, 15]
target = 7
# Tìm kiếm tuyến tính
linear_result = linear_search(numbers, target)
print(f"Tìm kiếm tuyến tính: Vị trí của {target} là {linear_result}")
# Tìm kiếm nhị phân
binary_result = binary_search(numbers, target)
print(f"Tìm kiếm nhị phân: Vị trí của {target} là {binary_result}")
Bài 4: Phân tích dữ liệu (10 phút)¶
Đề bài: Tính toán thống kê cơ bản cho một danh sách số.
Phân tích đề
Các chỉ số cần tính:
Chỉ số | Công thức | Ý nghĩa |
---|---|---|
Tổng | sum(numbers) | Tổng tất cả phần tử |
Trung bình | tổng / số lượng | Giá trị trung bình |
Median | Giá trị giữa (sau sắp xếp) | Giá trị trung vị |
Min/Max | Nhỏ nhất / Lớn nhất | Khoảng giá trị |
Tính Median: - Nếu n lẻ: median = arr[n//2] - Nếu n chẵn: median = (arr[n//2-1] + arr[n//2])/2
Input/Output mẫu:
Input | Tính toán | Output |
---|---|---|
[12,7,3,15,8] | Tổng: 45, TB: 9.0 | Trung bình: 9.0 |
Sắp xếp: [3,7,8,12,15] | Median: 8 | |
Chẵn: 1, Lẻ: 4 | Số chẵn: 1 |
Gợi ý code
def analyze_data(numbers):
"""Phân tích thống kê cơ bản"""
if not numbers:
return None
# Tính các giá trị cơ bản
total = sum(numbers)
count = len(numbers)
average = total / count
# Tìm min, max
minimum = min(numbers)
maximum = max(numbers)
# Tìm median
sorted_nums = sorted(numbers)
n = len(sorted_nums)
if n % 2 == 0:
median = (sorted_nums[n//2 - 1] + sorted_nums[n//2]) / 2
else:
median = sorted_nums[n//2]
# Đếm số chẵn, lẻ
even_count = sum(1 for x in numbers if x % 2 == 0)
odd_count = count - even_count
return {
'count': count,
'sum': total,
'average': round(average, 2),
'min': minimum,
'max': maximum,
'median': median,
'even_count': even_count,
'odd_count': odd_count
}
# Test
data = [12, 7, 3, 15, 8, 9, 11, 6, 14, 10]
stats = analyze_data(data)
print("PHÂN TÍCH DỮ LIỆU")
print("="*30)
print(f"Dữ liệu: {data}")
print(f"Số lượng: {stats['count']}")
print(f"Tổng: {stats['sum']}")
print(f"Trung bình: {stats['average']}")
print(f"Min: {stats['min']}")
print(f"Max: {stats['max']}")
print(f"Median: {stats['median']}")
print(f"Số chẵn: {stats['even_count']}")
print(f"Số lẻ: {stats['odd_count']}")
V. Dự án nhỏ: Quản lý điểm học sinh (25 phút)¶
Đề bài: Tạo chương trình quản lý điểm học sinh đơn giản.
Yêu cầu chức năng¶
- Nhập danh sách học sinh và điểm
- Hiển thị danh sách điểm
- Tính thống kê lớp học
- Tìm kiếm học sinh theo tên
- Sắp xếp theo điểm
Code mẫu¶
class StudentManager:
def __init__(self):
self.students = [] # List of tuples (name, score)
def add_student(self, name, score):
"""Thêm học sinh"""
self.students.append((name, score))
def display_students(self):
"""Hiển thị danh sách học sinh"""
if not self.students:
print("Chưa có học sinh nào!")
return
print("\nDANH SÁCH HỌC SINH")
print("="*40)
print(f"{'STT':<5}{'Tên':<20}{'Điểm':<10}")
print("-"*40)
for i, (name, score) in enumerate(self.students, 1):
print(f"{i:<5}{name:<20}{score:<10}")
def calculate_stats(self):
"""Tính thống kê lớp"""
if not self.students:
return None
scores = [score for name, score in self.students]
return analyze_data(scores)
def find_student(self, search_name):
"""Tìm học sinh theo tên"""
results = []
for name, score in self.students:
if search_name.lower() in name.lower():
results.append((name, score))
return results
def sort_by_score(self, ascending=True):
"""Sắp xếp theo điểm"""
self.students.sort(key=lambda x: x[1], reverse=not ascending)
def main():
manager = StudentManager()
while True:
print("\n" + "="*50)
print("QUẢN LÝ ĐIỂM HỌC SINH")
print("="*50)
print("1. Thêm học sinh")
print("2. Hiển thị danh sách")
print("3. Thống kê lớp")
print("4. Tìm kiếm học sinh")
print("5. Sắp xếp theo điểm")
print("0. Thoát")
choice = input("\nChọn chức năng (0-5): ")
if choice == '1':
name = input("Nhập tên học sinh: ").strip()
try:
score = float(input("Nhập điểm: "))
if 0 <= score <= 10:
manager.add_student(name, score)
print("✅ Đã thêm học sinh!")
else:
print("❌ Điểm phải từ 0-10!")
except ValueError:
print("❌ Điểm phải là số!")
elif choice == '2':
manager.display_students()
elif choice == '3':
stats = manager.calculate_stats()
if stats:
print("\nTHỐNG KÊ LỚP HỌC")
print("="*30)
print(f"Số học sinh: {stats['count']}")
print(f"Điểm trung bình: {stats['average']}")
print(f"Điểm cao nhất: {stats['max']}")
print(f"Điểm thấp nhất: {stats['min']}")
else:
print("Chưa có dữ liệu!")
elif choice == '4':
search_name = input("Nhập tên cần tìm: ")
results = manager.find_student(search_name)
if results:
print(f"\nTìm thấy {len(results)} kết quả:")
for name, score in results:
print(f"- {name}: {score} điểm")
else:
print("Không tìm thấy!")
elif choice == '5':
order = input("Sắp xếp tăng dần (t) hay giảm dần (g)? ").lower()
ascending = order == 't'
manager.sort_by_score(ascending)
print("✅ Đã sắp xếp!")
manager.display_students()
elif choice == '0':
print("Tạm biệt!")
break
else:
print("Lựa chọn không hợp lệ!")
if __name__ == "__main__":
main()
VI. Code Review và Best Practices (10 phút)¶
Các pattern quan trọng đã học¶
1. Xử lý danh sách:
# Tạo list từ input
numbers = [int(x) for x in input("Nhập các số: ").split()]
# Lọc dữ liệu
even_numbers = [x for x in numbers if x % 2 == 0]
# Tìm max/min với điều kiện
max_even = max([x for x in numbers if x % 2 == 0], default=0)
2. Vòng lặp hiệu quả:
# Enumerate để có index
for i, value in enumerate(my_list):
print(f"Vị trí {i}: {value}")
# Zip để ghép 2 list
names = ["An", "Bình", "Cường"]
scores = [8, 9, 7]
for name, score in zip(names, scores):
print(f"{name}: {score}")
3. Error handling:
try:
number = int(input("Nhập số: "))
result = 10 / number
except ValueError:
print("Vui lòng nhập số!")
except ZeroDivisionError:
print("Không thể chia cho 0!")
VII. Bài tập về nhà¶
Bài 1: Trò chơi đoán số nâng cao¶
Yêu cầu:
- Máy tính random số từ 1-100
- Người chơi có tối đa 7 lần đoán
- Hiển thị lịch sử các lần đoán
- Tính điểm dựa trên số lần đoán
- Lưu high score
Bài 2: Phân tích văn bản¶
Yêu cầu:
- Đọc một đoạn văn từ file hoặc input
- Đếm frequency của từng từ
- Tìm từ xuất hiện nhiều nhất
- Tìm các từ dài nhất/ngắn nhất
- Export kết quả ra file
Bài 3: Máy tính ma trận¶
Yêu cầu:
- Nhập 2 ma trận 2D (dùng list of lists)
- Thực hiện phép cộng ma trận
- Thực hiện phép nhân ma trận
- Tính ma trận chuyển vị
- Hiển thị kết quả đẹp
VIII. Chuẩn bị cho buổi sau¶
Buổi tiếp theo sẽ học về Set (Tập hợp) - cấu trúc dữ liệu đặc biệt không chứa phần tử trùng lặp. Hãy ôn lại:
- Khái niệm tập hợp trong toán học
- Các phép toán tập hợp: hợp, giao, hiệu
- List và cách loại bỏ phần tử trùng lặp
💡 Tip học tập: Thuật toán là linh hồn của lập trình. Hãy thường xuyên luyện tập với các bài toán logic để nâng cao tư duy!