Chương 5: Câu lệnh điều kiện và đệ quy

Trở về Mục lục cuốn sách

5.1 Toán tử chia dư

Toán tử chia dư tính với các số nguyên và cho kết quả là phần dư của phép chia số thứ nhất cho số thứ hai. Trong Python, toán tử chia dư có kí hiệu là dấu phần trăm (%). Cú pháp cũng giống như các toán tử khác:

>>> thuong = 7 / 3
>>> print thuong
2
>>> sodu = 7 % 3
>>> print sodu
1

Như vậy 7 chia cho 3 bằng 2 dư 1.

Toán tử số dư bất ngờ trở nên có ích. Chẳng hạn, bạn có thể kiểm tra xem một số có chia hết cho số khác không—nếu x % y bằng không thì x chia hết cho y.

Hơn nữa, bạn còn có thể lọc ra những chữ số cuối cùng bên phải từ số ban đầu. Chẳng hạn, x % 10 cho ta số hàng đơn vị của x (trong hệ thập phân). Tương tự, x % 100 cho ta hai chữ số hàng chục và đơn vị.

5.2 Biểu thức Boole

Một biểu thức Boole là một biểu thức có giá trị đúng hoặc sai. Các ví dụ sau đây dùng toán tử ==, để so sánh hai toán hạng và trả lại kết quả True (đúng) nếu chúng bằng nhau và False (sai) trong trường hợp còn lại:

>>> 5 == 5
True

>>> 5 == 6
False

TrueFalse là các giá trị đặc biệt thuộc về kiểu bool; chúng không phải là các chuỗi:

>>> type(True)
<type 'bool'>
>>> type(False)

<type 'bool'>

Toán tử == là một trong số các toán tử quan hệ; các toán tử quan hệ khác gồm có:

      x != y               # x không bằng y
      x > y                # x lớn hơn y
      x < y                # x nhỏ hơn y
      x >= y               # x lớn hơn hoặc bằng y
      x <= y               # x nhỏ hơn hoặc bằng y

Mặc dù có thể bạn đã quen thuộc với các toán tử này, song thực ra các kí hiệu Python khác với kí hiệu toán học. Một lỗi phổ biến là dùng nhầm một dấu bằng (=) thay vì viết hai dấu bằng (==). Nhớ lại rằng = là một toán tử gán, còn == là một toán tử quan hệ. Ngoài ra không có toán tử nào được viết là =< hoặc =>.

5.3 Toán tử lô-gic

Có ba toán tử lô-gic: and, or, và not. Nghĩa của các toán tử này giống như nghĩa các từ tương ứng trong tiếng Anh. Chẳng hạn, x > 0 and x < 10 chỉ đúng khi x lớn hơn 0 nhở hơn 10.

n%2 == 0 or n%3 == 0 chỉ đúng khi một trong hai điều kiện là đúng; nghĩa là nếu số n chia hết cho 2 hoặc 3.

Sau cùng, toán tử not phủ định một biểu thức Boole. Do vậy not (x > y) chỉ đúng khi x > y là sai; tức là nếu x nhỏ hơn hoặc bằng y.

Nói một cách chặt chẽ, các toán hạng đi theo toán tử lô-gic phải là các biểu thức Boole, nhưng Python thì không chặt chẽ vậy. Bất kì con số nào khác không đều được coi như True.

>>> 17 and True
True

Sự linh hoạt này có thể có lợi, nhưng có một số điểm bất lợi nhỏ khiến người dùng nhầm lẫn. Có thể bạn muốn tránh dùng nó (trừ khi bạn biết chắc rằng mình đang làm gì).

5.4 Thực hiện lệnh theo điều kiện

Để viết được những chương trình thực sự, chúng ta thường cần đến khả năng kiểm tra những điều kiện nhất định và thay đổi biểu hiện tương ứng của chương trình. Các câu lệnh điều kiện cung cấp cho ta khả năng này. Dạng đơn giản nhất là lệnh if:

if x > 0:
    print 'x là số dương'

Biểu thức Boole ở cuối lệnh if được gọi là điều kiện. Nếu nó được thoả mãn thì đoạn lệnh bên trong được thực thi. Nếu không, sẽ chẳng có điều gì xảy ra.

Các lệnh if có cùng cấu trúc với các định nghĩa hàm: chúng gồm có một phần đầu và tiếp theo là một lệnh bên trong được viết thụt vào so với lề. Các câu lệnh kiểu như vậy được gọi là lệnh phức hợp.

