Professional Documents
Culture Documents
Hồ Thanh Lam
Phạm Văn Toàn
Nguyễn Lương Chánh
Điểm
A. Tổng quan
được nhận giải thưởng FSF Award for the Advancement of Free
Software.
o Phiên bản 1.6.1 ra đời sau đó là phiên bản đâu tiền tuân theo bản
quyền GPL. Tuy nhiên, bản này hoàn toàn giống bản 1.6, trừ một số
sửa lỗi cần thiết.
• Python 2: vào năm 2000, Guido và nhóm phát triển Python dời đến
BeOpen.com và thành lập BeOpen PythonLabs team. Phiên bản Python 2.0
được phát hành tại đây. Sau khi phát hành Python 2.0, Guido và các thành
viên PythonLabs gia nhập Digital Creations.
o Python 2.1 ra đời kế thừa từ Python 1.6.1 và Python 2.0. Bản quyền
của phiên bản này được đổi thành Python Software Foundation
License. Từ thời điểm này trở đi, Python thuộc sở hữu của Python
Software Foundation (PSF), một tổ chức phi lợi nhuận được thành
lập theo mẫu Apache Software Foundation.
• Python 3: Về sự phát triển của Python trong tương lai, các nhà phát triển
vẫn đang thảo luận về phiên bản mới: Python 3.0 (dự án gọi là Python 3000
hoặc Py3K). Dự kiến, dòng 3.x sẽ không hoàn toàn tương thích với dòng
2.x. Nhóm phát triển cho biết sẽ lấp những chỗ hở của ngôn ngữ. Nguyên
tắc chủ đạo để phát triển Python 3.x là "bỏ cách làm việc cũ nhằm hạn chế
trùng lặp về mặt chức năng của Python". Tuy nhiên, cho đến nay vẫn chưa
có kế hoạch cụ thể cho phát triển Python 3.
Python được thiết kế để trở thành một ngôn ngữ dễ học, mã nguồn dễ đọc,
bố cục trực quan, dễ hiểu, thể hiện qua các điểm sau:
1. Từ khoá:
Python tăng cường sử dụng từ khóa tiếng Anh, hạn chế các kí hiệu và cấu
trúc cú pháp so với các ngôn ngữ khác. Python là một ngôn ngữ phân biệt kiểu
chữ. Như C/C++, các từ khóa của Python đều ở dạng chữ thường. Dưới đây là hệ
thống từ khóa chuẩn:
and,del,from,not,while,as,elif,global,or,with,asser
t,else,if,pass,yield,break,except,import,print,clas
s,exec,in,raise,continue,finally,is,return,def,for,
lambda,try
2. Khối lệnh
Python, có một cách rất đặc biệt để tạo khối lệnh, đó là thụt các câu lệnh trong
khối vào sâu hơn (về bên phải) so với các câu lệnh của khối lệnh cha chứa nó.Ví
dụ giả sử có đoạn mã sau trong C/C++:
#include <math.h>
//...
delta = b * b – 4 * a * c;
if (delta > 0)
{
// Khối lệnh mới bắt đầu từ kí tự { đến }
x1 = (- b + sqrt(delta)) / (2 * a);
x2 = (- b - sqrt(delta)) / (2 * a);
printf("Phuong trinh co hai nghiem phan biet:\n");
printf("x1 = %f; x2 = %f", x1, x2);
}
Đoạn mã trên có thể được viết lại bằng Python như sau:
import math
#...
delta = b * b – 4 * a * c
if delta > 0:
# Khối lệnh mới, thụt vào đầu dòng
x1 = (- b + math.sqrt(delta)) / (2 * a)
x2 = (- b – math.sqrt(delta)) / (2 * a)
print "Phuong trinh co hai nghiem phan biet:"
print "x1 = ", x1, "; ", "x2 = ", x2
Ta có thể sử dụng tab hoặc khoảng trống để thụt các câu lệnh vào.
Python là một ngôn ngữ lập trình dạng thông dịch. Ưu điểm của thông dịch là giúp
ta tiết kiệm thời gian phát triển ứng dụng vì không cần phải thực hiện biên dịch và
liên kết. Trình thông dịch có thể được sử dụng để chạy file script, hoặc cũng có thể
được sử dụng một cách tương tác. Ở chế độ tương tác, trình thông dịch Python
tương tự shell của các hệ điều hành họ Unix, tại đó, ta có thể nhập vào một biểu
thức tại một thời điểm rồi enter, và kết quả thực thi sẽ được hiển thị ngay lập tức.
Đặc điểm này rất hữu ích cho người mới học, giúp họ nghiên cứu tính năng của
ngôn ngữ; hoặc để các lập trình viên chạy thử mã trong suốt quá trình phát triển
phần mềm. Ngoài ra, nó cũng có thể được sử dụng như là một máy tính.
8. Đa năng:
Python là một ngôn ngữ lập trình đơn giản nhưng rất hiệu quả. So với Unix shell,
Python hỗ trợ các chương trình lớn hơn và cung cấp nhiều cấu trúc hơn. So với C,
Python cung cấp nhiều cơ chế kiểm tra lỗi hơn. Vì các lí do đó, Python là một
ngôn ngữ lập trình cấp rất cao. Nó cũng có sẵn nhiều kiểu dữ liệu cấp cao, ví dụ
như các mảng linh hoạt (flexible arrays) ( ) và từ điển (dictionaries) mà ta phải mất
nhiều thời gian để hiện thực trên C. Python cũng thích hợp với các chương trình
lớn hơn cả Awk và Perl. Python cũng được sử dụng để lập trình Web. Nó có thể
được sử dụng như là một ngôn ngữ kịch bản. Python được thiết kế để có thể nhúng
và phục vụ như là một ngôn ngữ kịch bản để tuỳ biến và mở rộng các ứng dụng
lớn hơn. Được tích hợp sẵn nhiều công cụ và có một thư viện chuẩn phong phú,
Python cho phép người dùng dễ dàng tạo ra các dịch vụ Web, sử dụng các thành
phần COM hay CORBA ( ). Nó hỗ trợ các định dạng email, dữ liệu Internet,
HTML, XML và các ngôn ngữ đánh dấu khác. Python cũng ứng dụng tất cả các
giao thức Internet thông dụng như HTTP, FTP,… Python cung cấp giao tiếp đến
hầu hết cơ sở dữ liệu, có khả năng xử lí văn bản, tài liệu hiệu quả, và có thể làm
việc tốt với các công nghệ Web khác. Python cũng đặc biệt hiệu quả cho lập trình
tính toán khoa học qua các công cụ Python Imaging Library, VTK, MayaVi 3D
Visualization Toolkits, Numeric Python, ScientificPython,… Python cũng có thể
được sử dụng để phát triển các ứng dụng Desktop. Người dùng có thể dùng
wxPython, PyQt, PyGtk để phát triển các ứng dụng giao diện đồ họa (GUI) chất
lượng cao. Python có thể hỗ trợ các GUI frameworks khác như MFC, Carbon,
Delphi, X11, Motif, và Tk. Python cũng có sẵn một unit testing framework để tạo
ra các các bộ test (test suites).
Python là một ngôn ngữ đa biến hóa (multiple paradigms). Có nghĩa là, thay
vì ép buộc mọi người phải sử dụng duy nhất một phương pháp lập trình, Python lại
cho phép sử dụng nhiều phương pháp lập trình khác nhau: hướng đối tượng, có
cấu trúc, chức năng, hoặc chỉ hướng đến một khía cạnh. Python kiểu kiểu động và
sử dụng bộ thu gom rác để quản lí bộ nhớ. Một đặc điểm quan trọng nữa của
Python là giải pháp tên động, kết nối tên biến và tên phương thức lại với nhau
trong suốt thực thi của chương trình.
CPython
Đây là phiên bản đầu tiên và được duy trì lâu nhất của Python, được viết
trong C. Những đặc điểm của ngôn ngữ mới xuất hiện đầu tiên từ đây
Jython
Là phiên bản Python trong môi trường Java. Bản này có thể được sử dụng
như là một ngôn ngữ script cho những ứng dụng Java. Nó cũng thường
được sử dụng để tạo ra những tests thử nghiệm cho thư viện Java
IronPython
Là một bản Python tiếp theo của .NET, không giống như Python.NET đây
là một bản Python hoàn chỉnh, tạo ra IL, và biên dịch mã Python trực tiếp
vào một tập hợp .NET.
PyPy
PyPy được viết trên Python, thậm chí cả việc thông dịch từng byte mã cũng
được viết trên Python. Nó sử dụng Cpython như một trình thông dịch cơ sở.
Một trong những mục đích của dự án cho ra đời phiên bản này là để khuyến
khích sự thử nghiệm bản thân ngôn ngữ này làm cho nó dễ dàng hơn để sửa
đổi thông dịch (bởi vì nó được viết trên Python).
Do Python không có một cú pháp rõ ràng để định nghĩa biến mới, nên chỉ có thể
khai báo một biến bằng cách gán giá trị cụ thể cho nó. Biến sẽ tự động được giải
phóng khi ra khỏi phạm vi của chương trình sử dụng nó.Các ví dụ ở đây thì >>> là
dấu nhắc lệnh của trình thông dịch.
- Kiểu None: Kiểu này chỉ có 1 giá trị , sử dụng để diện tả sự vắng
mặt của giá trị trong nhiều trường hợp , ví dụ nó được trả về từ hàm mà đã xác
định trước sẽ không trả về gì. Giá trị thực của nó là false.
- Kiểu NotImplemented : Kiểu này chỉ có 1 giá trị , chỉ có 1 đối
tượng có giá trị này .Đối tượng được truy cập thông qua tên được xây dựng sẵn
NotImplemented. Các phương thức số học và so sánh có thể trả về kiểu giá
trị này nếu chúng chưa cài đặt hành động cho toán tử được cung cấp.Giá trị
thực của nó là true.
- Kiểu Ellipsis : Kiểu này cũng có giá trị 1 đơn , cũng chí có 1 đối
tượng có giá trị này . Đối tượng được truy cập thông qua tên được xây dựng
sẵn Ellipsis . Nó được sử dụng để chỉ ra sự hiện diện của cú pháp “….” . Giá
trị thực của nó là true.
- Kiểu Numbers: Được tạo ra bởi các kí tự số và trả về kết quả bởi
phép toán số học hoặc các hàm số học. Đối tượng numbers là bất biến, giá trị
của nó không thay đổi kể từ khi được tạo ra. Có những giới hạn về giá trịcủa
số trong máy tính.
- Kiểu chuỗi String , giá trị của string được đặt trong cặp dấu ‘ hoặc
“.
>>>a = ‘abcdefg’
>>>b = “12345678”
-> a[0] = ‘a ‘
b[1] = ‘2’
- Kiểu từ điển Dictionary - định nghĩa một quan hệ 1-1 giữa khoá và
giá trị , không thể có khoá trùng nhau trong từ điển.
Ví dụ khai báo một từ điển :
>>> d = {"server":"mpilgrim","database": "master"}
>>> d
{'server': 'mpilgrim', 'database': 'master'}
>>> d["server"]
'mpilgrim'
>>> d["database"]
'master'
>>> d["mpilgrim"]
Traceback (innermost last):
- Kiểu danh sách List – làm việc như là 1 mảng các đối tượng. Sau
đây là các phương thức của List:
• append(x): Thêm một thành phần vào cuối của danh sách, tương
đương với: a[len(a):] = [x].
• extend(L): Mở rộng danh sách bằng cách thêm tất cả các thành phần
trong danh sách đã nhận. Tương đương với a[len(a):] = L.
• insert(i,x): Chèn một phần tử vào một ví trí đã định. Đối số đầu tiên
i là chỉ sổ của phần tử trước chỗ sẽ chèn, vì thế a.insert(0, x) chèn tại vị trí
đầu của danh sách, và a.insert( len(a), x) tương đương với
a.append(x).
• remove(x): Loại bỏ phần tử đầu tiên trong danh sách mà có giá trị là
x.Nếu không có phần tử như vậy thì báo lỗi.
• pop([i]): Loại bỏ phần tử tại vị trí i trong danh sách, và trả về nó.
Nếu không xác định chỉ số, a.pop( ) sẽ loại bỏ và trả về phần tử cuối cùng
trong danh sách.
• index(x): Trả về chỉ số của phần tử có giá trị x đầu tiên danh sách.
Nếu không có phần tử như vậy sẽ xảy ra lỗi.
• count(x): Trả về số lần x xuất hiện trong danh sách.
• sort( ): Sắp xếp các thành phần của danh sách.
• reverse( ): Đảo ngược các phần tử trong danh sách.
tượng set cũng hỗ trợ các phép toán như: hợp, giao, hiệu, và hiệu đối xứng.
Dưới đây là một ví dụ:
>>> basket = ['apple', 'orange', 'apple', 'pear',
'orange', 'banana']
>>> fruit = set(basket) # create a set without
duplicates
>>> fruit
set(['orange', 'pear', 'apple', 'banana'])
>>> 'orange' in fruit # fast membership testing
True
>>> 'crabgrass' in fruit
False
>>> # Demonstrate set operations on unique letters
from two words
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters in both a and b
set(['a', 'c'])
>>> a ^ b # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])
II. Cú pháp và các cấu trúc lập trình cơ bản trong Python
1. Toán tử:
Python sử dụng các toán tử sau:
+ - * /
// (chia làm tròn)
% (phần dư)
** (lũy thừa)
~ (not)
& (and)
| (or)
^ (xor)
<< (left shift)
>> (right shift)
== (bằng)
<=
>=
!= (khác)
2. Chú thích
Trong Python để viết dòng chú thích ta sử dụng dấu #
# dòng chú thích
3. Lệnh gán
tên biến = biểu thức
x = 23.8
y = -x ** 2
z1 = z2 = x + y
loiChao = "Hello!"
i += 1 # tăng biến i thêm 1 đơn vị
4. In giá trị
print biểu thức
print (7 + 8) / 2.0
print (2 + 3j) * (4 - 6j)
Câu lệnh for trong Python khác một chút so với trong C hoặc Pascal. Lệnh for lặp
lại qua các thành phần của một chuỗi bất kì (như là list hoặc string), theo thứ tự
mà các thành phần đó xuất hiện trong chuỗi. Ví dụ:
Vì lí do sử dụng như trên cho nên sẽ không an toàn nếu ta sửa đổi một
chuỗi mà đang sử dụng để lặp ( điều này chỉ xảy ra với kiểu chuỗi khả biến).
Trong trường hợp cần thay đổi chuỗi ( ví dụ lặp lại những thành phần nào đó) thì
phải lặp qua một bản sao của chuỗi ban đầu. Chỉ cần dùng kí tự : để làm điều này:
b. Lệnh while:
while biểu_thức_đúng:
# lệnh ...
7. Hàm range( ):
Nếu cần lặp qua một chuỗi số, hàm range( ) có thể được sử dụng. Nó tạo
ra một danh sách chứa chuỗi các số học:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Điểm kết thúc đã cho không bao giờ là một phần của chuỗi sẽ tạo ra;
range(10) tạo ra một danh sách 10 giá trị,giống như chỉ số các thành phần của một
chuỗi chiều dài 10. Cũng có thể đặt cho range( ) vị trí bắt đầu, hoặc xác định một
bước tăng khác.
>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]
Để lặp qua chỉ số của một chuỗi, sử dụng kết hợp range( ) và len( ) như
dưới đây:
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print i, a[i]
...
0 Mary
1 had
2 a
3 little
4 lamb
8. Các câu lệnh break và continue, và mệnh đề else trong vòng lặp
Câu lệnh break, giống nhau C, nhảy ra khỏi vòng lặp ngay trước nó mà
chứa nó.
Câu lệnh continue, cũng kế thừa từ C, để tiếp tục thực hiện với giá trị lặp
tiếp theo của vòng lặp.
Ngoài ra, các câu lệnh lặp cũng có thể sử dụng mệnh đề else. Nó sẽ được
thực hiện khi vòng lặp kết thúc ( đến cuối của danh sách với for, hoặc khi gặp điều
kiện sai với while ), nhưng không được thực hiện khi vòng lặp kết thúc bằng lệnh
break. Xem xét ví dụ dưới đây để tìm số nguyên tố:
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
9. Lệnh pass
Câu lệnh pass không chứa gì thêm ngoài từ khóa. Nó có thể được sử dụng
khi một lệnh được chờ đợi nhưng chương trình không cần có hành động nào. Ví
dụ:
Cũng như C/C++, bất kì một giá trị khác 0 nào cũng tương đương với true và
ngược lại, một giá trị 0 tương đương với false. Như vậy:
if a != 0:
Trong đó def là từ khóa bắt buộc dùng để khai bó hàm, tiếp theo là tên hàm được
đặt theo qui cách đặt tên, và cuối cùng là danh sách đối số(nếu có).
Ví dụ:
def binhPhuong(x):
return x*x
Câu lệnh đầu tiên ngay sau khai báo tên hàm có thể là một chuỗi kí tự tùy ý
(string), được dùng để chỉ dẫn cho hàm (thường gọi là docstring).
Các tham số không cần xác định kiểu , Python sẽ tự xác định chúng dựa theo
giá trị được truyền khi gọi hàm.
Python không phân biệt truyền tham biến hay truyền tham trị khi mà bản thân
biến cũng không cần khai báo.
Ví dụ một hàm tính số Fibonacy
def fib(n):
print 'n =', n
if n > 1:
return n * fib(n − 1)
else:
print 'end of the line'
return 1
hoặc như sau: ( in ra dãy Fibonacci đến một giới hạn tùy ý)
>>> def fib(n): # write Fibonacci
series up to n
... """Print a Fibonacci series up to
n."""
... a, b = 0, 1
... while b < n:
... print b,
... a, b = b, a+b
...
>>> # Now call the function we just
defined:
... fib(2000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
610 987 1597
Do không có khai báo rõ ràng đầu hàm và kết thúc hàm ,chỉ có dấu : nên quy
cách viết hàm phải khá phụ thuộc vào cách thụt vào của các lệnh.
Ở đây def fib(n): là khai báo hàm , nó phải được thụt vào it nhất , các lệnh
tiếp theo nằm bên trong hàm do vậy phải thụt vào nhiều hơn, các lệnh print , if ,
else ngang hàng nhau, lệnh return n*fib(n-1) phải thụt vào nhiều hơn if...
Một định nghĩa hàm đưa tên hàm đó vào một bảng ký hiệu hiện thời. Giá trị
của tên hàm là một kiểu mà được thông dịch như là một hàm người sử dụng định
nghĩa. Giá trị đó có thể được đăng kí một tên khác mà nó cũng có thể sử dụng như
một hàm. Điều này như là một thao tác đổi tên hàm:
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
1 1 2 3 5 8 13 21 34 55 89
Khi hàm không xác định kiểu giá trị trả về (giống như hàm fib ở trên) nó ngầm
định trả về một giá trị gọi là None. Ta có thể xem giá trị này như sau:
Cũng rất đơn giản để viết một hàm trả về một danh sách chuỗi Fibonacci thay vì in
ra nó:
Nếu thoát khỏi trình thông dịch Python và vào lại nó, những định nghĩa
(các hàm và biến) đã viết sẽ bị mất. Vì thế, nếu muốn viết chương trình tồn tại
được lâu, tốt nhất là sử dụng một trình soạn thảo để viết một file làm đầu vào cho
trình biên dịch rồi chạy file đó. Cái này được gọi là một script (kịch bản). Hoặc
khi muốn sử dụng một hàm đã xây dựng trong một vài chương trình mà không
muốn copy định nghĩa của nó vào từng chương trình. Để hỗ trợ điều này, Python
có một cách đặt các định nghĩa hàm trong một file và sử dụng chúng như một kịch
bản hoặc trong một instance tương tác của trình thông dịch. Một file như vậy gọi
là một module. Các định nghĩa từ một module có thể được nhập vào một module
khác hoặc vào module chính (tập hợp các biến mà có thể truy nhập đến một script
được thi hành tại mức cao nhất và trong chế độ tính toán).
Một module là một file chứa các định nghĩa và câu lệnh Python. Tên file là
tên module với phần mở rộng là .py. Trong một module, tên của module (như là
một xâu) là sẵn có như giá trị của biến toàn cục __name__. Ví dụ, dùng trình soạn
thảo, soạn file fibo.py với nội dung như sau:
Bây giờ mở trình thông dịch Pyhton và nhập module này bằng lệnh dưới
đây:
Thao tác này không nhập tên của các hàm đã được định nghĩa trong fibo
trực tiếp vào trong bảng kí hiệu hiện thời; nó chỉ nhập tên của module fibo vào đó.
Sử dụng tên module này để có thể truy nhập vào các hàm:
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Để thuận tiện, một hàm trong module định sử dụng thường được đăng kí
với một tên cục bộ:
Một module có thể chứa các câu lệnh thực thi cũng như các định nghĩa hàm.
Các câu lệnh đó được dùng để khởi tạo module đó. Chúng được thực hiện chỉ lần
đầu tiên module đó được nhập.
PYTHONPATH không được thiết lập. Có thể sửa đổi nó sử dụng thao tác danh
sách chuẩn:
Sau đây là danh sách đầy đủ các module chuẩn đã xây dựng trong Python.
Một số module có kèm theo tên các nền tảng mà module đó được sử dụng:
__builtin__ distutils.emxccompiler ossaudiodev(Linux,
__future__ distutils.errors FreeBSD)
__main__ distutils.extension parser
_winreg(Windows) distutils.fancy_getopt pdb
aepack(Mac) distutils.file_util pickle
aetools(Mac) distutils.filelist pickletools
aetypes(Mac) distutils.log pipes(Unix)
aifc distutils.msvccompiler PixMapWrapper(Mac)
AL(IRIX) distutils.mwerkscompiler pkgutil
al(IRIX) distutils.spawn platform
anydbm distutils.sysconfig popen2(Unix, Windows)
applesingle(Mac) distutils.text_file poplib
array distutils.unixccompiler ………………..
asynchat distutils.util
Module math cung cấp các truy cập tới các hàm thư viện cơ bản của C đối với các
phép toán trên số thực
>>> import math
>>> math.cos(math.pi / 4.0)
0.70710678118654757
>>> math.log(1024, 2)
10.0
Module random cung cấp một cách thức để tạo ra sự lựa chọn ngẫu nhiên
>>> import random
>>> random.choice(['apple', 'pear', 'banana'])
'apple'
>>> random.sample(xrange(100), 10) # sampling without
replacement
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
>>> random.random() # random float
0.17970987693706186
>>> random.randrange(6) # random integer chosen from
range(6)
4
Sau đây, ta sẽ tìm hiểu về các hàm được xây dựng trong 2 module math và cmath.
Modul này luôn sẵn dùng. Nó cung cấp phương thức truy nhập các hàm toán học
được định nghĩa theo chuẩn C.
Module math cung cấp các hàm dưới đây. Tất cả đều trả về số thực ngoại trừ một
số trường hợp đặc biệt.
ceil(x)
Hàm trả về giá trị cận trên của số thực x, tương ứng với giá trị nguyên nhỏ
nhất lớn hơn x.
fabs x)
(
Giá trị tuyệt đối của x.
floor(x)
Hàm trả về giá trị cận dưới của số thực x, tương ứng với giá trị nguyên lớn
nhất nhỏ hơn x.
.
fmod(x, y)
Trả về fmod(x,y), được định nghĩa theo chuẩn thư viện C. Chú ý rằng trong
Python phép toán x % y có thể không trả về cùng một kết quả tương tự.
Thực tế trong chuẩn thư viện C thì fmod(x,y) trả về chính xác(phép toán, độ
chính xác vô hạn) bằng x-n*y với 1 vài số nguyên n có cùng kết quả với
dấu của x và độ lớn trị tuyệt đối của y. Trong khi đó, đối với Python thì
phép toán x % y trả về kết quả là bao gồm cả dấu của y, và nó ko thểước
tính chính xác cho các đối số thực.Ví dụ, fmod(-1e-100,1e100) là -1e-100,
nhưng kết quả của -1e-100 % 1e100 là -1e-100,điều này không thể đưa ra
kết quả chính xác đối với số thực, và làm tròn 1e100. Chính vì nguyên
nhân này, hàm fmod() thường được ưu tiên khi làm việc với số thực, với x
% y trong Python thì được ưu tiên với số nguyên.
frexp(x)
Trả về phần định trị và số mũ của x dưới dạng (m,e). m có giá trị thực còn e
là số nguyên với x == m*2**e. Nếu x = 0, kết quả là (0.0,0), còn 0.5 <=
abs(m) < 1.
ldexp(x, i)
Trả về x * (2 ** i). Là hàm ngược của hàm frexp().
modf(x)
Trả về phần phân số và phần nguyên của x. Cả hai đều mang dấu của x
và đều có giá trị thực.
Chú ý rằng frexp() và modf() có kiều gọi/ trả về khác nhau tương
đương như trong C: Chúng lấy đối số đơn và trả về cặp giá trị, đúng hơn là
sự trả về giá trị thứ 2 thông qua “tham số ra”( không có những điều như vậy
trong Python).
Đối với các hàm ceil(), floor() và modf(), chú ý là không phải tất cả
các số thực có giá trị lớn đều chính xác là số nguyên. Số thực trong Python
có độ chính xác không vượt quá 32 bít( giống với kiểu Double trong C),
trong trường hợp giá trị thực x có abs(x) >=2**52 thì tất nhiên sẽ không có
các bít phân số.
Các hàm mũ và logarit:
exp(x)
Trả về e**x
log(x[,
base])
Trả về logarit của x với cơ số đưa ra là base. Nếu không đưa cơ cố base, thì
tự động trả về logarit tự nhiên của x( logarit với cơ số e).
log10(x)
Trả về logarit cơ số 10 của x.
pow x, y)
(
Trả về x ** y
sqrt(x)
Trả về căn bậc 2 của x.
Các hàm lượng giác:
acos(x)
Trả về arc coosin của x theo radian.
asin(x)
Trả về arc sin của x theo radian
atan(x)
Trả về arc tang của x theo radian
atan2(y, x)
Trả về atan(y/x) theo radian. Kết quả nằm trong khoảng từ -pi đến pi.
Vector trong mặt phẳng từ điểm gốc tọa độ tới điểm có tọa độ (x,y) tạo một
góc với trục tọa độ X . Điểm của atan2() mà dấu của cả hai đầu vào được
biết đến nó, vì vậy nó có thể tính toán chính xác độ của góc. Ví dụ, atan(1)
và atan2(1,1) đều bằng pi/4 nhưng atan2(-1,-1) lại bằng –pi/4.
cos(x)
Trả về giá trị cosin của x
hypot(x, y)
Trả về dạng Oclit của sqrt(x*x+y*y).Đây là độ dài véc tơ từ gốc tọa độ tới
điểm có tọa độ (x,y).
sin(x)
Trả về sin của x theo radian
tan(x)
Trả về tang của x theo radian.
degrees(x)
Chuyển góc x từ radian sang độ.
radians(x)
Chuyển góc x từ độ sang radian.
cosh(x)
Trả vè hyperbolic cosin của x.
sinh(x)
Trả về hyperbolic sin của x.
tanh(x)
Trả về hyperbolic tang của x.
pi
Sốpi = 3.14159265358979….
e
Sốe.
b. Các hàm toán học cho số phức trong module cmath:
Module này cung cấp cách truy nhập vào các hàm toán học cho số phức. Các
hàm này gồm có:
acos(x)
Trả về arccos của x. Có 2 miền được chọn: 1 miền kéo dài về phía phải từ 1
liên tục tới ∞. Miền còn lại kéo dài về phía trái từ -1 liên tục tới -∞.
acosh(x)
Trả về hypedolic arccos của x. Chỉ có một miền được lấy ra, kéo dài về
phía trái từ 1 liên tục cho tới -∞.
asin(x)
Trả về arcsin của x.Có dải giá trị cũng giống như arccos().
asinh(x)
Trả về hyperbolic arcsin của x. Có 2 miền giá trị được lấy ra, kéo dài liên
tục về bên trái từ ±1j tới ±-∞j. Những miền này cần tính toán đến các lỗi để
chính xác hơn. Miền chính xác được lấy ra sẽ mở rộng theo trục ảo, một
liên tục từ 1j tới ∞j từ phía phải và một liên tục từ -1j tới -∞j từ phía trái.
atan(x)
Trả về arc tang của x. Có 2 miền được lấy ra: Một kéo dài liên tục từ 1j
theo trục sốảo tới ∞j từ phía trái. Miền khác kéo dài liên tục từ -1j dọc theo
trục sốảo tới ∞j từ phía trái.( Điều này sẽ chắc chắn thay đổi vì với miền
cao hơn sẽ liên tục từ nhiều phía khác).
atanh(x)
Trả về hyperbolic arc tang của x. Có 2 miền giá trị được lấy ra: Một kéo dài
liên tục từ 1 dọc theo trục số thực tới ∞. Miền còn lại kéo dài liên tục từ -1
dọc theo trục số thực tới -∞.( Điều này chắc chắn sẽ bị thay đổi vì miền
phải lấy ra trở nên liên tục từ phía khác)
cos(x)
Trả về cosin của x.
cosh(x)
Trả về hyperbolic cosin của x.
exp(x)
Trả về giá trị mũ e**x.
log(x[,
base])
Trả về logarit của x với cơ số là base. Nếu base ko được đưa ra, trả về giá
trị logarit tự nhiên của x. Có một miền được lấy ra, từ 0 dọc theo miền âm
trục số thực tới -∞. Được thay đổi trong phiên bản 2.4 : đối số base được
thêm vào.
log10(x)
Trả về logarit cơ số 10 của x. Có miền tương tự như hàm log()
sin(x)
Trả về sin của x.
sinh(x)
Trả về hyperbolic sin của x.
sqrt(x)
Trả về căn bậc 2 của x. Miền được lấy ra tương tự như hàm log().
tan(x)
Trả về tang của x.
tanh(x)
Trả về hyperbolic tang của x.
6. Nén dữ liệu
Các định dạng nén và lưu trữ dữ liệu phổ biến được hỗ trợ trực tiếp bởi rất nhiều
thủ tục, bao gồm:zlib,gzip,bz2,zipfile và tarfile. Ví dụ:
1. File Input
Python có các kiểu file được cài sẵn. Các file có thể mở bằng cách sử dụng hàm
xây dựng kiểu file:
f = file('test.txt', 'r')
Điều này có nghĩa là file f được mở để đọc. Đối số đầu tiên là tên file và đối
số thứ 2 là chế độ mở file, bao gồm, ‘r’, ‘w’ hoặc ‘rw’
Cách phổ biến nhất để đọc một file là lặp lại tuần tự cho đến hết file:
f = open('test.txt', 'r')
for line in f:
print line[0]
f.close()
c = f.read(1)
while len(c) > 0:
if len(c.strip()) > 0: print c,
c = f.read(1)
Đoạn mã này sẽ lặp lại việc đọc một số kí tự từ file f, và in ra chúng nếu
chúng không phải là kí tự khoảng trắng
Một đối tượng file hoàn toàn chứa một dấu hiệu để mô tả vị trí hiện thời của
con trỏ file.
Con trỏ file sẽ di chuyển từ đầu file, có thể dùng phương thức seek để dịch
chuyển con trỏ file, ví dụ:
f.seek(0)
2. Output
Python sử dụng cách thức cơ bản nhất để xuất dữ liệu là dùng câu lệnh print.
print 'Hello, world'
Để in ra nhiều thứ trên cùng một dòng, ta sử dụng dấu phẩy giữa chúng, ví dụ:
print 'Hello,', 'World'
sẽ in ra như sau: Hello, World
Chú ý rằng mặc dù xâu không chứa khoảng trống, nó cũng được thêm vào bởi lệnh
print bởi vì dấu , giữa 2 đối tượng. Các kiểu dữ liệu tùy ý có thể được in theo cách
này:
print 1,2,0xff,0777,(10+5j),-0.999,map,sys
sẽ in ra :
1 2 255 511 (10+5j) -0.999 <built-in function map>
<module 'sys' (built-in)>
Các đối tượng có thể in trên cùng một dòng không cần viết trên một dòng mà chỉ
cần đặt một dấu , ở cuối của lệnh print
for i in range(10):
print i,
sẽ in ra:
0 1 2 3 4 5 6 7 8 9
Để kết thúc một dòng, cần thêm vào một lệnh print mà không có đối tượng nào, ví
dụ:
for i in range(10):
print i,
print
for i in range(10,20):
print i,
sẽ in ra: 0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
Nếu không có câu lệnh print trống thì nó sẽ in ra trên cùng một dòng
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Nếu không muốn in một dòng mới hoặc một khoảng trống ( khi sử dụng dấu , ở
cuối), ta có thể làm một điều khiển ngắn với sys.stdout.write và sử dụng để xuất
ra:
import sys
write = sys.stdout.write
write('20')
write('05\n')
sẽ in ra:
2005
Những cú pháp như trên có thể sử dụng khi viết vào file thay vì đến thiết bị ra
chuẩn, ví dụ:
print >> f, 'Hello, world'
Cái này sẽ được in trong bất kì đối tượng nào mà thi hành hàm write()
trong đó có đối tượng file.
Có khá nhiều các bộ lập trình giao diện với Python. Sau đây ta sẽ tìm hiểu
tổng quan về chúng.
1. Tkinter:
Đây là một công cụ lập trình giao diện Python cho Tcl/Tk, được đưa vào
Python (chạy trên nền Win32 mặc dù nó có thể được cài trên Unix/Linux hoặc
Mac) và cung cấp một giao diện người sử dụng. Không phải là đơn giản để học
cách sử dụng bộ công cụ mạnh này, nó cung cấp những thứ xuất hiện như là một
tập hợp các cửa sổ. Tuy nhiên, bởi vì các cửa sổ Tkinter có thể mở rộng, nhiều
cửa sổ được tạo ra khá dễ dàng. Tkinter được thiết kế như là một giao diện người
sử dụng do yêu cầu thực tế cho Python.
Để tạo ra một một khung cửa sổ đơn giản trong Tkinter chỉ cần làm như
đoạn code sau:
import Tkinter
root = Tkinter.Tk()
root.mainloop()
gfd From an object-oriented perspective one can do the
following:
import Tkinter
class App:
def __init__(self, master):
button = Tkinter.Button(master, text="I'm a Button.")
button.pack()
if __name__ == '__main__':
root = Tkinter.Tk()
app = App(root)
root.mainloop()
2. PyGTK
PyGTK cung cấp một công cụ thuận tiện cho GTK cộng với các thư viện sử
dụng trong các chương trình Python. Quan tâm đến nhiều chi tiết như quan lí bộ
nhớ và thay thế. Khi kết hợp với PyORBit và gnome-python, nó có thể được sử
dụng để viết các ứng dụng Gnome với đầy đủ các đặc điểm.
3. PyQt:
Sử dụng phổ biến trên Unix/Linux và các bộ công cụ Windows. PyKDE có
thể được sử dụng để viết các ứng dụng dựa trên KDE.
4. wxPython
Gắn với bộứng dụng wxWidgets, nó có thể chạy trên Windows, Macintosh,
và Unix/Linux.
1. Python Documentation
2. Python_Programming.pdf
3. website: http://www.python.org
4. website: http://en.wikipedia.org/wiki/Python_programming_language
5. website: http://pythonnet.sourceforge.net/readme.html
Cơ bản về Shell
A. Giới thiệu chung
1. Giới thiệu về shell
Khi chúng ta muốn thực hiện một lệnh nào đó trong hệ điều hành Unix chúng ta
cần phải ra
lệnh để Unix hiểu đ−ợc chúng ta muốn làm gì. Việc ra lệnh này đ−ợc thực hiện
qua shell. Nh−
vậy chúng ta có thể hiểu một cách đơn giản shell là giao diện để giao tiếp giữa
ng−ời sử dụng
và Unix. Shell nhận lệnh từ ng−ời sử dụng sau đó dịch và chuyển đến hệ thống
những hoạt
động cần thực hiện để đáp ứng yêu cầu.
Hiện nay có một số loại shell trong các hệ thống Unix, trong một số tr−ờng hợp
trong một
hệ thống nào đó có thể có một hoặc nhiều shell cùng tồn tại. Một số loại phổ biến
đang tồn tại
nh−: Bourne shell, Korn shell, C shell, ... Mỗi loại có sự khác nhau nh−ng tất cả
đều cung cấp
đầy đủ công cụ để thiết lập môi tr−ờng giao tiếp giữa ng−ời sử dụng và Unix.
2. Mục đích của shell
Shell có 3 mục đích chính nh− sau:
- T−ơng tác (interactive use)
- Đặt biến môi tr−ờng đối với mỗi ng−ời sử dụng
- Lập trình
T−ơng tác
Tr−ờng hợp đ−ợc coi là đơn giản khi sử dụng shell, shell đợi ng−ời sử dụng gõ các
lệnh tại
dấu nhắc, sau đó gửi tới hệ thống yêu cầu từ lệnh nhận đ−ợc.
Đặt biến môi tr−ờng đối với mỗi ng−ời sử dụng
Unix shell xác định các biến để điều khiển môi tr−ờng của ng−ời sử dụng đối với
mỗi
phiên sử dụng. Việc đặt các biến này sẽ xác định với hệ thống những tham số nh−
th− mục
nào sẽ đ−ợc sử dụng làm th− mục chính, nơi đặt mail, những th− mục nào đ−ợc sử
dụng mặc
định khi bạn gọi đến các lệnh Unix, ... Một số biến hệ thống có thể đ−ợc đặt trong
tệp khởi
động (start-up file) và đ−ợc đọc khi bạn login (đăng nhập). Trong tệp khởi động
bạn có thể đặt
các lệnh của Unix, nh−ng chú ý là những lệnh này sẽ đ−ợc thực hiện mỗi khi bạn
login.
Lập trình
Shell cung cấp tập hợp các lệnh đặc biệt mà từ đó có thể tạo nên những ch−ơng
trình, khi
đó đ−ợc gọi là shell script. Trong thực tế hầu hết các lệnh này có thể sử dụng trong
của sổ
lệnh của Unix và ng−ợc lại, các lệnh của Unix đều có thể viết trong shell script.
Shell script
rất tiện lợi trong việc gộp nhiều lệnh độc lập vào một và thực hiện nhiều lần.
Ngoài những lệnh đơn giản của hệ thống Unix, shell còn đ−ợc bổ sung thêm các
cấu trúc
phức tạp nh− điều khiển rẽ nhánh (if/case), vòng lặp (for/while).
VietHung soft group - viethung_group@email.com
Một tệp ch−ơng trình của shell không quan trọng đến tên và đuôi, không cần dịch
cũng nh−
không có môi tr−ờng phát triển. Việc soạn thảo một tệp shell có thể sử dụng bất kỳ
một công
cụ soạn thảo nào, chỉ cần ghi tệp đó với dạng text, sau đó đổi thành dạng tệp có thể
chạy
đ−ợc. Xem ví dụ 1 trong phần sau để hiểu thêm chi tiết.
Shell luôn gắn liền với hệ điều hành Unix, nh−ng để hiểu và học shell không nhất
thiết bạn
cần hiểu sâu về hệ thống cũng nh− các lệnh của Unix. Tuy nhiên thông qua những
ví dụ
chúng tôi nêu ở đây các bạn có thể hiểu thêm cách sử dụng lệnh và biến hệ thống.
Chú ý: Chúng tôi chỉ nhắc đến hệ điều hành Unix khi giới thiệu cũng nh− h−ớng
dẫn sử dụng,
nh−ng thực tế hiện nay Linux là một hệ điều hành kế thừa của Unix. Linux cũng
có những
shell t−ơng tự và bạn có thể sử dụng những giới thiệu về shell ở đây với các hệ
thống Linux.
3. Những loại shell hiện thời
Hiện nay có khá nhiều loại shell đ−ợc sử dụng trong các hệ thống Unix, nh−ng ở
đây chúng
tôi chỉ đề cập đến 3 loại cơ bản và phổ biến, đó là:
- Bourne shell, đ−ợc coi là shell chuẩn, cô đọng và là loại đơn giản nhất.
- Korn shell, cao cấp hơn Bourne shell và cho phép soạn dòng lệnh.
- C shell, sử dụng cú pháp của ngôn ngữ lập trình C và có thêm nhiều chức năng
tiện lợi.
Thông th−ờng các hệ thống có ít nhất là một loại shell và thông th−ờng Bourne
shell đ−ợc sử
dụng để viết shell script, còn sử dụng một loại khác cho việc t−ơng tác.
Tệp /etc/passwd sẽ xác định loại shell nào sẽ đ−ợc sử dụng mặc định trong hệ
thống cho
mỗi phiên làm việc của bạn. Trong phần cuối của dòng chứa tên bạn, bạn có thể
tìm thấy
thông tin về loại shell nào đ−ợc sử dụng. Mỗi khi bạn login, hệ thống sẽ đọc tệp
này để lấy
thông tin khởi tạo cho shell.
Thông tin có thể gồm một trong những dạng sau:
/bin/sh Bourne shell
/bin/jsh Bourne shell, có thêm phần điều khiển tác vụ (job control)
/bin/ksh Korn shell
/bin/csh C shell
Bạn có thể thay đổi shell mặc định sang một loại khác bằng cách sử dụng lệnh:
Ví dụ chuyển từ Bourne shell sang C shell:
exec csh
hoặc có thể đổi shell mới bằng lệnh:
chsh [<tên shell>]
Cấu trúc lệnh chsh nh− sau:
chsh [-s <tên shell>] [ -l ] [<tên ng−ời>]
chsh -l liệt kê các loại shell hiện có (thông tin chứa trong tệp /ect/shells).
Trong phần tiếp theo, chúng tôi sẽ giới thiệu về Bourne shell, loại tiêu chuẩn, đơn
giản và
phổ dụng nhất hiện nay trong các hệ thống Unix.
VietHung soft group - viethung_group@email.com
B. Bourne shell
1. In một dòng chữ ra màn hình
Ví dụ 1: Bạn tạo ra một tệp với tên vidu1, sau đó gõ vào những dòng sau:
#!/bin/sh
#vi du dau tien
echo .Vi du dau tien voi shell..
Bạn có thể sử dụng vi, emacs, .. để soạn thảo tệp trên. Sau đó dùng lệnh chmod để
chuyển tệp
vidu1 thành tệp có thể chạy đ−ợc, lệnh đó nh− sau:
chmod +x thidu1
Để chạy thử bạn chỉ việc gõ: vidu1 <enter>
Việc tạo và dùng chmod đều cần thực hiện đối với mỗi tệp sau khi tạo ra và cần
chuyển thành
tệp chạy đ−ợc, chúng tôi sẽ không nhắc lại về sau nữa. Nh−ng đối tệp đ∙ đ−ợc
chuyển mod
một lần thì không cần làm lại khi thay đổi nội dung hay đổi tên.
Giải thích:
- Dòng đầu tiên là dòng đặc biệt, dùng để xác định loại shell đ−ợc sử dụng và gọi
ch−ơng
trình thông dịch shell t−ơng ứng.
- Dòng thứ hai bắt đầu bằng dấu # để chỉ một dòng chú thích.
- Lệnh echo dùng để in ra màn hình xâu ký tự hay các biến, echo có cấu trúc nh−
sau:
echo [-n] [xâu ký tự]
Nếu có chức năng -n, con trỏ không bị ngắt xuống dòng sau khi in xâu ký tự.
Ngoài ra, bên trong xâu xâu ký tự các bạn còn có thể sử dụng một số chức năng
khác nh−:
\b lùi lại một ký tự (backspace).
\c không xuông dòng (nh− -n).
\n xuống dòng.
\t in ra ký tự tab.
\\ in ra ký tự \.
\0n in ra ký tự có số n (số thập phân) trong bảng m∙ ASCII.
Các bạn có thể in ra những ký tự đặc biệt bằng cách đặt sau ký tự \, ví dụ: \. để in
ký tự
nháy kép (.) ra màn hình.
Ví dụ:
echo .\.Thong bao co loi! \., \c \007.
2. Thực hiện các lệnh hệ thống
Ví dụ 2: Ví dụ thực hiện một lệnh của hệ thống.
#!/bin/sh
#vi du 2
echo
VietHung soft group - viethung_group@email.com
echo .Danh sach cac thu muc va tep:.
ls .l
echo
echo .Vi tri hien thoi: .‘pwd‘
Trong đó lệnh ls -l là một lệnh của hệ thống đ−ợc thực hiện mà không cần gõ từ
dấu nhắc.
Ngoài ra tất cả các lệnh và tham số khác của hệ thống đều có thể đ−ợc thực hiện
một cách
t−ơng tự, ví dụ nh−: cd, cp, mkdir, chmod, cat, ...
3. Biến và tham số hệ thống
Cũng nh− các ngôn ngữ lập trình, shell có thể sử dụng biến nh−ng không cần khai
báo và
định nghĩa kiểu. Các tham số của môi tr−ờng và hệ thống có thể sử dụng trực tiếp
bằng tên.
Tên của các tham số th−ờng là một cái tên, một ký tự, số hay một trong các ký
hiệu *, @, #,
?, -, $, !\^.
Ví dụ 3: Ví dụ về dử sụng tham số hệ thống.
#!/bin/sh
#Vi du 3
nháy đơn (.) thì sẽ in ra y nguyên nh− trong dòng văn bản. Thông th−ờng dấu nháy
đơn ít
đ−ợc sử dụng nh−ng lại rất tiện lợi khi muốn in y nguyên một dòng văn bản, đặc
biệt là khi có
các ký tự đặc biệt nh− $, \.
6. Các cấu trúc phức tạp
Nh− đ∙ giới thiệu, ngoài những lệnh đơn giản nh− đọc, in ra màn hình và thực hiện
các lệnh
hệ thống, shell còn hỗ trợ việc sử dụng các lệnh phức tạp hơn nh− if-then-else,
for/while.
Phần d−ới đây chúng tôi sẽ giới thiệu đến những cấu trúc này.
6.1 Cấu trúc vòng lặp: for
Cấu trúc vòng lặp for đ−ợc xây dựng nh− sau:
for <biến ký tự> in <xâu>
do
<các lệnh cần thực hiện>
done
Qua ví dụ d−ới đây bạn có thể hiểu rõ hơn cấu trúc vòng lặp for.
Ví dụ 5: Ví dụ về vòng lặp for.
#!/bin/sh
#Vi du 5
VietHung soft group - viethung_group@email.com
word= "abcde" # khởi tạo một xâu
dem = 0 # khởi tạo biến count
for letter in $word # vòng lặp với biến letter
do # lệnh bắt đầu vòng lặp
count=‘expr $count + 1‘ # tăng biến count lên 1
echo "Letter $count is [$letter]" # in ra biến letter
done # lệnh kết thúc vòng lặp
Có thể giải thích nh− sau: với mỗi letter trong word thì thực hiện những lệnh
nằm trong dodone,
trong ví dụ trên bao gồm tăng biến count và in biến letter ra màn hình.
Chú ý: Trong ví dụ trên có dùng lệnh expr để gọi lệnh thực hiện tính toán của hệ
thống tính
phép cộng tr−ớc khi gán vào biến count.
6.2 Cấu trúc vòng lặp: while
Cấu trúc của vòng lặp while đ−ợc thể hiện nh− sau:
while [ <điều kiện> ]
do
<các lệnh>
done
Ví dụ 6: Ví dụ về vòng lặp while.
#!/bin/sh
#Vi du 6
word= "abcde" # khởi tạo một xâu
dem = 0 # khởi tạo biến count
while [ $count .lt 5 ] # vòng lặp với biến letter
do # lệnh bắt đầu vòng lặp
count=‘expr $count + 1‘ # tăng biến count lên 1
echo "Letter $count is [$letter]" # in ra biến letter
done # lệnh kết thúc vòng lặp
Các bạn có thể thấy ngay cấu trúc hai vòng lặp trên gần hoàn toàn giống nhau, chỉ
khác
dòng for/while. Trong ví dụ trên, $count -lt 5 đ−ợc coi là điều kiện của vòng lặp.
Phép so
sánh .-lt. là phép so sánh .nhỏ hơn hoặc bằng. (less-than) trong lệnh test của
Unix/Linux.
Lệnh kiểm tra điều kiện trên sẽ trả ra giá đúng (1) trị hoặc sai (0) để thực hiện tiếp
hay thoát
khỏi vòng lặp.
Ngoài phép so sánh .-lt" còn có -gt-lớn hơn, -eq-bằng, -ne-không bằng. Trong
phần phụ
lục chúng tôi có liệt kê lại các lệnh, tham số và phép toán của shell, các bạn có thể
đọc để biết
thêm các phép toán khác.
VietHung soft group - viethung_group@email.com
Chú ý: Trong phần điều kiện của vòng lặp while cũng nh− trong những điều kiện
khác, sau
dấu .[. và tr−ớc dấu .]. bắt buộc phải có dấu trắng (dấu cách).
6.3 Cấu trúc vòng lặp: until
Chúng ta có thể hiểu vòng lặp until t−ơng tự nh− while. Cấu trúc của vong lặp
until nh− sau:
until [ <điều kiện> ]
do
<các lệnh>
done
6.4 Cấu trúc rẽ nhánh: if - else
Cấu trúc rẽ nhánh có thể đ−ợc hiểu qua các từ khóa có cấu trúc nh− sau:
if [ <điều kiện> ]
then
<lệnh>
[ elif <lệnh> then <lệnh> ] ...
[ else <lệnh> ]
fi
Đối với cấu trúc này có hai dạng, đơn giản và phức tạp. Sau đây chúng tôi sẽ giới
thiệu hai
read b
echo .Nhap so c: .
read c
if [ $a .lt $c ] && [ $b .lt $c ] #xem c có lớn nhất không
then
echo .so c là so lon nhat..
fi
Trong ví dụ trên, && (và) là dấu kiểm tra kép để kết hợp hai điều kiện. Ta có thể
hiểu điều
kiện sau if nh− sau: .Nếu a nhỏ hơn c và b nhỏ hơn c thì .... Ngoài ra còn có || (...
hoặc ...).
#!/bin/sh
#Vi du 8b
if [ -f $dir/$file ] || [ -f $dir/$newfile ]
then
echo "Hoac tep [$file] "
echo "hoac tep moi [$newfile] da ton tai"
VietHung soft group - viethung_group@email.com
elif [ -d $dir ]
then
echo "Duong dan [$dir] da ton tai"
else
echo "Ca duong dan [$dir], tep [$file va tep moi $newfile]
deu khong ton tai"
fi
6.5 Cấu trúc rẽ nhánh nhiều tr−ờng hợp: case
Cấu trúc case có thể đ−ợc hiểu qua tập các từ khóa sau:
case <biến>
in
biến-1)
<lệnh>
biến-2)
<lệnh>
biến-3)
<lệnh>
...
*) #còn lại
exit
esac
Ví dụ 9: Ví dụ về case đối với tham số đầu vào của một tệp ch−ơng trình.
#!/bin/sh
#Vi du 9
size=0
page=200
option = ..
while [ "$1" != "" ]
do
case $1
in
-?) echo .Su dung cac tham so .l,-p,-s..
exit;;
-l) line = 50
page = 500
option = .$option page[$page] line[$line] .
shift;;
-p) line = 40
VietHung soft group - viethung_group@email.com
option = .$option page[$page] line[$line] .
shift;;
-s) size = 10;
shift 2;;
*) echo "Tham so vao khong co trong [p, l, s]";
exit;;
esac
if [ $size = 0 ]
then
size=‘echo "$page / $lines" | bc‘
else
lines=‘echo "$page / $size" | bc‘
fi
done
echo .$option $lines $size.
Trong ví dụ trên đ∙ đ−a ra cách sử dụng cấu trúc case, đồng thời giới thiệu cách
nhận và xử
lý tham số đầu vào khi chạy một tệp shell script. Lệnh shift là lệnh dịch tham số
đầu vào sang
trái 1 để thực hiện các tham số tiếp theo. Đặc biệt trong đó còn chỉ cách gọi máy
tính số với
số cần tính đ−ợc đ−a vào tr−ớc.
6.6 Hàm
Shell hỗ trợ khai báo và sử dụng hàm con, đây là một hỗ trợ rất hữu ích nh−ng cần
phải khai
báo trong phần khởi động của ng−ời sử dụng, cụ thể là trong tệp .profile.
Một ví dụ đơn giản:
uppercase()
{
echo $1 | tr ’abcdefghijklmnopqrstuvwxyz’ \
’ABCDEFGHIJKLMNOPQRSTUVWXYZ’
}
Hàm trên dùng để sử dụng lệnh tr của hệ thống nhằm chuyển các chữ th−ờng
thành chữ hoa.
Việc gọi hàm trên chỉ cần viết:
uppercase .thu chuyen doi.
hoặc
smallword = .thu chuyen doi.
uppercase .$smallword.
Nh−ng nh− đ∙ nói về sự khác biệt của kết quả trong dấu nháy kép, kết quả của hai
dòng lệnh
sau:
largeword = ‘uppercase .$smallword.‘
VietHung soft group - viethung_group@email.com
largeword = ‘uppercase $smallword‘
là khác nhau. Dòng thứ nhất trả ra: .THU CHUYEN DOI., còn dong thứ hai se tra
ra:
.THU..
7. Làm việc với các tệp
Trong ví dụ 7b chúng tôi đ∙ giới thiệu cách kiểm tra sự tồn tại của một tệp hay môt
đ−ờng dẫn
nên trong phần này sẽ không đề cập đến nữa mà chỉ đ−a ra cách đọc và ghi một
tệp.
#!/bin/sh
#Vi du dem so tep trong thu muc
count=1
for file in ‘ls -1 *‘
do
echo "$count: $file" >> $mnu0
count=‘expr $count + 1‘
done
#Vi du doc va ghi tu tep inputfile sang tep outputfile
filelength=‘wc -l $inputfile | cut -c1-8‘
filelength=‘expr $filelength + 0‘
while $filelength
do
line=‘tail -$filelength $inputfile | head -1‘
words=‘s_count_args $line‘
echo "$line = $words words" >> $outputfile
file_length=‘expr $filelength - 1‘
done
Trong ví dụ trên có sử dụng một vài kỹ thuật nh− đọc phần cuối của tệp đầu vào
(với lệnh
tail)sau đó lại lấy dòng đầu của đoạn đó (với lệnh head -1) để lấy ra đ−ợc từng
dòng từ trên
xuống của tệp đầu vào. Hai tham số -c1-8 của lệnh wc dùng để bỏ phần tên tệp
trong kết quả
liệt kê số dòng trong tệp đó. Ngoài ra, các bạn có thể dùng lệnh:
Cat >> <tên tệp> <<-EOA
để tạo ra một tệp tr−ớc với tên trong <tên tệp>.
8. Tìm hiểu lệnh test
test là lầ lệnh kiểm tra sự tồn tại của các tệp, th− mục và so sánh biến số. Cấu trúc
của lệnh
test nh− sau:
test <điều kiện>
hoặc [<điều kiện>]
VietHung soft group - viethung_group@email.com
Có các tham số nh− sau:
Điều kiện với các tệp, th− mục:
-f <tên> sự tồn tại của tệp thông th−ờng.
-d <tên> sự tồn tại của th− mục.
-c <tên> sự tồn tại tệp dạng ký tự.
-r <tên> sự tồn tại và có thể đọc đ−ợc.
-s <tên> sự tồn tại và có kích th−ớc lớn hơn 0.
-w <tên> sự tồn tại và có thể ghi đ−ợc.
-x <tên> sự tồn tại và có thể chạy đ−ợc.
Điều kiện với các xâu ký tự:
-n s1 xâu s1 có độ dài lớn hơn 0.
-z s1 xâu s1 có độ dài bằng 0.
s1 = s2 hai xâu s1 và s2 giống nhau.
s1 != s2 hai xâu s1 và s2 không giống nhau.
s1 < s2 xâu s1 đứng tr−ớc xâu s2 theo thứ tự của bảng m∙ ASCII.
s1 > s2 xâu s1 đứng sau xâu s2 theo thứ tự của bảng m∙ ASCII.
string biến string không rỗng (not null).
Điều kiện với các số:
n1 -eq n2 so sánh bằng.
n1 -ge n2 so sánh lớn hơn hoặc bằng.
n1 -gt n2 so sánh lớn hơn.
n1 -le n2 so sánh nhỏ hơn hoặc bằng.
n1 -lt n2 so sánh nhỏ hơn.
n1 -ne n2 so sánh không bằng.
Ví dụ:
if test $# -gt 0 nếu có tham số
if [ -n .$1. ] nếu tham số khác trống
if [ $count -lt 5 ] nếu giá trị của biến count nhỏ hơn 5
Phụ lục
Danh sách phép toán, lệnh và tham số mô tr−ờng
$0 tên tệp đang đ−ợc thực hiện
$1 tham số thứ nhất
$2 tham số thứ hai
...
$# số tham số
$@ liệt kê tất cả các tham số
$$ chỉ số của process
VietHung soft group - viethung_group@email.com
$- cờ (flag)
+ phép cộng
- phép trừ
* phép nhân
/ phép chia
% phép lấy phần d−
== so sánh bằng
!= so sánh không bằng
< so sánh nhỏ hơn
> so sánh lớn hơn
>= so sánh lớn hơn hoặc bằng
<= so sánh nhỏ hơn hoặc bằng
| | hoặc
&& và
$USER tên ng−ời sử dụng hiện tại
echo in ra màn hình
read đọc từ bàn phím
$HOME/$home th− mục chính của ng−ời dùng hiện tại
$dir
$path
- Ncurses là bộ thư viện tạo môi trường lập trình ứng dụng, trên đó lập trình viên có thể
quản lý và phát triển các ứng dụng GUI-like (cái này dịch ra tiếng Việt khó sát nghĩa, tạm
hiểu là tựa môi trường đồ họa, để dễ liên tưởng thì có thể hiểu nó là đồ họa trên shell).
Nói chung là nó có ứng dụng trong nhiều trường hợp bởi ưu điểm của một chương trình
GUI-like là có được giao diện đồ họa và nhẹ hơn các ứng dụng thuần đồ họa khác.
Code:
$ tar xvzf ncurses-5.7.tar.gz
$ cd ncurses-5.7
$ ./configure
$ make
Code:
#include <ncurses.h>
int main()
{
initscr(); /*Khởi động chế độ ncurses */
printw("Hello World !!!"); /*In ra "Hello World!!!"
(chưa hiện ra màn hình!) */
refresh(); /* Hiện "Hello World!!!" ra màn
hình thật */
return 0;
}
Tóm lại:
- Khai báo ncurses.h trước khi sử dụng.
- Khi không sử dụng nữa phải khai báo bằng hàm endwin()
- Hàm printw() trong ncurses.h được thay thế hàm printf() của stdio.h
[code]
#include <stdio.h>
#include <ncurses.h>
#define WIDTH 30
#define HEIGHT 10
int startx = 0;
int starty = 0;
char *choices[] = {
"Choice 1",
"Choice 2",
"Choice 3",
"Choice 4",
"Exit",
};
int n_choices = sizeof(choices) / sizeof(char *);
void print_menu(WINDOW *menu_win, int highlight);
int main()
{ WINDOW *menu_win;
int highlight = 1;
int choice = 0;
int c;
initscr();
clear();
noecho(); /* Đánh vào chữ gì cũng không hiện ra màn hình! */
clrtoeol();
refresh();
getch();
endwin();
return 0;
}
x = 2;
y = 2;
box(menu_win, 0, 0);
for(i = 0; i < n_choices; ++i)
{ if(highlight == i + 1) /* Làm sáng ô đang chọn */
{ wattron(menu_win, A_REVERSE);
mvwprintw(menu_win, y, x, "%s", choices[i]);
wattroff(menu_win, A_REVERSE);
}
else
mvwprintw(menu_win, y, x, "%s", choices[i]);
++y;
}
wrefresh(menu_win);
}
Giải thích:
- Hàm cbreak(): Thông thường những gì ta đánh trên màn hình sẽ được lưu vào bộ
đệm tới khi nào có tín hiệu kết thúc (ví dụ phím Enter được ấn!). Tuy nhiên nhiều
chương trình yêu cầu mỗi khi một phím được ấn thì sẽ nhập vào luôn. Đó là nguyên
nhân sinh ra hàm cbreak(). Có một hàm tương tự là hàm raw(), sự khác nhau giữa hai
hàm này chỉ là khi ta tạm dừng (Ctrl+Z) hoặc ngắt chương trình rồi quit (Ctrl+C). Với
hàm raw() thì quit không để dấu vết gì (không gửi bất cứ tín hiệu gì tới trình điều
khiển chương trình), còn cbreak() lại gửi trước khi treo hoặc quit!
- Hàm keypad(): Khởi tạo chế đọc phím được ấn từ bàn phím.
- Hàm mvprintw(<tọa độ y>, <tọa độ x>, <chuỗi ký tự cần cho ra màn hình>): Cái
này thì đơn giản rồi, đoán được.
- Hàm wattron(<con trỏ kiểu WINDOW>,<thuộc tính>) Đặt thuộc tính cho một
WINDOW, các thuộc tính được liệt kê dưới đây: