Bài tập lần 4
Bài tập lần 4 gồm 9 bài tập, bao gồm
- 5 bài tập cơ bản: 1, 2, 3, 4, 5 (làm tối thiểu 3 bài).
- 4 bài tập nâng cao: 6, 7, 8, 9.
Danh sách bài tập
Bài tập 1. (sort a list)
Một list được gọi là ổn nếu nó chỉ chứa các số thực và có ít nhất một phần tử. Cho một list gồm các list con ổn. Viết một chương trình sắp xếp list này theo thứ tự tăng dẫn của tổng các số trong mỗi list con. Ví dụ:
A = [[1,2], [3,0,4], [2], [4,5]] # input
B = [[2], [1,2], [3,0,4], [4,5]] # output
Yêu cầu bổ sung: đặt ra thêm tiêu chí để so sánh hai list ổn bất kỳ và áp dụng tiêu chí này để sắp xếp list đầu vào.
Bài tập 2. (class Point)
Xây dựng class Point
để biểu diễn các điểm trong mặt phẳng tọa độ $Oxy$.
-
Thiết kế phần khởi tạo của class
Point
(chọn tên thuộc tính phù hợp) và khởi tạo một số instance của class này. -
Viết hàm
distance()
thuộc classPoint
để tính khoảng cách Euclid (hay còn gọi là chuẩn L2) giữa hai instance của classPoint
. - Bổ sung tham số
metric
(nhận giá trị là mộtstr
) trong hàmdistance()
vừa viết để tính khoảng cách giữa hai điểm theo một trong hai metric: khoảng cách Euclid (chuẩn L2) hoặc khoảng cách Manhattan (chuẩn L1). Dưới đây là ví dụ cách sử dụng hàmdistL1 = pointA.distance(pointB, metric='L1') distL2 = pointA.distance(pointB, metric='L2')
- Viết một method để tạo một điểm đối xứng với một điểm cho trước qua gốc tọa độ. Thực hiện yêu cầu này bằng một trong ba cách dưới đây:
- Cách 1. Viết một hàm tách biệt so với class
Point
, nhận vào một instance của classPoint
và trả về một instance mới. - Cách 2. Viết một hàm thuộc class
Point
để có thể sử dụng hàm bằng cách viết (ví dụ như)pointA.getSomething()
. - Cách 3. Cũng thực hiện như cách 2, nhưng trong nội dung của hàm này không có chữ
Point
. Gợi ý: sử dụng thuộc tínhself.__class__
.
- Cách 1. Viết một hàm tách biệt so với class
- Bổ sung hàm
__repr__()
cho classPoint
.
Đoạn code dưới đây minh họa một phần lời giải của bài tập này.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
return None
if __name__ == '__main__':
pointA = Point(4, 2)
print(pointA)
Bài tập 3. (class Line)
Xây dựng class Line
để biểu diễn các đường thẳng trong mặt phẳng $Oxy$ dựa theo những câu hỏi/yêu cầu dưới đây.
(a) Vì sao phương trình đường thẳng có dạng $y = ax + b$ với $a, b$ là hai tham số bất kỳ không phải là phương trình tổng quát của một đường thẳng trong mặt phẳng $Oxy$? Đường thẳng nào không biểu diễn được qua phương trình này?
(b) Xét phương trình $ax + by + c = 0$ với $a, b, c$ là ba tham số bất kỳ. Tìm điều kiện của ba tham số $a, b, c$ để phương trình này là phương trình tổng quát của một đường thẳng trong mặt phẳng $Oxy$.
(c) Phần khởi tạo của class Line
có thể được viết như sau
class Line:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
Nhận xét đoạn code trên.
(d) Viết một phương thức trong class Line
để xác định (những) giao điểm của hai đường thẳng (nếu có), đồng thời tự quyết định kiểu dữ liệu trả về của phương thức này.
Bình luận
- Về mặt toán học, có tất cả ba trường hợp có thể xảy ra khi xét đến giao điểm của hai đường thẳng:
- Trường hợp 1: hai đường thẳng không có giao điểm
- Trường hợp 2: hai đường thẳng có duy nhất một giao điểm
- Trường hợp 3: hai đường thẳng trùng nhau, có vô số giao điểm
-
Với ba trường hợp có thể xảy ra kể trên, có hai cách thiết kế dữ liệu trả về của phương thức này:
Cách cơ bản
- Trường hợp 1: trả về một tuple rỗng
- Trường hợp 2: trả về một tuple có một phần tử là một giao điểm với kiểu dữ liệu
Point
- Trường hợp 3: trả về một giá trị phù hợp nào đó
Cách nâng cao (liên quan đến cấu trúc
try-except
)- Trường hợp 1:
raise ValueError('no roots')
- Trường hợp 2: trả về một giao điểm với kiểu dữ liệu
Point
- Trường hợp 3:
raise ValueError('infinite roots')
(e) Viết một method trong class Line
để xác định khoảng cách giữa một điểm và một đường thẳng.
(f) Biết rằng có duy nhất một đường thẳng đi qua hai điểm phân biệt cho trước. Viết một method trong class Line
để khởi tạo một đường thẳng (là một instance của class Line
) với tham số đầu vào là hai instance của class Point
. Gợi ý: Sử dụng @classmethod
Bài tập 4. (triangle area)
Một điểm nguyên trên mặt phẳng $Oxy$ là một điểm có tung độ và hoành độ đều là các số nguyên. Cho ba điểm nguyên $A, B, C$ trên mặt phẳng. Tính diện tích của tam giác (có thể suy biến) $ABC$.
Bình luận
- Có ít nhất ba cách để thực hiện bài tập này.
- Có thể cần import class
Point
, classLine
để thực hiện bài tập này. Câu lệnh cần dùng thường có dạngfrom yourFileWithClassPoint import Point from yourFileWithClassLine import Line
Việc import này chính là lý do cần đặt phần code kiểm thử hai class trên (ở những bài tập trên) vào trong cấu trúc
if __name__ == '__main__'
.
Bài tập 5. (Morse code)
Nên làm gì khi nhận được đoạn mã Morse dưới đây
.- .-.. .-.. .. .-- .- -. - - --- ... .- -.-- .. ... -.. --- - -.. --- - ... .--. .- -.-. . -.. --- - -.. .- ... .... -.. --- - -.. --- - ... .--. .- -.-. . -.. .- ... .... -.. .- ... .... -.. .- ... .... ... .--. .- -.-. . -.. --- - -.. --- - -.. --- - -.. .- ... .... ... .--. .- -.-. . -.. --- - ... .--. .- -.-. . -.. .- ... .... -.. --- - -.. .- ... .... -.. .- ... .... ... .--. .- -.-. . -.. .- ... .... -.. .- ... .... -.. .- ... .... ... .--. .- -.-. . -.. --- - -.. --- - -.. .- ... ....
Bài tập 6. (class Circle)
Xây dựng class Circle
để biểu diễn các đường tròn trong mặt phẳng $Oxy$. Khởi tạo với các thuộc tính thích hợp đồng thời cài đặt những thuộc tính, property thích hợp. Tham khảo cách thiết kế trong the geometry module for SymPy package.
Bài tập 7. (class Datetime)
Xây dựng class Datetime
cho phép thực hiện các tác vụ liên quan đến thời gian. Tham khảo pandas.Timestamp
để nắm được những thuộc tính/phương thức cơ bản của class cần cài đặt.
Bài tập 8. (factorial number)
Cho $n$ là một số tự nhiên, ta định nghĩa $n!$ là tích của $n$ số nguyên dương đầu tiên với quy ước $0! = 1$. Ví dụ $5!=120$.
(a) Hỏi $n!$ có bao nhiêu chữ số 0 ở tận cùng bên phải?
(b) Ta bỏ tất cả chữ số 0 ở tận cùng bên phải của $n!$, khi đó chữ số tận cùng bên phải là chữ số nào?
Trả lời những câu hỏi trên với $n$ đủ lớn, đồng thời ghi lại thời gian thực thi của chương trình.
Bài tập 9. (left-most digit)
Tìm chữ số tận cùng bên trái của $a^b$ với $a,b$ là hai số nguyên dương cho trước. Lấy $a,b$ ngẫu nhiên thì những chữ số tận cùng bên trái có phân bố ra sao?
Một câu hỏi liên quan đến bài tập trên:
- Một số $n$ được gọi là $m$-slightly-above nếu $n$ bắt đầu bởi một chữ số nào đó và theo sau bởi $m$ chữ số 0. Ví dụ 800297 là 2-slightly-above.
- Một số $n$ được gọi là $m$-slightly-below nếu $n$ bắt đầu bởi một chữ số nào đó và theo sau bởi $m$ chữ số 9. Ví dụ 999183 là 2-slightly-below.
Cho trước số nguyên dương $k$, tìm $n$ nhỏ nhất sao cho lũy thừa $n^k$ là $m$-slightly-above hoặc $m$-slightly-below với $m=0,1,2,\ldots$
Thảo luận
- Có thể biểu diễn một
Line
qua mộtPoint
và mộtVector
. - Có nhiều cách để xác định (duy nhất) một
Circle
: từ 3 điểm không thẳng hàng, từ tâm và bán kính, từ đường tròn ngoại tiếp một tam giác, … Nên sử dụng@classmethod
để tách riêng những trường hợp này. - Đọc thêm về hàm zip() và hàm
zip_longest()
.