Bài 10-12: Thiết kế chương trình từ trên xuống và phương pháp mô đun hóa

Chủ đề Fcs – Bài 10-12: Thiết kế chương trình từ trên xuống và phương pháp mô đun hóa – sbt trang 62 lớp 11 Khoa học máy tính – Cánh Diều, Bumbii.

Chủ đề Fcs – Bài 10-12: Thiết kế chương trình từ trên xuống và phương pháp mô đun hóa

Câu FCS41 (DA1)

Đề bài

Thực hiện bài tập lớn về lập trình Python xử lí “Tam giác” với các yêu cầu sau:

Dữ liệu đầu vào:

Nhập từ tệp văn bản tamgiac.txt chứa số liệu độ dài của các tam giác, mỗi dòng trong tệp văn bản chứa ba số a, b, c là số liệu về một tam giác. Độ dài các cạnh của mỗi tam giác là số nguyên hoặc số thực.

Kết quả đầu ra:

KQ1 – Phân loại tam giác: Kiểm tra ba số a, b, c có phải là độ dài ba cạnh của một tam giác hay không? Nếu ba số a, b, c là độ dài ba cạnh của một tam giác thì phân loại tam giác đó và đếm số lượng từng loại (tam giác đều, tam giác vuông cân, tam giác vuông, tam giác cân, tam giác thường). Kết quả đưa vào tệp phanloaiTG.txt.

KQ2 – Đưa vào tệp cvdtTG.txt:

a) Chu vi, diện tích các hình tam giác hợp lệ.

b) Cho biết hình tam giác nào có chu vi lớn nhất, hình tam giác nào có diện tích lớn nhất.

c) Sắp xếp tăng dần theo diện tích của từng loại tam giác.

Yêu cầu kết quả:

Với mục đích luyện kĩ năng lập trình, mỗi nhóm cần hoàn thành hai sản phẩm chương trình SP#1 và SP#2 với yêu cầu như sau:

– SP#1: Tự viết các hàm (mô đun) chương trình, kế thừa những kết quả lập trình đã có được đến nay.

– SP#2: Sử dụng tối đa các hàm đã có sẵn trong Python để hoàn thành nhiệm vụ.

Câu trả lời

A. Liệt kê các việc lớn

– Nhập vào danh sách các tam giác và lưu trữ độ dài các cạnh của chúng.

– Xây dựng logic kiểm tra tính hợp lệ của ba cạnh tam giác. Nếu ba cạnh hợp lệ, em phân loại tam giác đó để có KQ1. Đồng thời, em lưu trữ các tam giác hợp lệ cùng chỉ số trên danh sách gốc để chuyển sang bước sau.

– Dùng công thức để tính chu vi, diện tích của các hình tam giác hợp lệ tìm thấy để có KQ2a.

– Với mỗi kết quả chu vi, diện tích tính được, em tìm chỉ số của hình tam giác có chu vi, diện tích lớn nhất để có KQ2b.

B. Thiết kế các hàm

1. Đọc dữ liệu từ tệp

Có thể viết hàm nhapTuTep (filename: str) đọc đầu vào từ tệp có tên là filename.

Đầu vào: Tệp văn bản như mô tả ở bài tập.

Đầu ra: Dữ liệu trong chương trình được tổ chức như sau:

– Mảng hai chiều các số liệu độ dài: Mảng n × 3, mỗi hàng chứa ba số b, c là độ dài các cạnh của một tam giác.

– Để dễ xử lí, em sắp xếp ba số a, b, c theo thứ tự tăng dần (a ≤ b ≤ c).

def nhapTuTep(filename):
    with open(filename, mode="r") as fin:
        n = int(fin.readline())
        cactamgiac = []
        for i in range(n):
            sides = list(map(float, fin.readline().split()))
            sides.sort()
            cactamgiac.append(sides)
        return n, cactamgiac
2. Kiểm tra tam giác
a) Tính hợp lệ:

Em có thể tạo hàm kiemtraTamgiac(a: float, b: float, c: float) ➝ bool để kiểm tra tính hợp lệ của tam giác. Cụ thể, vì a ≤ b ≤ c nên tổng hai cạnh a + b của tam giác phải lớn hơn cạnh c, vậy a + b > c

def kiemtraTamgiac (a, b, c) -> bool:
    return a + b > c
b) Phân loại tam giác:

Sau khi kiểm tra tính hợp lệ, em có thể phân loại tam giác bằng cách tạo hàm: phanloaiTamgiac (a: float, b: float, c: float) str.

– Dựa trên tên các loại: “đều”, “vuông cân”, “vuông”, “cân”, “thường”, em thấy cần phân loại dựa trên tính đều của nó trước. Vì vậy:

Trước hết, em kiểm tra tính đều của tam giác: a = b và b = c.

Sau đó, em kiểm tra tính vuông cân của tam giác: a2 + b2 = c2 và a = b.

Ngược lại, nếu a2 + b2 = c2 thì tam giác này có tính vuông.