Không có quy định về giới hạn tối đa số câu lệnh ở trong phần thân, nhưng ít nhất phải có một lệnh. Đôi khi ta cần có phần thân mà không chứa một lệnh thực sự nào (thường là chỉ để giữ chỗ cho mã lệnh sau này được viết thêm vào). Trong trường hợp đó, bạn có thể dùng lệnh pass để chỉ định “không làm gì cả”.

if x < 0:
    pass          # cần phải xử lý giá trị âm!

5.5 Thực hiện lệnh theo lựa chọn

Dạng thứ hai của lệnh if giúp cho việc thực hiện lệnh theo lựa chọn, trong đó có hai khả năng và điều kiện được đặt ra để căn cứ vào đó mà lựa chọn thực hiện một trong hai. Cú pháp có dạng như sau:

if x%2 == 0:
    print 'x là số chẵn'
else:
    print 'x là số lẻ'

Nếu phần dư của phép chia x cho 2 là 0, thì chúng ta biết rằng x là số chẵn, và chương trình sẽ hiển thị thông báo điều này. Nếu điều kiện không được thoả mã thì lệnh thứ hai sẽ được thực hiện. Vì điều kiện hoặc là được thoả mãn, hoặc không; nên luôn chỉ có một trong hai phương án được thực hiện. Các phương án này được gọi là nhánh, vì chúng là các nhánh rẽ trong luồng thực thi.

5.6 Các điều kiện xâu chuỗi

Đôi khi có nhiều hơn hai khả năng và ta cần nhiều nhánh. Một cách thể hiện quy trình tính toán là dùng các điều kiện xâu chuỗi:

if x < y:
    print 'x nhỏ hơn  y'
elif x > y:
    print 'x lớn hơn y'
else:
    print 'x bằng y'

elif là chữ viết tắt của “else if”. Một lần nữa, chỉ có đúng một nhánh được thực hiện. Không có giới hạn trên cho số các lệnh elif. Nếu có một vế else, thì nó phải đứng cuối cùng. Nhưng không nhất thiết cần có vế này.

if choice == 'a':
    draw_a()
elif choice == 'b':
    draw_b()
elif choice == 'c':
    draw_c()

Mỗi điều kiện được kiểm tra lần lượt. Nếu điều kiện thứ nhất sai, điều kiện tiếp theo sẽ được kiểm tra, và cứ như vậy. Nếu mộ ttrong các điều kiện đúng thì nhánh tương ứng được thực hiện; và cả câu lệnh lớn sẽ kết thúc. Ngay cả khi có nhiều hơn một điều kiện được thoả mãn, chỉ có nhánh đúng đầu tiên được thực hiện.

5.7 Các lệnh điều kiện lồng ghép

Một câu lệnh điều kiện có thể được đặt trong một lệnh điều khác. Ta có thể viết lại ví dụ so sánh ba trường hợp như sau:

if x == y:
    print 'x bằng y'
else:
    if x < y:
        print 'x nhỏ hơn y'
    else:
        print 'x lớn hơn y'

Câu lệnh điều kiện bên ngoài có hai nhánh. Nhánh thứ nhất chỉ chứa một lệnh đơn giản. Nhánh thứ hai lại chứa một câu lệnh if khác, mà bản thân nó lại có hai nhánh. Hai nhánh này đều chứa những câu lệnh đơn giản, mặc dù dĩ nhiên chúng có thể là những câu lệnh điều kiện khác.

Tuy cách viết thụt vào trong làm cho cấu trúc rõ ý, nhưng các lệnh điều kiện lồng ghép trở nên rất khó để người đọc nhanh. Nhìn chung, tốt hơn là ta nên cố gắng tránh dùng chúng.

Các toán tử lô-gic thường cho ta cách đơn giản hoá các câu lệnh điều kiện lồng ghép. Chẳng hạn, ta có thể viết lại mã lệnh sau bằng một lệnh điều kiện đơn:

if 0 < x:
    if x < 10:
        print 'x là số dương có một chữ số.'

Lệnh print chỉ được thực hiện một lần nếu ta làm cho nó qua cả hai điều kiện, vì vậy đoạn lệnh sau với toán tử and cũng có tác dụng tương tự:

if 0 < x and x < 10:
    print 'x là số dương có một chữ số.'

