Bài 10 – Hàm (Function) Trong Python

Giới thiệu: Hàm (function) là một khối mã được đặt tên, thực hiện một nhiệm vụ cụ thể. Sử dụng hàm giúp chương trình trở nên rõ ràng, dễ bảo trì và tái sử dụng mã nguồn. Bài học này cung cấp kiến thức toàn diện về cách định nghĩa và sử dụng hàm trong Python.

Mục tiêu bài học:
– Hiểu khái niệm và lợi ích của việc sử dụng hàm
– Biết cách định nghĩa và gọi hàm trong Python
– Phân biệt được tham số và đối số
– Sử dụng được giá trị trả về của hàm
– Áp dụng các loại tham số: mặc định, từ khóa, biến động
– Hiểu về phạm vi biến (scope) trong hàm


1. Khái Niệm Và Lợi Ích Của Hàm

Định nghĩa: Hàm là một khối mã thực hiện một tác vụ cụ thể, có thể được gọi nhiều lần từ các phần khác nhau của chương trình.

Lợi ích:

  • Tái sử dụng mã: Tránh lặp lại cùng một đoạn mã nhiều lần
  • Tổ chức mã: Chia chương trình thành các phần nhỏ, dễ quản lý
  • Dễ bảo trì: Thay đổi ở một chỗ ảnh hưởng đến mọi nơi sử dụng hàm
  • Trừu tượng hóa: Ẩn đi độ phức tạp, chỉ cần biết cách sử dụng

2. Định Nghĩa Và Gọi Hàm

Cú pháp định nghĩa hàm:

def ten_ham(tham_so1, tham_so2, ...):
    """Chuỗi mô tả hàm (docstring)"""
    # Khối lệnh thực hiện công việc
    return gia_tri_tra_ve

Ví dụ 2.1: Hàm đơn giản không tham số

def chao_hoi():
    """Hàm in lời chào"""
    print("Xin chào! Chào mừng đến với Python")

# Gọi hàm
chao_hoi()

Ví dụ 2.2: Hàm có tham số

def tinh_binh_phuong(so):
    """Tính bình phương của một số"""
    ket_qua = so ** 2
    return ket_qua

# Gọi hàm
x = tinh_binh_phuong(5)
print(f"Bình phương của 5 là: {x}")

3. Tham Số Và Đối Số

Tham số (parameter): Biến được định nghĩa trong khai báo hàm
Đối số (argument): Giá trị thực tế được truyền vào khi gọi hàm

Ví dụ 3.1: Tham số và đối số

def cong_so(a, b):  # a, b là tham số
    """Cộng hai số"""
    return a + b

ket_qua = cong_so(3, 5)  # 3, 5 là đối số
print(f"Kết quả: {ket_qua}")

4. Giá Trị Trả Về

Hàm có thể trả về giá trị bằng từ khóa return. Nếu không có return, hàm trả về None.

Ví dụ 4.1: Hàm trả về giá trị

def kiem_tra_chan_le(so):
    """Kiểm tra số chẵn hay lẻ"""
    if so % 2 == 0:
        return "chẵn"
    else:
        return "lẻ"

loai_so = kiem_tra_chan_le(7)
print(f"Số 7 là số {loai_so}")

Ví dụ 4.2: Hàm trả về nhiều giá trị

def tinh_toan(a, b):
    """Thực hiện nhiều phép tính"""
    tong = a + b
    hieu = a - b
    tich = a * b
    return tong, hieu, tich

t, h, ti = tinh_toan(10, 5)
print(f"Tổng: {t}, Hiệu: {h}, Tích: {ti}")

5. Các Loại Tham Số

A. Tham số mặc định (default parameters)

def gioi_thieu(ten, tuoi, quoc_tich="Việt Nam"):
    """Hàm với tham số mặc định"""
    print(f"Tôi tên {ten}, {tuoi} tuổi, quốc tịch {quoc_tich}")

gioi_thieu("An", 20)           # Sử dụng giá trị mặc định
gioi_thieu("Bob", 25, "Mỹ")    # Ghi đè giá trị mặc định

B. Tham số từ khóa (keyword arguments)

def tao_ho_ten(ho, ten_dem, ten):
    """Tạo họ tên đầy đủ"""
    return f"{ho} {ten_dem} {ten}"

# Truyền tham số theo tên
ho_ten = tao_ho_ten(ten="An", ho="Nguyễn", ten_dem="Văn")
print(ho_ten)  # Nguyễn Văn An