Ngược lại, nếu a = b hoặc b = c thì tam giác này có tính cân.

Ngược lại, tam giác này là tam giác thường.

Để thuận tiện cho các phần sau, em đánh số 4 loại tam giác từ 0 đến 4.

THUONG = 0; CAN = 1; VUONG = 2; VC = 3; DEU = 4
NAME = ["thường", "cân", "vuông", "vuông cân", "đều"]
def phanloaiTamgiac(tamgiac) -> str:
    a, b, c = tamgiac[0], tamgiac[1], tamgiac[2]
    if kiemtraTamgiac(a, b, c) == False:
        return - 1
    if a == b and b == c:
        return DEU
    elif a ** 2 + b ** 2 == c ** 2 and a == b:
        return VC
    elif a ** 2 + b ** 2 == c ** 2:
        return VUONG
    elif a == b or b == c:
        return CAN
    else:
        return THUONG

– Sau khi dựng xong hai hàm trên, em sẽ dựng hàm kq1(n, cactamgiac). Trong hàm đó, ta thực hiện như yêu cầu đề bài, đồng thời tạo ra một danh sách tam giác hợp lệ hople để lưu chỉ số các tam giác có ba cạnh hợp lệ. Sau khi in ra đáp án KQ1, ta thoát hàm và trả về danh sách hople để lưu cho việc xử lí KQ2.

def kq1(n, cactamgiac):
    hople = []
    cnt = [0] * 5
    for i in range(n):
        tamgiac = cactamgiac[i]
        loai = phanloaiTamgiac(tamgiac)
        if loai != -1:
            cnt[loai] += 1
            hople.append(i)
    with open("phanloaiTG.txt", "w") as fout:
        fout.write("Số tam giác Đều: " + str(cnt[DEU]) + " \n")
        fout.write("Số tam giác Vuông Cân: " +str(cnt[VC]) + " \n")
        fout.write("Số tam giác Vuông: " +str(cnt[VUONG]) + " \n")
        fout.write("Số tam giác Cân: " +str(cnt[CAN]) + " \n")
        fout.write("Số tam giác Cân: " +str(cnt[CAN]) + " \n")
        fout.write("Số tam giác Thường: " +str(cnt[THUONG]) + " \n")
        fout.close()
    return hople
c) Tính chu vi, diện tích tam giác:

Viết hai hàm:

- chuvi(a: float, b: float, c: float) -> float

- dientich(a: float, b: float, c: float) -> float

def chuvi(tamgiac):
    a, b, c = tamgiac[0], tamgiac[1], tamgiac[2]
    return a + b + c

def dientich(tamgiac):
    a, b, c = tamgiac[0], tamgiac[1], tamgiac[2]
    p = (a + b + c) / 2
    return (p * (p - a) * (p - b) * (p - c)) ** 0.5

Tìm hình có chu vi lớn nhất, có diện tích lớn nhất

Viết hàm kg2(n, cactamgiac, hople) để in ra KQ2, với hop le là chỉ số của các tam giác hợp lệ trong mảng đầu vào.

Đầu tiên, với mỗi hình hợp lệ có chỉ số x trong mảng ban đầu, ta tính chu vi, diện tích của hình cactamgiac[x]. Ta lưu vào một mảng hai chiều solieu có ba cột, cột thứ 0 là chỉ số x, cột 1 và 2 lần lượt là chu vi và diện tích của hình tam giác hợp lệ đó. Khi đó, ta có thể trả lời KQ2a ngay lúc này.

Tiếp theo, để tìm hình có chu vi, diện tích lớn nhất, ta có thể sử dụng tìm kiếm tuần tự cho mỗi câu hỏi, hoặc sắp xếp theo thứ tự giảm dần và lấy phần tử đầu tiên. Nếu dùng phương thức sort của list có thể dùng cú pháp solieu. sort(key=lambda tamgiac: tamgiac[k]) , với k = 1 thì sắp xếp theo chu vi, với k = 2 thì sắp xếp theo diện tích. Ngay sau mỗi lượt sắp xếp, ta in ra kết quả để trả lời cho KQ2b.

Tiếp theo, ta tạo ra một danh sách lớn triList gồm 5 danh sách con có chỉ số trong triList từ 0 → 4, tương ứng với 5 loại hình tam giác khác nhau, rồi với mỗi hình tam giác hợp lệ ta đưa chúng vào danh sách có mã thích hợp.

Cuối cùng, với từng danh sách con trong triList, ta sắp xếp các hình này theo thứ tự tăng dần theo diện tích, và in ra toàn bộ mảng triList để trả lời KQ2c.