5.8 Đệ quy

Việc một hàm gọi một hàm khác là hợp lệ; một hàm gọi chính nó cũng hợp lệ. Mặc dù bề ngoài thì có thể điều này không rõ hay dở ra sao, nhưng thực ra đó chính là một trong những đặc điểm tuyệt vời nhất trong lập trình. Chẳng hạn, hãy xét hàm sau:

def countdown(n):
    if n <= 0:
        print 'Bùm!'
    else:
        print n
        countdown(n-1)

Nếu n bằng 0 hoặc âm, chương trình sẽ in ra chữ, “Bùm!” Còn nếu không, nó sẽ in ra giá trị n và sau đó gọi một hàm có tên countdown—nghĩa là chính nó—nhưng chuyển vào đối số n-1.

Điều gì sẽ xảy ra khi ta gọi hàm kiểu như thế này?

>>> countdown(3)

Việc thực hiện countdown bắt đầu với n=3, và do n lớn hơn 0, nó đưa ra giá trị 3, và rồi gọi chính nó…

Việc thực hiện countdown bắt đầu với n=2, và do n lớn hơn 0, nó đưa ra giá trị 2, và rồi gọi chính nó…

Việc thực hiện countdown bắt đầu với n=1, và do n lớn hơn 0, nó đưa ra giá trị 1, và rồi gọi chính nó…

Việc thực hiện countdown bắt đầu với n=0, và do n không còn lớn hơn 0, nó đưa ra dòng chữ “Bùm!” và rồi quay về.

Hàm countdown ứng với n=1 quay về.

Hàm countdown ứng với n=2 quay về.

Hàm countdown ứng với n=3 quay về.

Và rồi bạn trở về với __main__. Như vậy, toàn bộ kết quả đầu ra như sau:

3
2
1
Bùm!

Một hàm gọi chính nó được gọi tên là đệ quy; quy trình tương ứng cũng được gọi là đệ quy.

Với ví dụ tiếp theo đây, ta viết một hàm để in một chuỗi n lần.

def print_n(s, n):
    if n <= 0:
        return
    print s
    print_n(s, n-1)

Nếu n <= 0 thì câu lệnh return sẽ kết thúc hàm ngay. Luồng thực hiện của chương trình sẽ lập tức trở về với nơi gọi nó, và phần còn lại của hàm sẽ không được thực hiện.

Phần còn lại của hàm cũng giống như countdown: nếu n lớn hơn 0, nó sẽ hiển thị s và sau đó sẽ gọi chính nó để in lại s thêm n - 1 lần nữa. Như vậy số dòng kết quả sẽ là 1 + (n - 1), tức là bằng n.

Với những ví dụ đơn giản như trên, có thể sẽ dễ hơn nếu ta dùng một vòng lặp for. Nhưng sau này ta sẽ gặp những ví dụ mà ở đó rất khó viết một vòng lặp for còn viết bằng đệ quy sẽ dễ hơn, vì vậy việc làm quen với đệ quy từ sớm là rất tốt.

5.9 Biểu đồ ngăn xếp cho các hàm đệ quy

Trong Mục {Biểu đồ ngăn xếp}, chúng ta đã dùng một biểu đồ ngăn xếp để biểu thị trạng thái của một chương trình trong quá trình hàm được gọi. Loại biểu đồ này cũng có thể được dùng để diễn giải hàm đệ quy.

Mỗi khi hàm được gọi, Python tạo ra một “khung” mới cho hàm, trong đó có chứa các biến cục bộ và tham số của hàm. Đối với hàm đệ quy, có thể cùng một thời điểm trên ngăn xếp sẽ tồn tại nhiều khung hàm.

Hình vẽ này minh hoạ một sơ đồ ngăn xếp cho hàm countdown khi gọi với n = 3:

ngăn xếp

Như thường lệ, đỉnh của ngăn xếp là một khung cho __main__. Nó trống không vì ta không tạo ra bất cứ biến nào trong __main__ hay chuyển đối số nào cho nó.

Bốn khung countdown có các giá trị khác nhau cho tham biến n. Đáy của ngăn xếp, ở đó n=0, được gọi là trường hợp cơ sở. Nó không thực hiện lời gọi đệ quy, do đó không có thêm khung nào.

Hãy vẽ một biểu đồ ngăn xếp cho print_n được gọi với s = 'Xin chào'n=2.