C. Tham số biến động (arbitrary arguments)

def tinh_tong(*cac_so):
    """Tính tổng nhiều số"""
    tong = 0
    for so in cac_so:
        tong += so
    return tong

print(tinh_tong(1, 2, 3))        # 6
print(tinh_tong(1, 2, 3, 4, 5))  # 15

6. Phạm Vi Biến (Variable Scope)

Biến cục bộ (local): Chỉ tồn tại trong hàm
Biến toàn cục (global): Tồn tại trong toàn bộ chương trình

Ví dụ 6.1: Biến cục bộ và toàn cục

bien_toan_cuc = 10  # Biến toàn cục

def ham_demo():
    bien_cuc_bo = 5  # Biến cục bộ
    print(f"Biến cục bộ: {bien_cuc_bo}")
    print(f"Biến toàn cục: {bien_toan_cuc}")

ham_demo()
# print(bien_cuc_bo)  # Lỗi: bien_cuc_bo không tồn tại ở ngoài hàm

Ví dụ 6.2: Sử dụng từ khóa global

dem = 0

def tang_dem():
    global dem  # Khai báo sử dụng biến toàn cục
    dem += 1

tang_dem()
print(f"Đếm: {dem}")  # 1

7. Hàm Có Sẵn Trong Python

Python có nhiều hàm được tích hợp sẵn. Dưới đây là các hàm thông dụng:

Bảng các hàm cơ bản:

Tên hàmChức năngĐầu vàoĐầu raVí dụ
print()In ra màn hìnhGiá trị cần inKhông cóprint("Hello")
input()Nhập từ bàn phímChuỗi hướng dẫnChuỗi nhậpinput("Nhập: ")
len()Đếm số phần tửChuỗi/List/TupleSố nguyênlen("abc") → 3
int()Chuyển thành số nguyênChuỗi/Số thựcSố nguyênint("123") → 123
float()Chuyển thành số thựcChuỗi/Số nguyênSố thựcfloat("3.14") → 3.14
str()Chuyển thành chuỗiBất kỳ kiểu nàoChuỗistr(100) → "100"
type()Kiểm tra kiểu dữ liệuBiến/giá trịKiểu dữ liệutype(5) → <class 'int'>
abs()Giá trị tuyệt đốiSố nguyên/thựcSố không âmabs(-10) → 10
max()Tìm giá trị lớn nhấtNhiều số/ListGiá trị lớn nhấtmax(5, 2, 8) → 8
min()Tìm giá trị nhỏ nhấtNhiều số/ListGiá trị nhỏ nhấtmin(5, 2, 8) → 2
sum()Tính tổngList/Tuple sốTổngsum([1,2,3]) → 6
round()Làm tròn sốSố thực, số chữ sốSố làm trònround(3.14159, 2) → 3.14
sorted()Sắp xếp danh sáchList/TupleList đã sắp xếpsorted([3,1,2]) → [1,2,3]

Ví dụ 7.1 sử dụng:

# Nhập và in thông tin
ten = input("Nhập tên của bạn: ")
print("Xin chào", ten)

# Tính toán cơ bản
numbers = [10, 20, 30, 40]
print("Số phần tử:", len(numbers))
print("Tổng:", sum(numbers))
print("Số lớn nhất:", max(numbers))

# Chuyển đổi kiểu
so = int("100") + 50  # "100" → 100, rồi + 50
print("Kết quả:", so)

8. Module Math – Toán Học Nâng Cao

Module là gì? Module là tập hợp các hàm, biến có sẵn, được nhóm theo chức năng.

Tham khảo chi tiết tại Bài 13: https://tiilaz.com/lap-trinh-python/lap-trinh-python-co-ban/bai-13-module-va-package-trong-python/

Để dùng, ta cần import module đó.

Ví dụ, Sử dụng module math:

import math  # Khai báo sử dụng module math

Bảng các hàm trong module math:

