Bài tập Mimgo Lập trình Python - Phần 5
Làm việc với tệp, xử lý lỗi
Danh sách bài tập
Note: Đề bài được tạo bằng pipeline scrape từ web trường (Moodle PHP) về, và reformat từng bài bằng Gemini 2.0 Flash (sửa lại markdown, nếu có ảnh, dịch ra latex hoặc sử dụng ASCII để minh họa). Để AI tự code rồi tự check trên Mimgo thì chắc cũng được nhưng mà thôi 🥴.
5.1 Tìm kiếm trong tệp
Viết chương trình tìm kiếm từ khóa trong các tệp văn bản. Từ khóa x là một chuỗi, thực hiện tìm kiếm x trong các tệp trong thư mục , kết quả trả về là một Danh sách các Bộ, mỗi phần tử trong danh sách là một bộ gồm (tên tệp, dòng văn bản đầu tiên chứa từ khóa x trong tệp), các phần tử trong danh sách được sắp xếp theo tên tệp. Hoàn thiện phương thức searchInFiles(x, path)
. Trong đó, x là từ khóa, path là đường dẫn tới thư mục chứa các file text.
- Để liệt kê danh sách các tệp và thư mục trong một thư mục có thể dùng phương thức listdir trong module os Ví dụ:
import os
os.listdir("đường dẫn tới thư mục")
Gợi ý:
os.listdir(path)
sẽ trả lại danh sách các file/thư mục con bên trong path.- Với mỗi file bên trong path, đọc từng dòng, kiểm tra xem x có trong dòng đó hay không, nếu có thì đưa kết quả vào danh sách chứa kết quả và làm việc với file tiếp theo.
- Thực hiện cho đến khi hết các file.
import os
def searchInFiles(x, path):
result = []
for filename in sorted(os.listdir(path)):
file_path = os.path.join(path, filename)
if os.path.isfile(file_path):
with open(file_path, encoding='utf-8') as f:
for line in f:
if x in line:
result.append((file_path, line))
break
return result
5.2 Di chuyển số 0
Hoàn thiện phương thức zeroMove(fileName)
, phương thức này thực hiện việc đọc các số nguyên từ file fileName, các số nguyên được viết trên 1 dòng, mỗi số cách nhau bởi 1 dấu cách. Lưu các số này vào trong một danh sách theo đúng thứ tự trong fileName.
Thực hiện việc di chuyển các số 0 về phía bên phải của danh sách trong khi vẫn giữ nguyên thứ tự của các số khác. Hàm zeroMove trả lại danh sách sau khi thực hiện việc di chuyển số 0.
Ví dụ:
- Cho file data.txt có nội dung như sau:
0 1 0 3 12
. - Kết quả trả về là
[1, 3, 12, 0, 0]
.
def zeroMove(fileName):
with open(fileName) as f:
nums = list(map(int, f.read().split()))
non_zero = [n for n in nums if n != 0]
return non_zero + [0] * (len(nums) - len(non_zero))
5.3 Số may mắn
Cho tệp văn bản chứa các chữ và các số trong đó có duy nhất 1 số may mắn. Số may mắn là số nguyên tố có tổng các chữ số chia hết cho 5.
Ví dụ:
- 5, 37, 73, … là các số may mắn.
- Tìm và in ra số may mắn trong file văn bản.
Các xâu trong văn bản cách nhau bởi 1 dấu cách, văn bản có thể có nhiều dòng và chứa ký tự Unicode. Nhiệm vụ của sinh viên là hoàn thiện hàm findLuckyNumber(filename)
. Hàm này nhận vào 1 đối là filename là tên file văn bản chứa dữ liệu, hàm trả về số may mắn có trong file filename.
Gợi ý:
- Mở file filename, đọc vào từng dòng của văn bản
- Với mỗi dòng, tách ra thành từng xâu (split), dùng phương thức của xâu để kiểm tra xem nó có phải là số hay không (xem lại phần xâu ký tự nếu cần).
- Nếu xâu đó là số, chuyển xâu thành số nguyên rồi kiểm tra xem số đó có phải số may mắn theo định nghĩa ở trên hay không, nếu đó là số may mắn trả lại kết quả cho hàm là số đó.
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def findLuckyNumber(filename):
with open(filename, encoding='utf-8') as f:
for line in f:
for word in line.split():
if word.isdigit():
num = int(word)
if is_prime(num) and sum(int(d) for d in word) % 5 == 0:
return num
return 0
5.4 Cặp đôi hoàn hảo
Cho file văn bản chứa các xâu, trong đó có chứa duy nhất 1 cặp đôi hoàn hảo.
- Một cặp đôi (a, b) được gọi là hoàn hảo nếu a khác b và là đảo ngược của b hay nói cách khác ab tạo thành 1 xâu đối xứng (a, b không phải xâu đối xứng)
- Ví dụ 123 và 321, hay dfg và gfd là các cặp đôi hoàn hảo.
- 12321 và 12321 không phải là cặp đôi hoàn hảo do chúng giống nhau.
- Các xâu trong văn bản được phân cách bởi dấu cách, file có nhiều dòng và chứa ký tự Unicode.
Sinh viên hoàn thiện phương thức findCouple(filename)
, phương thức này nhận vào đối số là tên file, kết quả trả về là 1 bộ (tuple) 2 phần tử tương ứng với cặp đôi hoàn hảo sắp theo thứ tự tăng dần. Ví dụ như minh họa trên thì kết quả trả về là (123, 321) và (dfg, gfd).
Gợi ý:
- Sinh viên đọc vào cả file văn bản hoặc từng dòng.
- Tách văn bản ra thành từng xâu bằng phương thức split() của xâu ký tự, lưu các xâu này vào trong 1 danh sách.
- Với mỗi phần tử x trong danh sách, tìm xem có xâu đảo ngược của x cũng có trong danh sách hay không.
- Nếu có thì x và đảo ngược của x chính là cặp đôi cần tìm.
def findCouple(filename):
with open(filename, encoding='utf-8') as f:
words = set()
for line in f:
words.update(line.split())
for word in words:
rev = word[::-1]
if rev in words and word != rev:
return tuple(sorted((word, rev)))
return 'None','None'