Viết một hàm có tên do_n trong đó nhận một đối tượng hàm và một số, n, làm hai tham biến, để gọi hàm được chỉ định đúng n lần.

5.10 Đệ quy vô hạn

Nếu một quá trình đệ quy không bao giờ đạt đến trường hợp cơ bản, nó tiếp tục thực hiện gọi hàm đệ quy mãi mãi, và chương trình không bao giờ kết thúc. Đây là đệ quy vô hạn, và là điều ta thường tránh khi lập trình. Sau đây là một chương trình đơn giản nhất có đệ quy vô hạn:

def recurse():
    recurse()

Trong phần lớn các ngôn ngữ lập trình, một chương trình có đệ quy vô hạn sẽ không chạy mãi mãi. Python thông báo một lỗi khi chương trình đạt đến mức độ sâu đệ quy tối đa:

  File "<stdin>", line 2, in recurse
  File "<stdin>", line 2, in recurse
  File "<stdin>", line 2, in recurse
                  .   
                  .
                  .
  File "<stdin>", line 2, in recurse
RuntimeError: Maximum recursion depth exceeded

Lần này kết quả lần vết ngược lớn hơn một chút so với ở chương trước. Khi một lỗi xảy ra, có 1000 khung hàm recurse trên ngăn xếp!

5.11 Đầu vào từ bàn phím

Cho đến giờ, các chương trình ta đã viết có phần khuyết điểm ở chỗ không cho người dùng nhập số liệu vào. Lần nào chương trình cũng chạy y nguyên như thế.

Python cung cấp một hàm có sẵn, tên là raw_input nhằm thu thập đầu vào từ bàn phím1. Khi hàm này được gọi, chương trình tạm dừng và chờ người dùng nhập thông tin từ bàn phím. Đến khi người dùng gõ phím {Return} hoặc {Enter}, chương trình chạy tiếp và raw_input trả lại những gì người dùng đã gõ vào dưới dạng một chuỗi kí tự.

>>> input = raw_input()
Bạn đang chờ đợi gì?
>>> print input
Bạn đang chờ đợi gì?

Trước khi nhận thông tin từ người dùng, có thể sẽ tốt hơn nếu ta in ra một lời nhắc để cho người dùng biết cần nhập vào điều gì. raw_input có thể nhận lời nhắc như là một đối số:

>>> name = raw_input('Tên bạn là gì?\n')
Tên bạn là gì?
Arthur, Vua xứ Britons!
>>> print name
Arthur, Vua xứ Britons!

Chuỗi \n ở cuối lời nhắc trên đại diện cho một newline (dòng mới), vốn là một kí tự đặc biệt để ngắt dòng. Điều này giải thích tại sao dòng chữ người dùng nhập vào lại xuất hiện phía dưới lời nhắc.

Nếu bạn trông đợi người dùng nhập vào một số nguyên, hãy thử chuyển đổi giá trị thu được sang kiểu int:

>>> prompt = 'Một con chim én không mang gì có thể bay nhanh bao nhiêu?\n'
>>> speed = raw_input(prompt)
Một con chim én không mang gì có thể bay nhanh bao nhiêu?
17
>>> int(speed)
17

Nhưng nếu người dùng nhập vào những thứ khác một chuỗi những chữ số thì có thể sẽ nhận được thông báo lỗi:

>>> speed = raw_input(prompt)
Một con chim én không mang gì có thể bay nhanh bao nhiêu?
Ý của bạn là sao, một con én châu Phi hay châu Âu?
>>> int(speed)
ValueError: invalid literal for int()

Trong các phần sau chúng ta sẽ xem xét cách khắc phục lỗi này.

5.12 Gỡ lỗi

Mỗi khi có lỗi, công cụ lần vết ngược trong Python hiển thị rất nhiều thông tin; có thể sẽ quá nhiều đối với người dùng, đặc biệt là khi có nhiều khung trên ngăn xếp. Thường những phần quan trọng nhất cần biết là:

  • Lỗi này thuộc loại gì, và
  • Nó xuất hiện ở đâu?

Các lỗi cú pháp thường dễ tìm, nhưng cũng có vài chỗ gây bất ngờ. Các lỗi liên quan đến khoảng trắng có thể sẽ khó phát hiện vì trên cửa sổ soạn thảo các dầu cách và dấu tab đều có thể lẫn với nhau.

>>> x = 5