def kq2(n, cactamgiac, hople):
    triList = [[], [], [], [], []]
    solieu = []
    with open("cvdtTG.txt", "w") as fout:
        for i in hople:
            tamgiac = cactamgiac[i]
            P = chuvi(tamgiac)
            S = dientich(tamgiac)
            loai = phanloaiTamgiac(tamgiac)
            print(i, loai)
            fout.write("Chu vi, diện tích của tam giac thứ {i} là: {P}, {S}\n".format(i=i, P=P, S=S))
                solieu.append([i, P, S])
                triList[loai].append([i, S])
            fout.write("\n")
            solieu.sort(key=lambda tamgiac:tamgiac[2], reverse=True)
            bestS = solieu[0]
            fout.write("Hình có diện tích lớn nhất là hình thứ {i} với độ dài {P}\n".format(i=bestS[0], P=bestS[2]))
            fout.write("\n")

            for loai in range(5):
                fout.write("Danh sách các hình tam giác {type} theo thứ tự diện tích tăng dần: \n ".format(type=NAME[loai]))
                triList[loai].sort(key=lambda tamgiac:tamgiac[1])
                for tamgiac in triList[loai]:
                    fout.write(str(tamgiac[0] + " "))
                fout.write("\n")
Tóm lại, đoạn code có dạng như sau:
def nhapTuTep(filename):
    with open(filename, mode="r") as fin:
        n = int(fin.readline())
        cactamgiac = []
        for i in range(n):
            sides = list(map(float, fin.readline().split()))
            sides.sort()
            cactamgiac.append(sides)
        return n, cactamgiac

def kiemtraTamgiac (a, b, c) -> bool:
    return a + b > c

THUONG = 0; CAN = 1; VUONG = 2; VC = 3; DEU = 4
NAME = ["thường", "cân", "vuông", "vuông cân", "đều"]
def phanloaiTamgiac(tamgiac) -> str:
    a, b, c = tamgiac[0], tamgiac[1], tamgiac[2]
    if kiemtraTamgiac(a, b, c) == False:
        return - 1
    if a == b and b == c:
        return DEU
    elif a ** 2 + b ** 2 == c ** 2 and a == b:
        return VC
    elif a ** 2 + b ** 2 == c ** 2:
        return VUONG
    elif a == b or b == c:
        return CAN
    else:
        return THUONG

def kq1(n, cactamgiac):
    hople = []
    cnt = [0] * 5
    for i in range(n):
        tamgiac = cactamgiac[i]
        loai = phanloaiTamgiac(tamgiac)
        if loai != -1:
            cnt[loai] += 1
            hople.append(i)
    with open("phanloaiTG.txt", "w") as fout:
        fout.write("Số tam giác Đều: " + str(cnt[DEU]) + " \n")
        fout.write("Số tam giác Vuông Cân: " +str(cnt[VC]) + " \n")
        fout.write("Số tam giác Vuông: " +str(cnt[VUONG]) + " \n")
        fout.write("Số tam giác Cân: " +str(cnt[CAN]) + " \n")
        fout.write("Số tam giác Cân: " +str(cnt[CAN]) + " \n")
        fout.write("Số tam giác Thường: " +str(cnt[THUONG]) + " \n")
        fout.close()
    return hople

def chuvi(tamgiac):
    a, b, c = tamgiac[0], tamgiac[1], tamgiac[2]
    return a + b + c

def dientich(tamgiac):
    a, b, c = tamgiac[0], tamgiac[1], tamgiac[2]
    p = (a + b + c) / 2
    return (p * (p - a) * (p - b) * (p - c)) ** 0.5

def kq2(n, cactamgiac, hople):
    triList = [[], [], [], [], []]
    solieu = []
    with open("cvdtTG.txt", "w") as fout:
        for i in hople:
            tamgiac = cactamgiac[i]
            P = chuvi(tamgiac)
            S = dientich(tamgiac)
            loai = phanloaiTamgiac(tamgiac)
            print(i, loai)
            fout.write("Chu vi, diện tích của tam giac thứ {i} là: {P}, {S}\n".format(i=i, P=P, S=S))
                solieu.append([i, P, S])
                triList[loai].append([i, S])
            fout.write("\n")
            solieu.sort(key=lambda tamgiac:tamgiac[2], reverse=True)
            bestS = solieu[0]
            fout.write("Hình có diện tích lớn nhất là hình thứ {i} với độ dài {P}\n".format(i=bestS[0], P=bestS[2]))
            fout.write("\n")

            for loai in range(5):
                fout.write("Danh sách các hình tam giác {type} theo thứ tự diện tích tăng dần: \n ".format(type=NAME[loai]))
                triList[loai].sort(key=lambda tamgiac:tamgiac[1])
                for tamgiac in triList[loai]:
                    fout.write(str(tamgiac[0] + " "))
                fout.write("\n")

n, cactamgiac = nhapTuTep("tamgiac.txt")
hople = kq1(n, cactamgiac)
kq2(n, cactamgiac, hople)

Xem các bài giải khác: Giải Bài Tập SBT Lớp 11 Khoa Học Máy Tính Cánh Diều

Thông tin liên hệ & mạng xã hội:
Website: https://bumbii.com/
Facebook: https://www.facebook.com/bumbiiapp
Pinterest: https://www.pinterest.com/bumbiitech

0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest

0 Bình luận
Phản hồi nội tuyến
Xem tất cả bình luận
0
Cùng chia sẻ bình luận của bạn nào!x