Tên hàmChức năngĐầu vàoĐầu raVí dụ
math.sqrt()Căn bậc haiSố không âmSố thựcmath.sqrt(25) → 5.0
math.pow()Lũy thừaHai số (x, y)x^y (số thực)math.pow(2, 3) → 8.0
math.ceil()Làm tròn lênSố thựcSố nguyênmath.ceil(4.2) → 5
math.floor()Làm tròn xuốngSố thựcSố nguyênmath.floor(4.9) → 4
math.fabs()Giá trị tuyệt đốiSố thựcSố thực không âmmath.fabs(-4.5) → 4.5
math.piHằng số PiKhông có3.14159…math.pi → 3.141592...
math.sin()Sin của góc (radian)Số thực (rad)Sinmath.sin(math.pi/2) → 1.0
math.cos()Cos của góc (radian)Số thực (rad)Cosmath.cos(0) → 1.0
math.tan()Tan của góc (radian)Số thực (rad)Tanmath.tan(math.pi/4) → 1.0
math.degrees()Đổi radian → độSố radianSố độmath.degrees(math.pi) → 180.0
math.radians()Đổi độ → radianSố độSố radianmath.radians(180) → 3.14159...

Ví dụ 8.1 sử dụng:

import math

# Tính toán hình học
ban_kinh = 5
dien_tich = math.pi * math.pow(ban_kinh, 2)
print(f"Diện tích hình tròn bán kính {ban_kinh}: {dien_tich:.2f}")

# Làm tròn số
so = 4.7
print(f"Làm tròn lên: {math.ceil(so)}")   # 5
print(f"Làm tròn xuống: {math.floor(so)}") # 4

# Giải phương trình bậc 2 đơn giản
a, b, c = 1, -3, 2
delta = math.pow(b, 2) - 4*a*c
if delta >= 0:
    x1 = (-b + math.sqrt(delta)) / (2*a)
    x2 = (-b - math.sqrt(delta)) / (2*a)
    print(f"Nghiệm: x1 = {x1}, x2 = {x2}")

9. Hàm Lambda (Anonymous Function)

Hàm lambda là hàm ẩn danh, được định nghĩa bằng từ khóa lambda.

Cú pháp:  lambda tham_so: bieu_thuc

Ví dụ 9.1: Hàm lambda cơ bản

binh_phuong = lambda x: x ** 2
print(binh_phuong(5))  # 25

cong = lambda a, b: a + b
print(cong(3, 7))     # 10

Ví dụ 9.2: Sử dụng với map() và filter()

so = [1, 2, 3, 4, 5]

# Sử dụng map() với lambda
so_binh_phuong = list(map(lambda x: x ** 2, so))
print(so_binh_phuong)  # [1, 4, 9, 16, 25]

# Sử dụng filter() với lambda
so_chan = list(filter(lambda x: x % 2 == 0, so))
print(so_chan)         # [2, 4]

Bài Tập Thực Hành (Tự Giải)

Bài 1: Viết hàm tính giai thừa của một số nguyên dương

Bài 2: Viết hàm tìm số lớn nhất và số nhỏ nhất của 3 số a, b,c

Bài 3: Viết hàm kiểm tra số nguyên tố

Bài 4: Viết hàm chuyển đổi nhiệt độ từ Celsius sang Fahrenheit

Bài 5: Viết hàm tính chỉ số BMI và phân loại

Bài 5: Viết hàm đếm số từ trong một chuỗi

Bài 6: Viết hàm tìm ước chung lớn nhất (UCLN) của hai số

Bài 7: Viết hàm tính tổng các số chẵn trong một list

Bài 8: Viết hàm mã hóa chuỗi bằng cách dịch chuyển ký tự đi k vị trí (vòng tròn)

Bài 9: Viết hàm giải phương trình bậc 2

Lưu Ý Quan Trọng

  1. Đặt tên hàm rõ ràng: Sử dụng động từ hoặc cụm động từ mô tả chức năng
  2. Docstring: Luôn thêm chuỗi mô tả cho hàm
  3. Một chức năng: Mỗi hàm chỉ nên thực hiện một nhiệm vụ cụ thể
  4. Tránh side effect: Hàm nên hạn chế thay đổi biến toàn cục
  5. Kiểm tra đầu vào: Xác thực tham số đầu vào của hàm

Tóm Tắt

  • Hàm giúp tổ chức mã nguồn và tái sử dụng
  • Định nghĩa hàm bằng từ khóa def
  • Tham số và đối số truyền dữ liệu vào hàm
  • Giá trị trả về sử dụng từ khóa return
  • Các loại tham số: mặc định, từ khóa, biến động
  • Phạm vi biến: cục bộ và toàn cục
  • Hàm lambda: hàm ẩn danh cho tác vụ đơn giản

Comments are closed.