>>>  y = 6
  File "<stdin>", line 1
    y = 6
    ^
SyntaxError: invalid syntax

Ở ví dụ này, sự phiền phức là ở chỗ dòng thứ hai được viết thụt vào một dấu cách. Nhưng thông báo lỗi lại chỉ đến y; điều này dễ gây ngộ nhận. Nói chung, các thông báo lỗi đều chỉ ra trục trặc được phát hiện ở đâu, nhưng lỗi thực sự lại có thể nằm ở trước đó trong đoạn mã lệnh, đôi khi là ở dòng ngay trước đó.

Điều tương tự cũng đúng với các lỗi runtime (lỗi trong lúc chạy). Chẳng hạn bạn đang thử tính tỉ số tín hiệu so với nhiễu động theo đơn vị đề-xi-ben. Công thức là SNRdb = 10log10(Psignal / Pnoise). Trong Python, bạn có thể viết một đoạn mã giống như sau:

import math
signal_power = 9
noise_power = 10
ratio = signal_power / noise_power
decibels = 10 * math.log10(ratio)
print decibels

Nhưng khi chạy nó, bạn lại nhận được thông báo lỗi2:

Traceback (most recent call last):
  File "snr.py", line 5, in ?
    decibels = 10 * math.log10(ratio)
OverflowError: math range error

Thông báo lỗi chỉ ra dòng thứ 5, nhưng bản thân dòng đó không có gì sai. Để tìm lỗi thực sự, có thể bạn cần phải in ra giá trị của ratio, hoá ra nó bằng 0. Vậy trục trặc xảy ra ở dòng 4, vì việc chia hai số tự nhiên là theo phép chia nguyên bỏ phần dư. Giải pháp khắc phục điều này là biểu thị cả công suất tín hiệu và công suất nhiễu động dưới dạng các giá trị số thập phân (dấu phẩy động).

Nói chung, các thông báo lỗi sẽ cho bạn biết trục trặc được phát hiện ở đâu, nhưng thường thì đó không phải là nguyên nhân gây ra lỗi.

5.13 Thuật ngữ

toán tử module:
Toán tử, kí hiệu là dấu phần trăm, (%), được dùng với các số nguyên và trả lại phần dư của phép chia hai số nguyên đó.
biểu thức Boole:
Biểu thức có giá trị là True (đúng) hoặc False (sai).
toán tử quan hệ:
Một trong các toán tử để so sánh các toán hạng của nó: ==, !=, >, <, >=, và <=.
toán tử lô-gic:
Một trong các toán tử để kết hợp các biểu thức Boole: and, or, và not.
câu lệnh điều kiện:
Câu lệnh để điều khiển dòng thực hiện chương trình tuỳ theo một điều kiện nào đó.
điêu kiện:
Biểu thức Boole trong một câu lệnh điều kiện để quyết định nhánh nào sẽ được thực hiện.
câu lệnh phức hợp:
Câu lệnh bao gồm một đoạn đầu và một phần thana. Đoạn đầu kết thúc bởi dấu hai chấm (:). Phần thân được viết thụt vào so với đoạn đầu.
phần thân:
Một loạt các câu lệnh ở trong một câu lệnh phức hợp.
nhánh:
Một trong số các phương án trong một câu lệnh điều kiện. Mỗi phương án có thể gồm một loạt các câu lệnh.
câu lệnh điều kiện xâu chuỗi:
Câu lệnh điều kiện với một chuỗi liên tiếp các nhánh phương án.
câu lệnh điều kiện lồng ghép:
Câu lệnh điều kiện xuất hiện bên trong của một trong số các nhánh của một câu lệnh điều kiện khác.
đệ quy:
Quá trình gọi hàm mà hiện thời đang được thực thi.
trường hợp cơ bản:
Nhánh điều kiện trong một hàm đệ quy mà bản thân không gọi đệ quy.
đệ quy vô hạn:
Đệ quy mà không có trường hợp cơ bản, hoặc không bao giờ đạt đên trường hợp cơ bản. Đệ quy vô hạn cuối cùng sẽ gây ra lỗi thực thi (runtime error).

5.14 Bài tập

Định lý cuối cùng của Fermat phát biểu rằng không có các số nguyên a, b, và c nào thoả mãn

