1. Các Phương Pháp Chạy Script Python
Có ba cách chính để thực thi một script Python:
-
Sử dụng trình thông dịch trực tiếp từ dòng lệnh:
Đây là cách phổ biến nhất. Bạn gọi trình thông dịch Python theo sau là tên tệp script. Ví dụ, nếu bạn có một tệp `chao_mung.py`:
# chao_mung.py
print("Chào mừng đến với Python!")
Bạn có thể chạy nó bằng lệnh:
python3 chao_mung.py
(Lưu ý: `python3` đảm bảo bạn sử dụng phiên bản Python 3. Nếu chỉ dùng `python`, có thể hệ thống sẽ chạy Python 2.)
-
Thực thi trực tiếp tệp script (với quyền thực thi):
Để chạy một script như một chương trình độc lập, bạn cần thêm một dòng shebang ở đầu tệp để chỉ định trình thông dịch, và cấp quyền thực thi cho tệp.
#!/usr/bin/env python3
# chao_mung.py
print("Đây là script có thể chạy trực tiếp!")
Sau đó, cấp quyền và chạy:
chmod +x chao_mung.py
./chao_mung.py
-
Sử dụng trình thông dịch tương tác:
Đối với các đoạn mã nhỏ hoặc để kiểm tra cú pháp nhanh chóng, bạn có thể nhập `python3` vào dòng lệnh để mở trình thông dịch tương tác.
python3
>>> print("Hello, world!")
Hello, world!
>>> 2 + 3
5
>>> # Nhấn Ctrl+Z (trên Windows) hoặc Ctrl+D (trên Linux/macOS) để thoát.
2. Mối Quan Hệ Giữa Bit và Byte
Đơn vị cơ bản nhất trong điện toán là
bit, có thể là 0 hoặc 1.
Một
byte là một nhóm gồm 8 bit.
Vì vậy,
1 byte = 8 bit.
3. Mối Quan Hệ Giữa ASCII, Unicode, UTF-8, GBK
-
ASCII (American Standard Code for Information Interchange):
Là một bộ mã hóa ký tự cũ chỉ hỗ trợ 128 ký tự (hoặc 256 ký tự mở rộng). Nó chủ yếu dựa trên bảng chữ cái Latinh và không thể biểu diễn các ký tự của nhiều ngôn ngữ khác, đặc biệt là tiếng Việt, tiếng Trung, tiếng Nhật.
-
Unicode:
Là một tiêu chuẩn mã hóa ký tự toàn cầu, được tạo ra để bao gồm tất cả các ký tự từ mọi ngôn ngữ và hệ thống chữ viết trên thế giới. Nó cung cấp một số duy nhất (code point) cho mỗi ký tự, bất kể nền tảng, chương trình hoặc ngôn ngữ. Unicode thường sử dụng 2 byte (UCS-2) hoặc 4 byte (UCS-4) để biểu diễn một ký tự.
-
UTF-8 (Unicode Transformation Format - 8-bit):
Là một cách mã hóa biến đổi của Unicode, được thiết kế để tối ưu hóa việc lưu trữ và truyền tải. Nó sử dụng mã hóa độ dài biến đổi:
- Các ký tự Latinh (như tiếng Anh) thường chiếm 1 byte.
- Các ký tự tiếng Châu Âu khác (ví dụ: có dấu) thường chiếm 2 byte.
- Các ký tự tiếng Trung, tiếng Nhật, tiếng Hàn thường chiếm 3 byte.
UTF-8 là mã hóa được khuyến nghị và sử dụng rộng rãi nhất trên internet và trong các hệ thống hiện đại (ví dụ: Linux).
-
GBK (Guo Biao Kuozhan - Tiêu chuẩn Quốc gia Mở rộng):
Là một bộ mã hóa ký tự của Trung Quốc, tương thích ngược với GB2312. GBK được sử dụng phổ biến trên các hệ thống Windows ở Trung Quốc. Nó thường dùng 2 byte để biểu diễn một ký tự tiếng Trung. GBK không tương thích trực tiếp với UTF-8 và có thể gây ra lỗi hiển thị nếu không được xử lý đúng cách.
4. Số Lượng Bit "李杰" Chiếm Dụng Khi Mã Hóa Bằng UTF-8 và GBK
Chuỗi "李杰" bao gồm 2 ký tự tiếng Trung.
-
Trong UTF-8:
Mỗi ký tự tiếng Trung chiếm 3 byte.
Vậy, 2 ký tự * 3 byte/ký tự = 6 byte.
Vì 1 byte = 8 bit, nên 6 byte * 8 bit/byte = 48 bit.
-
Trong GBK:
Mỗi ký tự tiếng Trung chiếm 2 byte.
Vậy, 2 ký tự * 2 byte/ký tự = 4 byte.
Vì 1 byte = 8 bit, nên 4 byte * 8 bit/byte = 32 bit.
5. Cách Đặt Chú Thích Trong Python
-
Chú thích một dòng: Sử dụng ký tự thăng (
#).
# Đây là một dòng chú thích đơn.
ma_so = 123 # Đây là chú thích cuối dòng.
-
Chú thích nhiều dòng: Sử dụng ba dấu nháy đơn (
''') hoặc ba dấu nháy kép (""").
'''
Đây là một khối
chú thích nhiều dòng.
Thường được dùng cho docstring.
'''
def ham_mau():
"""Đây cũng là một docstring,
giải thích chức năng của hàm."""
pass
6. Quy Tắc Đặt Tên Biến Trong Python
Khi đặt tên biến trong Python, bạn cần tuân thủ một số quy tắc sau:
- Không được bắt đầu bằng số: Tên biến phải bắt đầu bằng chữ cái (a-z, A-Z) hoặc dấu gạch dưới (
_).
- Chỉ chứa chữ cái, số và dấu gạch dưới: Tên biến có thể bao gồm các chữ cái, số và dấu gạch dưới (
_) sau ký tự đầu tiên.
- Không chứa ký tự đặc biệt: Tên biến không được chứa các ký tự đặc biệt như
@, #, $, %, ^, &, *, !, v.v.
- Không được trùng với từ khóa (keywords) của Python: Các từ khóa như `if`, `else`, `while`, `for`, `class`, `def`, v.v., đã được Python giữ riêng cho cú pháp của nó và không thể dùng làm tên biến.
- Phân biệt chữ hoa/thường: Python là ngôn ngữ phân biệt chữ hoa/thường, nghĩa là `tenBien`, `TenBien` và `tenbien` là ba biến khác nhau.
- Quy ước đặt tên (PEP 8): Mặc dù không bắt buộc, nhưng để mã dễ đọc và duy trì, cộng đồng Python khuyến nghị sử dụng `snake_case` (ví dụ: `ten_nguoi_dung`) cho tên biến và tên hàm.
7. Cách Kiểm Tra Địa Chỉ Bộ Nhớ Của Biến
Để xem địa chỉ bộ nhớ mà một biến đang trỏ tới, bạn sử dụng hàm `id()`:
ten_nguoi_dung = "Alice"
print(f"Địa chỉ bộ nhớ của 'ten_nguoi_dung': {id(ten_nguoi_dung)}")
so_nguyen = 42
print(f"Địa chỉ bộ nhớ của 'so_nguyen': {id(so_nguyen)}")
8. Mục Đích Của Tệp `.pyc` Được Tạo Tự Động
Khi bạn chạy một chương trình Python (ví dụ `my_script.py`), trình thông dịch Python sẽ biên dịch mã nguồn thành bytecode. Bytecode này sau đó được lưu trữ trong bộ nhớ dưới dạng đối tượng `PyCodeObject`.
Để tăng tốc độ thực thi trong tương lai, Python thường lưu trữ bytecode này vào một tệp có phần mở rộng `.pyc` (Python compiled) bên trong thư mục `__pycache__` cùng cấp với script gốc.
Lần sau khi bạn chạy `my_script.py`, trình thông dịch sẽ kiểm tra xem có tệp `.pyc` tương ứng không và liệu nó có được cập nhật so với tệp `.py` gốc hay không. Nếu có tệp `.pyc` hợp lệ, Python sẽ tải và thực thi bytecode trực tiếp, bỏ qua bước biên dịch mã nguồn, giúp chương trình khởi động nhanh hơn.
9. Bài Tập Viết Mã Python
a. Đăng nhập cơ bản
Yêu cầu: Người dùng nhập tên người dùng và mật khẩu. Nếu tên người dùng là "seven" và mật khẩu là "123", hiển thị "Đăng nhập thành công!", ngược lại hiển thị "Đăng nhập thất bại!".
input_username = input("Vui lòng nhập tên người dùng: ")
input_password = input("Vui lòng nhập mật khẩu: ")
if input_username == "seven" and input_password == "123":
print("Đăng nhập thành công!")
else:
print("Đăng nhập thất bại!")
b. Đăng nhập với 3 lần thử
Yêu cầu: Người dùng nhập tên người dùng và mật khẩu. Nếu tên người dùng là "seven" và mật khẩu là "123", hiển thị "Đăng nhập thành công!". Nếu không, hiển thị "Đăng nhập thất bại!" và cho phép thử lại tối đa 3 lần.
MAX_ATTEMPTS = 3
correct_username = "seven"
correct_password = "123"
for attempt_count in range(MAX_ATTEMPTS):
print(f"\n--- Lần thử {attempt_count + 1}/{MAX_ATTEMPTS} ---")
user_input_name = input("Nhập tên người dùng: ")
user_input_pass = input("Nhập mật khẩu: ")
if user_input_name == correct_username and user_input_pass == correct_password:
print("Đăng nhập thành công!")
break # Thoát vòng lặp khi đăng nhập thành công
else:
print("Đăng nhập thất bại. Tên người dùng hoặc mật khẩu không đúng.")
if attempt_count == MAX_ATTEMPTS - 1:
print("Bạn đã hết số lần thử. Tài khoản có thể bị khóa tạm thời.")
c. Đăng nhập với nhiều người dùng và 3 lần thử
Yêu cầu: Người dùng nhập tên người dùng và mật khẩu. Nếu tên người dùng là "seven" hoặc "alex" và mật khẩu là "123", hiển thị "Đăng nhập thành công!". Nếu không, hiển thị "Đăng nhập thất bại!" và cho phép thử lại tối đa 3 lần.
VALID_USERS = ["seven", "alex"]
EXPECTED_PASSWORD = "123" # Giữ nguyên là chuỗi để so sánh trực tiếp với input()
MAX_LOGIN_ATTEMPTS = 3
for attempt_num in range(MAX_LOGIN_ATTEMPTS):
print(f"\n--- Lần thử {attempt_num + 1}/{MAX_LOGIN_ATTEMPTS} ---")
entered_username = input("Nhập tên người dùng: ")
entered_password = input("Nhập mật khẩu: ")
if entered_username in VALID_USERS and entered_password == EXPECTED_PASSWORD:
print("Đăng nhập thành công!")
break
else:
print("Đăng nhập thất bại. Tên người dùng hoặc mật khẩu không đúng.")
if attempt_num == MAX_LOGIN_ATTEMPTS - 1:
print("Bạn đã hết số lần thử. Tài khoản có thể bị khóa tạm thời.")
10. Bài Tập Về Vòng Lặp
a. Tính tổng 2-3+4-5+6...+100 (sử dụng vòng lặp while)
total_sum = 0
current_number = 2
while current_number <= 100:
if current_number % 2 == 0: # Số chẵn thì cộng
total_sum += current_number
else: # Số lẻ thì trừ
total_sum -= current_number
current_number += 1
print(f"Tổng của dãy số 2-3+4-5+...+100 là: {total_sum}")
b. Tính tổng 1-2+3-4+5-6...+99 (sử dụng vòng lặp for và range)
calculated_total = 0
for value_n in range(1, 100): # Từ 1 đến 99
if value_n % 2 != 0: # Số lẻ thì cộng
calculated_total += value_n
else: # Số chẵn thì trừ
calculated_total -= value_n
print(f"Tổng của dãy số 1-2+3-4+...+99 là: {calculated_total}")
c. In ra 1,2,3,4,5, 7,8,9, 11,12 (sử dụng vòng lặp while)
number_to_print = 0
while number_to_print < 12:
number_to_print += 1
if number_to_print == 6 or number_to_print == 10:
continue # Bỏ qua số 6 và 10
print(number_to_print)
d. In ra tất cả các số lẻ từ 1 đến 100 (sử dụng vòng lặp while)
odd_num_iterator = 1
print("Các số lẻ từ 1 đến 100:")
while odd_num_iterator <= 100:
if odd_num_iterator % 2 != 0: # Kiểm tra số lẻ
print(odd_num_iterator)
odd_num_iterator += 1
e. In ra tất cả các số chẵn từ 1 đến 100 (sử dụng vòng lặp while)
even_num_iterator = 1
print("Các số chẵn từ 1 đến 100:")
while even_num_iterator <= 100:
if even_num_iterator % 2 == 0: # Kiểm tra số chẵn
print(even_num_iterator)
even_num_iterator += 1
11. Biểu Diễn Nhị Phân Của Các Số
Sử dụng hàm `bin()` trong Python để xem biểu diễn nhị phân của một số nguyên. Kết quả sẽ có tiền tố `0b`.
- Số 5:
bin(5) → 0b101
- Số 10:
bin(10) → 0b1010
- Số 32:
bin(32) → 0b100000
- Số 7:
bin(7) → 0b111
12. Mối Quan Hệ Giữa Đối Tượng và Lớp (Class)
Có thể ví von:
-
Lớp (Class) giống như một bản thiết kế hoặc một khuôn mẫu. Nó định nghĩa các thuộc tính (dữ liệu) và phương thức (hành vi) mà các đối tượng thuộc lớp đó sẽ có. Lớp mang tính trừu tượng, không tồn tại vật lý trực tiếp.
Ví dụ: "Bản vẽ thiết kế của một chiếc ô tô" là một lớp.
-
Đối tượng (Object) là một thể hiện cụ thể, một sản phẩm được tạo ra từ bản thiết kế đó. Mỗi đối tượng có các thuộc tính và phương thức riêng biệt dựa trên định nghĩa của lớp. Đối tượng tồn tại vật lý trong bộ nhớ của chương trình.
Ví dụ: "Chiếc ô tô màu đỏ của bạn" hoặc "Chiếc ô tô màu xanh của tôi" đều là các đối tượng được tạo ra từ bản vẽ thiết kế ô tô.
Tóm lại, lớp là định nghĩa, đối tượng là hiện thực của định nghĩa đó.
13. Mối Quan Hệ Giữa Các Biến Số Nguyên Nhỏ
a. num1 = 123 và num2 = 123
Trong Python, đối với các số nguyên trong một phạm vi nhỏ (thường từ -5 đến 256), Python tối ưu hóa bằng cách "intern" chúng, nghĩa là chỉ tạo một đối tượng số nguyên duy nhất trong bộ nhớ và các biến có cùng giá trị sẽ trỏ đến cùng đối tượng đó. Do đó, `num1` và `num2` có thể trỏ đến cùng một địa chỉ bộ nhớ.
num1 = 123
num2 = 123
print(f"ID của num1: {id(num1)}")
print(f"ID của num2: {id(num2)}")
print(f"num1 is num2: {num1 is num2}") # Thường là True cho các số nhỏ
b. num1 = 123456 và num2 = 123456
Đối với các số nguyên lớn hơn phạm vi "intern" của Python, khi bạn tạo hai biến với cùng một giá trị, Python sẽ tạo hai đối tượng số nguyên riêng biệt trong bộ nhớ. Do đó, `num1` và `num2` sẽ trỏ đến các địa chỉ bộ nhớ khác nhau.
num1 = 123456
num2 = 123456
print(f"ID của num1: {id(num1)}")
print(f"ID của num2: {id(num2)}")
print(f"num1 is num2: {num1 is num2}") # Thường là False cho các số lớn
c. num1 = 123456 và num2 = num1
Trong trường hợp này, `num2` không tạo ra một đối tượng số nguyên mới. Thay vào đó, `num2` chỉ đơn giản là một tham chiếu (alias) đến cùng một đối tượng mà `num1` đang trỏ tới trong bộ nhớ. Do đó, `num1` và `num2` sẽ có cùng địa chỉ bộ nhớ.
Tuy nhiên, cần lưu ý rằng số nguyên là kiểu dữ liệu bất biến (immutable). Nếu `num1` sau đó được gán lại một giá trị mới (ví dụ: `num1 = num1 + 1`), Python sẽ tạo một đối tượng số nguyên *mới* cho `num1`. Khi đó, `num1` sẽ trỏ đến địa chỉ bộ nhớ mới, trong khi `num2` vẫn sẽ trỏ đến đối tượng số nguyên ban đầu.
num1_original = 123456
num2_alias = num1_original
print(f"Ban đầu - ID của num1_original: {id(num1_original)}")
print(f"Ban đầu - ID của num2_alias: {id(num2_alias)}")
print(f"num1_original is num2_alias: {num1_original is num2_alias}")
# Thay đổi giá trị của num1_original
num1_original = num1_original + 100 # Tạo một đối tượng số nguyên mới cho num1_original
print(f"\nSau khi thay đổi - ID của num1_original: {id(num1_original)}")
print(f"Sau khi thay đổi - ID của num2_alias: {id(num2_alias)}")
print(f"num1_original is num2_alias: {num1_original is num2_alias}")
print(f"Giá trị của num1_original: {num1_original}, giá trị của num2_alias: {num2_alias}")
14. Số Bit Tối Thiểu Để Biểu Diễn Một Số Nguyên
Để tìm số bit tối thiểu cần thiết để biểu diễn một số nguyên trong hệ nhị phân (không bao gồm dấu và tiền tố `0b`), bạn có thể sử dụng phương thức `bit_length()` của đối tượng số nguyên.
number_val = 5
print(f"Số 5 cần {number_val.bit_length()} bit để biểu diễn.") # Kết quả: 3 (vì 5 là 101 trong nhị phân)
another_num = 32
print(f"Số 32 cần {another_num.bit_length()} bit để biểu diễn.") # Kết quả: 6 (vì 32 là 100000 trong nhị phân)
15. Các Giá Trị Boolean
Python có hai giá trị Boolean:
Đây là các hằng số được định nghĩa sẵn và bắt đầu bằng chữ hoa.
16. Kết Quả Thực Thi Mã (String capitalize)
string_a = "hello world"
string_b = string_a.capitalize()
print(string_a)
print(string_b)
Kết quả:
hello world
Hello world
Giải thích: Phương thức `capitalize()` trả về một chuỗi mới với ký tự đầu tiên được viết hoa, còn chuỗi gốc không bị thay đổi vì chuỗi là kiểu dữ liệu bất biến trong Python.
17. Các Thao Tác Với Chuỗi
Cho biến `text_data = " python string "`
text_data = " python string "
# a. Xóa khoảng trắng ở hai đầu và in ra
stripped_text = text_data.strip()
print(f"Chuỗi sau khi loại bỏ khoảng trắng: '{stripped_text}'")
# b. Kiểm tra chuỗi có bắt đầu bằng "py" không và in kết quả
# Lưu ý: ' python string ' không bắt đầu bằng 'py' vì có khoảng trắng ở đầu
starts_with_py = text_data.startswith("py")
print(f"Chuỗi bắt đầu bằng 'py'? {starts_with_py}")
# c. Kiểm tra chuỗi có kết thúc bằng "ng" không và in kết quả
ends_with_ng = text_data.endswith("ng ") # Kết thúc bằng 'ng ' chứ không phải 'ng'
print(f"Chuỗi kết thúc bằng 'ng'? {ends_with_ng}")
# d. Thay thế tất cả các ký tự "t" bằng "T" và in ra
replaced_text = text_data.replace("t", "T")
print(f"Chuỗi sau khi thay thế 't' bằng 'T': '{replaced_text}'")
# e. Chia chuỗi theo ký tự " " (khoảng trắng) và in ra
split_text = text_data.split(" ")
print(f"Chuỗi sau khi chia: {split_text}")
# f. Loại của giá trị nhận được từ câu (e)?
# Kết quả từ split() là một list các chuỗi.
print(f"Loại của kết quả từ câu e là: {type(split_text)}")
# g. Chuyển chuỗi thành chữ hoa và in ra
upper_text = text_data.upper()
print(f"Chuỗi viết hoa: '{upper_text}'")
# h. Chuyển chuỗi thành chữ thường và in ra
lower_text = text_data.lower()
print(f"Chuỗi viết thường: '{lower_text}'")
# i. In ra ký tự thứ 2 (chỉ mục 1) của chuỗi
# Lưu ý: Ký tự đầu tiên có chỉ mục 0
second_char = text_data[1]
print(f"Ký tự thứ 2: '{second_char}'")
# j. In ra 3 ký tự đầu tiên của chuỗi (slice)
first_three_chars = text_data[:3]
print(f"Ba ký tự đầu tiên: '{first_three_chars}'")
# k. In ra 2 ký tự cuối cùng của chuỗi (slice)
last_two_chars = text_data[-2:]
print(f"Hai ký tự cuối cùng: '{last_two_chars}'")
# l. In ra vị trí chỉ mục của ký tự "g" trong chuỗi
index_of_g = text_data.index("g")
print(f"Vị trí của ký tự 'g': {index_of_g}")
Kết quả chạy:
Chuỗi sau khi loại bỏ khoảng trắng: 'python string'
Chuỗi bắt đầu bằng 'py'? False
Chuỗi kết thúc bằng 'ng'? False
Chuỗi sau khi thay thế 't' bằng 'T': ' pyThon sTring '
Chuỗi sau khi chia: ['', 'python', 'string', '']
Loại của kết quả từ câu e là: <class 'list'>
Chuỗi viết hoa: ' PYTHON STRING '
Chuỗi viết thường: ' python string '
Ký tự thứ 2: 'p'
Ba ký tự đầu tiên: ' p'
Hai ký tự cuối cùng: 'g '
Vị trí của ký tự 'g': 9
18. Chuỗi Có Thể Lặp Lại Được Không?
Có, chuỗi (string) là một kiểu dữ liệu có thể lặp lại (iterable) trong Python. Bạn có thể sử dụng vòng lặp `for` để duyệt qua từng ký tự trong chuỗi.
sample_message = "Xin chào Python!"
print(f"Chuỗi '{sample_message}' có thể lặp lại.")
print("Các ký tự trong chuỗi:")
for char_element in sample_message:
print(char_element)
19. Các Thao Tác Với Danh Sách (List)
Cho danh sách `my_list = ['apple', 'banana', 'cherry']`
my_list = ['apple', 'banana', 'cherry']
# a. Tính độ dài danh sách và in ra
list_length = len(my_list)
print(f"Độ dài của danh sách: {list_length}")
# b. Thêm phần tử "grape" vào cuối danh sách và in ra
my_list.append("grape")
print(f"Danh sách sau khi thêm 'grape': {my_list}")
# c. Chèn phần tử "orange" vào vị trí đầu tiên (chỉ mục 0) và in ra
my_list.insert(0, "orange")
print(f"Danh sách sau khi chèn 'orange': {my_list}")
# d. Sửa đổi phần tử ở vị trí thứ 2 (chỉ mục 1) thành "kiwi" và in ra
my_list[1] = "kiwi"
print(f"Danh sách sau khi sửa đổi: {my_list}")
# e. Xóa phần tử "cherry" khỏi danh sách và in ra
my_list.remove("cherry")
print(f"Danh sách sau khi xóa 'cherry': {my_list}")
# f. Xóa phần tử thứ 2 (chỉ mục 1), in ra giá trị của phần tử đã xóa và danh sách còn lại
removed_element = my_list.pop(1)
print(f"Phần tử đã xóa (chỉ mục 1): '{removed_element}'")
print(f"Danh sách sau khi xóa phần tử: {my_list}")
# g. Xóa phần tử thứ 3 (chỉ mục 2), in ra giá trị của phần tử đã xóa và danh sách còn lại
removed_element_2 = my_list.pop(2)
print(f"Phần tử đã xóa (chỉ mục 2): '{removed_element_2}'")
print(f"Danh sách sau khi xóa phần tử: {my_list}")
# h. Xóa các phần tử từ vị trí thứ 2 đến thứ 4 (chỉ mục 1, 2, 3).
# Giả sử danh sách gốc trước khi xóa là ['orange', 'kiwi', 'banana', 'grape']
# (để minh họa, vì các thao tác trên đã thay đổi my_list)
# Cần lưu ý rằng các thao tác e, f, g đã thay đổi my_list.
# Để đơn giản, ta sẽ tạo lại danh sách cho ví dụ này, hoặc theo dõi trạng thái.
# Dựa vào các bước trước, my_list hiện tại là ['orange', 'kiwi', 'grape']
# Không thể xóa từ 2 đến 4.
# Ta sẽ dùng một ví dụ khác để minh họa 'del li[1:4]'
temp_list = ['a', 'b', 'c', 'd', 'e', 'f']
print(f"\nDanh sách tạm thời ban đầu: {temp_list}")
del temp_list[1:4] # Xóa các phần tử ở chỉ mục 1, 2, 3 ('b', 'c', 'd')
print(f"Danh sách tạm thời sau khi xóa [1:4]: {temp_list}")
# i. Đảo ngược thứ tự các phần tử trong danh sách và in ra
# Trở lại my_list (hiện tại là ['orange', 'kiwi', 'grape'])
my_list.reverse()
print(f"Danh sách sau khi đảo ngược: {my_list}")
# j. Sử dụng for, len, range để in ra các chỉ mục của danh sách
print("\nChỉ mục của danh sách:")
for idx in range(len(my_list)):
print(idx)
# k. Sử dụng enumerate để in ra phần tử và số thứ tự (bắt đầu từ 100)
print("\nPhần tử và số thứ tự (bắt đầu từ 100):")
for index, item in enumerate(my_list, start=100):
print(f"Số thứ tự {index}: {item}")
# l. Sử dụng for để in ra tất cả các phần tử của danh sách
print("\nTất cả các phần tử của danh sách:")
for element in my_list:
print(element)
20. Thao Tác Với Danh Sách Lồng Nhau
Cho danh sách `nested_list = ["start", 'middle', ["sub1", ["nested_h", "target_kelly"], 'sub_all'], 123, 446]`
nested_list = ["start", 'middle', ["sub1", ["nested_h", "target_kelly"], 'sub_all'], 123, 446]
# a. In ra "target_kelly"
print(f"Giá trị 'target_kelly': {nested_list[2][1][1]}")
# b. Tìm phần tử 'sub_all' và sửa đổi thành "ALL"
nested_list[2][2] = "ALL"
print(f"Danh sách sau khi sửa đổi 'sub_all' thành 'ALL': {nested_list}")
21. Các Thao Tác Với Tuple
Cho tuple `data_tuple = ('alpha', 'beta', 'gamma')`
data_tuple = ('alpha', 'beta', 'gamma')
# a. Tính độ dài tuple và in ra
tuple_length = len(data_tuple)
print(f"Độ dài của tuple: {tuple_length}")
# b. Lấy phần tử thứ 2 (chỉ mục 1) và in ra
second_element = data_tuple[1]
print(f"Phần tử thứ 2: '{second_element}'")
# c. Lấy các phần tử từ vị trí 1 đến 2 (slice) và in ra
slice_elements = data_tuple[0:2]
print(f"Các phần tử từ vị trí 1 đến 2: {slice_elements}")
# d. Sử dụng for để in ra các phần tử của tuple
print("\nCác phần tử của tuple:")
for item in data_tuple:
print(item)
# e. Sử dụng for, len, range để in ra các chỉ mục của tuple
print("\nChỉ mục của tuple:")
for idx in range(len(data_tuple)):
print(idx)
# f. Sử dụng enumerate để in ra phần tử và số thứ tự (bắt đầu từ 10)
print("\nPhần tử và số thứ tự (bắt đầu từ 10):")
for index, item in enumerate(data_tuple, start=10):
print(f"Số thứ tự {index}: {item}")
22. Tuple Với Các Kiểu Dữ Liệu Lồng Nhau
Cho biến `complex_tuple = ("item_a", [10, 20, {"key1": 'val1', "key2": ["age", "name"], "key3": (1,2,3)}, 40])`
a. Đặc tính của Tuple
Tuple là một kiểu dữ liệu tập hợp có thứ tự và
bất biến (immutable). Điều này có nghĩa là một khi một tuple được tạo, bạn không thể thêm, xóa hoặc thay đổi thứ tự các phần tử của nó. Tuy nhiên, nếu một phần tử bên trong tuple là một đối tượng có thể thay đổi (như danh sách hoặc từ điển), thì nội dung của đối tượng có thể thay đổi đó *có thể* được sửa đổi.
b. Phần tử "item_a" có thể được sửa đổi không?
Không. Phần tử "item_a" là một chuỗi (string), và chuỗi là kiểu dữ liệu bất biến. Hơn nữa, nó là một phần tử trực tiếp của tuple, mà tuple lại bất biến. Vì vậy, bạn không thể thay đổi "item_a" thành một giá trị khác mà không tạo lại toàn bộ tuple.
c. Giá trị tương ứng với "key2" là loại gì? Có thể sửa đổi không? Nếu có, hãy thêm "NewValue".
Giá trị tương ứng với "key2" là một
danh sách (list): `["age", "name"]`.
Có, danh sách là kiểu dữ liệu
có thể thay đổi (mutable). Do đó, bạn có thể sửa đổi nội dung của danh sách này.
complex_tuple = ("item_a", [10, 20, {"key1": 'val1', "key2": ["age", "name"], "key3": (1,2,3)}, 40])
print(f"Tuple ban đầu: {complex_tuple}")
# Thêm "NewValue" vào danh sách của "key2"
complex_tuple[1][2]['key2'].append("NewValue")
print(f"Tuple sau khi thêm 'NewValue' vào danh sách của 'key2': {complex_tuple}")
d. Giá trị tương ứng với "key3" là loại gì? Có thể sửa đổi không? Nếu có, hãy thêm "NewValue".
Giá trị tương ứng với "key3" là một
tuple: `(1,2,3)`.
Không, tuple là kiểu dữ liệu
bất biến (immutable). Vì vậy, bạn không thể sửa đổi nội dung của tuple này (ví dụ: thêm hoặc xóa phần tử).
23. Các Thao Tác Với Từ Điển (Dictionary)
Cho từ điển `my_dict = {'item1': "value1", "item2": "value2", "item3": [10,20,30]}`
my_dict = {'item1': "value1", "item2": "value2", "item3": [10,20,30]}
# a. Lặp và in ra tất cả các khóa
print("Các khóa trong từ điển:")
for key_name in my_dict.keys():
print(key_name)
# b. Lặp và in ra tất cả các giá trị
print("\nCác giá trị trong từ điển:")
for val_item in my_dict.values():
print(val_item)
# c. Lặp và in ra tất cả các khóa và giá trị
print("\nCác khóa và giá trị trong từ điển:")
for key, value in my_dict.items():
print(f"Khóa: {key}, Giá trị: {value}")
# d. Thêm một cặp khóa-giá trị mới: "item4": "value4" và in ra từ điển sau khi thêm
my_dict["item4"] = "value4"
print(f"\nTừ điển sau khi thêm 'item4': {my_dict}")
# e. Sửa đổi giá trị tương ứng với khóa "item1" thành "new_value_for_item1" và in ra
my_dict["item1"] = "new_value_for_item1"
print(f"\nTừ điển sau khi sửa đổi 'item1': {my_dict}")
# f. Thêm phần tử 40 vào danh sách tương ứng với khóa "item3" và in ra
my_dict["item3"].append(40)
print(f"\nTừ điển sau khi thêm 40 vào 'item3': {my_dict}")
# g. Chèn phần tử 5 vào vị trí đầu tiên của danh sách tương ứng với khóa "item3" và in ra
my_dict["item3"].insert(0, 5)
print(f"\nTừ điển sau khi chèn 5 vào 'item3': {my_dict}")
24. Chuyển Đổi Kiểu Dữ Liệu
a. Chuyển chuỗi `s = "example"` thành danh sách
str_val = "example"
list_from_str = list(str_val)
print(f"Chuỗi '{str_val}' thành danh sách: {list_from_str}")
b. Chuyển chuỗi `s = "example"` thành tuple
str_val = "example"
tuple_from_str = tuple(str_val)
print(f"Chuỗi '{str_val}' thành tuple: {tuple_from_str}")
c. Chuyển danh sách `items_list = ["alpha", "beta"]` thành tuple
items_list = ["alpha", "beta"]
tuple_from_list = tuple(items_list)
print(f"Danh sách {items_list} thành tuple: {tuple_from_list}")
d. Chuyển tuple `data_tuple = ('delta', "epsilon")` thành danh sách
data_tuple = ('delta', "epsilon")
list_from_tuple = list(data_tuple)
print(f"Tuple {data_tuple} thành danh sách: {list_from_tuple}")
e. Chuyển danh sách `items_list = ["value_a", "value_b"]` thành từ điển với khóa tăng dần bắt đầu từ 10
items_list_for_dict = ["value_a", "value_b"]
dict_from_list = {}
for key_index, dict_value in enumerate(items_list_for_dict, start=10):
dict_from_list[key_index] = dict_value
print(f"Danh sách {items_list_for_dict} thành từ điển: {dict_from_list}")
25. Mã Hóa và Giải Mã Chuỗi
Cho chuỗi `text = "Python"` (hoặc một chuỗi tiếng Việt/Trung để minh họa rõ hơn)
a. Chuyển chuỗi "Python" thành byte theo mã hóa UTF-8, sau đó chuyển ngược lại thành chuỗi UTF-8.
vietnamese_text = "Xin chào Việt Nam"
# Mã hóa chuỗi thành byte bằng UTF-8
encoded_bytes_utf8 = vietnamese_text.encode("utf-8")
print(f"Chuỗi '{vietnamese_text}' mã hóa UTF-8 (bytes): {encoded_bytes_utf8}")
# Giải mã byte trở lại thành chuỗi UTF-8
decoded_string_utf8 = encoded_bytes_utf8.decode("utf-8")
print(f"Byte đã mã hóa UTF-8 giải mã thành chuỗi: {decoded_string_utf8}")
b. Chuyển chuỗi "老男孩" thành byte theo mã hóa GBK, sau đó chuyển ngược lại thành chuỗi GBK.
chinese_text = "老男孩"
# Mã hóa chuỗi thành byte bằng GBK
encoded_bytes_gbk = chinese_text.encode("gbk")
print(f"Chuỗi '{chinese_text}' mã hóa GBK (bytes): {encoded_bytes_gbk}")
# Giải mã byte trở lại thành chuỗi GBK
decoded_string_gbk = encoded_bytes_gbk.decode("gbk")
print(f"Byte đã mã hóa GBK giải mã thành chuỗi: {decoded_string_gbk}")
26. Tính Tổng Các Số Từ 1 Đến 100
sum_of_numbers = 0
for i in range(1, 101): # Bao gồm 100
sum_of_numbers += i
print(f"Tổng các số từ 1 đến 100 là: {sum_of_numbers}")
# Cách khác: print(sum(range(1, 101)))
27. Phân Loại Phần Tử Vào Từ Điển
Cho tập hợp giá trị `[11,22,33,44,55,66,77,88,99,90]`. Lưu tất cả các giá trị lớn hơn 66 vào một khóa trong từ điển, và các giá trị nhỏ hơn hoặc bằng 66 vào một khóa khác.
input_numbers = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90]
classified_numbers = {"lon_hon_66": [], "nho_hon_hoac_bang_66": []}
for number_val in input_numbers:
if number_val > 66:
classified_numbers["lon_hon_66"].append(number_val)
else:
classified_numbers["nho_hon_hoac_bang_66"].append(number_val)
print(f"Từ điển phân loại: {classified_numbers}")
Kết quả:
Từ điển phân loại: {'lon_hon_66': [77, 88, 99, 90], 'nho_hon_hoac_bang_66': [11, 22, 33, 44, 55, 66]}
28. Chức Năng Giỏ Hàng Đơn Giản
Yêu cầu: Người dùng nhập tổng tài sản. Hiển thị danh sách sản phẩm. Cho phép người dùng chọn sản phẩm theo số thứ tự để thêm vào giỏ hàng. Nếu tổng tiền mua hàng lớn hơn tổng tài sản, thông báo không đủ tiền và dừng. Ngược lại, thông báo mua hàng thành công và cập nhật số dư.
available_products = [
{"name": "Máy tính xách tay", "price": 1999},
{"name": "Chuột máy tính", "price": 10},
{"name": "Thuyền buồm", "price": 20},
{"name": "Sách lập trình", "price": 998},
]
customer_funds_str = input("Vui lòng nhập số tiền bạn có: ")
try:
customer_funds = int(customer_funds_str)
except ValueError:
print("Số tiền nhập vào không hợp lệ. Vui lòng nhập một số.")
exit()
purchased_items = []
while True:
print("\n--- Danh Sách Sản Phẩm ---")
for index, product in enumerate(available_products, 1):
print(f"{index}. {product['name']} - Giá: {product['price']} VND")
print("--------------------------")
print("Nhập 'thoat' để kết thúc mua sắm.")
user_choice_input = input("Nhập số sản phẩm bạn muốn mua (hoặc 'thoat'): ").lower()
if user_choice_input == 'thoat':
print("\nCảm ơn bạn đã mua sắm!")
break
try:
selected_product_index = int(user_choice_input)
if 1 <= selected_product_index <= len(available_products):
chosen_product = available_products[selected_product_index - 1]
product_name = chosen_product['name']
product_price = chosen_product['price']
if customer_funds >= product_price:
customer_funds -= product_price
purchased_items.append(product_name)
print(f"Đã mua '{product_name}' thành công. Số dư còn lại: {customer_funds} VND")
else:
print(f"Số dư tài khoản không đủ để mua '{product_name}'. Bạn cần thêm {product_price - customer_funds} VND.")
print("Kết thúc phiên mua sắm do không đủ tiền.")
break # Dừng mua sắm nếu không đủ tiền cho sản phẩm đã chọn
else:
print("Lựa chọn không hợp lệ. Vui lòng nhập số thứ tự sản phẩm đúng.")
except ValueError:
print("Đầu vào không hợp lệ. Vui lòng nhập số hoặc 'thoat'.")
if purchased_items:
print("\n--- Các Sản Phẩm Đã Mua ---")
for item in purchased_items:
print(f"- {item}")
else:
print("\nBạn chưa mua sản phẩm nào.")
print(f"Số dư cuối cùng của bạn: {customer_funds} VND")