an + bn = cn
với bất kì giá trị nào của n lớn hơn 2.

  1. Viết một hàm có tên là check_fermat nhận vào bốn tham số—a, b, cn—rồi kiểm tra xem có thoả mãn định lý Fermat không. Nếu n lớn hơn 2 và hoá raan + bn = cn
    thì chương trình sẽ in ra “Trời, Fermat đã lầm!” Còn nếu không thì chương trình sẽ in ra, “Không, vẫn không đúng”.
  2. Viết một hàm nhắc người dùng nhập vào các giá trị của Write a function that prompts the user to input values a, b, cn, chuyển chúng sang dạng số nguyên và dùng check_fermat để kiểm tra xem liệu chúng có vi phạm định lý Fermat hay không.

Nếu bạn có trong tay ba thanh thẳng, bạn có thể hoặc không thể xếp thành một hình tam giác. Chẳng hạn, nếu một thanh dài 30 cm và hai thanh kia chỉ đều chỉ dài 3 cm, rõ ràng là bạn không thể làm cho hai thanh ngắn nối với nhau được. Với ba thanh có độ dài bất kì, có một cách đơn giản để kiểm tra xem chúng có tạo nên hình tam giác được không.

“Nếu bất kì một độ dài nào lớn hơn tổng hai độ dài còn lại thì bạn không thể tạo thành tam giác. Ngược lại, bạn có thể. 3

  1. Viết một hàm có tên là is_triangle nhận vào ba tham số là các số nguyên, sau đó in ra “Yes” hoặc “No”, tuỳ theo bạn có thể hay không thể tạo thành hình tam giác từ ba thanh với các độ dài đó.
  2. Viết một hàm nhắc người dùng nhập vào độ dài ba thanh, chuyển thành dạng số nguyên, rồi dùng is_triangle để kiểm tra xem ba thanh với các độ dài đó có thể được xếp thành tam giác hay không.

Các bài tập tiếp theo đây dùng TurtleWorld từ Chương 4:

Hãy đọc hàm sau đây và thử xem bạn có thể hình dung được mục đích của nó không. Sau đó thì chạy nó (xem các ví dụ ở Chương 4).

def draw(t, length, n):
    if n == 0:
        return
    angle = 50
    fd(t, length*n)
    lt(t, angle)
    draw(t, length, n-1)
    rt(t, 2*angle)
    draw(t, length, n-1)
    lt(t, angle)
    bk(t, length*n)

Đường cong Koch là một hình phân mảnh (fractal) có dạng như hình sau:

đường cong koch

Để vẽ một đường cong Koch với độ dài x, tất cả những việc bạn cần làm là

  1. Vẽ một đường cong Koch với độ dài x / 3.
  2. Quay trái 60 độ.
  3. Vẽ một đường cong Koch với độ dài x / 3.
  4. Quay phải 120 độ.
  5. Vẽ một đường cong Koch với độ dài x / 3.
  6. Quay trái 60 độ.
  7. Vẽ một đường cong Koch với độ dài x / 3.

Ngoại lệ duy nhất là nếu x nhỏ hơn 3. Trong trường hợp đó, bạn chỉ cần vẽ một đoạn thẳng có độ dài x.

  1. Viết một hàm có tên là koch nhận vào các tham số là một Turtle và một độ dài, sau đó dùng Turtle để vẽ một đường cong Koch với độ dài cho trước đó.
  2. Viết một hàm có tên là snowflake để vẽ ba đường cong Koch nối thành hình một bông tuyết.Bạn có thể xem lời giải của tôi ở thinkpython.com/code/koch.py.
  3. Có một số cách khái quát hoá đường cong Koch. Hãy xem các ví dụ ở wikipedia.org/wiki/Koch_snowflake và viết mã lệnh cho ví dụ mà bạn thích.

  1. Trong Python 3.0, hàm này có tên là input.
  2. Với Python 3.0, bạn không còn phải nhận thông báo lỗi nữa; toán tử chia sẽ thực hiện phép chia với số có phần thập phân ngay cả khi các toán hạng là số nguyên.
  3. Nếu tổng hai độ dài bằng độ dài thứ ba thì chúng sẽ tạo ra một “tam giác suy biến”.
Advertisements

2 phản hồi

Filed under Sách, Think Python

2 responses to “Chương 5: Câu lệnh điều kiện và đệ quy

  1. Pingback: Think Python: Cách tư duy như nhà khoa học máy tính | Blog của Chiến

  2. Pingback: Phụ lục: Lumpy | Blog của Chiến

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s